awasum closed pull request #7: Document Identity API to manage identities, 
roles and permissions
URL: https://github.com/apache/fineract-cn-identity/pull/7
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/component-test/build.gradle b/component-test/build.gradle
index 87a5696..6e2d080 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -26,6 +26,7 @@ buildscript {
 
     dependencies {
         classpath 
("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.3")
     }
 }
 
@@ -35,6 +36,7 @@ plugins {
 }
 
 apply from: '../shared.gradle'
+apply plugin: 'org.asciidoctor.convert'
 
 dependencies {
     compile(
@@ -45,6 +47,16 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'api', version: 
versions.frameworkapi],
             [group: 'org.apache.fineract.cn', name: 'test', version: 
versions.frameworktest],
             [group: 'org.apache.fineract.cn.anubis', name: 'api', version: 
versions.frameworkanubis],
-            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: 
versions.frameworkanubis]
+            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: 
versions.frameworkanubis],
+            [group: 'org.springframework.restdocs', name: 
'spring-restdocs-mockmvc'],
+            [group: 'junit', name: 'junit', version: '4.12']
     )
 }
+
+asciidoctor {
+        sourceDir 'build/doc/asciidoc/'
+        outputDir 'build/doc/html5'
+        options backend: "html", doctype: "book"
+        attributes "source-highlighter": "highlightjs", \
+                'snippets': file('build/doc/generated-snippets/')
+    }
\ No newline at end of file
diff --git a/component-test/src/main/java/AbstractComponentTest.java 
b/component-test/src/main/java/AbstractIdentityTest.java
similarity index 83%
rename from component-test/src/main/java/AbstractComponentTest.java
rename to component-test/src/main/java/AbstractIdentityTest.java
index aeb6b08..3d45af6 100644
--- a/component-test/src/main/java/AbstractComponentTest.java
+++ b/component-test/src/main/java/AbstractIdentityTest.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 import org.apache.fineract.cn.identity.api.v1.PermittableGroupIds;
 import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
 import org.apache.fineract.cn.identity.api.v1.domain.Authentication;
@@ -26,8 +27,10 @@
 import 
org.apache.fineract.cn.identity.api.v1.events.ApplicationPermissionEvent;
 import org.apache.fineract.cn.identity.api.v1.events.ApplicationSignatureEvent;
 import org.apache.fineract.cn.identity.api.v1.events.EventConstants;
+
 import java.util.Arrays;
 import javax.annotation.PostConstruct;
+
 import org.apache.commons.lang.RandomStringUtils;
 import org.apache.fineract.cn.anubis.api.v1.domain.AllowedOperation;
 import org.apache.fineract.cn.anubis.api.v1.domain.Signature;
@@ -61,21 +64,20 @@
 @SuppressWarnings("SpringAutowiredFieldsWarningInspection")
 @RunWith(SpringRunner.class)
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
-        classes = {AbstractComponentTest.TestConfiguration.class})
+        classes = {AbstractIdentityTest.TestConfiguration.class})
 @TestPropertySource(properties = {"cassandra.cl.read = LOCAL_QUORUM", 
"cassandra.cl.write = LOCAL_QUORUM", "cassandra.cl.delete = LOCAL_QUORUM", 
"identity.token.refresh.secureCookie = false", "identity.passwordExpiresInDays 
= 93"})
-public class AbstractComponentTest extends SuiteTestEnvironment {
+public class AbstractIdentityTest extends SuiteTestEnvironment {
   @Configuration
   @EnableApiFactory
   @EnableEventRecording
   @Import({IdentityServiceConfig.class})
   @ComponentScan("listener")
   public static class TestConfiguration {
-    public TestConfiguration() {
+    public TestConfiguration ( ) {
       super();
     }
   }
 
-
   static final String ADMIN_PASSWORD = "golden_osiris";
   static final String ADMIN_ROLE = "pharaoh";
   static final String ADMIN_IDENTIFIER = "antony";
@@ -99,27 +101,26 @@ public TestConfiguration() {
   private IdentityManager identityManager;
 
   @PostConstruct
-  public void provision() throws Exception {
-    identityManager =  apiFactory.create(IdentityManager.class, 
testEnvironment.serverURI());
+  public void provision ( ) throws Exception {
+    identityManager = apiFactory.create(IdentityManager.class, 
testEnvironment.serverURI());
 
     try (final AutoUserContext ignored
-             = tenantApplicationSecurityEnvironment.createAutoSeshatContext()) 
{
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
       
identityManager.initialize(TestEnvironment.encodePassword(ADMIN_PASSWORD));
     }
   }
 
   @After
-  public void after() {
+  public void after ( ) {
     UserContextHolder.clear();
     eventRecorder.clear();
   }
 
-  IdentityManager getTestSubject()
-  {
+  IdentityManager getTestSubject ( ) {
     return identityManager;
   }
 
-  AutoUserContext loginAdmin() throws InterruptedException {
+  AutoUserContext loginAdmin ( ) throws InterruptedException {
     final Authentication adminAuthentication =
             getTestSubject().login(ADMIN_IDENTIFIER, 
TestEnvironment.encodePassword(ADMIN_PASSWORD));
     Assert.assertNotNull(adminAuthentication);
@@ -137,7 +138,7 @@ AutoUserContext loginAdmin() throws InterruptedException {
    * In identityManager, the user is created with an expired password.  The 
user must change the password him- or herself
    * to access any other endpoint.
    */
-  String createUserWithNonexpiredPassword(final String password, final String 
role) throws InterruptedException {
+  String createUserWithNonexpiredPassword (final String password, final String 
role) throws InterruptedException {
     final String username = testEnvironment.generateUniqueIdentifer("Ahmes");
     try (final AutoUserContext ignore = loginAdmin()) {
       getTestSubject().createUser(new UserWithPassword(username, role, 
TestEnvironment.encodePassword(password)));
@@ -149,8 +150,7 @@ String createUserWithNonexpiredPassword(final String 
password, final String role
 
       final Authentication passwordOnlyAuthentication = 
getTestSubject().login(username, TestEnvironment.encodePassword(password));
 
-      try (final AutoUserContext ignore2 = new AutoUserContext(username, 
passwordOnlyAuthentication.getAccessToken()))
-      {
+      try (final AutoUserContext ignore2 = new AutoUserContext(username, 
passwordOnlyAuthentication.getAccessToken())) {
         getTestSubject().changeUserPassword(username, new 
Password(TestEnvironment.encodePassword(password)));
         final boolean found = 
eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, username);
         Assert.assertTrue(found);
@@ -159,58 +159,58 @@ String createUserWithNonexpiredPassword(final String 
password, final String role
     return username;
   }
 
-  String generateRoleIdentifier() {
+  String generateRoleIdentifier ( ) {
     return testEnvironment.generateUniqueIdentifer("scribe");
   }
 
-  Role buildRole(final String identifier, final Permission... permission) {
+  Role buildRole (final String identifier, final Permission... permission) {
     final Role scribe = new Role();
     scribe.setIdentifier(identifier);
     scribe.setPermissions(Arrays.asList(permission));
     return scribe;
   }
 
-  Permission buildRolePermission() {
+  Permission buildRolePermission ( ) {
     final Permission permission = new Permission();
     permission.setAllowedOperations(AllowedOperation.ALL);
     
permission.setPermittableEndpointGroupIdentifier(PermittableGroupIds.ROLE_MANAGEMENT);
     return permission;
   }
 
-  Permission buildUserPermission() {
+  Permission buildUserPermission ( ) {
     final Permission permission = new Permission();
     permission.setAllowedOperations(AllowedOperation.ALL);
     
permission.setPermittableEndpointGroupIdentifier(PermittableGroupIds.IDENTITY_MANAGEMENT);
     return permission;
   }
 
-  Permission buildSelfPermission() {
+  Permission buildSelfPermission ( ) {
     final Permission permission = new Permission();
     permission.setAllowedOperations(AllowedOperation.ALL);
     
permission.setPermittableEndpointGroupIdentifier(PermittableGroupIds.SELF_MANAGEMENT);
     return permission;
   }
 
-  Permission buildApplicationSelfPermission() {
+  Permission buildApplicationSelfPermission ( ) {
     final Permission permission = new Permission();
     permission.setAllowedOperations(AllowedOperation.ALL);
     
permission.setPermittableEndpointGroupIdentifier(PermittableGroupIds.APPLICATION_SELF_MANAGEMENT);
     return permission;
   }
 
-  String createRoleManagementRole() throws InterruptedException {
+  String createRoleManagementRole ( ) throws InterruptedException {
     return createRole(buildRolePermission());
   }
 
-  String createSelfManagementRole() throws InterruptedException {
+  String createSelfManagementRole ( ) throws InterruptedException {
     return createRole(buildSelfPermission());
   }
 
-  String createApplicationSelfManagementRole() throws InterruptedException {
+  String createApplicationSelfManagementRole ( ) throws InterruptedException {
     return createRole(buildApplicationSelfPermission());
   }
 
-  String createRole(final Permission... permission) throws 
InterruptedException {
+  String createRole (final Permission... permission) throws 
InterruptedException {
     final String roleIdentifier = generateRoleIdentifier();
     final Role role = buildRole(roleIdentifier, permission);
 
@@ -221,7 +221,7 @@ String createRole(final Permission... permission) throws 
InterruptedException {
     return roleIdentifier;
   }
 
-  AutoUserContext loginUser(final String userId, final String password) {
+  AutoUserContext loginUser (final String userId, final String password) {
     final Authentication authentication;
     try (AutoUserContext ignored = new AutoGuest()) {
       authentication = getTestSubject().login(userId, 
TestEnvironment.encodePassword(password));
@@ -229,8 +229,7 @@ AutoUserContext loginUser(final String userId, final String 
password) {
     return new AutoUserContext(userId, authentication.getAccessToken());
   }
 
-  private String createTestApplicationName()
-  {
+  private String createTestApplicationName ( ) {
     return "test" + RandomStringUtils.randomNumeric(3) + "-v1";
   }
 
@@ -238,25 +237,25 @@ private String createTestApplicationName()
     private final String applicationIdentifier;
     private final RsaKeyPairFactory.KeyPairHolder keyPair;
 
-    ApplicationSignatureTestData(final String applicationIdentifier, final 
RsaKeyPairFactory.KeyPairHolder keyPair) {
+    ApplicationSignatureTestData (final String applicationIdentifier, final 
RsaKeyPairFactory.KeyPairHolder keyPair) {
       this.applicationIdentifier = applicationIdentifier;
       this.keyPair = keyPair;
     }
 
-    String getApplicationIdentifier() {
+    String getApplicationIdentifier ( ) {
       return applicationIdentifier;
     }
 
-    RsaKeyPairFactory.KeyPairHolder getKeyPair() {
+    RsaKeyPairFactory.KeyPairHolder getKeyPair ( ) {
       return keyPair;
     }
 
-    String getKeyTimestamp() {
+    String getKeyTimestamp ( ) {
       return keyPair.getTimestamp();
     }
   }
 
-  ApplicationSignatureTestData setApplicationSignature() throws 
InterruptedException {
+  ApplicationSignatureTestData setApplicationSignature ( ) throws 
InterruptedException {
     final String testApplicationName = createTestApplicationName();
     final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
     final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
@@ -267,7 +266,7 @@ ApplicationSignatureTestData setApplicationSignature() 
throws InterruptedExcepti
     return new ApplicationSignatureTestData(testApplicationName, keyPair);
   }
 
-  void createApplicationPermission(final String applicationIdentifier, final 
Permission permission) throws InterruptedException {
+  void createApplicationPermission (final String applicationIdentifier, final 
Permission permission) throws InterruptedException {
     getTestSubject().createApplicationPermission(applicationIdentifier, 
permission);
     
Assert.assertTrue(eventRecorder.wait(EventConstants.OPERATION_POST_APPLICATION_PERMISSION,
             new ApplicationPermissionEvent(applicationIdentifier,
diff --git a/component-test/src/main/java/IdentityApiDocumentation.java 
b/component-test/src/main/java/IdentityApiDocumentation.java
new file mode 100644
index 0000000..9d960ee
--- /dev/null
+++ b/component-test/src/main/java/IdentityApiDocumentation.java
@@ -0,0 +1,1075 @@
+/*
+ * 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 com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.fineract.cn.anubis.api.v1.domain.AllowedOperation;
+import org.apache.fineract.cn.anubis.api.v1.domain.PermittableEndpoint;
+import org.apache.fineract.cn.anubis.api.v1.domain.Signature;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.identity.api.v1.PermittableGroupIds;
+import org.apache.fineract.cn.identity.api.v1.domain.*;
+import org.apache.fineract.cn.identity.api.v1.events.*;
+import org.apache.fineract.cn.lang.security.RsaKeyPairFactory;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.util.Collections;
+import java.util.List;
+
+import static 
org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static 
org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static 
org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static 
org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static 
org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static 
org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static 
org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
+import static 
org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
+import static 
org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
+import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static 
org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static 
org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
+import static 
org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
+
+
+public class IdentityApiDocumentation extends AbstractIdentityTest {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new 
JUnitRestDocumentation("build/doc/generated-snippets/test-identity");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  @Before
+  public void setUp ( ) {
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .build();
+  }
+
+  @Test
+  public void documentCreateRole ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String roleIdentifier = generateRoleIdentifier();
+      final Permission rolePermission = buildRolePermission();
+      final Role copyist = buildRole(roleIdentifier, rolePermission);
+
+      Gson serializer = new Gson();
+      this.mockMvc.perform(post("/roles")
+              .accept(MediaType.APPLICATION_JSON_VALUE)
+              .contentType(MediaType.APPLICATION_JSON_VALUE)
+              .content(serializer.toJson(copyist)))
+              .andExpect(status().isAccepted())
+              .andDo(document("document-create-role", 
preprocessRequest(prettyPrint()),
+                      requestFields(
+                              
fieldWithPath("identifier").description("Identifier"),
+                              
fieldWithPath("permissions[].permittableEndpointGroupIdentifier").description("permittable
 endpoints"),
+                              
fieldWithPath("permissions[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of allowed operations")
+                      )
+              ));
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void documentDeleteRole ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+      final String roleIdentifier = generateRoleIdentifier();
+
+      final Permission rolePermission = buildRolePermission();
+      final Role scribe = buildRole(roleIdentifier, rolePermission);
+
+      getTestSubject().createRole(scribe);
+      super.eventRecorder.wait(EventConstants.OPERATION_POST_ROLE, 
scribe.getIdentifier());
+
+      try {
+        this.mockMvc.perform(delete("/roles/" + scribe.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-delete-role", 
preprocessRequest(prettyPrint())));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void documentUpdateRole ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+      final String roleIdentifier = createRoleManagementRole();
+
+      final Role role = getTestSubject().getRole(roleIdentifier);
+      role.getPermissions().add(buildUserPermission());
+
+      Gson gson = new Gson();
+      role.getPermissions().remove(0);
+
+      try {
+        this.mockMvc.perform(put("/roles/" + role.getIdentifier())
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(gson.toJson(role)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-update-role", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                
fieldWithPath("identifier").description("Identifier"),
+                                
fieldWithPath("permissions[].permittableEndpointGroupIdentifier").description("permittable
 endpoints"),
+                                
fieldWithPath("permissions[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of allowed operations")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetRole ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String roleIdentifier = generateRoleIdentifier();
+
+      final Permission rolePermission = buildRolePermission();
+      final Role scribe = buildRole(roleIdentifier, rolePermission);
+
+      getTestSubject().createRole(scribe);
+      super.eventRecorder.wait(EventConstants.OPERATION_POST_ROLE, 
scribe.getIdentifier());
+
+      try {
+        this.mockMvc.perform(get("/roles/" + scribe.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-role", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("identifier").description("Identifier"),
+                                
fieldWithPath("permissions[].permittableEndpointGroupIdentifier").description("permittable
 endpoints"),
+                                
fieldWithPath("permissions[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of allowed operations")
+                        )));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void documentFindRoles ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String roleIdentifierOne = generateRoleIdentifier();
+
+      final Permission rolePermission = buildRolePermission();
+      final Role scribeOne = buildRole(roleIdentifierOne, rolePermission);
+
+      getTestSubject().createRole(scribeOne);
+      super.eventRecorder.wait(EventConstants.OPERATION_POST_ROLE, 
scribeOne.getIdentifier());
+
+      final String roleIdentifierTwo = generateRoleIdentifier();
+
+      final Permission userPermission = buildUserPermission();
+      final Role scribeTwo = buildRole(roleIdentifierTwo, userPermission);
+
+      List <Role> roles = Lists.newArrayList(scribeOne, scribeTwo);
+      roles.stream()
+              .forEach(scribe -> {
+                try {
+                  super.eventRecorder.wait(EventConstants.OPERATION_POST_ROLE, 
scribe.getIdentifier());
+                } catch (InterruptedException e) {
+                  e.printStackTrace();
+                }
+              });
+
+      try {
+        this.mockMvc.perform(get("/roles")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-find-roles", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].identifier").description("first role's identifier"),
+                                
fieldWithPath("[].permissions[].permittableEndpointGroupIdentifier").description("first
 role's roles permittable"),
+                                
fieldWithPath("[].permissions[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of first role's allowed operations"),
+                                
fieldWithPath("[].permissions[1].permittableEndpointGroupIdentifier").description("first
 role's users permittable"),
+                                
fieldWithPath("[].permissions[1].allowedOperations").type("Set<AllowedOperation>").description("Set
 of first role's allowed operations"),
+                                
fieldWithPath("[].permissions[2].permittableEndpointGroupIdentifier").description("first
 role's self permittable"),
+                                
fieldWithPath("[].permissions[2].allowedOperations").type("Set<AllowedOperation>").description("Set
 of first role's allowed operations"),
+                                
fieldWithPath("[].permissions[3].permittableEndpointGroupIdentifier").description("first
 role's app_self permittable"),
+                                
fieldWithPath("[].permissions[3].allowedOperations").type("Set<AllowedOperation>").description("Set
 of first role's allowed operations"),
+                                
fieldWithPath("[1].identifier").description("second role's identifier"),
+                                
fieldWithPath("[1].permissions[].permittableEndpointGroupIdentifier").description("second
 role's roles permittable"),
+                                
fieldWithPath("[1].permissions[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of second role's allowed operations")
+                        )));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void documentCreatePGroup ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String identifier = 
testEnvironment.generateUniqueIdentifer("group");
+
+      final PermittableEndpoint permittableEndpoint = 
buildPermittableEndpoint();
+      final PermittableGroup pgroup = buildPermittableGroup(identifier, 
permittableEndpoint);
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(post("/permittablegroups")
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serializer.toJson(pgroup)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-create-p-group", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                
fieldWithPath("identifier").description("Permittable group identifier"),
+                                
fieldWithPath("permittables[].path").description("RequestMapping value"),
+                                
fieldWithPath("permittables[].method").type("RequestMethod").description("HTTP 
Request Method"),
+                                
fieldWithPath("permittables[].groupId").type("String").description("permittable 
identifier"),
+                                
fieldWithPath("permittables[].acceptTokenIntendedForForeignApplication").type(Boolean.TYPE).description("Accept
 token for foreign application")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentFindPGroup ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String identifier = 
testEnvironment.generateUniqueIdentifer("pgroup");
+
+      final PermittableEndpoint permittableEndpoint = 
buildPermittableEndpoint();
+      final PermittableGroup pgroup = buildPermittableGroup(identifier, 
permittableEndpoint);
+
+      getTestSubject().createPermittableGroup(pgroup);
+
+      {
+        final boolean found = 
eventRecorder.wait(EventConstants.OPERATION_POST_PERMITTABLE_GROUP, 
pgroup.getIdentifier());
+        Assert.assertTrue(found);
+      }
+
+      try {
+        this.mockMvc.perform(get("/permittablegroups/" + 
pgroup.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-find-p-group", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("identifier").description("Permittable group identifier"),
+                                
fieldWithPath("permittables[].path").description("RequestMapping value"),
+                                
fieldWithPath("permittables[].method").type("RequestMethod").description("HTTP 
Request Method"),
+                                
fieldWithPath("permittables[].groupId").type("String").description("permittable 
identifier"),
+                                
fieldWithPath("permittables[].acceptTokenIntendedForForeignApplication").type(Boolean.TYPE).description("Accept
 token for foreign application ?")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentFindAllPGroups ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignore = loginAdmin()) {
+
+      final String firstIdentifier = 
testEnvironment.generateUniqueIdentifer("pgroup");
+      final String secondIdentifier = 
testEnvironment.generateUniqueIdentifer("pgroup");
+
+      final List <String> identifierstrings = 
Lists.newArrayList(firstIdentifier, secondIdentifier);
+
+      identifierstrings.stream()
+              .forEach(string -> {
+
+                final PermittableEndpoint permittableEndpoint = 
buildPermittableEndpoint();
+                final PermittableGroup pGroup = buildPermittableGroup(string, 
permittableEndpoint);
+
+                getTestSubject().createPermittableGroup(pGroup);
+
+                {
+                  final boolean found;
+                  try {
+                    found = 
eventRecorder.wait(EventConstants.OPERATION_POST_PERMITTABLE_GROUP, 
pGroup.getIdentifier());
+                    Assert.assertTrue(found);
+                  } catch (InterruptedException e) {
+                    e.printStackTrace();
+                  }
+                }
+              });
+
+      try {
+        this.mockMvc.perform(get("/permittablegroups")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-find-all-p-groups", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].identifier").description("Permittable group identifier"),
+                                
fieldWithPath("[].permittables[].path").description("RequestMapping value"),
+                                
fieldWithPath("[].permittables[].method").type("RequestMethod").description("HTTP
 Request Method"),
+                                
fieldWithPath("[].permittables[].groupId").type("String").description("permittable
 identifier"),
+                                
fieldWithPath("[].permittables[].acceptTokenIntendedForForeignApplication").type(Boolean.TYPE).description("Accept
 token for foreign application ?"),
+                                
fieldWithPath("[1].identifier").description("Permittable group identifier"),
+                                
fieldWithPath("[1].permittables[].path").description("RequestMapping value"),
+                                
fieldWithPath("[1].permittables[].method").type("RequestMethod").description("HTTP
 Request Method"),
+                                
fieldWithPath("[1].permittables[].groupId").type("String").description("permittable
 identifier"),
+                                
fieldWithPath("[1].permittables[].acceptTokenIntendedForForeignApplication").type(Boolean.TYPE).description("Accept
 token for foreign application ?")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentCreateUser ( ) throws InterruptedException {
+
+    final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(username, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(username, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword newUser = new UserWithPassword("Ahmes_friend_zero", 
"scribe_zero",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(post("/users")
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serializer.toJson(newUser)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-create-user", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                
fieldWithPath("identifier").description("user's identifier"),
+                                fieldWithPath("role").description("user's 
role"),
+                                fieldWithPath("password").description("user's 
password")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentFindUser ( ) throws InterruptedException {
+
+    final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(username, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(username, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword newUser = new UserWithPassword("Ahmes_friend_three", 
"scribe_three",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+      getTestSubject().createUser(newUser);
+      final boolean found = 
eventRecorder.wait(EventConstants.OPERATION_POST_USER, newUser.getIdentifier());
+      Assert.assertTrue(found);
+
+      try {
+        this.mockMvc.perform(get("/users/" + newUser.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-find-user", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("identifier").description("user's identifier"),
+                                fieldWithPath("role").description("user's 
role")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentFindAllUsers ( ) throws InterruptedException {
+
+    final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(username, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(username, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword ahmesFriend = new UserWithPassword("Ahmes_friend", 
"scribe",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+      getTestSubject().createUser(ahmesFriend);
+      final boolean found = 
eventRecorder.wait(EventConstants.OPERATION_POST_USER, 
ahmesFriend.getIdentifier());
+      Assert.assertTrue(found);
+
+      UserWithPassword ahmesOtherFriend = new 
UserWithPassword("Ahmes_Other_friend", "cobbler",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD + 
"Other"));
+      getTestSubject().createUser(ahmesOtherFriend);
+      Assert.assertTrue(eventRecorder.wait(EventConstants.OPERATION_POST_USER, 
ahmesOtherFriend.getIdentifier()));
+
+      try {
+        this.mockMvc.perform(get("/users")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-find-all-users", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].identifier").description("first user's identifier"),
+                                fieldWithPath("[].role").description("first 
user's role"),
+                                
fieldWithPath("[1].identifier").description("second user's identifier"),
+                                fieldWithPath("[1].role").description("second 
user's role"),
+                                
fieldWithPath("[2].identifier").description("third user's identifier"),
+                                fieldWithPath("[2].role").description("third 
user's role"),
+                                
fieldWithPath("[3].identifier").description("fourth user's identifier"),
+                                fieldWithPath("[3].role").description("fourth 
user's role")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentChangeUserRole ( ) throws InterruptedException {
+
+    final String userName = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(userName, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(userName, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword user = new UserWithPassword("Ahmes_friend_One", 
"scribe_one",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+      getTestSubject().createUser(user);
+      Assert.assertTrue(eventRecorder.wait(EventConstants.OPERATION_POST_USER, 
user.getIdentifier()));
+
+      RoleIdentifier newRole = new RoleIdentifier("cobbler");
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(put("/users/" + user.getIdentifier() + 
"/roleIdentifier")
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serializer.toJson(newRole)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-change-user-role", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                fieldWithPath("identifier").description(" 
updated role identifier")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetUserPermissions ( ) throws InterruptedException {
+
+    final String userName = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(userName, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(userName, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword user = new UserWithPassword("Ahmes_friend_Two", 
"scribe_two",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+      getTestSubject().createUser(user);
+      Assert.assertTrue(eventRecorder.wait(EventConstants.OPERATION_POST_USER, 
user.getIdentifier()));
+
+      try {
+        this.mockMvc.perform(get("/users/" + user.getIdentifier() + 
"/permissions")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-user-permissions", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].permittableEndpointGroupIdentifier").description(" 
permittable endpoint group identifier"),
+                                
fieldWithPath("[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of allowed operations")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentChangeUserPassword ( ) throws InterruptedException {
+
+    final String userName = createUserWithNonexpiredPassword(AHMES_PASSWORD, 
ADMIN_ROLE);
+
+    final Authentication userAuthentication =
+            getTestSubject().login(userName, 
TestEnvironment.encodePassword(AHMES_PASSWORD));
+
+    try (final AutoUserContext ignored = new AutoUserContext(userName, 
userAuthentication.getAccessToken())) {
+
+      UserWithPassword user = new UserWithPassword("Daddy", "bearer",
+              TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD));
+      getTestSubject().createUser(user);
+      Assert.assertTrue(eventRecorder.wait(EventConstants.OPERATION_POST_USER, 
user.getIdentifier()));
+
+      Password passw = new 
Password(TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD + "Daddy"));
+
+      user.setPassword(passw.getPassword());
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(put("/users/" + user.getIdentifier() + 
"/password")
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serializer.toJson(passw)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-change-user-password", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                fieldWithPath("password").description("updated 
password")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetApplications ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignored = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData firstApplication = 
setApplicationSignature();
+      final ApplicationSignatureTestData secondApplication = 
setApplicationSignature();
+
+      try {
+        this.mockMvc.perform(get("/applications")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-applications", 
preprocessResponse(prettyPrint())));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentDeleteApplication ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignored = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData firstApplication = 
setApplicationSignature();
+
+      try {
+        this.mockMvc.perform(delete("/applications/" + 
firstApplication.getApplicationIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-delete-application", 
preprocessResponse(prettyPrint())));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentSetApplicationSignature ( ) throws InterruptedException {
+
+    final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+
+    final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+
+    final String appTimeStamp = keyPair.getTimestamp();
+
+    final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+    Gson serializer = new Gson();
+    try {
+      this.mockMvc.perform(put("/applications/" + appIdentifier + 
"/signatures/" + appTimeStamp)
+              .accept(MediaType.APPLICATION_JSON_VALUE)
+              .contentType(MediaType.APPLICATION_JSON_VALUE)
+              .content(serializer.toJson(signature)))
+              .andExpect(status().isAccepted())
+              .andDo(document("document-set-application-signature", 
preprocessRequest(prettyPrint()),
+                      requestFields(
+                              
fieldWithPath("publicKeyMod").type("BigInteger").description(" public key mod"),
+                              
fieldWithPath("publicKeyExp").type("BigInteger").description(" public key exp")
+                      )
+              ));
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void documentGetApplicationSignature ( ) throws InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+
+      final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+
+      final String appTimeStamp = keyPair.getTimestamp();
+
+      final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+      getTestSubject().setApplicationSignature(appIdentifier, appTimeStamp, 
signature);
+      
this.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_SIGNATURE, new 
ApplicationSignatureEvent(appIdentifier, keyPair.getTimestamp()));
+
+      try {
+        this.mockMvc.perform(get("/applications/" + appIdentifier + 
"/signatures/" + appTimeStamp)
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.ALL_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-application-signature", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("publicKeyMod").type("BigInteger").description("public key mod"),
+                                
fieldWithPath("publicKeyExp").type("BigInteger").description("public key exp")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentCreateApplicationPermission ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+
+      final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+
+      final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+
+      final String appTimeStamp = keyPair.getTimestamp();
+
+      final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+      getTestSubject().setApplicationSignature(appIdentifier, appTimeStamp, 
signature);
+      
this.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_SIGNATURE, new 
ApplicationSignatureEvent(appIdentifier, keyPair.getTimestamp()));
+
+      final Permission newPermission = new 
Permission(PermittableGroupIds.IDENTITY_MANAGEMENT, 
Sets.newHashSet(AllowedOperation.READ));
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(post("/applications/" + appIdentifier + 
"/permissions")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serializer.toJson(newPermission)))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-create-application-permission", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                
fieldWithPath("permittableEndpointGroupIdentifier").description("permittable 
group endpoint identifier"),
+                                
fieldWithPath("allowedOperations").type("Set<AllowedOperation>").description("Set
 of Allowed Operations")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetApplicationPermission ( ) throws InterruptedException 
{
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+
+      final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+
+      final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+
+      final String appTimeStamp = keyPair.getTimestamp();
+
+      final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+      getTestSubject().setApplicationSignature(appIdentifier, appTimeStamp, 
signature);
+      
this.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_SIGNATURE, new 
ApplicationSignatureEvent(appIdentifier, keyPair.getTimestamp()));
+
+      final Permission newPermission = new 
Permission(PermittableGroupIds.IDENTITY_MANAGEMENT, 
Sets.newHashSet(AllowedOperation.CHANGE));
+
+      createApplicationPermission(appIdentifier, newPermission);
+
+      Gson serializer = new Gson();
+      try {
+        this.mockMvc.perform(get("/applications/" + appIdentifier + 
"/permissions/" + newPermission.getPermittableEndpointGroupIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-application-permission", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("permittableEndpointGroupIdentifier").description("permittable 
group endpoint identifier"),
+                                
fieldWithPath("allowedOperations").type("Set<AllowedOperation>").description("Set
 of Allowed Operations")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetApplicationPermissions ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+
+      final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+
+      final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+
+      final String appTimeStamp = keyPair.getTimestamp();
+
+      final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+      getTestSubject().setApplicationSignature(appIdentifier, appTimeStamp, 
signature);
+      
this.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_SIGNATURE, new 
ApplicationSignatureEvent(appIdentifier, keyPair.getTimestamp()));
+
+      final Permission firstPermission = new 
Permission(PermittableGroupIds.IDENTITY_MANAGEMENT, 
Sets.newHashSet(AllowedOperation.CHANGE));
+      createApplicationPermission(appIdentifier, firstPermission);
+
+      final Permission secondPermission = new 
Permission(PermittableGroupIds.ROLE_MANAGEMENT, 
Sets.newHashSet(AllowedOperation.DELETE));
+      createApplicationPermission(appIdentifier, secondPermission);
+
+      try {
+        this.mockMvc.perform(get("/applications/" + appIdentifier + 
"/permissions")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-application-permissions", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].permittableEndpointGroupIdentifier").description("first 
permittable group endpoint identifier"),
+                                
fieldWithPath("[].allowedOperations").type("Set<AllowedOperation>").description("Set
 of Allowed Operations"),
+                                
fieldWithPath("[1].permittableEndpointGroupIdentifier").description("second 
permittable group endpoint identifier"),
+                                
fieldWithPath("[1].allowedOperations").type("Set<AllowedOperation>").description("Set
 of Allowed Operations")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentDeleteApplicationPermission ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+
+      final String appIdentifier = "testApp" + 
RandomStringUtils.randomNumeric(3) + "-v1";
+      final RsaKeyPairFactory.KeyPairHolder keyPair = 
RsaKeyPairFactory.createKeyPair();
+      final String appTimeStamp = keyPair.getTimestamp();
+      final Signature signature = new Signature(keyPair.getPublicKeyMod(), 
keyPair.getPublicKeyExp());
+
+      getTestSubject().setApplicationSignature(appIdentifier, appTimeStamp, 
signature);
+      
this.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_SIGNATURE, new 
ApplicationSignatureEvent(appIdentifier, keyPair.getTimestamp()));
+
+      final Permission newPermission = new 
Permission(PermittableGroupIds.IDENTITY_MANAGEMENT, 
Sets.newHashSet(AllowedOperation.CHANGE));
+      createApplicationPermission(appIdentifier, newPermission);
+
+      try {
+        this.mockMvc.perform(delete("/applications/" + appIdentifier + 
"/permissions/" + newPermission.getPermittableEndpointGroupIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isAccepted())
+                .andDo(document("document-delete-application-permission", 
preprocessResponse(prettyPrint())));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentCreateApplicationCallEndpointSet ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData application = 
setApplicationSignature();
+
+      final String endpointSetIdentifier = 
testEnvironment.generateUniqueIdentifer("end_pt_set");
+      final CallEndpointSet endpointSet = new CallEndpointSet();
+      endpointSet.setIdentifier(endpointSetIdentifier);
+      
endpointSet.setPermittableEndpointGroupIdentifiers(Collections.emptyList());
+
+      Gson serial = new Gson();
+      try {
+        this.mockMvc.perform(post("/applications/" + 
application.getApplicationIdentifier() + "/callendpointset")
+                .accept(MediaType.APPLICATION_JSON_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serial.toJson(endpointSet)))
+                .andExpect(status().isAccepted())
+                
.andDo(document("document-create-application-call-endpoint-set", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                fieldWithPath("identifier").description("call 
endpoint set identifier"),
+                                
fieldWithPath("permittableEndpointGroupIdentifiers").type("List<String>").description("permittable
 group endpoint identifier")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentChangeApplicationCallEndpointSet ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData application = 
setApplicationSignature();
+
+      final String endpointSetIdentifier = 
testEnvironment.generateUniqueIdentifer("end_pt_set");
+      PermittableEndpoint pEndPointOne = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointTwo = buildPermittableEndpoint();
+
+      PermittableGroup pgroup1 = buildPermittableGroup("ideeOne", 
pEndPointOne);
+      PermittableGroup pgroup2 = buildPermittableGroup("ideeTwo", 
pEndPointTwo);
+
+      List enlist = Lists.newArrayList(pgroup1.getIdentifier(), 
pgroup2.getIdentifier());
+
+      final CallEndpointSet endpointSet = new CallEndpointSet();
+      endpointSet.setIdentifier(endpointSetIdentifier);
+      endpointSet.setPermittableEndpointGroupIdentifiers(enlist);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSet);
+      
super.eventRecorder.wait(EventConstants.OPERATION_POST_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifier));
+
+      Gson serial = new Gson();
+      try {
+        this.mockMvc.perform(put("/applications/" + 
application.getApplicationIdentifier() + "/callendpointset/" + 
endpointSet.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .content(serial.toJson(endpointSet)))
+                .andExpect(status().isAccepted())
+                
.andDo(document("document-change-application-call-endpoint-set", 
preprocessRequest(prettyPrint()),
+                        requestFields(
+                                fieldWithPath("identifier").description("call 
endpoint set identifier"),
+                                
fieldWithPath("permittableEndpointGroupIdentifiers").type("List<String>").description("permittable
 group endpoint identifier")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetApplicationCallEndpointSets ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData application = 
setApplicationSignature();
+
+      final String endpointSetIdentifierOne = 
testEnvironment.generateUniqueIdentifer("end_pt_set");
+      final String endpointSetIdentifierTwo = 
testEnvironment.generateUniqueIdentifer("endptset");
+
+      PermittableEndpoint pEndPointZero = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointOne = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointTwo = buildPermittableEndpoint();
+
+      PermittableGroup pgroup = buildPermittableGroup("ideeZero", 
pEndPointZero);
+      PermittableGroup pgroup1 = buildPermittableGroup("ideeOne", 
pEndPointOne);
+      PermittableGroup pgroup2 = buildPermittableGroup("ideeTwo", 
pEndPointTwo);
+
+      List enlist1 = Lists.newArrayList(pgroup1.getIdentifier(), 
pgroup2.getIdentifier());
+
+      final CallEndpointSet endpointSetOne = new CallEndpointSet();
+      endpointSetOne.setIdentifier(endpointSetIdentifierOne);
+      endpointSetOne.setPermittableEndpointGroupIdentifiers(enlist1);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSetOne);
+      
super.eventRecorder.wait(EventConstants.OPERATION_POST_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifierOne));
+
+      List enlist2 = Lists.newArrayList(pgroup.getIdentifier());
+      final CallEndpointSet endpointSetTwo = new CallEndpointSet();
+      endpointSetTwo.setIdentifier(endpointSetIdentifierTwo);
+      endpointSetTwo.setPermittableEndpointGroupIdentifiers(enlist2);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSetTwo);
+      
super.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifierTwo));
+
+      
Assert.assertTrue(getTestSubject().getApplicationCallEndpointSets(application.getApplicationIdentifier()).size()
 == 2);
+
+      try {
+        this.mockMvc.perform(get("/applications/" + 
application.getApplicationIdentifier() + "/callendpointset")
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-application-call-endpoint-sets", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                
fieldWithPath("[].identifier").description("first call endpoint call set 
identifier"),
+                                
fieldWithPath("[].permittableEndpointGroupIdentifiers").type("List<String>").description("first
 permittable group endpoint identifier"),
+                                
fieldWithPath("[2].identifier").description("second call endpoint call set 
identifier"),
+                                
fieldWithPath("[2].permittableEndpointGroupIdentifiers").type("List<String>").description("second
 permittable group endpoint identifier")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentGetApplicationCallEndpointSet ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData application = 
setApplicationSignature();
+
+      final String endpointSetIdentifierOne = 
testEnvironment.generateUniqueIdentifer("end_pt_set");
+      final String endpointSetIdentifierTwo = 
testEnvironment.generateUniqueIdentifer("endptset");
+
+      PermittableEndpoint pEndPointZero = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointOne = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointTwo = buildPermittableEndpoint();
+
+      PermittableGroup pgroup = buildPermittableGroup("ideeZero", 
pEndPointZero);
+      PermittableGroup pgroup1 = buildPermittableGroup("ideeOne", 
pEndPointOne);
+      PermittableGroup pgroup2 = buildPermittableGroup("ideeTwo", 
pEndPointTwo);
+
+      List enlist1 = Lists.newArrayList(pgroup1.getIdentifier(), 
pgroup2.getIdentifier());
+
+      final CallEndpointSet endpointSetOne = new CallEndpointSet();
+      endpointSetOne.setIdentifier(endpointSetIdentifierOne);
+      endpointSetOne.setPermittableEndpointGroupIdentifiers(enlist1);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSetOne);
+      
super.eventRecorder.wait(EventConstants.OPERATION_POST_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifierOne));
+
+      List enlist2 = Lists.newArrayList(pgroup.getIdentifier());
+      final CallEndpointSet endpointSetTwo = new CallEndpointSet();
+      endpointSetTwo.setIdentifier(endpointSetIdentifierTwo);
+      endpointSetTwo.setPermittableEndpointGroupIdentifiers(enlist2);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSetTwo);
+      
super.eventRecorder.wait(EventConstants.OPERATION_PUT_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifierTwo));
+
+      
Assert.assertTrue(getTestSubject().getApplicationCallEndpointSets(application.getApplicationIdentifier()).size()
 == 2);
+
+      try {
+        this.mockMvc.perform(get("/applications/" + 
application.getApplicationIdentifier() + "/callendpointset/" + 
endpointSetOne.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk())
+                .andDo(document("document-get-application-call-endpoint-set", 
preprocessResponse(prettyPrint()),
+                        responseFields(
+                                fieldWithPath("identifier").description("call 
endpoint call set identifier"),
+                                
fieldWithPath("permittableEndpointGroupIdentifiers").type("List<String>").description("permittable
 group endpoint identifier")
+                        )
+                ));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void documentDeleteApplicationCallEndpointSet ( ) throws 
InterruptedException {
+
+    try (final AutoUserContext ignored
+                 = 
tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+      final ApplicationSignatureTestData application = 
setApplicationSignature();
+
+      final String endpointSetIdentifier = 
testEnvironment.generateUniqueIdentifer("end_pt_set");
+      PermittableEndpoint pEndPointOne = buildPermittableEndpoint();
+      PermittableEndpoint pEndPointTwo = buildPermittableEndpoint();
+
+      PermittableGroup pgroup1 = buildPermittableGroup("yepue", pEndPointOne);
+      PermittableGroup pgroup2 = buildPermittableGroup("yetah", pEndPointTwo);
+
+      List enlist = Lists.newArrayList(pgroup1.getIdentifier(), 
pgroup2.getIdentifier());
+
+      final CallEndpointSet endpointSet = new CallEndpointSet();
+      endpointSet.setIdentifier(endpointSetIdentifier);
+      endpointSet.setPermittableEndpointGroupIdentifiers(enlist);
+
+      
getTestSubject().createApplicationCallEndpointSet(application.getApplicationIdentifier(),
 endpointSet);
+      
super.eventRecorder.wait(EventConstants.OPERATION_POST_APPLICATION_CALLENDPOINTSET,
+              new 
ApplicationCallEndpointSetEvent(application.getApplicationIdentifier(), 
endpointSetIdentifier));
+
+      try {
+        this.mockMvc.perform(delete("/applications/" + 
application.getApplicationIdentifier() + "/callendpointset/" + 
endpointSet.getIdentifier())
+                .accept(MediaType.ALL_VALUE)
+                .contentType(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isAccepted())
+                
.andDo(document("document-delete-application-call-endpoint-set", 
preprocessRequest(prettyPrint())));
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  private PermittableGroup buildPermittableGroup (final String identifier, 
final PermittableEndpoint permittableEndpoint) {
+    final PermittableGroup ret = new PermittableGroup();
+    ret.setIdentifier(identifier);
+    ret.setPermittables(Collections.singletonList(permittableEndpoint));
+    return ret;
+  }
+
+  private PermittableEndpoint buildPermittableEndpoint ( ) {
+    final PermittableEndpoint ret = new PermittableEndpoint();
+    ret.setPath("/exx/eyy/eze");
+    ret.setMethod("POST");
+    ret.setGroupId("id");
+    return ret;
+  }
+}
diff --git a/component-test/src/main/java/TestApplications.java 
b/component-test/src/main/java/TestApplications.java
index 524b17d..d65a144 100644
--- a/component-test/src/main/java/TestApplications.java
+++ b/component-test/src/main/java/TestApplications.java
@@ -41,7 +41,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestApplications extends AbstractComponentTest {
+public class TestApplications extends AbstractIdentityTest {
 
   private static final String CALL_ENDPOINT_SET_IDENTIFIER = "doughboy";
 
diff --git a/component-test/src/main/java/TestAuthentication.java 
b/component-test/src/main/java/TestAuthentication.java
index 05a6875..b3f5259 100644
--- a/component-test/src/main/java/TestAuthentication.java
+++ b/component-test/src/main/java/TestAuthentication.java
@@ -53,7 +53,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestAuthentication extends AbstractComponentTest {
+public class TestAuthentication extends AbstractIdentityTest {
   @Test
   //@Repeat(25)
   public void testAdminLogin() throws InterruptedException {
diff --git a/component-test/src/main/java/TestKeyRotation.java 
b/component-test/src/main/java/TestKeyRotation.java
index e2f0935..0f414d0 100644
--- a/component-test/src/main/java/TestKeyRotation.java
+++ b/component-test/src/main/java/TestKeyRotation.java
@@ -33,7 +33,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestKeyRotation extends AbstractComponentTest {
+public class TestKeyRotation extends AbstractIdentityTest {
   @Test
   public void testKeyRotation() throws InterruptedException {
     final Anubis anubis = tenantApplicationSecurityEnvironment.getAnubis();
diff --git a/component-test/src/main/java/TestPasswords.java 
b/component-test/src/main/java/TestPasswords.java
index 35fd73c..7ac761a 100644
--- a/component-test/src/main/java/TestPasswords.java
+++ b/component-test/src/main/java/TestPasswords.java
@@ -33,7 +33,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestPasswords extends AbstractComponentTest {
+public class TestPasswords extends AbstractIdentityTest {
 
   @Test
   public void testAdminChangeUserPassword() throws InterruptedException {
diff --git a/component-test/src/main/java/TestPermittableGroups.java 
b/component-test/src/main/java/TestPermittableGroups.java
index 8ee0255..d6376b7 100644
--- a/component-test/src/main/java/TestPermittableGroups.java
+++ b/component-test/src/main/java/TestPermittableGroups.java
@@ -29,7 +29,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestPermittableGroups extends AbstractComponentTest {
+public class TestPermittableGroups extends AbstractIdentityTest {
   @Test
   public void getPermittableGroups() throws InterruptedException {
     try (final AutoUserContext ignore = loginAdmin()) {
diff --git a/component-test/src/main/java/TestProvisioning.java 
b/component-test/src/main/java/TestProvisioning.java
index 52fb76a..30c70ae 100644
--- a/component-test/src/main/java/TestProvisioning.java
+++ b/component-test/src/main/java/TestProvisioning.java
@@ -41,7 +41,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestProvisioning extends AbstractComponentTest {
+public class TestProvisioning extends AbstractIdentityTest {
 
   @Test
   public void testBoundaryInitializeCases() throws InterruptedException {
diff --git a/component-test/src/main/java/TestRefreshToken.java 
b/component-test/src/main/java/TestRefreshToken.java
index 290f25f..469fa24 100644
--- a/component-test/src/main/java/TestRefreshToken.java
+++ b/component-test/src/main/java/TestRefreshToken.java
@@ -43,7 +43,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestRefreshToken extends AbstractComponentTest {
+public class TestRefreshToken extends AbstractIdentityTest {
   private static final int ACCESS_TOKEN_TIME_TO_LIVE = 5;
   private static final int REFRESH_TOKEN_TIME_TO_LIVE = 10;
 
diff --git a/component-test/src/main/java/TestRoles.java 
b/component-test/src/main/java/TestRoles.java
index 9be2f6a..383fbf2 100644
--- a/component-test/src/main/java/TestRoles.java
+++ b/component-test/src/main/java/TestRoles.java
@@ -33,7 +33,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestRoles extends AbstractComponentTest {
+public class TestRoles extends AbstractIdentityTest {
   @Test
   public void testRolesSortedAlphabetically() throws InterruptedException {
     try (final AutoUserContext ignore = loginAdmin()) {
diff --git a/component-test/src/main/java/TestUsers.java 
b/component-test/src/main/java/TestUsers.java
index 3c41030..267ea93 100644
--- a/component-test/src/main/java/TestUsers.java
+++ b/component-test/src/main/java/TestUsers.java
@@ -40,7 +40,7 @@
 /**
  * @author Myrle Krantz
  */
-public class TestUsers extends AbstractComponentTest {
+public class TestUsers extends AbstractIdentityTest {
 
 
   @Test


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to