Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLOUDTRUST-2296] Add a method on account API to send execute actions email #26

Merged
merged 2 commits into from
Feb 25, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,43 @@
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.authentication.actiontoken.execactions.ExecuteActionsActionToken;
import org.keycloak.common.Profile;
import org.keycloak.common.util.Time;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailTemplateProvider;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.models.*;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.managers.Auth;
import org.keycloak.services.resources.Cors;
import org.keycloak.services.resources.LoginActionsService;
import org.keycloak.services.resources.account.AccountRestService;

import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;

/**
* This is a copy of org.keycloak.services.resources.account.AccountRestService that fixes a bug with CORS
* The inspiration for the fix came from org.keycloak.services.resources.admin.AdminRoot.
*/
public class FixedAccountRestService extends AccountRestService {

private KeycloakSession session;
private Auth auth;
private EventBuilder event;
Expand Down Expand Up @@ -86,4 +100,49 @@ public Response deleteAccount() {
}
}

/**
* Send execute actions email
* @param lifespan
* @param actions
* @return
*/
@Path("execute-actions-email")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response executeActionsEmail(@QueryParam("lifespan") Integer lifespan, List<String> actions) {
if (user.getEmail()==null) {
return ErrorResponse.error("User email missing", Status.BAD_REQUEST);
}

if (!user.isEnabled()) {
throw new WebApplicationException(
ErrorResponse.error("User is disabled", Status.BAD_REQUEST));
}

if (lifespan == null) {
lifespan = realm.getActionTokenGeneratedByAdminLifespan();
}
int expiration = Time.currentTime() + lifespan;
String redirectUri = null;
String clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand where does this Constants come from ... I don't see it in imports neither in package. What am I missing ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It comes from org.keycloak.models
(the code to send the mail is mainly copied from Keycloak)

ExecuteActionsActionToken token = new ExecuteActionsActionToken(user.getId(), expiration, actions, redirectUri, clientId);

try {
UriBuilder builder = LoginActionsService.actionTokenProcessor(session.getContext().getUri());
builder.queryParam("key", token.serialize(session, realm, session.getContext().getUri()));

String link = builder.build(realm.getName()).toString();

this.session.getProvider(EmailTemplateProvider.class)
.setAttribute(Constants.TEMPLATE_ATTR_REQUIRED_ACTIONS, token.getRequiredActions())
.setRealm(realm)
.setUser(user)
.sendExecuteActions(link, TimeUnit.SECONDS.toMinutes(lifespan));

return Response.ok().build();
} catch (EmailException e) {
ServicesLogger.LOGGER.failedToSendActionsEmail(e);
return ErrorResponse.error("Failed to send execute actions email", Status.INTERNAL_SERVER_ERROR);
}
}
}