use of org.keycloak.storage.ReadOnlyException in project keycloak by keycloak.
the class UserResource method resetPassword.
/**
* Set up a new password for the user.
*
* @param cred The representation must contain a rawPassword with the plain-text password
*/
@Path("reset-password")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void resetPassword(CredentialRepresentation cred) {
auth.users().requireManage(user);
if (cred == null || cred.getValue() == null) {
throw new BadRequestException("No password provided");
}
if (Validation.isBlank(cred.getValue())) {
throw new BadRequestException("Empty password not allowed");
}
try {
session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password(cred.getValue(), false));
} catch (IllegalStateException ise) {
throw new BadRequestException("Resetting to N old passwords is not allowed.");
} catch (ReadOnlyException mre) {
throw new BadRequestException("Can't reset password as account is read only");
} catch (ModelException e) {
logger.warn("Could not update user password.", e);
Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
throw new ErrorResponseException(e.getMessage(), MessageFormat.format(messages.getProperty(e.getMessage(), e.getMessage()), e.getParameters()), Status.BAD_REQUEST);
}
if (cred.isTemporary() != null && cred.isTemporary()) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
} else {
// Remove a potentially existing UPDATE_PASSWORD action when explicitly assigning a non-temporary password.
user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
}
adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri()).success();
}
use of org.keycloak.storage.ReadOnlyException in project keycloak by keycloak.
the class AccountFormService method processAccountUpdate.
/**
* Update account information.
* <p>
* Form params:
* <p>
* firstName
* lastName
* email
*
* @return
*/
@Path("/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processAccountUpdate() {
MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
if (auth == null) {
return login(null);
}
auth.require(AccountRoles.MANAGE_ACCOUNT);
String action = formData.getFirst("submitAction");
if (action != null && action.equals("Cancel")) {
setReferrerOnPage();
return account.createResponse(AccountPages.ACCOUNT);
}
csrfCheck(formData);
UserModel user = auth.getUser();
event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()).detail(Details.CONTEXT, UserProfileContext.ACCOUNT_OLD.name());
UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
UserProfile profile = profileProvider.create(UserProfileContext.ACCOUNT_OLD, formData, user);
try {
// backward compatibility with old account console where attributes are not removed if missing
profile.update(false, new EventAuditingAttributeChangeListener(profile, event));
} catch (ValidationException pve) {
List<FormMessage> errors = Validation.getFormErrorsFromValidation(pve.getErrors());
if (!errors.isEmpty()) {
setReferrerOnPage();
Response.Status status = Status.OK;
if (pve.hasError(Messages.READ_ONLY_USERNAME)) {
status = Response.Status.BAD_REQUEST;
} else if (pve.hasError(Messages.EMAIL_EXISTS, Messages.USERNAME_EXISTS)) {
status = Response.Status.CONFLICT;
}
return account.setErrors(status, errors).setProfileFormData(formData).createResponse(AccountPages.ACCOUNT);
}
} catch (ReadOnlyException e) {
setReferrerOnPage();
return account.setError(Response.Status.BAD_REQUEST, Messages.READ_ONLY_USER).setProfileFormData(formData).createResponse(AccountPages.ACCOUNT);
}
event.success();
setReferrerOnPage();
return account.setSuccess(Messages.ACCOUNT_UPDATED).createResponse(AccountPages.ACCOUNT);
}
use of org.keycloak.storage.ReadOnlyException 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);
}
use of org.keycloak.storage.ReadOnlyException in project keycloak by keycloak.
the class ClientRoleMappingsResource method addClientRoleMapping.
/**
* Add client-level roles to the user role mapping
*
* @param roles
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void addClientRoleMapping(List<RoleRepresentation> roles) {
managePermission.require();
try {
for (RoleRepresentation role : roles) {
RoleModel roleModel = client.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException("Role not found");
}
auth.roles().requireMapRole(roleModel);
user.grantRole(roleModel);
}
} catch (ModelException | ReadOnlyException me) {
logger.warn(me.getMessage(), me);
throw new ErrorResponseException("invalid_request", "Could not add user role mappings!", Response.Status.BAD_REQUEST);
}
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
}
use of org.keycloak.storage.ReadOnlyException in project keycloak by keycloak.
the class ClientRoleMappingsResource method deleteClientRoleMapping.
/**
* Delete client-level roles from user role mapping
*
* @param roles
*/
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public void deleteClientRoleMapping(List<RoleRepresentation> roles) {
managePermission.require();
if (roles == null) {
roles = user.getClientRoleMappingsStream(client).peek(roleModel -> {
auth.roles().requireMapRole(roleModel);
user.deleteRoleMapping(roleModel);
}).map(ModelToRepresentation::toBriefRepresentation).collect(Collectors.toList());
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = client.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException("Role not found");
}
auth.roles().requireMapRole(roleModel);
try {
user.deleteRoleMapping(roleModel);
} catch (ModelException | ReadOnlyException me) {
logger.warn(me.getMessage(), me);
throw new ErrorResponseException("invalid_request", "Could not remove user role mappings!", Response.Status.BAD_REQUEST);
}
}
}
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
}
Aggregations