Merge pull request #1282 from behana/master
Add send-verify-email endpoint to admin-rest-api
This commit is contained in:
commit
f9d51db182
3 changed files with 192 additions and 35 deletions
|
@ -12,6 +12,7 @@ import javax.ws.rs.POST;
|
|||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -49,6 +50,18 @@ public interface UserResource {
|
|||
@Path("reset-password-email")
|
||||
public void resetPasswordEmail();
|
||||
|
||||
@PUT
|
||||
@Path("reset-password-email")
|
||||
public void resetPasswordEmail(@QueryParam("client_id") String clientId);
|
||||
|
||||
@PUT
|
||||
@Path("send-verify-email")
|
||||
public void sendVerifyEmail();
|
||||
|
||||
@PUT
|
||||
@Path("send-verify-email")
|
||||
public void sendVerifyEmail(@QueryParam("client_id") String clientId);
|
||||
|
||||
@GET
|
||||
@Path("sessions")
|
||||
public List<UserSessionRepresentation> getUserSessions();
|
||||
|
|
|
@ -57,6 +57,7 @@ import javax.ws.rs.core.MediaType;
|
|||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -786,46 +787,12 @@ public class UsersResource {
|
|||
return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!user.isEnabled()) {
|
||||
return ErrorResponse.error("User is disabled", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if (user.getEmail() == null) {
|
||||
return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if(redirectUri != null && clientId == null){
|
||||
return ErrorResponse.error("Client id missing", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if(clientId == null){
|
||||
clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
|
||||
}
|
||||
|
||||
ClientModel client = realm.getClientByClientId(clientId);
|
||||
if (client == null || !client.isEnabled()) {
|
||||
return ErrorResponse.error(clientId + " not enabled", Response.Status.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
String redirect;
|
||||
if(redirectUri != null){
|
||||
redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||
if(redirect == null){
|
||||
return ErrorResponse.error("Invalid redirect uri.", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
}else{
|
||||
redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
|
||||
}
|
||||
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", false, null, null);
|
||||
//audit.session(userSession);
|
||||
ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
|
||||
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
clientSession.setUserSession(userSession);
|
||||
ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId);
|
||||
ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
|
||||
|
||||
accessCode.setAction(ClientSessionModel.Action.RECOVER_PASSWORD);
|
||||
|
||||
try {
|
||||
|
@ -848,4 +815,98 @@ public class UsersResource {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email to the user with a link they can click to verify their email address.
|
||||
* The redirectUri and clientId parameters are optional. The default for the
|
||||
* redirect is the account client.
|
||||
*
|
||||
* @param username username (not id!)
|
||||
* @param redirectUri redirect uri
|
||||
* @param clientId client id
|
||||
* @return
|
||||
*/
|
||||
@Path("{username}/send-verify-email")
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response sendVerifyEmail(@PathParam("username") String username, @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri, @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId) {
|
||||
auth.requireManage();
|
||||
|
||||
UserModel user = session.users().getUserByUsername(username, realm);
|
||||
if (user == null) {
|
||||
return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
if (user.getEmail() == null) {
|
||||
return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId);
|
||||
ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
|
||||
|
||||
accessCode.setAction(ClientSessionModel.Action.VERIFY_EMAIL);
|
||||
|
||||
try {
|
||||
UriBuilder builder = Urls.loginActionEmailVerificationBuilder(uriInfo.getBaseUri());
|
||||
builder.queryParam("key", accessCode.getCode());
|
||||
|
||||
String link = builder.build(realm.getName()).toString();
|
||||
long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
|
||||
|
||||
this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
|
||||
|
||||
//audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success();
|
||||
|
||||
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
|
||||
|
||||
return Response.ok().build();
|
||||
} catch (EmailException e) {
|
||||
logger.error("Failed to send verification email", e);
|
||||
return ErrorResponse.error("Failed to send email", Response.Status.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientSessionModel createClientSession(UserModel user, String redirectUri, String clientId) {
|
||||
|
||||
if (!user.isEnabled()) {
|
||||
throw new WebApplicationException(
|
||||
ErrorResponse.error("User is disabled", Response.Status.BAD_REQUEST));
|
||||
}
|
||||
|
||||
if (redirectUri != null && clientId == null) {
|
||||
throw new WebApplicationException(
|
||||
ErrorResponse.error("Client id missing", Response.Status.BAD_REQUEST));
|
||||
}
|
||||
|
||||
if (clientId == null) {
|
||||
clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
|
||||
}
|
||||
|
||||
ClientModel client = realm.getClientByClientId(clientId);
|
||||
if (client == null || !client.isEnabled()) {
|
||||
throw new WebApplicationException(
|
||||
ErrorResponse.error(clientId + " not enabled", Response.Status.BAD_REQUEST));
|
||||
}
|
||||
|
||||
String redirect;
|
||||
if (redirectUri != null) {
|
||||
redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||
if (redirect == null) {
|
||||
throw new WebApplicationException(
|
||||
ErrorResponse.error("Invalid redirect uri.", Response.Status.BAD_REQUEST));
|
||||
}
|
||||
} else {
|
||||
redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
|
||||
}
|
||||
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), "form", false, null, null);
|
||||
//audit.session(userSession);
|
||||
ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
|
||||
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
clientSession.setUserSession(userSession);
|
||||
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -320,4 +320,87 @@ public class UserTest extends AbstractClientTest {
|
|||
assertNull(user1.getAttributes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendResetPasswordEmail() {
|
||||
UserRepresentation userRep = new UserRepresentation();
|
||||
userRep.setUsername("user1");
|
||||
realm.users().create(userRep);
|
||||
UserResource user = realm.users().get("user1");
|
||||
|
||||
try {
|
||||
user.resetPasswordEmail();
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("User email missing", error.getErrorMessage());
|
||||
}
|
||||
try {
|
||||
userRep = user.toRepresentation();
|
||||
userRep.setEmail("user1@localhost");
|
||||
userRep.setEnabled(false);
|
||||
user.update(userRep);
|
||||
user.resetPasswordEmail();
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("User is disabled", error.getErrorMessage());
|
||||
}
|
||||
try {
|
||||
userRep.setEnabled(true);
|
||||
user.update(userRep);
|
||||
user.resetPasswordEmail("invalidClientId");
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("invalidClientId not enabled", error.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendVerifyEmail() {
|
||||
UserRepresentation userRep = new UserRepresentation();
|
||||
userRep.setUsername("user1");
|
||||
realm.users().create(userRep);
|
||||
UserResource user = realm.users().get("user1");
|
||||
|
||||
try {
|
||||
user.sendVerifyEmail();
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("User email missing", error.getErrorMessage());
|
||||
}
|
||||
try {
|
||||
userRep = user.toRepresentation();
|
||||
userRep.setEmail("user1@localhost");
|
||||
userRep.setEnabled(false);
|
||||
user.update(userRep);
|
||||
user.sendVerifyEmail();
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("User is disabled", error.getErrorMessage());
|
||||
}
|
||||
try {
|
||||
userRep.setEnabled(true);
|
||||
user.update(userRep);
|
||||
user.sendVerifyEmail("invalidClientId");
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(400, e.getResponse().getStatus());
|
||||
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("invalidClientId not enabled", error.getErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue