diff --git a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionToken.java b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionToken.java index fbc6a63..ad17337 100644 --- a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionToken.java +++ b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionToken.java @@ -6,8 +6,6 @@ import lombok.Setter; import org.keycloak.authentication.actiontoken.DefaultActionToken; -import java.util.UUID; - @Getter @Setter @NoArgsConstructor(access = AccessLevel.PRIVATE) // required for JSON de-/serialization @@ -16,25 +14,11 @@ public class CustomActionToken extends DefaultActionToken { public static final String TOKEN_TYPE = "custom-action"; private String redirectUri; - private boolean reuse; - private String scope; - private String state; + private String scope = "openid"; - public CustomActionToken(String userId, String clientId, int expirationInSeconds, boolean reuse, - String redirectUri, String scope, String nonce, String state) { - super(userId, TOKEN_TYPE, expirationInSeconds, uuidOf(nonce)); + public CustomActionToken(String userId, String clientId, String redirectUri) { + super(userId, TOKEN_TYPE, 10, null); this.issuedFor = clientId; this.redirectUri = redirectUri; - this.reuse = reuse; - this.scope = scope; - this.state = state; - } - - static UUID uuidOf(String s) { - try { - return UUID.fromString(s); - } catch (Exception ignored) { - } - return null; } } diff --git a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionTokenHandler.java b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionTokenHandler.java index b5327ad..2490124 100644 --- a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionTokenHandler.java +++ b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomActionTokenHandler.java @@ -46,12 +46,6 @@ public Response handleToken(CustomActionToken token, ActionTokenContext tokenContext) { - return token.isReuse(); + return false; } } diff --git a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenRequest.java b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenRequest.java index 8a3f2a2..77a2920 100644 --- a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenRequest.java +++ b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenRequest.java @@ -5,15 +5,6 @@ @Data public class CustomTokenRequest { private String username; - private String email; private String clientId; private String redirectUri; - private String scope = null; - private String nonce = null; - private String state = null; - private Integer expirationSeconds = null; - private boolean forceCreate = false; - private boolean updateProfile = false; - private boolean updatePassword = false; - private boolean reuse = false; } diff --git a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenResource.java b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenResource.java index 4f1b258..4eced94 100644 --- a/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenResource.java +++ b/actiontoken/src/main/java/dasniko/keycloak/actiontoken/CustomTokenResource.java @@ -12,11 +12,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.keycloak.Config; -import org.keycloak.common.ClientConnection; -import org.keycloak.common.util.Time; -import org.keycloak.events.Details; -import org.keycloak.events.EventBuilder; -import org.keycloak.events.EventType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakContext; import org.keycloak.models.KeycloakSession; @@ -56,21 +51,12 @@ public CustomTokenResponse createTokenLink(CustomTokenRequest payload) { throw new BadRequestException("redirectUri %s disallowed by client.".formatted(redirectUri)); } - String emailOrUsername = payload.getEmail(); - boolean forceCreate = payload.isForceCreate(); - if (payload.getUsername() != null) { - emailOrUsername = payload.getUsername(); - forceCreate = false; - } - - UserModel user = getOrCreateUser(emailOrUsername, forceCreate, payload.isUpdateProfile(), payload.isUpdatePassword()); + UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, payload.getUsername()); if (user == null) { - throw new NotFoundException("User with email/username %s not found, and forceCreate is off.".formatted(emailOrUsername)); + throw new NotFoundException("User with email/username %s not found, and forceCreate is off.".formatted(payload.getUsername())); } - CustomActionToken token = createActionToken( - user, clientId, payload.getExpirationSeconds(), redirectUri, payload.isReuse(), - payload.getScope(), payload.getNonce(), payload.getState()); + CustomActionToken token = createActionToken(user, clientId, redirectUri); String tokenUrl = getActionTokenUrl(token); @@ -85,40 +71,8 @@ private boolean validateRedirectUri(ClientModel client, String redirectUri) { return redirectUri.equals(redirect); } - private UserModel getOrCreateUser(String email, boolean forceCreate, boolean updateProfile, boolean updatePassword) { - UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, email); - if (user == null && forceCreate) { - user = session.users().addUser(realm, email); - user.setEnabled(true); - user.setEmail(email); - registerEvent(user); - if (updatePassword) { - user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); - } - if (updateProfile) { - user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); - } - } - return user; - } - - private void registerEvent(UserModel user) { - ClientConnection clientConnection = session.getContext().getConnection(); - EventBuilder eventBuilder = new EventBuilder(realm, session, clientConnection).realm(realm); - eventBuilder - .event(EventType.REGISTER) - .detail(Details.REGISTER_METHOD, CustomActionToken.TOKEN_TYPE) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.EMAIL, user.getEmail()) - .user(user) - .success(); - } - - private CustomActionToken createActionToken(UserModel user, String clientId, Integer expiration, String redirectUri, - boolean reuse, String scope, String nonce, String state) { - int expirationInSecs = (expiration != null && expiration > 0) ? expiration : (60 * 60 * 24); - int absoluteExpirationInSecs = Time.currentTime() + expirationInSecs; - return new CustomActionToken(user.getId(), clientId, absoluteExpirationInSecs, reuse, redirectUri, scope, nonce, state); + private CustomActionToken createActionToken(UserModel user, String clientId, String redirectUri) { + return new CustomActionToken(user.getId(), clientId, redirectUri); } private String getActionTokenUrl(CustomActionToken token) {