blob: 2c558822bcb5014c2e98c352f10d68d51bb708a6 [file] [log] [blame]
package org.apache.archiva.redback.rest.services.v2;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import net.sf.ehcache.CacheManager;
import org.apache.archiva.components.cache.Cache;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.Token;
import org.apache.archiva.redback.authentication.TokenBasedAuthenticationDataSource;
import org.apache.archiva.redback.authentication.jwt.JwtAuthenticator;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.configuration.UserConfigurationKeys;
import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
import org.apache.archiva.redback.integration.mail.Mailer;
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.keys.KeyManager;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.keys.KeyNotFoundException;
import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.policy.PasswordEncoder;
import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.rest.api.Constants;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.ErrorMessage;
import org.apache.archiva.redback.rest.api.model.Operation;
import org.apache.archiva.redback.rest.api.model.Permission;
import org.apache.archiva.redback.rest.api.model.v2.SelfUserData;
import org.apache.archiva.redback.rest.api.model.v2.RegistrationKey;
import org.apache.archiva.redback.rest.api.model.ResetPasswordRequest;
import org.apache.archiva.redback.rest.api.model.Resource;
import org.apache.archiva.redback.rest.api.model.VerificationStatus;
import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
import org.apache.archiva.redback.rest.api.model.v2.PingResult;
import org.apache.archiva.redback.rest.api.model.v2.User;
import org.apache.archiva.redback.rest.api.model.v2.UserRegistrationRequest;
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
import org.apache.archiva.redback.rest.api.services.v2.UserService;
import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
import org.apache.archiva.redback.rest.services.interceptors.RedbackPrincipal;
import org.apache.archiva.redback.rest.services.utils.PasswordValidator;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.role.RoleManagerException;
import org.apache.archiva.redback.system.SecuritySession;
import org.apache.archiva.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.inject.Named;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.apache.archiva.redback.rest.api.Constants.*;
@Service( "v2.userService#rest" )
public class DefaultUserService
implements UserService
{
private final Logger log = LoggerFactory.getLogger( getClass() );
private static final String VALID_USERNAME_CHARS = "[a-zA-Z_0-9\\-.@]*";
private static final String[] INVALID_CREATE_USER_NAMES = { "admin", "guest", "me" };
private UserManager userManager;
private SecuritySystem securitySystem;
@Inject
@Named( value = "userConfiguration#default" )
private UserConfiguration config;
@Inject
private JwtAuthenticator jwtAuthenticator;
@Inject
private RoleManager roleManager;
/**
* cache used for user assignments
*/
@Inject
@Named( value = "cache#userAssignments" )
private Cache<String, ? extends UserAssignment> userAssignmentsCache;
/**
* cache used for user permissions
*/
@Inject
@Named( value = "cache#userPermissions" )
private Cache<String, ? extends Permission> userPermissionsCache;
/**
* Cache used for users
*/
@Inject
@Named( value = "cache#users" )
private Cache<String, ? extends User> usersCache;
@Inject
private Mailer mailer;
@Inject
@Named( value = "rbacManager#default" )
private RBACManager rbacManager;
private HttpAuthenticator httpAuthenticator;
@Inject
private PasswordValidator passwordValidator;
@Context
private HttpServletRequest httpServletRequest;
@Context
private HttpServletResponse httpServletResponse;
@Context
private UriInfo uriInfo;
@Context
private SecurityContext securityContext;
@Inject
public DefaultUserService( @Named( value = "userManager#default" ) UserManager userManager,
SecuritySystem securitySystem )
{
this.userManager = userManager;
this.securitySystem = securitySystem;
}
RedbackPrincipal getPrincipal() {
if (this.securityContext!=null) {
Principal pri = this.securityContext.getUserPrincipal( );
if (pri!=null && pri instanceof RedbackPrincipal) {
return (RedbackPrincipal) pri;
}
}
return null;
}
@Override
public User createUser( User user )
throws RedbackServiceException
{
User result;
if ( Arrays.binarySearch( INVALID_CREATE_USER_NAMES, user.getUserId( ) ) >=0 )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_ID_INVALID, user.getUserId() ), 422 );
}
try
{
org.apache.archiva.redback.users.User u = userManager.findUser( user.getUserId() );
if ( u != null )
{
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( u.getUsername( ) ).build( ).toString( ) );
throw new RedbackServiceException(
ErrorMessage.of( ERR_USER_EXISTS, user.getUserId() ), 303 );
}
}
catch ( UserNotFoundException e )
{
//ignore we just want to prevent non human readable error message from backend :-)
log.debug( "user {} not exists", user.getUserId() );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_UNKNOWN, e.getMessage() ) );
}
// data validation
if ( StringUtils.isEmpty( user.getUserId() ) )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_ID_EMPTY ), 422 );
}
if ( StringUtils.isEmpty( user.getFullName() ) )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_FULL_NAME_EMPTY ), 422 );
}
if ( StringUtils.isEmpty( user.getEmail() ) )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_EMAIL_EMPTY ), 422 );
}
try
{
org.apache.archiva.redback.users.User u =
userManager.createUser( user.getUserId(), user.getFullName(), user.getEmail() );
u.setPassword( user.getPassword() );
u.setLocked( user.isLocked() );
u.setPasswordChangeRequired( user.isPasswordChangeRequired() );
u.setPermanent( user.isPermanent() );
u.setValidated( user.isValidated() );
u = userManager.addUser( u );
if ( !user.isPasswordChangeRequired() )
{
u.setPasswordChangeRequired( false );
try
{
u = userManager.updateUser( u );
log.debug( "user {} created", u.getUsername() );
}
catch ( UserNotFoundException e )
{
throw new RedbackServiceException( e.getMessage() );
}
}
roleManager.assignRole( RedbackRoleConstants.REGISTERED_USER_ROLE_ID, u.getUsername() );
result = getRestUser( u );
httpServletResponse.setStatus( 201 );
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path( user.getUserId() ).build( ).toString() );
}
catch ( RoleManagerException rpe )
{
log.error( "RoleProfile Error: {}", rpe.getMessage(), rpe );
throw new RedbackServiceException( ErrorMessage.of(ERR_USER_ASSIGN_ROLE ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of(ERR_UNKNOWN, e.getMessage() ) );
}
return result;
}
@Override
public void deleteUser( String userId )
throws RedbackServiceException
{
try
{
if ( rbacManager.userAssignmentExists( userId ) )
{
UserAssignment assignment = rbacManager.getUserAssignment( userId );
rbacManager.removeUserAssignment( assignment );
}
}
catch ( RbacManagerException e )
{
log.error( e.getMessage(), e );
throw new RedbackServiceException( ErrorMessage.of( ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
}
try
{
userManager.deleteUser( userId );
}
catch ( UserNotFoundException e )
{
log.error( e.getMessage(), e );
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND ), 404 );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
}
finally
{
removeFromCache( userId );
}
httpServletResponse.setStatus( 200 );
}
@Override
public User getUser( String userId )
throws RedbackServiceException
{
try
{
if ("guest".equals(userId)) {
return getRestUser( userManager.getGuestUser( ) );
}
org.apache.archiva.redback.users.User user = userManager.findUser( userId );
return getRestUser( user );
}
catch ( UserNotFoundException e )
{
return null;
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
@Override
public PagedResult<User> getUsers(Integer offset,
Integer limit)
throws RedbackServiceException
{
try
{
List<? extends org.apache.archiva.redback.users.User> users = userManager.getUsers();
if (offset>=users.size()) {
return new PagedResult<>( users.size( ), offset, limit, Collections.emptyList( ) );
}
int endIndex = PagingHelper.getLastIndex( offset, limit, users.size( ) );
List<? extends org.apache.archiva.redback.users.User> resultList = users.subList( offset, endIndex );
List<User> simpleUsers = new ArrayList<>( resultList.size() );
for ( org.apache.archiva.redback.users.User user : resultList )
{
simpleUsers.add( getRestUser( user ) );
}
return new PagedResult<>( users.size( ), offset, limit, simpleUsers );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
@Override
public User updateMe( SelfUserData user )
throws RedbackServiceException
{
RedbackPrincipal principal = getPrincipal( );
if (principal==null) {
throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_UNAUTHORIZED_REQUEST ), 401 );
}
// check oldPassword with the current one
// only 3 fields to update
// ui can limit to not update password
org.apache.archiva.redback.users.User foundUser = updateUser( principal.getName(), realUser -> {
try
{
// current password is only needed, if password change is requested
if ( StringUtils.isNotBlank( user.getPassword( ) ) )
{
String previousEncodedPassword =
securitySystem.getUserManager( ).findUser( principal.getName(), false ).getEncodedPassword( );
// check oldPassword with the current one
PasswordEncoder encoder = securitySystem.getPolicy( ).getPasswordEncoder( );
if ( !encoder.isPasswordValid( previousEncodedPassword, user.getCurrentPassword( ) ) )
{
return new RedbackServiceException( ErrorMessage.of( ERR_USER_BAD_PASSWORD ),
Response.Status.BAD_REQUEST.getStatusCode( ) );
}
}
}
catch ( UserNotFoundException e )
{
return new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND ),
Response.Status.BAD_REQUEST.getStatusCode( ) );
}
catch ( UserManagerException e )
{
return new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
}
// only 3 fields to update
if (StringUtils.isNotBlank( user.getFullName() ))
{
realUser.setFullName( user.getFullName( ) );
}
if (StringUtils.isNotBlank( user.getEmail() ))
{
realUser.setEmail( user.getEmail( ) );
}
// ui can limit to not update password
if ( StringUtils.isNotBlank( user.getPassword( ) ) )
{
realUser.setPassword( user.getPassword( ) );
}
return null;
} );
return getRestUser( foundUser );
}
@Override
public User getLoggedInUser( )
throws RedbackServiceException
{
RedbackPrincipal principal = getPrincipal( );
if (principal==null) {
throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_UNAUTHORIZED_REQUEST ), 401 );
}
try
{
org.apache.archiva.redback.users.User foundUser = userManager.findUser( principal.getUser().getUsername(), false );
return getRestUser( foundUser );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage( ) ), 400 );
}
}
@Override
public User updateUser( String userId, User user )
throws RedbackServiceException
{
try
{
org.apache.archiva.redback.users.User rawUser = userManager.findUser( userId, false );
if (user.getFullName()!=null)
rawUser.setFullName( user.getFullName() );
if (user.getEmail()!=null)
rawUser.setEmail( user.getEmail() );
rawUser.setValidated( user.isValidated() );
rawUser.setLocked( user.isLocked() );
if ( !StringUtils.isEmpty( user.getPassword( ) ) )
rawUser.setPassword( user.getPassword() );
rawUser.setPasswordChangeRequired( user.isPasswordChangeRequired() );
rawUser.setPermanent( user.isPermanent() );
org.apache.archiva.redback.users.User updatedUser = userManager.updateUser( rawUser );
return getRestUser( updatedUser );
}
catch ( UserNotFoundException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND ), 404 );
} catch ( PasswordRuleViolationException e ) {
List<ErrorMessage> messages = e.getViolations( ).getViolations( ).stream( ).map( m -> ErrorMessage.of( m.getKey( ), m.getArgs( ) ) ).collect( Collectors.toList() );
throw new RedbackServiceException( messages, 422 );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
@Override
public ActionStatus removeFromCache( String userId )
throws RedbackServiceException
{
if ( userAssignmentsCache != null )
{
userAssignmentsCache.remove( userId );
}
if ( userPermissionsCache != null )
{
userPermissionsCache.remove( userId );
}
if ( usersCache != null )
{
usersCache.remove( userId );
}
CacheManager cacheManager = CacheManager.getInstance();
String[] caches = cacheManager.getCacheNames();
for ( String cacheName : caches )
{
if ( StringUtils.startsWith( cacheName, "org.apache.archiva.redback.rbac.jdo" ) )
{
cacheManager.getCache( cacheName ).removeAll();
}
}
return ActionStatus.SUCCESS;
}
@Override
public PingResult ping()
throws RedbackServiceException
{
return new PingResult( true );
}
private User getRestUser( org.apache.archiva.redback.users.User user )
{
if ( user == null )
{
return null;
}
return new User( user );
}
@Override
public User createAdminUser( User adminUser )
throws RedbackServiceException
{
User result;
if ( getAdminStatus().isExists() )
{
log.warn( "Admin user exists already" );
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePath().toString() );
throw new RedbackServiceException( ErrorMessage.of( Constants.ERR_USER_ADMIN_EXISTS ), 303 );
}
log.debug("Creating admin admin user '{}'", adminUser.getUserId());
if (!RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME.equals(adminUser.getUserId())) {
log.error("Wrong admin user name {}", adminUser.getUserId());
throw new RedbackServiceException(ErrorMessage.of(Constants.ERR_USER_ADMIN_BAD_NAME ), 422);
}
try
{
org.apache.archiva.redback.users.User user =
userManager.createUser( RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME, adminUser.getFullName(),
adminUser.getEmail() );
user.setPassword( adminUser.getPassword() );
user.setLocked( false );
user.setPasswordChangeRequired( false );
user.setPermanent( true );
user.setValidated( true );
userManager.addUser( user );
result = getRestUser( user );
roleManager.assignRole( "system-administrator", user.getUsername() );
}
catch ( RoleManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ) );
}
httpServletResponse.setStatus( 201 );
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePath().toString() );
return result;
}
@Override
public AvailabilityStatus getAdminStatus()
throws RedbackServiceException
{
try
{
org.apache.archiva.redback.users.User user = userManager.findUser( config.getString( UserConfigurationKeys.DEFAULT_ADMIN ) );
if (user.getAccountCreationDate()!=null)
{
return new AvailabilityStatus( true, user.getAccountCreationDate( ).toInstant( ) );
} else {
return new AvailabilityStatus( true );
}
}
catch ( UserNotFoundException e )
{
// ignore
}
catch ( UserManagerException e )
{
Throwable cause = e.getCause();
if ( cause != null && cause instanceof UserNotFoundException )
{
return new AvailabilityStatus( false );
}
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ) );
}
return new AvailabilityStatus( false );
}
@Override
public ActionStatus resetPassword( String userId, ResetPasswordRequest resetPasswordRequest )
throws RedbackServiceException
{
String username = resetPasswordRequest.getUsername();
if ( StringUtils.isEmpty( username ) )
{
throw new RedbackServiceException( new ErrorMessage( "username.cannot.be.empty" ) );
}
UserManager userManager = securitySystem.getUserManager();
KeyManager keyManager = securitySystem.getKeyManager();
UserSecurityPolicy policy = securitySystem.getPolicy();
try
{
org.apache.archiva.redback.users.User user = userManager.findUser( username );
AuthenticationKey authkey = keyManager.createKey( username, "Password Reset Request",
policy.getUserValidationSettings().getEmailValidationTimeout() );
String applicationUrl = resetPasswordRequest.getApplicationUrl();
if ( StringUtils.isBlank( applicationUrl ) )
{
applicationUrl = getBaseUrl();
}
mailer.sendPasswordResetEmail( Arrays.asList( user.getEmail() ), authkey, applicationUrl );
log.info( "password reset request for username {}", username );
}
catch ( UserNotFoundException e )
{
log.info( "Password Reset on non-existant user [{}].", username );
throw new RedbackServiceException( new ErrorMessage( "password.reset.failure" ) );
}
catch ( KeyManagerException e )
{
log.info( "Unable to issue password reset.", e );
throw new RedbackServiceException( new ErrorMessage( "password.reset.email.generation.failure" ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
return ActionStatus.SUCCESS;
}
@Override
public RegistrationKey registerUser( String userId, UserRegistrationRequest userRegistrationRequest )
throws RedbackServiceException
{
User user = userRegistrationRequest.getUser();
if ( user == null )
{
throw new RedbackServiceException( new ErrorMessage( "invalid.user.credentials", null ) );
}
UserSecurityPolicy securityPolicy = securitySystem.getPolicy();
boolean emailValidationRequired = securityPolicy.getUserValidationSettings().isEmailValidationRequired();
if ( emailValidationRequired )
{
validateCredentialsLoose( user );
}
else
{
validateCredentialsStrict( user );
}
org.apache.archiva.redback.users.User u = null;
try
{
// NOTE: Do not perform Password Rules Validation Here.
if ( userManager.userExists( user.getUserId() ) )
{
throw new RedbackServiceException(
new ErrorMessage( "user.already.exists", new String[]{ user.getUserId() } ) );
}
u = userManager.createUser( user.getUserId(), user.getFullName(), user.getEmail() );
u.setPassword( user.getPassword() );
u.setValidated( false );
u.setLocked( false );
roleManager.assignRole( RedbackRoleConstants.REGISTERED_USER_ROLE_ID, u.getUsername() );
}
catch ( RoleManagerException rpe )
{
log.error( "RoleProfile Error: {}", rpe.getMessage(), rpe );
throw new RedbackServiceException( new ErrorMessage( "assign.role.failure", null ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
if ( emailValidationRequired )
{
u.setLocked( true );
try
{
AuthenticationKey authkey =
securitySystem.getKeyManager().createKey( u.getUsername(), "New User Email Validation",
securityPolicy.getUserValidationSettings().getEmailValidationTimeout() );
String baseUrl = userRegistrationRequest.getApplicationUrl();
if ( StringUtils.isBlank( baseUrl ) )
{
baseUrl = getBaseUrl();
}
log.debug( "register user {} with email {} and app url {}", u.getUsername(), u.getEmail(), baseUrl );
mailer.sendAccountValidationEmail( Arrays.asList( u.getEmail() ), authkey, baseUrl );
securityPolicy.setEnabled( false );
userManager.addUser( u );
return new RegistrationKey( authkey.getKey(), true );
}
catch ( KeyManagerException e )
{
log.error( "Unable to register a new user.", e );
throw new RedbackServiceException( new ErrorMessage( "cannot.register.user", null ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
finally
{
securityPolicy.setEnabled( true );
}
}
else
{
try
{
userManager.addUser( u );
return new RegistrationKey( "-1", false );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
// FIXME log this event
/*
AuditEvent event = new AuditEvent( getText( "log.account.create" ) );
event.setAffectedUser( username );
event.log();
*/
}
@Override
public Collection<Permission> getCurrentUserPermissions( )
throws RedbackServiceException
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
String userName = UserManager.GUEST_USERNAME;
if ( redbackRequestInformation != null && redbackRequestInformation.getUser() != null )
{
userName = redbackRequestInformation.getUser().getUsername();
}
else
{
log.warn( "RedbackRequestInformation from ThreadLocal is null" );
}
return getUserPermissions( userName );
}
@Override
public Collection<Operation> getCurrentUserOperations( )
throws RedbackServiceException
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
String userName = UserManager.GUEST_USERNAME;
if ( redbackRequestInformation != null && redbackRequestInformation.getUser() != null )
{
userName = redbackRequestInformation.getUser().getUsername();
}
else
{
log.warn( "RedbackRequestInformation from ThreadLocal is null" );
}
return getUserOperations( userName );
}
@Override
public VerificationStatus validateUserRegistration( String userId, String key ) throws RedbackServiceException
{
String principal = null;
try
{
AuthenticationKey authkey = securitySystem.getKeyManager().findKey( key );
org.apache.archiva.redback.users.User user =
securitySystem.getUserManager().findUser( authkey.getForPrincipal() );
user.setValidated( true );
user.setLocked( false );
user.setPasswordChangeRequired( true );
user.setEncodedPassword( "" );
principal = user.getUsername();
TokenBasedAuthenticationDataSource authsource = new TokenBasedAuthenticationDataSource();
authsource.setPrincipal( principal );
authsource.setToken( authkey.getKey() );
authsource.setEnforcePasswordChange( false );
securitySystem.getUserManager().updateUser( user );
VerificationStatus status = new VerificationStatus(false );
SecuritySession authStatus = securitySystem.authenticate( authsource );
if (authStatus.isAuthenticated()) {
Token accessToken = jwtAuthenticator.generateToken( principal );
status.setAccessToken( accessToken.getData() );
status.setSuccess( true );
}
log.info( "account validated for user {}", user.getUsername() );
return status;
}
catch ( MustChangePasswordException | AccountLockedException | AuthenticationException e )
{
throw new RedbackServiceException( e.getMessage(), Response.Status.FORBIDDEN.getStatusCode() );
}
catch ( KeyNotFoundException e )
{
log.info( "Invalid key requested: {}", key );
throw new RedbackServiceException( new ErrorMessage( "cannot.find.key" ) );
}
catch ( KeyManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( "cannot.find.key.at.the.momment" ) );
}
catch ( UserNotFoundException e )
{
throw new RedbackServiceException( new ErrorMessage( "cannot.find.user", new String[]{ principal } ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
@Override
public Collection<Operation> getUserOperations( String userName )
throws RedbackServiceException
{
Collection<Permission> permissions = getUserPermissions( userName );
List<Operation> operations = new ArrayList<>( permissions.size( ) );
for ( Permission permission : permissions )
{
if ( permission.getOperation() != null )
{
Operation operation = new Operation();
operation.setName( permission.getOperation().getName() );
operations.add( operation );
}
}
return operations;
}
@Override
public Collection<Permission> getUserPermissions( String userName )
throws RedbackServiceException
{
try
{
Set<? extends org.apache.archiva.redback.rbac.Permission> permissions =
rbacManager.getAssignedPermissions( userName );
// FIXME return guest permissions !!
List<Permission> userPermissions = new ArrayList<>( permissions.size( ) );
for ( org.apache.archiva.redback.rbac.Permission p : permissions )
{
Permission permission = new Permission();
permission.setName( p.getName() );
if ( p.getOperation() != null )
{
Operation operation = new Operation();
operation.setName( p.getOperation().getName() );
permission.setOperation( operation );
}
if ( p.getResource() != null )
{
Resource resource = new Resource();
resource.setIdentifier( p.getResource().getIdentifier() );
resource.setPattern( p.getResource().isPattern() );
permission.setResource( resource );
}
userPermissions.add( permission );
}
return userPermissions;
}
catch ( RbacManagerException e )
{
log.error( e.getMessage(), e );
throw new RedbackServiceException( e.getMessage() );
}
}
public void validateCredentialsLoose( User user )
throws RedbackServiceException
{
RedbackServiceException redbackServiceException =
new RedbackServiceException( "issues during validating user", 422 );
if ( StringUtils.isEmpty( user.getUserId() ) )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "username.required", null ) );
}
else
{
if ( !user.getUserId().matches( VALID_USERNAME_CHARS ) )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "username.invalid.characters", null ) );
}
}
if ( StringUtils.isEmpty( user.getFullName() ) )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "fullName.required", null ) );
}
if ( StringUtils.isEmpty( user.getEmail() ) )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "email.required", null ) );
}
if ( !StringUtils.equals( user.getPassword(), user.getConfirmPassword() ) )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "passwords.do.not.match", null ) );
}
try
{
if ( !StringUtils.isEmpty( user.getEmail() ) )
{
new InternetAddress( user.getEmail(), true );
}
}
catch ( AddressException e )
{
redbackServiceException.addErrorMessage( new ErrorMessage( "email.invalid", null ) );
}
if ( !redbackServiceException.getErrorMessages().isEmpty() )
{
throw redbackServiceException;
}
}
public void validateCredentialsStrict( User user )
throws RedbackServiceException
{
validateCredentialsLoose( user );
try
{
org.apache.archiva.redback.users.User tmpuser =
userManager.createUser( user.getUserId(), user.getFullName(), user.getEmail() );
user.setPassword( user.getPassword() );
securitySystem.getPolicy().validatePassword( tmpuser );
if ( ( StringUtils.isEmpty( user.getPassword() ) ) )
{
throw new RedbackServiceException( new ErrorMessage( "password.required", null ) );
}
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
private String getBaseUrl()
{
if ( httpServletRequest != null )
{
if ( httpServletRequest != null )
{
return httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName() + (
httpServletRequest.getServerPort() == 80
? ""
: ":" + httpServletRequest.getServerPort() ) + httpServletRequest.getContextPath();
}
}
return null;
}
private org.apache.archiva.redback.users.User updateUser( String userId, Function<org.apache.archiva.redback.users.User, RedbackServiceException> updateFunction ) throws RedbackServiceException
{
try
{
org.apache.archiva.redback.users.User rawUser = userManager.findUser( userId, false );
if ( rawUser != null )
{
RedbackServiceException result = updateFunction.apply( rawUser );
if (result!=null) {
throw result;
}
userManager.updateUser( rawUser, false );
} else {
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND, userId ), 404 );
}
return rawUser;
}
catch ( UserNotFoundException e )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND ), 404 );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
}
}
@Override
public void unlockUser( String userId )
throws RedbackServiceException
{
updateUser( userId, user -> {
user.setLocked( false );
return null;
} );
httpServletResponse.setStatus( 200 );
}
@Override
public void lockUser( String userId )
throws RedbackServiceException
{
updateUser( userId, user -> {
user.setLocked( true );
return null;
} );
httpServletResponse.setStatus( 200 );
}
@Override
public void setRequirePasswordChangeFlag( String userId )
throws RedbackServiceException
{
updateUser( userId, user -> {
user.setPasswordChangeRequired( true );
return null;
} );
httpServletResponse.setStatus( 200 );
}
@Override
public void clearRequirePasswordChangeFlag( String userId )
throws RedbackServiceException
{
updateUser( userId, user -> {
user.setPasswordChangeRequired( false );
return null;
} );
httpServletResponse.setStatus( 200 );
}
}