Adding template method for REST v2
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTemplate.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTemplate.java
new file mode 100644
index 0000000..24d4468
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTemplate.java
@@ -0,0 +1,118 @@
+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 io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.redback.role.model.ModelApplication;
+import org.apache.archiva.redback.role.model.ModelTemplate;
+
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Schema(name="roleTemplate",description = "Information about role templates")
+public class RoleTemplate implements Serializable
+{
+    private static final long serialVersionUID = 8639174144508127048L;
+
+    private String id;
+    private String name;
+    private String description;
+    private String applicationId;
+    private boolean assignable;
+    private boolean permanent;
+
+    public static RoleTemplate of( ModelApplication application, ModelTemplate template ) {
+        RoleTemplate tmpl = new RoleTemplate( );
+        tmpl.setApplicationId( application.getId( ) );
+        tmpl.setId( template.getId( ) );
+        tmpl.setName( template.getNamePrefix() );
+        tmpl.setAssignable( template.isAssignable( ) );
+        tmpl.setPermanent( template.isPermanent() );
+        tmpl.setDescription( template.getDescription( ) );
+        return tmpl;
+    }
+
+
+    @Schema(description = "The template identifier")
+    public String getId( )
+    {
+        return id;
+    }
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    @Schema(description = "The name of the template")
+    public String getName( )
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    @Schema(description = "The template description")
+    public String getDescription( )
+    {
+        return description;
+    }
+
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+    @Schema(description = "Identifier of the application this template is part of")
+    public String getApplicationId( )
+    {
+        return applicationId;
+    }
+
+    public void setApplicationId( String applicationId )
+    {
+        this.applicationId = applicationId;
+    }
+
+    @Schema(description = "If a template instance can be assigned")
+    public boolean isAssignable( )
+    {
+        return assignable;
+    }
+
+    public void setAssignable( boolean assignable )
+    {
+        this.assignable = assignable;
+    }
+
+    @Schema(description = "If the template is permanent and cannot be deleted")
+    public boolean isPermanent( )
+    {
+        return permanent;
+    }
+
+    public void setPermanent( boolean permanent )
+    {
+        this.permanent = permanent;
+    }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
index 818e650..c88bc61 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
@@ -32,6 +32,7 @@
 import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
 import org.apache.archiva.redback.rest.api.model.v2.Role;
 import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.model.v2.RoleTemplate;
 import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
 
 import javax.ws.rs.DELETE;
@@ -152,7 +153,7 @@
      * @param oldResource the resource of the current role
      * @param newResource the resource of the new role
      */
-    @Path( "template/{templateId}/{oldResource}/moveto/{newResource}" )
+    @Path( "templates/{templateId}/{oldResource}/moveto/{newResource}" )
     @POST
     @Produces( {APPLICATION_JSON} )
     @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@@ -182,7 +183,7 @@
                                 @PathParam( "newResource" ) String newResource )
         throws RedbackServiceException;
 
-    @Path( "template/{templateId}/{resource}" )
+    @Path( "templates/{templateId}/{resource}" )
     @HEAD
     @Produces( { APPLICATION_JSON} )
     @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@@ -207,7 +208,7 @@
                                 @PathParam( "resource" ) String resource )
         throws RedbackServiceException;
 
-    @Path( "template/{templateId}/{resource}" )
+    @Path( "templates/{templateId}/{resource}" )
     @PUT
     @Produces( { APPLICATION_JSON } )
     @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@@ -249,7 +250,7 @@
      * @param templateId
      * @param resource
      */
-    @Path( "template/{templateId}/{resource}" )
+    @Path( "templates/{templateId}/{resource}" )
     @DELETE
     @Produces( { APPLICATION_JSON } )
     @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@@ -308,7 +309,7 @@
      * @param resource
      * @param userId
      */
-    @Path( "template/{templateId}/{resource}/user/{userId}" )
+    @Path( "templates/{templateId}/{resource}/user/{userId}" )
     @PUT
     @Produces( { APPLICATION_JSON } )
     @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@@ -388,5 +389,22 @@
     RoleInfo updateRole( @PathParam("roleId") String roleId, Role role )
     throws RedbackServiceException;
 
+    @Path( "templates" )
+    @GET
+    @Produces( { APPLICATION_JSON } )
+    @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+    @Operation( summary = "Returns all role templates",
+        security = {
+            @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+        },
+        responses = {
+            @ApiResponse( responseCode = "200",
+                description = "If the list could be retrieved"
+            ),
+            @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role assignment.",
+                content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+        }
+    )
+    List<RoleTemplate> getTemplates( ) throws RedbackServiceException;
 
 }
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java
index a95b499..43adc13 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java
@@ -26,6 +26,7 @@
 import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
 import org.apache.archiva.redback.rest.api.model.v2.Role;
 import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.model.v2.RoleTemplate;
 import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
 import org.apache.archiva.redback.rest.api.services.v2.RoleService;
 import org.apache.archiva.redback.role.PermanentRoleDeletionInvalid;
@@ -33,6 +34,8 @@
 import org.apache.archiva.redback.role.RoleManager;
 import org.apache.archiva.redback.role.RoleManagerException;
 import org.apache.archiva.redback.role.RoleNotFoundException;
+import org.apache.archiva.redback.role.model.ModelApplication;
+import org.apache.archiva.redback.role.model.ModelTemplate;
 import org.apache.archiva.redback.role.util.RoleModelUtils;
 import org.apache.archiva.redback.users.UserManager;
 import org.apache.archiva.redback.users.UserManagerException;
@@ -472,41 +475,13 @@
     }
 
 
-
-//    public List<Role> getEffectivelyAssignedRoles( String username )
-//        throws RedbackServiceException
-//    {
-//        if ( StringUtils.isEmpty( username ) )
-//        {
-//            throw new RedbackServiceException( new ErrorMessage( "user.cannot.be.null" ) );
-//        }
-//        try
-//        {
-//            List<? extends org.apache.archiva.redback.rbac.Role> roles =
-//                filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( username ) );
-//
-//            List<Role> effectivelyAssignedRoles = new ArrayList<Role>( roles.size() );
-//
-//            for ( org.apache.archiva.redback.rbac.Role r : roles )
-//            {
-//                effectivelyAssignedRoles.add( new Role( r ) );
-//            }
-//
-//            Collections.sort( effectivelyAssignedRoles, RoleComparator.INSTANCE  );
-//
-//            return effectivelyAssignedRoles;
-//        }
-//        catch ( RbacManagerException rme )
-//        {
-//            // ignore, this can happen when the user has no roles assigned
-//        }
-//        return new ArrayList<Role>( 0 );
-//    }
-
-
-    //----------------------------------------------------------------
-    // Internal methods
-    //----------------------------------------------------------------
+    @Override
+    public List<RoleTemplate> getTemplates( ) throws RedbackServiceException
+    {
+        return roleManager.getModel( ).getApplications( ).stream( ).flatMap( app ->
+            app.getTemplates( ).stream( ).map( modelTempl -> RoleTemplate.of( app, modelTempl ) )
+        ).collect( Collectors.toList( ) );
+    }
 
 
 }
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java
index 8ded8e8..936a160 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java
@@ -20,6 +20,7 @@
 
 import io.restassured.response.Response;
 import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.model.v2.RoleTemplate;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.DisplayName;
@@ -38,6 +39,7 @@
 import java.util.List;
 import java.util.Map;
 
+import static io.restassured.RestAssured.get;
 import static io.restassured.RestAssured.given;
 import static io.restassured.http.ContentType.JSON;
 import static org.apache.archiva.redback.rest.api.Constants.DEFAULT_PAGE_LIMIT;
@@ -92,7 +94,7 @@
         {
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository01" )
+                .put( "templates/archiva-repository-manager/repository01" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             assertNotNull( response );
             RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
@@ -100,16 +102,16 @@
             assertTrue( response.getHeader( "Location" ).endsWith( "/roles/" + roleInfo.getId( ) ) );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository01" )
+                .put( "templates/archiva-repository-manager/repository01" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .head( "template/archiva-repository-manager/repository01" )
+                .head( "templates/archiva-repository-manager/repository01" )
                 .then( ).statusCode( 200 );
             // Repository observer is child template of repository-manager and will be created too
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .head( "template/archiva-repository-observer/repository01" )
+                .head( "templates/archiva-repository-observer/repository01" )
                 .then( ).statusCode( 200 );
 
         }
@@ -117,11 +119,11 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository01" )
+                .delete( "templates/archiva-repository-manager/repository01" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository01" )
+                .delete( "templates/archiva-repository-observer/repository01" )
                 .then( ).statusCode( 200 );
         }
     }
@@ -132,7 +134,7 @@
         String token = getAdminToken( );
         given( ).spec( getRequestSpec( token ) ).contentType( JSON )
             .when( )
-            .put( "template/abcdefg/repository01" )
+            .put( "templates/abcdefg/repository01" )
             .then( ).statusCode( 404 );
     }
 
@@ -142,23 +144,23 @@
         String token = getAdminToken( );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository05" )
+                .put( "templates/archiva-repository-manager/repository05" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository01" )
+                .delete( "templates/archiva-repository-manager/repository01" )
                 .then( ).statusCode( 404 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository05" )
+                .delete( "templates/archiva-repository-manager/repository05" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository05" )
+                .delete( "templates/archiva-repository-manager/repository05" )
                 .then( ).statusCode( 404 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository05" )
+                .delete( "templates/archiva-repository-observer/repository05" )
                 .then( ).statusCode( 200 );
 
     }
@@ -170,13 +172,13 @@
         String token = getAdminToken( );
         given( ).spec( getRequestSpec( token ) ).contentType( JSON )
             .when( )
-            .put( "template/archiva-repository-observer/repository06" )
+            .put( "templates/archiva-repository-observer/repository06" )
             .then( ).statusCode( 201 );
         try
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .head( "template/archiva-repository-observer/repository06" )
+                .head( "templates/archiva-repository-observer/repository06" )
                 .then( ).statusCode( 200 );
 
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
@@ -188,7 +190,7 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository06" )
+                .delete( "templates/archiva-repository-observer/repository06" )
                 .then( ).statusCode( 200 );
         }
 
@@ -214,11 +216,11 @@
                 String suffix = String.format( "%03d", i );
                 given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                     .when( )
-                    .put( "template/archiva-repository-manager/repo" + suffix )
+                    .put( "templates/archiva-repository-manager/repo" + suffix )
                     .then( ).statusCode( 201 ).extract( ).response( );
                 given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                     .when( )
-                    .put( "template/archiva-repository-observer/repo" + suffix )
+                    .put( "templates/archiva-repository-observer/repo" + suffix )
                     .then( ).statusCode( anyOf( equalTo( 200 ), equalTo( 201 ) ) ).extract( ).response( );
             }
         }
@@ -328,9 +330,9 @@
             {
                 String suffix = String.format( "%03d", i );
                 given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                    .when( ).delete( "template/archiva-repository-manager/repo" + suffix ).then( ).statusCode( 200 );
+                    .when( ).delete( "templates/archiva-repository-manager/repo" + suffix ).then( ).statusCode( 200 );
                 given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                    .when( ).delete( "template/archiva-repository-observer/repo" + suffix ).then( ).statusCode( 200 );
+                    .when( ).delete( "templates/archiva-repository-observer/repo" + suffix ).then( ).statusCode( 200 );
             }
 
         }
@@ -377,39 +379,39 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository07" )
+                .put( "templates/archiva-repository-manager/repository07" )
                 .then( ).statusCode( 201 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).head( "template/archiva-repository-observer/repository07" ).then( ).statusCode( 200 );
+                .when( ).head( "templates/archiva-repository-observer/repository07" ).then( ).statusCode( 200 );
 
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).post( "template/archiva-repository-manager/repository07/moveto/repository08" ).then( ).statusCode( 201 ).extract( ).response( );
+                .when( ).post( "templates/archiva-repository-manager/repository07/moveto/repository08" ).then( ).statusCode( 201 ).extract( ).response( );
             RoleInfo role = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
             assertNotNull( role );
             assertEquals( "archiva-repository-manager.repository08", role.getId( ) );
             assertEquals( "repository08", role.getResource( ) );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).head( "template/archiva-repository-manager/repository07" ).then( ).statusCode( 404 );
+                .when( ).head( "templates/archiva-repository-manager/repository07" ).then( ).statusCode( 404 );
             // Child templates are copied and not moved
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).head( "template/archiva-repository-observer/repository07" ).then( ).statusCode( 200 );
+                .when( ).head( "templates/archiva-repository-observer/repository07" ).then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).head( "template/archiva-repository-observer/repository08" ).then( ).statusCode( 200 );
+                .when( ).head( "templates/archiva-repository-observer/repository08" ).then( ).statusCode( 200 );
 
         }
         finally
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository08" )
+                .delete( "templates/archiva-repository-manager/repository08" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository07" )
+                .delete( "templates/archiva-repository-observer/repository07" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository08" )
+                .delete( "templates/archiva-repository-observer/repository08" )
                 .then( ).statusCode( 200 );
 
         }
@@ -424,37 +426,37 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository09" )
+                .put( "templates/archiva-repository-manager/repository09" )
                 .then( ).statusCode( 201 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository10" )
+                .put( "templates/archiva-repository-manager/repository10" )
                 .then( ).statusCode( 201 );
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( ).redirects( ).follow( false )
-                .post( "template/archiva-repository-manager/repository09/moveto/repository10" ).then( ).statusCode( 303 )
+                .post( "templates/archiva-repository-manager/repository09/moveto/repository10" ).then( ).statusCode( 303 )
                 .extract( ).response( );
-            assertTrue( response.getHeader( "Location" ).endsWith( "/roles/template/archiva-repository-manager/repository10" ) );
+            assertTrue( response.getHeader( "Location" ).endsWith( "/roles/templates/archiva-repository-manager/repository10" ) );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
-                .when( ).head( "template/archiva-repository-manager/repository09" ).then( ).statusCode( 200 );
+                .when( ).head( "templates/archiva-repository-manager/repository09" ).then( ).statusCode( 200 );
         }
         finally
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository09" )
+                .delete( "templates/archiva-repository-manager/repository09" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository09" )
+                .delete( "templates/archiva-repository-observer/repository09" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository10" )
+                .delete( "templates/archiva-repository-manager/repository10" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository10" )
+                .delete( "templates/archiva-repository-observer/repository10" )
                 .then( ).statusCode( 200 );
 
         }
@@ -489,7 +491,6 @@
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
                 .put( "system-administrator/user/aragorn" )
-                .prettyPeek( )
                 .then( ).statusCode( 200 );
             response = given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
                 .when( )
@@ -533,7 +534,6 @@
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
                 .put( "abcdefg/user/aragorn" )
-                .prettyPeek( )
                 .then( ).statusCode( 404 );
             response = given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
                 .when( )
@@ -557,7 +557,6 @@
         given( ).spec( getRequestSpec( token ) ).contentType( JSON )
             .when( )
             .put( "system-administrator/user/aragorn" )
-            .prettyPeek( )
             .then( ).statusCode( 404 );
     }
 
@@ -576,7 +575,7 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository11" )
+                .put( "templates/archiva-repository-manager/repository11" )
                 .then( ).statusCode( 201 );
 
             given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
@@ -593,8 +592,7 @@
             assertFalse( roles.stream( ).filter( role -> "archiva-repository-manager.repository11".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository11/user/aragorn" )
-                .prettyPeek( )
+                .put( "templates/archiva-repository-manager/repository11/user/aragorn" )
                 .then( ).statusCode( 200 );
             response = given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
                 .when( )
@@ -610,10 +608,10 @@
                 .delete( "aragorn" ).then().statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository11" ).then().statusCode( 200 );
+                .delete( "templates/archiva-repository-manager/repository11" ).then().statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository11" ).then().statusCode( 200 );
+                .delete( "templates/archiva-repository-observer/repository11" ).then().statusCode( 200 );
 
         }
     }
@@ -679,7 +677,7 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository12" )
+                .put( "templates/archiva-repository-manager/repository12" )
                 .then( ).statusCode( 201 );
             given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
                 .body( jsonAsMap )
@@ -688,7 +686,7 @@
                 .then( ).statusCode( 201 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository12/user/aragorn" )
+                .put( "templates/archiva-repository-manager/repository12/user/aragorn" )
                 .then( ).statusCode( 200 );
             Response response = given( ).spec( getRequestSpec( token, getUserServicePath( ) ) ).contentType( JSON )
                 .when( )
@@ -714,10 +712,10 @@
                 .delete( "aragorn" ).then().statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository12" ).then().statusCode( 200 );
+                .delete( "templates/archiva-repository-manager/repository12" ).then().statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository12" ).then().statusCode( 200 );
+                .delete( "templates/archiva-repository-observer/repository12" ).then().statusCode( 200 );
 
         }
     }
@@ -730,7 +728,7 @@
         {
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository13" )
+                .put( "templates/archiva-repository-manager/repository13" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             assertNotNull( response );
             RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
@@ -756,11 +754,11 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository13" )
+                .delete( "templates/archiva-repository-manager/repository13" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository13" )
+                .delete( "templates/archiva-repository-observer/repository13" )
                 .then( ).statusCode( 200 );
         }
     }
@@ -786,7 +784,7 @@
 
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository14" )
+                .put( "templates/archiva-repository-manager/repository14" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             assertNotNull( response );
             RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
@@ -835,11 +833,11 @@
 
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository14" )
+                .delete( "templates/archiva-repository-manager/repository14" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository14" )
+                .delete( "templates/archiva-repository-observer/repository14" )
                 .then( ).statusCode( 200 );
         }
     }
@@ -853,7 +851,7 @@
         {
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository15" )
+                .put( "templates/archiva-repository-manager/repository15" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             assertNotNull( response );
             RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
@@ -871,11 +869,11 @@
         {
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository15" )
+                .delete( "templates/archiva-repository-manager/repository15" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository15" )
+                .delete( "templates/archiva-repository-observer/repository15" )
                 .then( ).statusCode( 200 );
         }
     }
@@ -889,7 +887,7 @@
         {
             Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .put( "template/archiva-repository-manager/repository16" )
+                .put( "templates/archiva-repository-manager/repository16" )
                 .then( ).statusCode( 201 ).extract( ).response( );
             assertNotNull( response );
             RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
@@ -908,7 +906,7 @@
 
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository16" )
+                .delete( "templates/archiva-repository-manager/repository16" )
                 .then( ).statusCode( 400 );
 
         }
@@ -924,11 +922,11 @@
                 .then( ).statusCode( 200 ).extract( ).response( );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-manager/repository16" )
+                .delete( "templates/archiva-repository-manager/repository16" )
                 .then( ).statusCode( 200 );
             given( ).spec( getRequestSpec( token ) ).contentType( JSON )
                 .when( )
-                .delete( "template/archiva-repository-observer/repository16" )
+                .delete( "templates/archiva-repository-observer/repository16" )
                 .then( ).statusCode( 200 );
         }
 
@@ -950,4 +948,19 @@
                 .then( ).statusCode( 404 );
     }
 
+
+    @Test
+    void getTemplates() {
+        String token = getAdminToken( );
+        Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+            .when( )
+            .get( "templates" )
+            .then( ).statusCode( 200 ).extract( ).response( );
+        assertNotNull( response );
+        List<RoleTemplate> templates = response.getBody( ).jsonPath( ).getList( "", RoleTemplate.class );
+        assertEquals( 2, templates.size( ) );
+        assertTrue( templates.stream( ).filter( tmpl -> "archiva-repository-manager".equals( tmpl.getId( ) ) ).findAny().isPresent() );
+        assertTrue( templates.stream( ).filter( tmpl -> "archiva-repository-observer".equals( tmpl.getId( ) ) ).findAny().isPresent() );
+    }
+
 }