Updating userservice v2
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 c280e55..54a03e8 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
@@ -29,6 +29,7 @@
     String ERR_USERMANAGER_FAIL = "redback:usermanager_error";
     String ERR_ROLEMANAGER_FAIL = "redback:rolemanager_error";
     String ERR_RBACMANAGER_FAIL = "redback:rbacmanager_error";
+    String ERR_KEYMANAGER_FAIL = "reback:keymanager_error";
     String ERR_INVALID_POST_DATA = "redback:invalid_post_data";
 
     String ERR_USER_EXISTS = "redback:user.exists";
@@ -57,8 +58,14 @@
     String ERR_AUTH_INVALID_TOKEN = "redback:auth.invalid_token";
     String ERR_AUTH_UNAUTHORIZED_REQUEST = "redback:auth.unauthorized_request";
 
+    String ERR_PASSWD_RESET_FAILED = "redback:passwd.reset.fail";
+
     String ERR_USER_BAD_PASSWORD = "redback:user.bad.password";
 
+    String ERR_REGISTRATION_KEY_INVALID = "redback:registration.key.invalid";
+    String ERR_REGISTRATION_USER_VALIDATED = "redback:registration.user.validated";
+    String ERR_REGISTRATION_ROLE_ASSIGNMENT_FAILED = "redback:registration.role.assignment.failed";
+
 
 
 
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
index e87d77d..d6d1c27 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
@@ -488,7 +488,7 @@
 
 
     @Path( "{userId}/register/{key}/validate" )
-    @GET
+    @POST
     @Produces( {MediaType.APPLICATION_JSON} )
     @RedbackAuthorization( noRestriction = true, noPermission = true )
     @io.swagger.v3.oas.annotations.Operation( summary = "Validate the user registration for the given userid by checking the provided key.",
@@ -496,7 +496,7 @@
             @ApiResponse( responseCode = "200",
                 description = "If the verification was successful"
             ),
-            @ApiResponse( responseCode = "404", description = "No user registration was found for the given id and key" ),
+            @ApiResponse( responseCode = "404", description = "No user registration was found for the given id and key" )
         }
     )
     VerificationStatus validateUserRegistration( @PathParam( "userId" ) String userId, @PathParam( "key" ) String key )
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 40d50b7..d7c64b3 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
@@ -475,7 +475,7 @@
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
         }
     }
 
@@ -560,11 +560,11 @@
         }
         catch ( RoleManagerException e )
         {
-            throw new RedbackServiceException( ErrorMessage.of( ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_ROLEMANAGER_FAIL, e.getMessage( ) ), 400 );
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
         }
         httpServletResponse.setStatus( 201 );
         httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePath().toString() );
@@ -597,7 +597,7 @@
             {
                 return new AvailabilityStatus( false );
             }
-            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL,  e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL,  e.getMessage() ), 400 );
         }
         return new AvailabilityStatus( false );
     }
@@ -631,16 +631,16 @@
         catch ( UserNotFoundException e )
         {
             log.info( "Password Reset on non-existant user [{}].", username );
-            throw new RedbackServiceException( new ErrorMessage( ERR_USER_NOT_FOUND ), 404 );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND, userId ), 404 );
         }
         catch ( KeyManagerException e )
         {
             log.info( "Unable to issue password reset.", e );
-            throw new RedbackServiceException( new ErrorMessage( "password.reset.email.generation.failure" ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_PASSWD_RESET_FAILED, e.getMessage() ), 400 );
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
         }
 
         return ActionStatus.SUCCESS;
@@ -653,7 +653,7 @@
         User user = userRegistrationRequest.getUser();
         if ( user == null )
         {
-            throw new RedbackServiceException( new ErrorMessage( "invalid.user.credentials", null ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND, userId ), 404 );
 
         }
 
@@ -693,11 +693,11 @@
         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_REGISTRATION_ROLE_ASSIGNMENT_FAILED, rpe.getMessage( ) ), 400 );
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
         }
 
         if ( emailValidationRequired )
@@ -728,11 +728,11 @@
             catch ( KeyManagerException e )
             {
                 log.error( "Unable to register a new user.", e );
-                throw new RedbackServiceException( new ErrorMessage( "cannot.register.user", null ) );
+                throw new RedbackServiceException( ErrorMessage.of( ERR_KEYMANAGER_FAIL, e.getMessage() ), 400 );
             }
             catch ( UserManagerException e )
             {
-                throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+                throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
             }
             finally
             {
@@ -748,7 +748,7 @@
             }
             catch ( UserManagerException e )
             {
-                throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+                throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
             }
         }
 
@@ -809,11 +809,14 @@
             org.apache.archiva.redback.users.User user =
                 securitySystem.getUserManager().findUser( authkey.getForPrincipal() );
 
+            if (user.isValidated()) {
+                throw new RedbackServiceException( ErrorMessage.of( ERR_REGISTRATION_USER_VALIDATED ), 404 );
+            }
             user.setValidated( true );
             user.setLocked( false );
             user.setPasswordChangeRequired( true );
             user.setEncodedPassword( "" );
-
+            securitySystem.getUserManager().updateUser( user );
             principal = user.getUsername();
 
             TokenBasedAuthenticationDataSource authsource = new TokenBasedAuthenticationDataSource();
@@ -821,42 +824,53 @@
             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 );
+            } else {
+                user.setValidated( false );
+                user.setLocked( true );
+                user.setPasswordChangeRequired( false );
+                securitySystem.getUserManager().updateUser( user );
             }
 
             log.info( "account validated for user {}", user.getUsername() );
 
             return status;
         }
-        catch ( MustChangePasswordException | AccountLockedException | AuthenticationException e )
+        catch ( MustChangePasswordException e )
         {
-            throw new RedbackServiceException( e.getMessage(), Response.Status.FORBIDDEN.getStatusCode() );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_PASSWORD_CHANGE_REQUIRED ), Response.Status.FORBIDDEN.getStatusCode() );
+        }
+        catch ( AccountLockedException e )
+        {
+            throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_ACCOUNT_LOCKED ), Response.Status.FORBIDDEN.getStatusCode() );
+        }
+        catch ( AuthenticationException e )
+        {
+            throw new RedbackServiceException( ErrorMessage.of( ERR_AUTH_INVALID_CREDENTIALS ), Response.Status.FORBIDDEN.getStatusCode() );
         }
         catch ( KeyNotFoundException e )
         {
             log.info( "Invalid key requested: {}", key );
-            throw new RedbackServiceException( new ErrorMessage( "cannot.find.key" ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_REGISTRATION_KEY_INVALID ), 404 );
         }
         catch ( KeyManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( "cannot.find.key.at.the.momment" ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_KEYMANAGER_FAIL, e.getMessage( ) ), 400 );
 
         }
         catch ( UserNotFoundException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( "cannot.find.user", new String[]{ principal } ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USER_NOT_FOUND, principal ), 404 );
 
         }
         catch ( UserManagerException e )
         {
-            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_USERMANAGER_FAIL, e.getMessage() ), 400 );
         }
     }
 
@@ -915,7 +929,7 @@
         catch ( RbacManagerException e )
         {
             log.error( e.getMessage(), e );
-            throw new RedbackServiceException( e.getMessage() );
+            throw new RedbackServiceException( ErrorMessage.of( ERR_RBACMANAGER_FAIL, e.getMessage() ), 400 );
         }
     }
 
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 09e051b..56e24ab 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
@@ -21,6 +21,8 @@
 import io.restassured.response.Response;
 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.VerificationStatus;
+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.services.mock.EmailMessage;
 import org.junit.jupiter.api.AfterAll;
@@ -1221,4 +1223,129 @@
                 .then( ).statusCode( 200 );
         }
     }
+
+    @Test
+    void getOwnPermissions( )
+    {
+        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( "validated", true );
+        jsonAsMap.put( "password", "pAssw0rD" );
+        given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+            .body( jsonAsMap )
+            .when( )
+            .post( )
+            .then( ).statusCode( 201 );
+        try
+        {
+
+            String token = getUserToken( "aragorn", "pAssw0rD" );
+            Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+                .when( )
+                .get( "me/permissions" )
+                .then( ).statusCode( 200 ).extract( ).response( );
+            List<Permission> result = response.getBody( ).jsonPath( ).getList( "", Permission.class );
+            assertNotNull( result );
+            assertEquals( 2, result.size( ) );
+            assertTrue( result.stream( ).anyMatch( permission -> permission.getName( ).equals( "Edit User Data by Username" ) ) );
+            assertTrue( result.stream( ).anyMatch( permission -> permission.getName( ).equals( "View User Data by Username" ) ) );
+        }
+        finally
+        {
+            given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+                .delete( "aragorn" )
+                .then( ).statusCode( 200 );
+        }
+    }
+
+    @Test
+    void getOwnOperations( )
+    {
+        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( "validated", true );
+        jsonAsMap.put( "password", "pAssw0rD" );
+        given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+            .body( jsonAsMap )
+            .when( )
+            .post( )
+            .then( ).statusCode( 201 );
+        try
+        {
+
+            String token = getUserToken( "aragorn", "pAssw0rD" );
+            Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+                .when( )
+                .get( "me/operations" )
+                .prettyPeek( )
+                .then( ).statusCode( 200 ).extract( ).response( );
+            List<Operation> result = response.getBody( ).jsonPath( ).getList( "", Operation.class );
+            assertNotNull( result );
+            assertEquals( 2, result.size( ) );
+            assertTrue( result.stream( ).anyMatch( operation -> operation.getName( ).equals( "user-management-user-edit" ) ) );
+            assertTrue( result.stream( ).anyMatch( operation -> operation.getName( ).equals( "user-management-user-view" ) ) );
+
+
+
+        }
+        finally
+        {
+            given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+                .delete( "aragorn" )
+                .then( ).statusCode( 200 );
+        }
+    }
+
+    @Test
+    void validateUserRegistration() {
+        String adminToken = getAdminToken( );
+
+        Map<String, Object> userMap = new HashMap<>( );
+        Map<String, Object> requestMap = new HashMap<>( );
+
+
+        userMap.put( "user_id", "bilbo" );
+        userMap.put( "email", "bilbo@lordoftherings.org" );
+        userMap.put( "fullName", "Bilbo Beutlin" );
+        userMap.put( "validated", true );
+        userMap.put( "password", "pAssw0rD" );
+        userMap.put( "confirmPassword", "pAssw0rD" );
+        requestMap.put( "user", userMap );
+        requestMap.put( "applicationUrl", "http://localhost" );
+
+        try
+        {
+            Response response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+                .body( requestMap )
+                .when( )
+                .post( "bilbo/register" )
+                .then( ).statusCode( 200 ).extract( ).response( );
+            RegistrationKey key = response.getBody( ).jsonPath( ).getObject( "", RegistrationKey.class );
+            assertNotNull( key );
+            assertNotNull( key.getKey( ) );
+
+            response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+                .body( requestMap )
+                .when( )
+                .post( "bilbo/register/"+key.getKey()+"/validate" )
+                .then( ).statusCode( 200 ).extract( ).response( );
+
+            assertNotNull( response );
+            VerificationStatus verificationStatus = response.getBody( ).jsonPath( ).getObject( "", VerificationStatus.class );
+            assertNotNull( verificationStatus );
+            assertTrue( verificationStatus.isSuccess( ) );
+
+        } finally
+        {
+            given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+                .delete( "bilbo" )
+                .then( ).statusCode( 200 );
+        }
+    }
 }