This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva-redback-core.git

commit 8242f07b084ede25c768afb14f4c647ddacf5563
Author: Martin Stockhammer <[email protected]>
AuthorDate: Sun Jul 26 21:10:44 2020 +0200

    Improving V2 REST services
---
 .../apache/archiva/redback/rest/api/Constants.java |  28 ++-
 .../redback/rest/api/model/ErrorMessage.java       |   4 +
 .../services/v2/DefaultAuthenticationService.java  |  35 ++--
 .../rest/services/v2/DefaultGroupService.java      |  24 ++-
 .../rest/services/v2/DefaultUserService.java       |  33 ++--
 .../services/v2/AbstractNativeRestServices.java    |  14 ++
 .../rest/services/v2/NativeUserServiceTest.java    | 197 +++++++++++++++++++--
 7 files changed, 277 insertions(+), 58 deletions(-)

diff --git 
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
 
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
index cd72bf5..cc20152 100644
--- 
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
+++ 
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
@@ -21,7 +21,31 @@ package org.apache.archiva.redback.rest.api;
 /**
  * @author Martin Stockhammer <[email protected]>
  */
-public class Constants
+public interface Constants
 {
-    public static final String DEFAULT_PAGE_LIMIT = "1000";
+    String DEFAULT_PAGE_LIMIT = "1000";
+
+    String ERR_UNKNOWN = "redback:unknown_error";
+    String ERR_USER_EXISTS = "redback:user.exists";
+    String ERR_USER_ID_EMPTY = "redback:user.id.empty";
+    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_LDAP_GENERIC = "redback:ldap.error";
+    String ERR_ROLE_MAPPING = "redback:role.mapping.error";
+    String ERR_ROLE_MAPPING_NOT_FOUND = "redback:role.mapping.not_found";
+
+    String ERR_AUTH_BAD_CODE = "redback:auth.bad_authorization_code";
+    String ERR_AUTH_INVALID_CREDENTIALS = "redback:auth.invalid_credentials";
+    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";
+
+
 }
diff --git 
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/ErrorMessage.java
 
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/ErrorMessage.java
index d47e746..0615639 100644
--- 
a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/ErrorMessage.java
+++ 
b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/ErrorMessage.java
@@ -57,6 +57,10 @@ public class ErrorMessage
         this.args = args;
     }
 
+    public static ErrorMessage of(String errorKey, String... args) {
+        return new ErrorMessage( errorKey, args );
+    }
+
     public String getErrorKey()
     {
         return errorKey;
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
index 2c62703..1272b97 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultAuthenticationService.java
@@ -31,11 +31,11 @@ import 
org.apache.archiva.redback.policy.AccountLockedException;
 import org.apache.archiva.redback.policy.MustChangePasswordException;
 import org.apache.archiva.redback.rest.api.model.ErrorMessage;
 import org.apache.archiva.redback.rest.api.model.GrantType;
-import org.apache.archiva.redback.rest.api.model.v2.PingResult;
-import org.apache.archiva.redback.rest.api.model.v2.TokenRequest;
 import org.apache.archiva.redback.rest.api.model.TokenResponse;
 import org.apache.archiva.redback.rest.api.model.User;
 import org.apache.archiva.redback.rest.api.model.UserLogin;
+import org.apache.archiva.redback.rest.api.model.v2.PingResult;
+import org.apache.archiva.redback.rest.api.model.v2.TokenRequest;
 import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
 import org.apache.archiva.redback.rest.api.services.v2.AuthenticationService;
 import org.apache.archiva.redback.rest.services.interceptors.RedbackPrincipal;
@@ -56,9 +56,10 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
 import java.security.Principal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
+import static org.apache.archiva.redback.rest.api.Constants.*;
+
 /**
  *
  * Authentication service provides REST methods for authentication and 
verification.
@@ -127,7 +128,7 @@ public class DefaultAuthenticationService
         throws RedbackServiceException
     {
         if (!GrantType.AUTHORIZATION_CODE.equals(loginRequest.getGrantType())) 
{
-            throw new RedbackServiceException( 
"redback:bad_authorization_code", Response.Status.FORBIDDEN.getStatusCode( ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_BAD_CODE ), Response.Status.FORBIDDEN.getStatusCode( ) );
         }
         String userName = loginRequest.getUserId(), password = 
loginRequest.getPassword();
         PasswordBasedAuthenticationDataSource authDataSource =
@@ -146,7 +147,7 @@ public class DefaultAuthenticationService
                 if ( !user.isValidated() )
                 {
                     log.info( "user {} not validated", user.getUsername() );
-                    throw new RedbackServiceException( 
"redback:user-not-validated", Response.Status.FORBIDDEN.getStatusCode() );
+                    throw new RedbackServiceException( ErrorMessage.of( 
ERR_USER_NOT_VALIDATED, user.getUsername() ), 
Response.Status.FORBIDDEN.getStatusCode() );
                 }
                 // Stateless services no session
                 // httpAuthenticator.authenticate( authDataSource, 
httpServletRequest.getSession( true ) );
@@ -162,45 +163,43 @@ public class DefaultAuthenticationService
                 {
                     if ( authenticationFailureCause.getCause() == 
AuthenticationConstants.AUTHN_NO_SUCH_USER )
                     {
-                        errorMessages.add( new ErrorMessage( 
"redback:incorrect.username.password" ) );
+                        errorMessages.add( ErrorMessage.of( 
ERR_AUTH_INVALID_CREDENTIALS ) );
                     }
                     else
                     {
-                        errorMessages.add( new ErrorMessage().message( 
"redback:"+authenticationFailureCause.getMessage() ) );
+                        errorMessages.add( ErrorMessage.of( ERR_AUTH_FAIL_MSG, 
authenticationFailureCause.getMessage() ) );
                     }
                 }
                 response.setHeader( "WWW-Authenticate", "redback-login 
realm="+httpServletRequest.getRemoteHost() );
                 throw new RedbackServiceException( errorMessages , 
Response.Status.UNAUTHORIZED.getStatusCode());
             }
             response.setHeader( "WWW-Authenticate", "redback-login 
realm="+httpServletRequest.getRemoteHost() );
-            throw new RedbackServiceException( "redback:login-failed", 
Response.Status.UNAUTHORIZED.getStatusCode() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_FAIL_MSG ), Response.Status.UNAUTHORIZED.getStatusCode() );
         }
 
         catch ( AuthenticationException e )
         {
             log.debug( "Authentication error: {}", e.getMessage( ), e );
-            throw new RedbackServiceException( "redback:login-failed", 
Response.Status.UNAUTHORIZED.getStatusCode() );
+            throw new RedbackServiceException(ErrorMessage.of( 
ERR_AUTH_FAIL_MSG ), Response.Status.UNAUTHORIZED.getStatusCode() );
         }
         catch ( UserNotFoundException e )
         {
             log.debug( "User not found: {}", e.getMessage( ), e );
-            throw new RedbackServiceException( "redback:login-failed", 
Response.Status.UNAUTHORIZED.getStatusCode() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_INVALID_CREDENTIALS ), Response.Status.UNAUTHORIZED.getStatusCode() );
         }
         catch (AccountLockedException e) {
             log.info( "Account locked: {}", e.getMessage( ), e );
-            throw new RedbackServiceException( "redback:account-locked", 
Response.Status.FORBIDDEN.getStatusCode() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_ACCOUNT_LOCKED ), Response.Status.FORBIDDEN.getStatusCode() );
         }
         catch ( MustChangePasswordException e )
         {
             log.debug( "Password change required: {}", e.getMessage( ), e );
-            throw new RedbackServiceException( 
"redback:password-change-required", Response.Status.FORBIDDEN.getStatusCode( ) 
);
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_PASSWORD_CHANGE_REQUIRED ), Response.Status.FORBIDDEN.getStatusCode( ) 
);
         }
         catch ( UserManagerException e )
         {
             log.warn( "UserManagerException: {}", e.getMessage() );
-            List<ErrorMessage> errorMessages =
-                Arrays.asList( new ErrorMessage().message( 
"UserManagerException: " + e.getMessage() ) );
-            throw new RedbackServiceException( errorMessages );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_USERMANAGER_FAIL, e.getMessage( ) ) );
         }
 
     }
@@ -210,7 +209,7 @@ public class DefaultAuthenticationService
     {
         if (!GrantType.REFRESH_TOKEN.equals(request.getGrantType())) {
             log.debug( "Bad grant type {}, expected: refresh_token", 
request.getGrantType( ).name( ).toLowerCase( ) );
-            throw new RedbackServiceException( "redback:bad_grant", 
Response.Status.FORBIDDEN.getStatusCode( ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_UNSUPPORTED_GRANT_TYPE, request.getGrantType().getLabel() ), 
Response.Status.FORBIDDEN.getStatusCode( ) );
         }
         try
         {
@@ -222,7 +221,7 @@ public class DefaultAuthenticationService
         }
         catch ( TokenAuthenticationException e )
         {
-            throw new RedbackServiceException( e.getError( ).getError( ), 
Response.Status.UNAUTHORIZED.getStatusCode( ) );
+            throw new RedbackServiceException( 
ErrorMessage.of(ERR_AUTH_INVALID_TOKEN, e.getError( ).getError( )), 
Response.Status.UNAUTHORIZED.getStatusCode( ) );
         }
     }
 
@@ -235,7 +234,7 @@ public class DefaultAuthenticationService
         {
             return buildRestUser( pri.getUser( ) );
         } else {
-            throw new RedbackServiceException( "redback:not_authenticated", 
Response.Status.UNAUTHORIZED.getStatusCode( ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_AUTH_UNAUTHORIZED_REQUEST ), Response.Status.UNAUTHORIZED.getStatusCode( ) 
);
         }
     }
 
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
index ff70ea7..d5610ac 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
@@ -27,6 +27,7 @@ import org.apache.archiva.redback.common.ldap.role.LdapGroup;
 import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
 import org.apache.archiva.redback.common.ldap.role.LdapRoleMapperConfiguration;
 import org.apache.archiva.redback.rest.api.model.ActionStatus;
+import org.apache.archiva.redback.rest.api.model.ErrorMessage;
 import org.apache.archiva.redback.rest.api.model.Group;
 import org.apache.archiva.redback.rest.api.model.v2.GroupMapping;
 import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
@@ -51,6 +52,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static org.apache.archiva.redback.rest.api.Constants.*;
+
 /**
  *
  * LDAP implementation of the group service
@@ -106,10 +109,13 @@ public class DefaultGroupService
             List<LdapGroup> groups = ldapRoleMapper.getAllGroupObjects( 
context );
             return PagedResult.of( groups.size( ), offset, limit, 
groups.stream( ).skip( offset ).limit( limit ).map( 
DefaultGroupService::getGroupFromLdap ).collect( Collectors.toList( ) ) );
         }
-        catch ( LdapException | MappingException e )
+        catch ( LdapException  e )
         {
-            log.error( e.getMessage(), e );
-            throw new RedbackServiceException( e.getMessage() );
+            log.error( "LDAP Error {}", e.getMessage(), e );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_LDAP_GENERIC ) );
+        } catch (MappingException e) {
+            log.error( "Mapping Error {}", e.getMessage(), e );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING, e.getMessage( ) ) );
         }
         finally
         {
@@ -150,7 +156,7 @@ public class DefaultGroupService
                 catch ( LdapException e )
                 {
                     log.error( "Could not create ldap connection {}", 
e.getMessage( ) );
-                    throw new RedbackServiceException( "Error while talking to 
group registry", 500 );
+                    throw new RedbackServiceException( ErrorMessage.of( 
ERR_LDAP_GENERIC, "Error while talking to group registry"), 500 );
                 }
                 catch ( ObjectNotFoundException e ) {
                     GroupMapping ldapGroupMapping = new GroupMapping( 
groupName, "", new ArrayList<>( entry.getValue( ) ) );
@@ -168,7 +174,7 @@ public class DefaultGroupService
         catch ( MappingException e )
         {
             log.error( e.getMessage(), e );
-            throw new RedbackServiceException( e.getMessage() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING, e.getMessage( ) ) );
         }
     }
 
@@ -189,7 +195,7 @@ public class DefaultGroupService
         catch ( MappingException e )
         {
             log.error( e.getMessage(), e );
-            throw new RedbackServiceException( e.getMessage() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING, e.getMessage( ) ) );
         }
         return ActionStatus.SUCCESS;
     }
@@ -205,7 +211,7 @@ public class DefaultGroupService
         catch ( MappingException e )
         {
             log.error( e.getMessage(), e );
-            throw new RedbackServiceException( e.getMessage() );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING, e.getMessage( ) ) );
         }
         return ActionStatus.SUCCESS;
     }
@@ -219,7 +225,7 @@ public class DefaultGroupService
         }
         catch ( MappingException e )
         {
-            throw new RedbackServiceException( "Group mapping not found ", 404 
);
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING_NOT_FOUND), 404 );
         }
         try
         {
@@ -230,7 +236,7 @@ public class DefaultGroupService
         catch ( MappingException e )
         {
             log.error( "Could not update mapping {}", e.getMessage( ) );
-            throw new RedbackServiceException( e.getMessage( ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_ROLE_MAPPING, e.getMessage( ) ) );
         }
     }
 
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
index 63bc816..b69db52 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
@@ -45,16 +45,16 @@ 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.ErrorMessage;
 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.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.model.VerificationStatus;
 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;
@@ -77,8 +77,10 @@ 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.UriInfo;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -86,6 +88,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
+import static org.apache.archiva.redback.rest.api.Constants.*;
+
 @Service( "v2.userService#rest" )
 public class DefaultUserService
     implements UserService
@@ -145,6 +149,12 @@ public class DefaultUserService
     @Context
     private HttpServletRequest httpServletRequest;
 
+    @Context
+    private HttpServletResponse httpServletResponse;
+
+    @Context
+    private UriInfo uriInfo;
+
     @Inject
     public DefaultUserService( @Named( value = "userManager#default" ) 
UserManager userManager,
                                SecuritySystem securitySystem )
@@ -164,8 +174,9 @@ public class DefaultUserService
             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(
-                    new ErrorMessage( "user " + user.getUserId() + " already 
exists" ) );
+                    ErrorMessage.of( ERR_USER_EXISTS, user.getUserId() ), 303 
);
             }
         }
         catch ( UserNotFoundException e )
@@ -175,23 +186,23 @@ public class DefaultUserService
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( 
e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_UNKNOWN, 
e.getMessage() ) );
         }
 
         // data validation
         if ( StringUtils.isEmpty( user.getUserId() ) )
         {
-            throw new RedbackServiceException( new ErrorMessage( "username 
cannot be empty" ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_USER_ID_EMPTY ), 405 );
         }
 
         if ( StringUtils.isEmpty( user.getFullName() ) )
         {
-            throw new RedbackServiceException( new ErrorMessage( "fullName 
cannot be empty" ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_USER_FULL_NAME_EMPTY ), 405 );
         }
 
         if ( StringUtils.isEmpty( user.getEmail() ) )
         {
-            throw new RedbackServiceException( new ErrorMessage( "email cannot 
be empty" ) );
+            throw new RedbackServiceException( ErrorMessage.of( 
ERR_USER_EMAIL_EMPTY ), 405 );
         }
 
         try
@@ -220,15 +231,17 @@ public class DefaultUserService
             }
 
             roleManager.assignRole( 
RedbackRoleConstants.REGISTERED_USER_ROLE_ID, u.getUsername() );
+            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( new ErrorMessage( 
"assign.role.failure", null ) );
+            throw new RedbackServiceException( 
ErrorMessage.of(ERR_USER_ASSIGN_ROLE ) );
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( 
e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of(ERR_UNKNOWN,  
e.getMessage() ) );
         }
         return ActionStatus.SUCCESS;
     }
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
index 54b84ec..da80867 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
@@ -382,6 +382,19 @@ public abstract class AbstractNativeRestServices
         this.adminRefreshToken = result.body( ).jsonPath( ).getString( 
"refresh_token" );
     }
 
+    protected String getUserToken(String userId, String password) {
+        Map<String, Object> jsonAsMap = new HashMap<>();
+        jsonAsMap.put( "grant_type", "authorization_code" );
+        jsonAsMap.put("user_id", userId);
+        jsonAsMap.put("password", password );
+        Response result = given( ).spec( getAuthRequestSpecBuilder().build() )
+            .contentType( JSON )
+            .body( jsonAsMap )
+            .when( ).post( "/authenticate").prettyPeek().then( ).statusCode( 
200 )
+            .extract( ).response( );
+        result.getBody( ).prettyPrint( );
+        return result.body( ).jsonPath( ).getString( "access_token" );
+    }
     protected String getAdminToken()  {
         if (this.adminToken == null) {
             initAdminToken();
@@ -389,6 +402,7 @@ public abstract class AbstractNativeRestServices
         return this.adminToken;
     }
 
+
     protected String getAdminRefreshToken()  {
         if (this.adminRefreshToken == null) {
             initAdminToken();
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
index 9fecfd9..0888c19 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
@@ -19,22 +19,36 @@ package org.apache.archiva.redback.rest.services.v2;
  */
 
 import io.restassured.response.Response;
-import org.apache.archiva.redback.rest.api.model.Group;
+import org.apache.archiva.redback.rest.api.model.v2.User;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
 
+import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Map;
 
 import static io.restassured.RestAssured.given;
 import static io.restassured.http.ContentType.JSON;
 import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
 
 /**
  * @author Martin Stockhammer <[email protected]>
  */
+@ExtendWith( SpringExtension.class )
+@ContextConfiguration(
+    locations = {"classpath:/ldap-spring-test.xml"} )
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag("rest-native")
+@TestMethodOrder( MethodOrderer.Random.class )
 public class NativeUserServiceTest extends AbstractNativeRestServices
 {
     @Override
@@ -55,21 +69,166 @@ public class NativeUserServiceTest extends 
AbstractNativeRestServices
         super.shutdownNative();
     }
 
-//    @Test
-//    void getGroups() {
-//        String token = getAdminToken( );
-//        Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON ).when( )
-//            .get( ).then( ).statusCode( 200 ).extract( ).response( );
-//        assertNotNull( response );
-//        List<Group> data = response.body( ).jsonPath( ).getList(  "data", 
Group.class );
-//        assertNotNull( data );
-//        assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( 
).get( "pagination.offset" ) );
-//        assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( 
).get( "pagination.limit" ) );
-//        assertEquals( Integer.valueOf( 6 ), response.body( ).jsonPath( 
).get( "pagination.totalCount" ) );
-//        assertEquals( 6, data.size( ) );
-//        String[] values = data.stream( ).map( ldapInfo -> ldapInfo.getName( 
) ).sorted( ).collect( Collectors.toList( ) ).toArray( new String[0] );
-//        assertArrayEquals( getTestGroupList( ).toArray( new String[0] ), 
values );
-//        assertEquals( "uid=admin," + this.peopleSuffix, data.get( 0 
).getMemberList( ).get( 0 ) );
-//    }
+    @Test
+    void getUsers() {
+        String token = getAdminToken( );
+        Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+            .when( ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+        assertNotNull( response );
+        List<User> userData = response.body( ).jsonPath( ).getList( "data", 
User.class );
+        assertNotNull( userData );
+        assertEquals( 2, userData.size( ) );
+        assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( 
"pagination.offset" ) );
+        assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( 
).get( "pagination.limit" ) );
+        assertEquals( Integer.valueOf( 2 ), response.body( ).jsonPath( ).get( 
"pagination.totalCount" ) );
+    }
+
+    @Test
+    void getUsersWithoutLogin() {
+        given( ).spec( getRequestSpec(  ) ).contentType( JSON )
+            .when( ).get( ).then( ).statusCode( 403 );
+    }
+
+    @Test
+    void getUser() {
+        String token = getAdminToken( );
+        Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+            .when( ).get( "admin" ).then( ).statusCode( 200 ).extract( 
).response( );
+        assertNotNull( response );
+        assertEquals( "jpa:admin", response.body( ).jsonPath( ).get( "id" ) );
+        assertEquals( "admin", response.body( ).jsonPath( ).get( "user_id" ) );
+        assertEquals( "the admin user", response.body( ).jsonPath( ).get( 
"fullName" ) );
+    }
+
+    @Test
+    void getUserWithoutLogin() {
+        given( ).spec( getRequestSpec(  ) ).contentType( JSON )
+            .when( ).get( "admin" ).then( ).statusCode( 403 );
+    }
+
+
+    @Test
+    void createUser() {
+        String token = getAdminToken( );
+        try
+        {
+            Map<String, Object> jsonAsMap = new HashMap<>( );
+            jsonAsMap.put( "user_id", "aragorn" );
+            jsonAsMap.put( "email", "[email protected]" );
+            jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
+            jsonAsMap.put( "password", "pAssw0rD" );
+            Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+                .body( jsonAsMap )
+                .when( )
+                .post( )
+                .then( ).statusCode( 201 ).extract( ).response( );
+            assertTrue( response.getHeader( "Location" ).endsWith( "/aragorn" 
) );
+
+        } finally
+        {
+            given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+                .when( ).delete( "aragorn").then( ).statusCode( 200 );
+
+        }
+    }
+
+    @Test
+    void createInvalidUser() {
+        String token = getAdminToken( );
+        Map<String, Object> jsonAsMap = new HashMap<>( );
+        jsonAsMap.put( "user_id", "" );
+        jsonAsMap.put( "email", "[email protected]" );
+        jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
+        jsonAsMap.put( "password", "pAssw0rD" );
+        Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+            .body( jsonAsMap )
+            .when( )
+            .post( )
+            .then( ).statusCode( 405 ).extract( ).response( );
+
+    }
+
+
+    @Test
+    void createUserAndPermissionFail() {
+        String token = getAdminToken( );
+        try
+        {
+            Map<String, Object> jsonAsMap = new HashMap<>( );
+            jsonAsMap.put( "user_id", "aragorn" );
+            jsonAsMap.put( "email", "[email protected]" );
+            jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
+            jsonAsMap.put( "validated", true );
+            jsonAsMap.put( "password", "pAssw0rD" );
+            Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+                .body( jsonAsMap )
+                .when( )
+                .post( )
+                .then( ).statusCode( 201 ).extract( ).response( );
+            assertTrue( response.getHeader( "Location" ).endsWith( "/aragorn" 
) );
+
+            String userToken = getUserToken( "aragorn", "pAssw0rD" );
+
+            jsonAsMap = new HashMap<>( );
+            jsonAsMap.put( "user_id", "arwen" );
+            jsonAsMap.put( "email", "[email protected]" );
+            jsonAsMap.put( "fullName", "Arwen Daughter of Elrond" );
+            jsonAsMap.put( "password", "pAssw0rD" );
+            given( ).spec( getRequestSpec( userToken ) ).contentType( JSON )
+                .body( jsonAsMap )
+                .when( )
+                .post( )
+                .then( ).statusCode( 403 );
+
+
+        } finally
+        {
+            given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+                .when( ).delete( "aragorn").then( ).statusCode( 200 );
+
+        }
+    }
+
+    @Test
+    void createUserExistsAlready() {
+        String token = getAdminToken( );
+        try
+        {
+            Map<String, Object> jsonAsMap = new HashMap<>( );
+            jsonAsMap.put( "user_id", "aragorn" );
+            jsonAsMap.put( "email", "[email protected]" );
+            jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
+            jsonAsMap.put( "validated", true );
+            jsonAsMap.put( "password", "pAssw0rD" );
+            Response response = given( ).spec( getRequestSpec( token ) 
).contentType( JSON )
+                .body( jsonAsMap )
+                .when( )
+                .post( )
+                .then( ).statusCode( 201 ).extract( ).response( );
+            assertTrue( response.getHeader( "Location" ).endsWith( "/aragorn" 
) );
+
+            jsonAsMap = new HashMap<>( );
+            jsonAsMap.put( "user_id", "aragorn" );
+            jsonAsMap.put( "email", "[email protected]" );
+            jsonAsMap.put( "fullName", "Aragorn King of Gondor" );
+            jsonAsMap.put( "validated", true );
+            jsonAsMap.put( "password", "pAssw0rD" );
+
+            response = given( ).spec( getRequestSpec( token ) ).contentType( 
JSON )
+                .body( jsonAsMap )
+                .when( )
+                .redirects().follow( false ) // Rest assured default is 
following the 303 redirect
+                .post( )
+                .prettyPeek()
+                .peek()
+                .then( ).statusCode( 303 ).extract().response();
+            assertTrue( response.getHeader( "Location" ).endsWith( "/aragorn" 
) );
+        } finally
+        {
+            given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+                .when( ).delete( "aragorn").then( ).statusCode( 200 );
+
+        }
+    }
 
 }

Reply via email to