Additional updates for REST V2

This commit is contained in:
Martin Stockhammer 2020-08-01 22:50:33 +02:00
parent 8242f07b08
commit f24695020b
13 changed files with 397 additions and 70 deletions

View File

@ -26,12 +26,22 @@ public interface Constants
String DEFAULT_PAGE_LIMIT = "1000";
String ERR_UNKNOWN = "redback:unknown_error";
String ERR_USERMANAGER_FAIL = "redback:usermanager_error";
String ERR_ROLEMANAGER_FAIL = "redback:rolemanager_error";
String ERR_RBACMANAGER_FAIL = "redback:rbacmanager_error";
String ERR_USER_EXISTS = "redback:user.exists";
String ERR_USER_ID_EMPTY = "redback:user.id.empty";
String ERR_USER_ID_INVALID = "redback:user.id.invalid";
String ERR_USER_FULL_NAME_EMPTY = "redback:user.fullname.empty";
String ERR_USER_EMAIL_EMPTY = "redback:user.email.empty";
String ERR_USER_ASSIGN_ROLE = "redback:user.role.assign.failure";
String ERR_USER_NOT_VALIDATED = "redback:user.not_validated";
String ERR_USER_ADMIN_EXISTS = "redback:user.admin.exists";
String ERR_USER_ADMIN_BAD_NAME = "redback:user.admin.badname";
String ERR_USER_NOT_FOUND = "redback:user.not_found";
String ERR_PASSWORD_VIOLATION = "redback:user.password_violation";
String ERR_LDAP_GENERIC = "redback:ldap.error";
String ERR_ROLE_MAPPING = "redback:role.mapping.error";
@ -42,10 +52,11 @@ public interface Constants
String ERR_AUTH_FAIL_MSG = "redback:auth.fail";
String ERR_AUTH_ACCOUNT_LOCKED = "redback:auth.account_locked";
String ERR_AUTH_PASSWORD_CHANGE_REQUIRED = "redback:auth.password_change_required";
String ERR_AUTH_USERMANAGER_FAIL = "redback:auth.usermanager_error";
String ERR_AUTH_UNSUPPORTED_GRANT_TYPE = "redback:auth.unsupported_grant";
String ERR_AUTH_INVALID_TOKEN = "redback:auth.invalid_token";
String ERR_AUTH_UNAUTHORIZED_REQUEST = "redback:auth.unauthorized_request";
}

View File

@ -1,4 +1,4 @@
package org.apache.archiva.redback.rest.api.model;
package org.apache.archiva.redback.rest.api.model.v2;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -19,6 +19,9 @@ package org.apache.archiva.redback.rest.api.model;
*/
import javax.xml.bind.annotation.XmlRootElement;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
/**
* @author Martin Stockhammer <martin_s@apache.org>
@ -27,13 +30,21 @@ import javax.xml.bind.annotation.XmlRootElement;
public class AvailabilityStatus
{
boolean exists = false;
OffsetDateTime since;
public AvailabilityStatus() {
public AvailabilityStatus(boolean exists, OffsetDateTime since) {
this.exists = exists;
this.since = since;
}
public AvailabilityStatus(boolean exists, Instant since) {
this.exists = exists;
setSinceByInstant( since );
}
public AvailabilityStatus(boolean exists) {
this.exists = exists;
this.since = OffsetDateTime.ofInstant( Instant.EPOCH, ZoneId.systemDefault() );
}
public boolean isExists( )
@ -45,4 +56,18 @@ public class AvailabilityStatus
{
this.exists = exists;
}
public OffsetDateTime getSince( )
{
return since;
}
public void setSince( OffsetDateTime since )
{
this.since = since;
}
public void setSinceByInstant( Instant since ) {
this.since = OffsetDateTime.ofInstant( since, ZoneId.systemDefault( ) );
}
}

View File

@ -0,0 +1,65 @@
package org.apache.archiva.redback.rest.api.model.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 javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
/**
* @author Olivier Lamy
* @author Martin Stockhammer
*/
@XmlRootElement( name = "registrationKey" )
public class RegistrationKey
implements Serializable
{
private String key;
boolean emailValidationRequired=true;
public RegistrationKey()
{
// nope
}
public RegistrationKey( String key, boolean emailValidationRequired )
{
this.key = key;
this.emailValidationRequired = emailValidationRequired;
}
public String getKey()
{
return key;
}
public void setKey( String key )
{
this.key = key;
}
public boolean isEmailValidationRequired( )
{
return emailValidationRequired;
}
public void setEmailValidationRequired( boolean emailValidationRequired )
{
this.emailValidationRequired = emailValidationRequired;
}
}

View File

@ -23,7 +23,7 @@ import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.Role;
import org.apache.archiva.redback.rest.api.model.User;
import org.apache.archiva.redback.rest.api.model.VerificationStatus;

View File

@ -21,7 +21,6 @@ package org.apache.archiva.redback.rest.api.services;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
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.RegistrationKey;

View File

@ -23,7 +23,7 @@ import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.Role;
import org.apache.archiva.redback.rest.api.model.User;
import org.apache.archiva.redback.rest.api.model.VerificationStatus;

View File

@ -26,14 +26,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.Operation;
import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
import org.apache.archiva.redback.rest.api.model.PasswordStatus;
import org.apache.archiva.redback.rest.api.model.Permission;
import org.apache.archiva.redback.rest.api.model.v2.PingResult;
import org.apache.archiva.redback.rest.api.model.RegistrationKey;
import org.apache.archiva.redback.rest.api.model.ResetPasswordRequest;
import org.apache.archiva.redback.rest.api.model.v2.RegistrationKey;
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.model.VerificationStatus;
@ -97,7 +97,7 @@ public interface UserService
)
}
)
ActionStatus createUser( User user )
User createUser( User user )
throws RedbackServiceException;
@ -125,14 +125,14 @@ public interface UserService
)
}
)
ActionStatus createAdminUser( User user )
User createAdminUser( User user )
throws RedbackServiceException;
@Path( "admin/exists" )
@Path( "admin/status" )
@GET
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true )
AvailabilityStatus isAdminUserExists()
AvailabilityStatus getAdminStatus()
throws RedbackServiceException;
@ -140,14 +140,31 @@ public interface UserService
@DELETE
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_DELETE_OPERATION )
ActionStatus deleteUser( @PathParam( "userId" ) String userId )
@io.swagger.v3.oas.annotations.Operation( summary = "Creates a user",
responses = {
@ApiResponse( responseCode = "200",
description = "If user deletion was successful"
),
@ApiResponse( responseCode = "404", description = "User does not exist" )
}
)
void deleteUser( @PathParam( "userId" ) String userId )
throws RedbackServiceException;
@Path( "{userId}" )
@PUT
@Produces( { MediaType.APPLICATION_JSON } )
@Produces( {MediaType.APPLICATION_JSON} )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
ActionStatus updateUser( @PathParam( "userId" ) String userId, User user )
@io.swagger.v3.oas.annotations.Operation( summary = "Creates a user",
responses = {
@ApiResponse( responseCode = "200",
description = "If update was successful"
),
@ApiResponse( responseCode = "404", description = "User does not exist" ),
@ApiResponse( responseCode = "422", description = "Update data was not valid. E.g. password violations." )
}
)
User updateUser( @PathParam( "userId" ) String userId, User user )
throws RedbackServiceException;
/**
@ -171,18 +188,18 @@ public interface UserService
/**
*/
@Path( "{userId}/passwordStatus" )
@Path( "{userId}/password/status" )
@GET
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
PasswordStatus passwordChangeRequired( @PathParam( "userId" ) String userId )
PasswordStatus getPasswordStatus( @PathParam( "userId" ) String userId )
throws RedbackServiceException;
/**
* update only the current user and this fields: fullname, email, password.
* The service verifies the current logged user with the one passed in the method
*/
@Path( "{userId}" )
@Path( "me" )
@PUT
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noPermission = true )
@ -196,7 +213,7 @@ public interface UserService
PingResult ping()
throws RedbackServiceException;
@Path( "{userId}/clearCache" )
@Path( "{userId}/cache/clear" )
@POST
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
@ -218,9 +235,9 @@ public interface UserService
throws RedbackServiceException;
/**
* if redback is not configured for email validation is required, -1 is returned as key
* @since 1.4
*/
*
*
* @return*/
@Path( "{userId}/register" )
@POST
@Produces( { MediaType.APPLICATION_JSON } )
@ -231,9 +248,8 @@ public interface UserService
/**
*
* @param resetPasswordRequest contains username for send a password reset email
* @since 1.4
*/
@Path( "{userId}/resetPassword" )
@Path( "{userId}/password/reset" )
@POST
@Produces( { MediaType.APPLICATION_JSON } )
@Consumes( { MediaType.APPLICATION_JSON } )
@ -242,7 +258,6 @@ public interface UserService
throws RedbackServiceException;
/**
* @since 1.4
*/
@Path( "{userId}/permissions" )
@GET
@ -265,26 +280,26 @@ public interface UserService
* @return the current logged user permissions, if no logged user guest permissions are returned
* @since 1.4
*/
@Path( "{userId}/self/permissions" )
@Path( "me/permissions" )
@GET
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true, noPermission = true )
Collection<Permission> getCurrentUserPermissions(@PathParam( "userId" ) String userId)
Collection<Permission> getCurrentUserPermissions( )
throws RedbackServiceException;
/**
* @return the current logged user operations, if no logged user guest operations are returned
* @since 1.4
*/
@Path( "{userId}/self/operations" )
@Path( "me/operations" )
@GET
@Produces( { MediaType.APPLICATION_JSON } )
@RedbackAuthorization( noRestriction = true, noPermission = true )
Collection<Operation> getCurrentUserOperations(@PathParam( "userId" ) String userId)
Collection<Operation> getCurrentUserOperations( )
throws RedbackServiceException;
@Path( "{userId}/registration/{key}/validate" )
@Path( "{userId}/register/{key}/validate" )
@GET
@Produces( {MediaType.APPLICATION_JSON} )
@RedbackAuthorization( noRestriction = true, noPermission = true )

View File

@ -29,7 +29,7 @@ import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
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.Role;
import org.apache.archiva.redback.rest.api.model.RoleTemplate;

View File

@ -199,7 +199,7 @@ public class DefaultAuthenticationService
catch ( UserManagerException e )
{
log.warn( "UserManagerException: {}", e.getMessage() );
throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_USERMANAGER_FAIL, e.getMessage( ) ) );
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
}
}

View File

@ -37,17 +37,19 @@ 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.AvailabilityStatus;
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.PasswordStatus;
import org.apache.archiva.redback.rest.api.model.Permission;
import org.apache.archiva.redback.rest.api.model.RegistrationKey;
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;
@ -87,6 +89,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.apache.archiva.redback.rest.api.Constants.*;
@ -98,6 +101,7 @@ public class DefaultUserService
private final Logger log = LoggerFactory.getLogger( getClass() );
private static final String VALID_USERNAME_CHARS = "[a-zA-Z_0-9\\-.@]*";
private static final String[] INVALID_USER_NAMES = { "me" };
private UserManager userManager;
@ -165,9 +169,14 @@ public class DefaultUserService
@Override
public ActionStatus createUser( User user )
public User createUser( User user )
throws RedbackServiceException
{
User result;
if ( Arrays.binarySearch( INVALID_USER_NAMES, user.getUserId( ) ) >=0 )
{
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_ID_INVALID, user.getUserId() ), 405 );
}
try
{
@ -231,6 +240,7 @@ public class DefaultUserService
}
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() );
}
@ -243,11 +253,11 @@ public class DefaultUserService
{
throw new RedbackServiceException( ErrorMessage.of(ERR_UNKNOWN, e.getMessage() ) );
}
return ActionStatus.SUCCESS;
return result;
}
@Override
public ActionStatus deleteUser( String userId )
public void deleteUser( String userId )
throws RedbackServiceException
{
@ -264,26 +274,26 @@ public class DefaultUserService
catch ( RbacManagerException e )
{
log.error( e.getMessage(), e );
throw new RedbackServiceException( e.getMessage() );
throw new RedbackServiceException( ErrorMessage.of( ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
}
try
{
userManager.deleteUser( userId );
return ActionStatus.SUCCESS;
}
catch ( UserNotFoundException e )
{
log.error( e.getMessage(), e );
throw new RedbackServiceException( e.getMessage() );
throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND ), 404 );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
}
finally
{
removeFromCache( userId );
}
httpServletResponse.setStatus( 200 );
}
@ -405,26 +415,33 @@ public class DefaultUserService
}
@Override
public ActionStatus updateUser( String userId, User user )
public User updateUser( String userId, User user )
throws RedbackServiceException
{
try
{
org.apache.archiva.redback.users.User rawUser = userManager.findUser( user.getUserId(), false );
rawUser.setFullName( user.getFullName() );
rawUser.setEmail( user.getEmail() );
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() );
rawUser.setPassword( user.getPassword() );
if ( !StringUtils.isEmpty( user.getPassword( ) ) )
rawUser.setPassword( user.getPassword() );
rawUser.setPasswordChangeRequired( user.isPasswordChangeRequired() );
rawUser.setPermanent( user.isPermanent() );
userManager.updateUser( rawUser );
return ActionStatus.SUCCESS;
org.apache.archiva.redback.users.User updatedUser = userManager.updateUser( rawUser );
return getRestUser( updatedUser );
}
catch ( UserNotFoundException e )
{
throw new RedbackServiceException( e.getMessage() );
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 )
{
@ -532,18 +549,20 @@ public class DefaultUserService
}
@Override
public ActionStatus createAdminUser( User adminUser )
public User createAdminUser( User adminUser )
throws RedbackServiceException
{
if ( isAdminUserExists().isExists() )
User result;
if ( getAdminStatus().isExists() )
{
log.warn( "Admin user exists already" );
return ActionStatus.FAIL;
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(new ErrorMessage("admin.wrongUsername"));
throw new RedbackServiceException(ErrorMessage.of(Constants.ERR_USER_ADMIN_BAD_NAME ), 405);
}
try
@ -559,27 +578,35 @@ public class DefaultUserService
user.setValidated( true );
userManager.addUser( user );
result = getRestUser( user );
roleManager.assignRole( "system-administrator", user.getUsername() );
}
catch ( RoleManagerException e )
{
throw new RedbackServiceException( e.getMessage() );
throw new RedbackServiceException( ErrorMessage.of( ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
}
catch ( UserManagerException e )
{
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ) );
}
return ActionStatus.SUCCESS;
httpServletResponse.setStatus( 201 );
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePath().toString() );
return result;
}
@Override
public AvailabilityStatus isAdminUserExists()
public AvailabilityStatus getAdminStatus()
throws RedbackServiceException
{
try
{
userManager.findUser( config.getString( UserConfigurationKeys.DEFAULT_ADMIN ) );
return new AvailabilityStatus( true );
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 )
{
@ -593,7 +620,7 @@ public class DefaultUserService
{
return new AvailabilityStatus( false );
}
throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ) );
}
return new AvailabilityStatus( false );
}
@ -722,7 +749,7 @@ public class DefaultUserService
securityPolicy.setEnabled( false );
userManager.addUser( u );
return new RegistrationKey( authkey.getKey() );
return new RegistrationKey( authkey.getKey(), true );
}
catch ( KeyManagerException e )
@ -744,7 +771,7 @@ public class DefaultUserService
try
{
userManager.addUser( u );
return new RegistrationKey( "-1" );
return new RegistrationKey( "-1", false );
}
catch ( UserManagerException e )
{
@ -763,7 +790,7 @@ public class DefaultUserService
@Override
public Collection<Permission> getCurrentUserPermissions(String userId)
public Collection<Permission> getCurrentUserPermissions( )
throws RedbackServiceException
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
@ -781,7 +808,7 @@ public class DefaultUserService
}
@Override
public Collection<Operation> getCurrentUserOperations(String userId)
public Collection<Operation> getCurrentUserOperations( )
throws RedbackServiceException
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
@ -1036,7 +1063,7 @@ public class DefaultUserService
}
@Override
public PasswordStatus passwordChangeRequired( String userId )
public PasswordStatus getPasswordStatus( String userId )
throws RedbackServiceException
{
User user = getUser( userId );

View File

@ -24,6 +24,7 @@ import org.apache.archiva.redback.rest.api.model.User;
import org.apache.archiva.redback.rest.api.services.RoleManagementService;
import org.apache.archiva.redback.rest.api.services.UserService;
import org.apache.commons.lang3.StringUtils;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
@ -45,6 +46,7 @@ public class RoleManagementServiceTest
{
@Ignore
@Test
public void roleExist()
throws Exception

View File

@ -37,6 +37,7 @@ import java.util.List;
import java.util.Map;
import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.replaceFiltersWith;
import static io.restassured.http.ContentType.JSON;
import static org.junit.jupiter.api.Assertions.*;
@ -140,11 +141,27 @@ public class NativeUserServiceTest extends AbstractNativeRestServices
jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
jsonAsMap.put( "password", "pAssw0rD" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 405 ).extract( ).response( );
.then( ).statusCode( 405 );
}
@Test
void createInvalidMeUser() {
String token = getAdminToken( );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "me" );
jsonAsMap.put( "email", "me@lordoftherings.org" );
jsonAsMap.put( "fullName", "Its just me" );
jsonAsMap.put( "password", "pAssw0rD" );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 405 );
}
@ -231,4 +248,171 @@ public class NativeUserServiceTest extends AbstractNativeRestServices
}
}
@Test
void createExistingAdminUser() {
String token = null;
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "admin" );
jsonAsMap.put( "email", "admin@lordoftherings.org" );
jsonAsMap.put( "fullName", "Admin" );
jsonAsMap.put( "password", "pAssw0rD" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.redirects().follow( false )
.post( "admin" )
.then( ).statusCode( 303 ).extract( ).response( );
assertTrue( response.getHeader( "Location" ).endsWith( "/users/admin" ) );
}
@Test
void checkAdminStatus() {
String token = null;
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.get( "admin/status" )
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );
assertTrue( response.body( ).jsonPath( ).getBoolean("exists" ) );
assertNotNull( response.body( ).jsonPath( ).get( "since" ) );
}
@Test
void deleteUser() {
String token = getAdminToken( );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "aragorn" );
jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
jsonAsMap.put( "password", "pAssw0rD" );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 201 );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.delete( "aragorn" )
.then( ).statusCode( 200 ).extract( ).response( );
}
@Test
void deleteNonexistingUser() {
String token = getAdminToken( );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.delete( "galadriel" )
.then( ).statusCode( 404 ).extract( ).response( );
}
@Test
void deleteUserPermissionDenied() {
String adminToken = getAdminToken( );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "aragorn" );
jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
jsonAsMap.put( "password", "pAssw0rD" );
given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 201 );
try
{
String token = null;
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.delete( "aragorn" )
.then( ).statusCode( 401 ).extract( ).response( );
} finally
{
given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
.delete( "aragorn" )
.then( ).statusCode( 200 );
}
}
@Test
void updateUser() {
String token = getAdminToken( );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "aragorn" );
jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
jsonAsMap.put( "password", "pAssw0rD" );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 201 );
try
{
jsonAsMap = new HashMap<>( );
jsonAsMap.put( "email", "aragorn2@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor the Second" );
jsonAsMap.put( "password", "pAssw0rDXX" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.put( "aragorn" )
.then( ).statusCode( 200 ).extract( ).response( );
assertNotNull( response );
assertEquals( "aragorn2@lordoftherings.org", response.body( ).jsonPath( ).getString( "email" ) );
}finally
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.delete( "aragorn" )
.then( ).statusCode( 200 );
}
}
@Test
void updateNonExistingUser() {
String token = getAdminToken( );
HashMap<Object, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "email", "aragorn2@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor the Second" );
jsonAsMap.put( "password", "pAssw0rDXX" );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.put( "aragorn" )
.then( ).statusCode( 404 );
}
@Test
void updateUserPasswordViolation() {
String token = getAdminToken( );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "user_id", "aragorn" );
jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
jsonAsMap.put( "password", "pAssw0rD" );
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.post( )
.then( ).statusCode( 201 );
try
{
jsonAsMap = new HashMap<>( );
jsonAsMap.put( "email", "aragorn2@lordoftherings.org" );
jsonAsMap.put( "fullName", "Aragorn King of Gondor the Second" );
jsonAsMap.put( "password", "pAssw0rD" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.body( jsonAsMap )
.when( )
.put( "aragorn" )
.prettyPeek()
.then( ).statusCode( 422 ).extract( ).response( );
assertNotNull( response );
assertEquals( "user.password.violation.reuse", response.body( ).jsonPath( ).get( "errorMessages[0].errorKey" ) );
}finally
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.delete( "aragorn" )
.then( ).statusCode( 200 );
}
}
}

View File

@ -129,7 +129,6 @@ public class UserServiceTest
@Test
public void getUsersWithoutAuthz( )
throws Exception
{
UserService userService = getUserService( null );
assertThrows( ForbiddenException.class, ( ) -> {
@ -471,7 +470,7 @@ public class UserServiceTest
throws Exception
{
createGuestIfNeeded( );
Collection<Permission> permissions = getUserService( null ).getCurrentUserPermissions("guest" );
Collection<Permission> permissions = getUserService( null ).getCurrentUserPermissions( );
log.info( "guest permisssions: {}", permissions );
}
@ -488,7 +487,7 @@ public class UserServiceTest
throws Exception
{
createGuestIfNeeded( );
Collection<Operation> operations = getUserService( null ).getCurrentUserOperations("guest" );
Collection<Operation> operations = getUserService( null ).getCurrentUserOperations( );
log.info( "guest operations: {}", operations );
}