Search in sources :

Example 36 with ModelException

use of org.keycloak.models.ModelException in project keycloak by keycloak.

the class LDAPOperationManager method renameEntry.

/**
 * Rename LDAPObject name (DN)
 *
 * @param oldDn
 * @param newDn
 * @param fallback With fallback=true, we will try to find the another DN in case of conflict. For example if there is an
 *                 attempt to rename to "CN=John Doe", but there is already existing "CN=John Doe", we will try "CN=John Doe0"
 * @return the non-conflicting DN, which was used in the end
 */
public String renameEntry(String oldDn, String newDn, boolean fallback) {
    try {
        String newNonConflictingDn = execute(new LdapOperation<String>() {

            @Override
            public String execute(LdapContext context) throws NamingException {
                String dn = newDn;
                // Max 5 attempts for now
                int max = 5;
                for (int i = 0; i < max; i++) {
                    try {
                        context.rename(new LdapName(oldDn), new LdapName(dn));
                        return dn;
                    } catch (NameAlreadyBoundException ex) {
                        if (!fallback) {
                            throw ex;
                        } else {
                            String failedDn = dn;
                            if (i < max) {
                                dn = findNextDNForFallback(newDn, i);
                                logger.warnf("Failed to rename DN [%s] to [%s]. Will try to fallback to DN [%s]", oldDn, failedDn, dn);
                            } else {
                                logger.warnf("Failed all fallbacks for renaming [%s]", oldDn);
                                throw ex;
                            }
                        }
                    }
                }
                throw new ModelException("Could not rename entry from DN [" + oldDn + "] to new DN [" + newDn + "]. All fallbacks failed");
            }

            @Override
            public String toString() {
                return new StringBuilder("LdapOperation: renameEntry\n").append(" oldDn: ").append(oldDn).append("\n").append(" newDn: ").append(newDn).toString();
            }
        });
        return newNonConflictingDn;
    } catch (NamingException e) {
        throw new ModelException("Could not rename entry from DN [" + oldDn + "] to new DN [" + newDn + "]", e);
    }
}
Also used : NameAlreadyBoundException(javax.naming.NameAlreadyBoundException) ModelException(org.keycloak.models.ModelException) NamingException(javax.naming.NamingException) InitialLdapContext(javax.naming.ldap.InitialLdapContext) LdapContext(javax.naming.ldap.LdapContext) LdapName(javax.naming.ldap.LdapName)

Example 37 with ModelException

use of org.keycloak.models.ModelException in project keycloak by keycloak.

the class LDAPStorageProvider method proxy.

protected UserModel proxy(RealmModel realm, UserModel local, LDAPObject ldapObject, boolean newUser) {
    UserModel existing = userManager.getManagedProxiedUser(local.getId());
    if (existing != null) {
        return existing;
    }
    // We need to avoid having CachedUserModel as cache is upper-layer then LDAP. Hence having CachedUserModel here may cause StackOverflowError
    if (local instanceof CachedUserModel) {
        local = session.userStorageManager().getUserById(realm, local.getId());
        existing = userManager.getManagedProxiedUser(local.getId());
        if (existing != null) {
            return existing;
        }
    }
    UserModel proxied = local;
    checkDNChanged(realm, local, ldapObject);
    switch(editMode) {
        case READ_ONLY:
            if (model.isImportEnabled()) {
                proxied = new ReadonlyLDAPUserModelDelegate(local);
            } else {
                proxied = new ReadOnlyUserModelDelegate(local);
            }
            break;
        case WRITABLE:
        case UNSYNCED:
            // This check is skipped when register new user as there are many "generic" attributes always written (EG. enabled, emailVerified) and those are usually unsupported by LDAP schema
            if (!model.isImportEnabled() && !newUser) {
                UserModel readOnlyDelegate = new ReadOnlyUserModelDelegate(local, ModelException::new);
                proxied = new LDAPWritesOnlyUserModelDelegate(readOnlyDelegate, this);
            }
            break;
    }
    AtomicReference<UserModel> proxy = new AtomicReference<>(proxied);
    realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName()).sorted(ldapMappersComparator.sortAsc()).forEachOrdered(mapperModel -> {
        LDAPStorageMapper ldapMapper = mapperManager.getMapper(mapperModel);
        proxy.set(ldapMapper.proxy(ldapObject, proxy.get(), realm));
    });
    proxied = proxy.get();
    if (!model.isImportEnabled()) {
        proxied = new UpdateOnlyChangeUserModelDelegate(proxied);
    }
    userManager.setManagedProxiedUser(proxied, ldapObject);
    return proxied;
}
Also used : CachedUserModel(org.keycloak.models.cache.CachedUserModel) UserModel(org.keycloak.models.UserModel) ReadOnlyUserModelDelegate(org.keycloak.models.utils.ReadOnlyUserModelDelegate) LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) ModelException(org.keycloak.models.ModelException) CachedUserModel(org.keycloak.models.cache.CachedUserModel) AtomicReference(java.util.concurrent.atomic.AtomicReference) UpdateOnlyChangeUserModelDelegate(org.keycloak.storage.adapter.UpdateOnlyChangeUserModelDelegate)

Example 38 with ModelException

use of org.keycloak.models.ModelException in project keycloak by keycloak.

the class MapResourceServerStore method create.

@Override
public ResourceServer create(ClientModel client) {
    String clientId = client.getId();
    LOG.tracef("create(%s)%s", clientId, getShortStackTrace());
    if (clientId == null)
        return null;
    if (!StorageId.isLocalStorage(clientId)) {
        throw new ModelException("Creating resource server from federated ClientModel not supported");
    }
    if (tx.read(clientId) != null) {
        throw new ModelDuplicateException("Resource server already exists: " + clientId);
    }
    MapResourceServerEntity entity = new MapResourceServerEntityImpl();
    entity.setId(clientId);
    return entityToAdapter(tx.create(entity));
}
Also used : MapResourceServerEntityImpl(org.keycloak.models.map.authorization.entity.MapResourceServerEntityImpl) ModelException(org.keycloak.models.ModelException) ModelDuplicateException(org.keycloak.models.ModelDuplicateException) MapResourceServerEntity(org.keycloak.models.map.authorization.entity.MapResourceServerEntity)

Example 39 with ModelException

use of org.keycloak.models.ModelException in project keycloak by keycloak.

the class MigrateTo14_0_0 method migrateRealm.

private void migrateRealm(KeycloakSession session, RealmModel realm) {
    try {
        session.clientPolicy().updateClientProfiles(realm, new ClientProfilesRepresentation());
        session.clientPolicy().updateClientPolicies(realm, new ClientPoliciesRepresentation());
    } catch (ClientPolicyException cpe) {
        throw new ModelException("Exception during migration client profiles or client policies", cpe);
    }
}
Also used : ModelException(org.keycloak.models.ModelException) ClientPoliciesRepresentation(org.keycloak.representations.idm.ClientPoliciesRepresentation) ClientProfilesRepresentation(org.keycloak.representations.idm.ClientProfilesRepresentation) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException)

Example 40 with ModelException

use of org.keycloak.models.ModelException in project keycloak by keycloak.

the class AccountFormService method processPasswordUpdate.

/**
 * Update account password
 * <p>
 * Form params:
 * <p>
 * password - old password
 * password-new
 * pasword-confirm
 *
 * @return
 */
@Path("password")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processPasswordUpdate() {
    MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
    if (auth == null) {
        return login("password");
    }
    auth.require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(formData);
    UserModel user = auth.getUser();
    boolean requireCurrent = isPasswordSet(session, realm, user);
    account.setPasswordSet(requireCurrent);
    String password = formData.getFirst("password");
    String passwordNew = formData.getFirst("password-new");
    String passwordConfirm = formData.getFirst("password-confirm");
    EventBuilder errorEvent = event.clone().event(EventType.UPDATE_PASSWORD_ERROR).client(auth.getClient()).user(auth.getSession().getUser());
    if (requireCurrent) {
        if (Validation.isBlank(password)) {
            setReferrerOnPage();
            errorEvent.error(Errors.PASSWORD_MISSING);
            return account.setError(Status.OK, Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
        }
        UserCredentialModel cred = UserCredentialModel.password(password);
        if (!session.userCredentialManager().isValid(realm, user, cred)) {
            setReferrerOnPage();
            errorEvent.error(Errors.INVALID_USER_CREDENTIALS);
            return account.setError(Status.OK, Messages.INVALID_PASSWORD_EXISTING).createResponse(AccountPages.PASSWORD);
        }
    }
    if (Validation.isBlank(passwordNew)) {
        setReferrerOnPage();
        errorEvent.error(Errors.PASSWORD_MISSING);
        return account.setError(Status.OK, Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
    }
    if (!passwordNew.equals(passwordConfirm)) {
        setReferrerOnPage();
        errorEvent.error(Errors.PASSWORD_CONFIRM_ERROR);
        return account.setError(Status.OK, Messages.INVALID_PASSWORD_CONFIRM).createResponse(AccountPages.PASSWORD);
    }
    try {
        session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password(passwordNew, false));
    } catch (ReadOnlyException mre) {
        setReferrerOnPage();
        errorEvent.error(Errors.NOT_ALLOWED);
        return account.setError(Response.Status.BAD_REQUEST, Messages.READ_ONLY_PASSWORD).createResponse(AccountPages.PASSWORD);
    } catch (ModelException me) {
        ServicesLogger.LOGGER.failedToUpdatePassword(me);
        setReferrerOnPage();
        errorEvent.detail(Details.REASON, me.getMessage()).error(Errors.PASSWORD_REJECTED);
        return account.setError(Response.Status.NOT_ACCEPTABLE, me.getMessage(), me.getParameters()).createResponse(AccountPages.PASSWORD);
    } catch (Exception ape) {
        ServicesLogger.LOGGER.failedToUpdatePassword(ape);
        setReferrerOnPage();
        errorEvent.detail(Details.REASON, ape.getMessage()).error(Errors.PASSWORD_REJECTED);
        return account.setError(Response.Status.INTERNAL_SERVER_ERROR, ape.getMessage()).createResponse(AccountPages.PASSWORD);
    }
    session.sessions().getUserSessionsStream(realm, user).filter(s -> !Objects.equals(s.getId(), auth.getSession().getId())).collect(// collect to avoid concurrent modification as backchannelLogout removes the user sessions.
    Collectors.toList()).forEach(s -> AuthenticationManager.backchannelLogout(session, realm, s, session.getContext().getUri(), clientConnection, headers, true));
    event.event(EventType.UPDATE_PASSWORD).client(auth.getClient()).user(auth.getUser()).success();
    setReferrerOnPage();
    return account.setPasswordSet(true).setSuccess(Messages.ACCOUNT_PASSWORD_UPDATED).createResponse(AccountPages.PASSWORD);
}
Also used : UserModel(org.keycloak.models.UserModel) EventBuilder(org.keycloak.events.EventBuilder) ModelException(org.keycloak.models.ModelException) UserCredentialModel(org.keycloak.models.UserCredentialModel) ReadOnlyException(org.keycloak.storage.ReadOnlyException) ReadOnlyException(org.keycloak.storage.ReadOnlyException) NotFoundException(javax.ws.rs.NotFoundException) ForbiddenException(org.keycloak.services.ForbiddenException) IOException(java.io.IOException) ModelException(org.keycloak.models.ModelException) ValidationException(org.keycloak.userprofile.ValidationException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Aggregations

ModelException (org.keycloak.models.ModelException)74 RealmModel (org.keycloak.models.RealmModel)20 NamingException (javax.naming.NamingException)13 UserModel (org.keycloak.models.UserModel)13 ClientModel (org.keycloak.models.ClientModel)11 ComponentModel (org.keycloak.component.ComponentModel)10 LDAPObject (org.keycloak.storage.ldap.idm.model.LDAPObject)10 IOException (java.io.IOException)9 Consumes (javax.ws.rs.Consumes)9 NotFoundException (javax.ws.rs.NotFoundException)8 BasicAttribute (javax.naming.directory.BasicAttribute)7 KeycloakSession (org.keycloak.models.KeycloakSession)7 RoleModel (org.keycloak.models.RoleModel)7 ErrorResponseException (org.keycloak.services.ErrorResponseException)7 ReadOnlyException (org.keycloak.storage.ReadOnlyException)7 POST (javax.ws.rs.POST)6 Path (javax.ws.rs.Path)6 Test (org.junit.Test)6 ArrayList (java.util.ArrayList)5 AttributeInUseException (javax.naming.directory.AttributeInUseException)5