Transporting the application source of a refresh token to its access token, and validating that application's permission.
diff --git a/component-test/src/main/java/AbstractComponentTest.java b/component-test/src/main/java/AbstractComponentTest.java
index 26761ed..e246a96 100644
--- a/component-test/src/main/java/AbstractComponentTest.java
+++ b/component-test/src/main/java/AbstractComponentTest.java
@@ -200,6 +200,13 @@
return permission;
}
+ Permission buildApplicationSelfPermission() {
+ final Permission permission = new Permission();
+ permission.setAllowedOperations(AllowedOperation.ALL);
+ permission.setPermittableEndpointGroupIdentifier(PermittableGroupIds.APPLICATION_SELF_MANAGEMENT);
+ return permission;
+ }
+
String createRoleManagementRole() throws InterruptedException {
return createRole(buildRolePermission());
}
@@ -208,6 +215,10 @@
return createRole(buildSelfPermission());
}
+ String createApplicationSelfManagementRole() throws InterruptedException {
+ return createRole(buildApplicationSelfPermission());
+ }
+
String createRole(final Permission... permission) throws InterruptedException {
final String roleIdentifier = generateRoleIdentifier();
final Role role = buildRole(roleIdentifier, permission);
diff --git a/component-test/src/main/java/TestApplications.java b/component-test/src/main/java/TestApplications.java
index df185a6..a4e5a77 100644
--- a/component-test/src/main/java/TestApplications.java
+++ b/component-test/src/main/java/TestApplications.java
@@ -318,4 +318,69 @@
Assert.assertFalse(users.isEmpty());
}
}
+
+ @Test
+ public void applicationIssuedRefreshTokenToCreatePermissionRequest() throws InterruptedException {
+ final ApplicationSignatureTestData appPlusSig;
+ try (final AutoUserContext ignored
+ = tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
+ appPlusSig = setApplicationSignature();
+ createApplicationPermission(appPlusSig.getApplicationIdentifier(), buildApplicationSelfPermission());
+ }
+
+ final String userid;
+ final String userid2;
+ final String userPassword;
+ try (final AutoUserContext ignored = loginAdmin()) {
+
+ final String roleId = createApplicationSelfManagementRole();
+
+ userPassword = RandomStringUtils.randomAlphanumeric(5);
+ userid = createUserWithNonexpiredPassword(userPassword, roleId);
+ userid2 = createUserWithNonexpiredPassword(userPassword, roleId);
+
+ }
+
+ try (final AutoUserContext ignored = loginUser(userid, userPassword)) {
+ getTestSubject().setApplicationPermissionEnabledForUser(appPlusSig.getApplicationIdentifier(), PermittableGroupIds.APPLICATION_SELF_MANAGEMENT, userid, true);
+ }
+
+
+ final TokenSerializationResult tokenSerializationResult =
+ new TenantRefreshTokenSerializer().build(new TenantRefreshTokenSerializer.Specification()
+ .setUser(userid)
+ .setSecondsToLive(30)
+ .setKeyTimestamp(appPlusSig.getKeyTimestamp())
+ .setPrivateKey(appPlusSig.getKeyPair().privateKey())
+ .setSourceApplication(appPlusSig.getApplicationIdentifier()));
+
+
+ final Authentication applicationAuthentication = getTestSubject().refresh(tokenSerializationResult.getToken());
+
+ try (final AutoUserContext ignored = new AutoUserContext(userid, applicationAuthentication.getAccessToken())) {
+ final Permission rolePermission = buildRolePermission();
+ createApplicationPermission(appPlusSig.getApplicationIdentifier(), rolePermission);
+
+ final List<Permission> appPermissions = getTestSubject().getApplicationPermissions(
+ appPlusSig.getApplicationIdentifier());
+
+ Assert.assertTrue(appPermissions.contains(rolePermission));
+
+ try {
+ getTestSubject().setApplicationPermissionEnabledForUser(appPlusSig.getApplicationIdentifier(), rolePermission.getPermittableEndpointGroupIdentifier(), userid2, true);
+ Assert.fail("This call to create enable permission for another user should've failed.");
+ }
+ catch (final NotFoundException ignored2) {
+
+ }
+
+ try {
+ createApplicationPermission("madeupname-v1", rolePermission);
+ Assert.fail("This call to create application permission should've failed.");
+ }
+ catch (final NotFoundException ignored2) {
+
+ }
+ }
+ }
}
diff --git a/service/src/main/java/io/mifos/identity/internal/command/handler/AuthenticationCommandHandler.java b/service/src/main/java/io/mifos/identity/internal/command/handler/AuthenticationCommandHandler.java
index b674b4e..3dd9c43 100644
--- a/service/src/main/java/io/mifos/identity/internal/command/handler/AuthenticationCommandHandler.java
+++ b/service/src/main/java/io/mifos/identity/internal/command/handler/AuthenticationCommandHandler.java
@@ -277,7 +277,8 @@
final TokenSerializationResult accessToken = getAuthenticationResponse(
user.getIdentifier(),
tokenPermissions,
- privateSignature);
+ privateSignature,
+ sourceApplicationName);
return new AuthenticationCommandResponse(
accessToken.getToken(), DateConverter.toIsoString(accessToken.getExpiration()),
@@ -326,7 +327,8 @@
private TokenSerializationResult getAuthenticationResponse(
final String userIdentifier,
final Set<TokenPermission> tokenPermissions,
- final PrivateSignatureEntity privateSignatureEntity) {
+ final PrivateSignatureEntity privateSignatureEntity,
+ final String sourceApplication) {
final PrivateKey privateKey = new RsaPrivateKeyBuilder()
.setPrivateKeyExp(privateSignatureEntity.getPrivateKeyExp())
@@ -339,7 +341,8 @@
.setPrivateKey(privateKey)
.setTokenContent(new TokenContent(new ArrayList<>(tokenPermissions)))
.setSecondsToLive(accessTtl)
- .setUser(userIdentifier);
+ .setUser(userIdentifier)
+ .setSourceApplication(sourceApplication);
return tenantAccessTokenSerializer.build(x);
}
diff --git a/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java b/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
index 2353947..ecf1c61 100644
--- a/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
+++ b/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
@@ -120,10 +120,13 @@
createPermittablesGroup(PermittableGroupIds.ROLE_MANAGEMENT, "/roles/*", "/permittablegroups/*");
createPermittablesGroup(PermittableGroupIds.IDENTITY_MANAGEMENT, "/users/*");
createPermittablesGroup(PermittableGroupIds.SELF_MANAGEMENT, "/users/{useridentifier}/password", "/applications/*/permissions/*/users/{useridentifier}/enabled");
+ createPermittablesGroup(PermittableGroupIds.APPLICATION_SELF_MANAGEMENT, "/applications/{applicationidentifier}/permissions");
final List<PermissionType> permissions = new ArrayList<>();
permissions.add(fullAccess(PermittableGroupIds.ROLE_MANAGEMENT));
permissions.add(fullAccess(PermittableGroupIds.IDENTITY_MANAGEMENT));
+ permissions.add(fullAccess(PermittableGroupIds.SELF_MANAGEMENT));
+ permissions.add(fullAccess(PermittableGroupIds.APPLICATION_SELF_MANAGEMENT));
final RoleEntity suRole = new RoleEntity();
suRole.setIdentifier(IdentityConstants.SU_ROLE);
diff --git a/service/src/main/java/io/mifos/identity/rest/ApplicationRestController.java b/service/src/main/java/io/mifos/identity/rest/ApplicationRestController.java
index 8c83a9c..a3529aa 100644
--- a/service/src/main/java/io/mifos/identity/rest/ApplicationRestController.java
+++ b/service/src/main/java/io/mifos/identity/rest/ApplicationRestController.java
@@ -22,6 +22,7 @@
import io.mifos.anubis.api.v1.validation.ValidKeyTimestamp;
import io.mifos.core.command.gateway.CommandGateway;
import io.mifos.core.lang.ServiceException;
+import io.mifos.identity.api.v1.PermittableGroupIds;
import io.mifos.identity.api.v1.domain.Permission;
import io.mifos.identity.internal.command.CreateApplicationPermissionCommand;
import io.mifos.identity.internal.command.DeleteApplicationCommand;
@@ -112,7 +113,7 @@
consumes = {MediaType.ALL_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE})
@Permittable(value = AcceptedTokenType.SYSTEM)
- @Permittable(groupId = io.mifos.identity.api.v1.PermittableGroupIds.APPLICATION_SELF_MANAGEMENT)
+ @Permittable(value = AcceptedTokenType.TENANT, permittedEndpoint = "applications/{applicationidentifier}/permissions", groupId = PermittableGroupIds.APPLICATION_SELF_MANAGEMENT)
public @ResponseBody
ResponseEntity<Void>
createApplicationPermission(@PathVariable("applicationidentifier") @Nonnull String applicationIdentifier,
@@ -127,6 +128,7 @@
consumes = {MediaType.ALL_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE})
@Permittable(value = AcceptedTokenType.SYSTEM)
+ @Permittable(value = AcceptedTokenType.TENANT, permittedEndpoint = "applications/{applicationidentifier}/permissions", groupId = PermittableGroupIds.APPLICATION_SELF_MANAGEMENT)
public @ResponseBody
ResponseEntity<List<Permission>>
getApplicationPermissions(@PathVariable("applicationidentifier") @Nonnull String applicationIdentifier) {