Merge pull request #8 from myrle-krantz/develop
Initialization via permitted-feign-client.
diff --git a/component-test/src/main/java/io/mifos/provisioner/tenant/Fixture.java b/component-test/src/main/java/io/mifos/provisioner/tenant/Fixture.java
index a7cf7f2..eb457f9 100644
--- a/component-test/src/main/java/io/mifos/provisioner/tenant/Fixture.java
+++ b/component-test/src/main/java/io/mifos/provisioner/tenant/Fixture.java
@@ -16,20 +16,17 @@
package io.mifos.provisioner.tenant;
+import io.mifos.core.test.env.TestEnvironment;
import io.mifos.provisioner.api.v1.domain.CassandraConnectionInfo;
import io.mifos.provisioner.api.v1.domain.DatabaseConnectionInfo;
import io.mifos.provisioner.api.v1.domain.Tenant;
class Fixture {
-
- private static Tenant compTestTenant = new Tenant();
-
- static final String TENANT_IDENTIFIER = "comp-test";
-
static final String TENANT_NAME = "Comp Test";
- static {
- compTestTenant.setIdentifier(TENANT_IDENTIFIER);
+ static Tenant getCompTestTenant() {
+ final Tenant compTestTenant = new Tenant();
+ compTestTenant.setIdentifier(TestEnvironment.getRandomTenantName());
compTestTenant.setName(TENANT_NAME);
compTestTenant.setDescription("Component Test Tenant");
@@ -49,9 +46,7 @@
databaseConnectionInfo.setPort("3306");
databaseConnectionInfo.setUser("root");
databaseConnectionInfo.setPassword("mysql");
- }
- static Tenant getCompTestTenant() {
return compTestTenant;
}
}
diff --git a/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenantApplicationAssignment.java b/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenantApplicationAssignment.java
index 6375a2c..9b46af3 100644
--- a/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenantApplicationAssignment.java
+++ b/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenantApplicationAssignment.java
@@ -16,6 +16,7 @@
package io.mifos.provisioner.tenant;
import io.mifos.anubis.api.v1.client.Anubis;
+import io.mifos.anubis.api.v1.domain.AllowedOperation;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.api.v1.domain.PermittableEndpoint;
import io.mifos.anubis.api.v1.domain.Signature;
@@ -29,7 +30,11 @@
import io.mifos.core.lang.security.RsaKeyPairFactory;
import io.mifos.core.test.env.TestEnvironment;
import io.mifos.identity.api.v1.client.IdentityManager;
+import io.mifos.identity.api.v1.domain.CallEndpointSet;
+import io.mifos.identity.api.v1.domain.Permission;
import io.mifos.identity.api.v1.domain.PermittableGroup;
+import io.mifos.permittedfeignclient.api.v1.client.ApplicationPermissionRequirements;
+import io.mifos.permittedfeignclient.api.v1.domain.ApplicationPermission;
import io.mifos.provisioner.ProvisionerCassandraInitializer;
import io.mifos.provisioner.ProvisionerMariaDBInitializer;
import io.mifos.provisioner.api.v1.client.Provisioner;
@@ -175,18 +180,24 @@
private final String keyTimestamp;
private final BigInteger modulus;
private final BigInteger exponent;
+ private final String tenantIdentifier;
private boolean validSecurityContext = false;
- VerifyIsisInitializeContext(final String keyTimestamp, final BigInteger modulus, final BigInteger exponent) {
+ VerifyIsisInitializeContext(
+ final String keyTimestamp,
+ final BigInteger modulus,
+ final BigInteger exponent,
+ final String tenantIdentifier) {
this.keyTimestamp = keyTimestamp;
this.modulus = modulus;
this.exponent = exponent;
+ this.tenantIdentifier = tenantIdentifier;
}
@Override
public ApplicationSignatureSet answer(final InvocationOnMock invocation) throws Throwable {
- validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext("identity", "1", Fixture.TENANT_IDENTIFIER);
+ validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext("identity", "1", tenantIdentifier);
final Signature fakeSignature = new Signature();
fakeSignature.setPublicKeyMod(modulus);
@@ -209,14 +220,16 @@
private boolean validSecurityContext = false;
final private String target;
+ private final String tenantIdentifier;
- private VerifyAnubisInitializeContext(final String target) {
+ private VerifyAnubisInitializeContext(final String target, String tenantIdentifier) {
this.target = target;
+ this.tenantIdentifier = tenantIdentifier;
}
@Override
public Void answer(final InvocationOnMock invocation) throws Throwable {
- validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext(target, "1", Fixture.TENANT_IDENTIFIER);
+ validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext(target, "1", tenantIdentifier);
return null;
}
@@ -227,22 +240,26 @@
private class VerifyCreateSignatureSetContext implements Answer<ApplicationSignatureSet> {
+ private final RsaKeyPairFactory.KeyPairHolder answer;
private boolean validSecurityContext = false;
final private String target;
+ private final String tenantIdentifier;
- private VerifyCreateSignatureSetContext(final String target) {
+ private VerifyCreateSignatureSetContext(final RsaKeyPairFactory.KeyPairHolder answer, final String target, final String tenantIdentifier) {
+ this.answer = answer;
this.target = target;
+ this.tenantIdentifier = tenantIdentifier;
}
@Override
public ApplicationSignatureSet answer(final InvocationOnMock invocation) throws Throwable {
final String timestamp = invocation.getArgumentAt(0, String.class);
final Signature identityManagerSignature = invocation.getArgumentAt(1, Signature.class);
- validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext(target, "1", Fixture.TENANT_IDENTIFIER);
- final RsaKeyPairFactory.KeyPairHolder keys = RsaKeyPairFactory.createKeyPair();
+ validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext(target, "1", tenantIdentifier);
+
return new ApplicationSignatureSet(
timestamp,
- new Signature(keys.getPublicKeyMod(), keys.getPublicKeyExp()),
+ new Signature(answer.getPublicKeyMod(), answer.getPublicKeyExp()),
identityManagerSignature);
}
@@ -256,14 +273,39 @@
private boolean validSecurityContext = false;
private final List<PermittableEndpoint> answer;
+ private final String tenantIdentifier;
- private VerifyAnubisPermittablesContext(final List<PermittableEndpoint> answer) {
+ private VerifyAnubisPermittablesContext(final List<PermittableEndpoint> answer, final String tenantIdentifier) {
this.answer = answer;
+ this.tenantIdentifier = tenantIdentifier;
}
@Override
public List<PermittableEndpoint> answer(final InvocationOnMock invocation) throws Throwable {
- validSecurityContext = systemSecurityEnvironment.isValidGuestSecurityContext(Fixture.TENANT_IDENTIFIER);
+ validSecurityContext = systemSecurityEnvironment.isValidGuestSecurityContext(tenantIdentifier);
+ return answer;
+ }
+
+ boolean isValidSecurityContext() {
+ return validSecurityContext;
+ }
+ }
+
+
+ private class VerifyAnputRequiredPermissionsContext implements Answer<List<ApplicationPermission>> {
+
+ private boolean validSecurityContext = false;
+ private final List<ApplicationPermission> answer;
+ private final String tenantIdentifier;
+
+ private VerifyAnputRequiredPermissionsContext(final List<ApplicationPermission> answer, final String tenantIdentifier) {
+ this.answer = answer;
+ this.tenantIdentifier = tenantIdentifier;
+ }
+
+ @Override
+ public List<ApplicationPermission> answer(final InvocationOnMock invocation) throws Throwable {
+ validSecurityContext = systemSecurityEnvironment.isValidGuestSecurityContext(tenantIdentifier);
return answer;
}
@@ -298,16 +340,16 @@
when(applicationCallContextProviderSpy.getApplication(IdentityManager.class, "http://xyz.identity:2020/v1")).thenReturn(identityServiceMock);
final VerifyIsisInitializeContext verifyInitializeContextAndReturnSignature;
- try (final AutoTenantContext ignored = new AutoTenantContext(Fixture.TENANT_IDENTIFIER)) {
+ try (final AutoTenantContext ignored = new AutoTenantContext(tenant.getIdentifier())) {
verifyInitializeContextAndReturnSignature = new VerifyIsisInitializeContext(
systemSecurityEnvironment.tenantKeyTimestamp(),
systemSecurityEnvironment.tenantPublicKey().getModulus(),
- systemSecurityEnvironment.tenantPublicKey().getPublicExponent());
+ systemSecurityEnvironment.tenantPublicKey().getPublicExponent(), tenant.getIdentifier());
}
doAnswer(verifyInitializeContextAndReturnSignature).when(identityServiceMock).initialize(anyString());
final TokenChecker tokenChecker = new TokenChecker();
- doAnswer(tokenChecker).when(tokenProviderSpy).createToken(Fixture.TENANT_IDENTIFIER, "identity-v1", 2L, TimeUnit.MINUTES);
+ doAnswer(tokenChecker).when(tokenProviderSpy).createToken(tenant.getIdentifier(), "identity-v1", 2L, TimeUnit.MINUTES);
{
final IdentityManagerInitialization identityServiceAdminInitialization
@@ -318,7 +360,7 @@
Assert.assertNotNull(identityServiceAdminInitialization.getAdminPassword());
}
- verify(applicationCallContextProviderSpy, atMost(2)).getApplicationCallContext(Fixture.TENANT_IDENTIFIER, "identity-v1");
+ verify(applicationCallContextProviderSpy, atMost(2)).getApplicationCallContext(tenant.getIdentifier(), "identity-v1");
//Create horus application.
@@ -338,38 +380,60 @@
final Anubis anubisMock = Mockito.mock(Anubis.class);
when(applicationCallContextProviderSpy.getApplication(Anubis.class, "http://xyz.office:2021/v1")).thenReturn(anubisMock);
+ final ApplicationPermissionRequirements anputMock = Mockito.mock(ApplicationPermissionRequirements.class);
+ when(applicationCallContextProviderSpy.getApplication(ApplicationPermissionRequirements.class, "http://xyz.office:2021/v1")).thenReturn(anputMock);
+
+ final RsaKeyPairFactory.KeyPairHolder keysInApplicationSignature = RsaKeyPairFactory.createKeyPair();
final PermittableEndpoint xxPermittableEndpoint = new PermittableEndpoint("/x/y", "POST", "x");
final PermittableEndpoint xyPermittableEndpoint = new PermittableEndpoint("/y/z", "POST", "x");
final PermittableEndpoint xyGetPermittableEndpoint = new PermittableEndpoint("/y/z", "GET", "x");
final PermittableEndpoint mPermittableEndpoint = new PermittableEndpoint("/m/n", "GET", "m");
+ final ApplicationPermission forFooPermission = new ApplicationPermission("forPurposeFoo", new Permission("x", AllowedOperation.ALL));
+ final ApplicationPermission forBarPermission = new ApplicationPermission("forPurposeBar", new Permission("m", Collections.singleton(AllowedOperation.READ)));
+
final VerifyAnubisInitializeContext verifyAnubisInitializeContext;
final VerifyCreateSignatureSetContext verifyCreateSignatureSetContext;
final VerifyAnubisPermittablesContext verifyAnubisPermittablesContext;
- try (final AutoTenantContext ignored = new AutoTenantContext(Fixture.TENANT_IDENTIFIER)) {
- verifyAnubisInitializeContext = new VerifyAnubisInitializeContext("office");
- verifyCreateSignatureSetContext = new VerifyCreateSignatureSetContext("office");
- verifyAnubisPermittablesContext = new VerifyAnubisPermittablesContext(Arrays.asList(xxPermittableEndpoint, xxPermittableEndpoint, xyPermittableEndpoint, xyGetPermittableEndpoint, mPermittableEndpoint));
+ final VerifyAnputRequiredPermissionsContext verifyAnputRequiredPermissionsContext;
+ try (final AutoTenantContext ignored = new AutoTenantContext(tenant.getIdentifier())) {
+ verifyAnubisInitializeContext = new VerifyAnubisInitializeContext("office", tenant.getIdentifier());
+ verifyCreateSignatureSetContext = new VerifyCreateSignatureSetContext(keysInApplicationSignature, "office", tenant.getIdentifier());
+ verifyAnubisPermittablesContext = new VerifyAnubisPermittablesContext(Arrays.asList(xxPermittableEndpoint, xxPermittableEndpoint, xyPermittableEndpoint, xyGetPermittableEndpoint, mPermittableEndpoint), tenant.getIdentifier());
+ verifyAnputRequiredPermissionsContext = new VerifyAnputRequiredPermissionsContext(Arrays.asList(forFooPermission, forBarPermission), tenant.getIdentifier());
}
doAnswer(verifyAnubisInitializeContext).when(anubisMock).initializeResources();
doAnswer(verifyCreateSignatureSetContext).when(anubisMock).createSignatureSet(anyString(), anyObject());
doAnswer(verifyAnubisPermittablesContext).when(anubisMock).getPermittableEndpoints();
+ doAnswer(verifyAnputRequiredPermissionsContext).when(anputMock).getRequiredPermissions();
+
{
provisioner.assignApplications(tenant.getIdentifier(), Collections.singletonList(officeAssigned));
- Thread.sleep(500L); //Application assigning is asynchronous.
+ Thread.sleep(1500L); //Application assigning is asynchronous and I have no message queue.
}
- verify(applicationCallContextProviderSpy).getApplicationCallContext(Fixture.TENANT_IDENTIFIER, "office-v1");
+ verify(applicationCallContextProviderSpy).getApplicationCallContext(tenant.getIdentifier(), "office-v1");
verify(applicationCallContextProviderSpy, never()).getApplicationCallContext(eq(Fixture.TENANT_NAME), Mockito.anyString());
- verify(tokenProviderSpy).createToken(Fixture.TENANT_IDENTIFIER, "office-v1", 2L, TimeUnit.MINUTES);
+ verify(tokenProviderSpy).createToken(tenant.getIdentifier(), "office-v1", 2L, TimeUnit.MINUTES);
- verify(identityServiceMock).createPermittableGroup(new PermittableGroup("x", Arrays.asList(xxPermittableEndpoint, xyPermittableEndpoint, xyGetPermittableEndpoint)));
- verify(identityServiceMock).createPermittableGroup(new PermittableGroup("m", Collections.singletonList(mPermittableEndpoint)));
+ try (final AutoTenantContext ignored = new AutoTenantContext(tenant.getIdentifier())) {
+ verify(identityServiceMock).setApplicationSignature(
+ "office-v1",
+ systemSecurityEnvironment.tenantKeyTimestamp(),
+ new Signature(keysInApplicationSignature.getPublicKeyMod(), keysInApplicationSignature.getPublicKeyExp()));
+ verify(identityServiceMock).createPermittableGroup(new PermittableGroup("x", Arrays.asList(xxPermittableEndpoint, xyPermittableEndpoint, xyGetPermittableEndpoint)));
+ verify(identityServiceMock).createPermittableGroup(new PermittableGroup("m", Collections.singletonList(mPermittableEndpoint)));
+ verify(identityServiceMock).createApplicationPermission("office-v1", new Permission("x", AllowedOperation.ALL));
+ verify(identityServiceMock).createApplicationPermission("office-v1", new Permission("m", Collections.singleton(AllowedOperation.READ)));
+ verify(identityServiceMock).createApplicationCallEndpointSet("office-v1", new CallEndpointSet("forPurposeFoo", Collections.singletonList("x")));
+ verify(identityServiceMock).createApplicationCallEndpointSet("office-v1", new CallEndpointSet("forPurposeBar", Collections.singletonList("m")));
+ }
Assert.assertTrue(verifyAnubisInitializeContext.isValidSecurityContext());
Assert.assertTrue(verifyCreateSignatureSetContext.isValidSecurityContext());
Assert.assertTrue(verifyAnubisPermittablesContext.isValidSecurityContext());
+ Assert.assertTrue(verifyAnputRequiredPermissionsContext.isValidSecurityContext());
}
}
diff --git a/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenants.java b/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenants.java
index 73d8af8..2fade74 100644
--- a/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenants.java
+++ b/component-test/src/main/java/io/mifos/provisioner/tenant/TestTenants.java
@@ -48,7 +48,6 @@
@After
public void after() throws InterruptedException {
provisioner.deleteTenant(Fixture.getCompTestTenant().getIdentifier());
- Thread.sleep(1200L);
autoSeshat.close();
}
diff --git a/service/build.gradle b/service/build.gradle
index fea755c..edb1055 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -33,6 +33,7 @@
[group: 'io.mifos.provisioner', name: 'api', version: project.version],
[group: 'io.mifos.anubis', name: 'library', version: versions.frameworkanubis],
[group: 'io.mifos.anubis', name: 'api', version: versions.frameworkanubis],
+ [group: 'io.mifos.permitted-feign-client', name: 'api', version: versions.frameworkanput],
[group: 'io.mifos.identity', name: 'api', version: versions.mifosidentityservice],
[group: 'com.google.code.gson', name: 'gson', version: versions.gson],
[group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
diff --git a/service/src/main/java/io/mifos/provisioner/internal/repository/TenantCassandraRepository.java b/service/src/main/java/io/mifos/provisioner/internal/repository/TenantCassandraRepository.java
index bbc1b84..7294702 100644
--- a/service/src/main/java/io/mifos/provisioner/internal/repository/TenantCassandraRepository.java
+++ b/service/src/main/java/io/mifos/provisioner/internal/repository/TenantCassandraRepository.java
@@ -21,6 +21,7 @@
import com.datastax.driver.core.PlainTextAuthProvider;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
+import com.datastax.driver.core.exceptions.AlreadyExistsException;
import com.datastax.driver.core.schemabuilder.SchemaBuilder;
import com.datastax.driver.mapping.Mapper;
import com.datastax.driver.mapping.MappingManager;
@@ -102,10 +103,15 @@
throw ServiceException.conflict("Tenant {0} already exists!", tenant.getIdentifier());
}
final Session session = this.getCluster(tenant).connect();
- session.execute("CREATE KEYSPACE " + tenant.getKeyspaceName() + " WITH REPLICATION = " +
- ReplicationStrategyResolver.replicationStrategy(
- tenant.getReplicationType(),
- tenant.getReplicas()));
+ try {
+ session.execute("CREATE KEYSPACE " + tenant.getKeyspaceName() + " WITH REPLICATION = " +
+ ReplicationStrategyResolver.replicationStrategy(
+ tenant.getReplicationType(),
+ tenant.getReplicas()));
+ }
+ catch (final AlreadyExistsException e) {
+ throw ServiceException.conflict("Tenant {0} already exists!", tenant.getIdentifier());
+ }
final String createCommandSourceTable =
SchemaBuilder.createTable(tenant.getKeyspaceName(), "command_source")
diff --git a/service/src/main/java/io/mifos/provisioner/internal/service/TenantApplicationService.java b/service/src/main/java/io/mifos/provisioner/internal/service/TenantApplicationService.java
index 6ac79ff..149f062 100644
--- a/service/src/main/java/io/mifos/provisioner/internal/service/TenantApplicationService.java
+++ b/service/src/main/java/io/mifos/provisioner/internal/service/TenantApplicationService.java
@@ -19,7 +19,6 @@
import com.datastax.driver.mapping.Mapper;
import com.datastax.driver.mapping.Result;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
-import io.mifos.anubis.api.v1.domain.Signature;
import io.mifos.anubis.config.TenantSignatureRepository;
import io.mifos.core.cassandra.core.CassandraSessionProvider;
import io.mifos.core.lang.AutoTenantContext;
@@ -70,22 +69,39 @@
Assert.notNull(tenantApplicationEntity);
Assert.notNull(appNameToUriMap);
- final Optional<TenantEntity> tenantEntity = tenantCassandraRepository.get(tenantApplicationEntity.getTenantIdentifier());
- tenantEntity.ifPresent(x -> {
- checkApplications(tenantApplicationEntity.getApplications());
+ final TenantEntity tenantEntity = tenantCassandraRepository.get(tenantApplicationEntity.getTenantIdentifier())
+ .orElseThrow(() -> ServiceException.notFound("Tenant {0} not found.", tenantApplicationEntity.getTenantIdentifier()));
- saveTenantApplicationAssignment(tenantApplicationEntity);
+ checkApplicationsExist(tenantApplicationEntity.getApplications());
- final Set<ApplicationNameToUriPair> applicationNameToUriPairs =
- getApplicationNameToUriPairs(tenantApplicationEntity, appNameToUriMap);
+ saveTenantApplicationAssignment(tenantApplicationEntity);
- initializeIsis(x, applicationNameToUriPairs);
+ final Set<ApplicationNameToUriPair> applicationNameToUriPairs =
+ getApplicationNameToUriPairs(tenantApplicationEntity, appNameToUriMap);
- getLatestIdentityManagerSignatureSet(x).ifPresent(y -> initializeAnubis(x, y.getTimestamp(), y.getIdentityManagerSignature(), applicationNameToUriPairs));
+ getLatestIdentityManagerSignatureSet(tenantEntity)
+ .ifPresent(y -> initializeSecurity(tenantEntity, y, applicationNameToUriPairs));
+ }
+
+ private void initializeSecurity(final TenantEntity tenantEntity,
+ final ApplicationSignatureSet identityManagerSignatureSet,
+ final Set<ApplicationNameToUriPair> applicationNameToUriPairs) {
+ applicationNameToUriPairs.forEach(x -> {
+ final ApplicationSignatureSet applicationSignatureSet = anubisInitializer.initializeAnubis(
+ tenantEntity.getIdentifier(),
+ x.name,
+ x.uri,
+ identityManagerSignatureSet.getTimestamp(),
+ identityManagerSignatureSet.getIdentityManagerSignature());
+
+ identityServiceInitializer.postApplicationDetails(
+ tenantEntity.getIdentifier(),
+ tenantEntity.getIdentityManagerApplicationName(),
+ tenantEntity.getIdentityManagerApplicationUri(),
+ x.name,
+ x.uri,
+ applicationSignatureSet);
});
-
- tenantEntity.orElseThrow(
- () -> ServiceException.notFound("Tenant {0} not found.", tenantApplicationEntity.getTenantIdentifier()));
}
private void saveTenantApplicationAssignment(final @Nonnull TenantApplicationEntity tenantApplicationEntity) {
@@ -134,32 +150,6 @@
}
}
- private void initializeIsis(
- final @Nonnull TenantEntity tenantEntity,
- final @Nonnull Set<ApplicationNameToUriPair> applicationNameToUriPairs) {
- applicationNameToUriPairs.forEach(applicationNameUriPair ->
- identityServiceInitializer.postPermittableGroups(
- tenantEntity.getIdentifier(),
- tenantEntity.getIdentityManagerApplicationName(),
- tenantEntity.getIdentityManagerApplicationUri(),
- applicationNameUriPair.uri));
- }
-
- private void initializeAnubis(
- final @Nonnull TenantEntity tenantEntity,
- final @Nonnull String keyTimestamp,
- final @Nonnull Signature identityServiceTenantSignature,
- final @Nonnull Set<ApplicationNameToUriPair> applicationNameToUriPairs) {
- applicationNameToUriPairs.forEach(applicationNameUriPair ->
- anubisInitializer.initializeAnubis(
- tenantEntity.getIdentifier(),
- applicationNameUriPair.name,
- applicationNameUriPair.uri,
- keyTimestamp,
- identityServiceTenantSignature)
- );
- }
-
public TenantApplicationEntity find(final String tenantIdentifier) {
checkTenant(tenantIdentifier);
@@ -195,7 +185,7 @@
}
}
- private void checkApplications(final Set<String> applications) {
+ private void checkApplicationsExist(final Set<String> applications) {
final Mapper<ApplicationEntity> applicationEntityMapper =
this.cassandraSessionProvider.getAdminSessionMappingManager().mapper(ApplicationEntity.class);
diff --git a/service/src/main/java/io/mifos/provisioner/internal/service/applications/AnubisInitializer.java b/service/src/main/java/io/mifos/provisioner/internal/service/applications/AnubisInitializer.java
index c30876e..657923d 100644
--- a/service/src/main/java/io/mifos/provisioner/internal/service/applications/AnubisInitializer.java
+++ b/service/src/main/java/io/mifos/provisioner/internal/service/applications/AnubisInitializer.java
@@ -16,12 +16,12 @@
package io.mifos.provisioner.internal.service.applications;
import io.mifos.anubis.api.v1.client.Anubis;
+import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.api.v1.domain.Signature;
import io.mifos.provisioner.config.ProvisionerConstants;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Nonnull;
@@ -42,20 +42,20 @@
this.logger = logger;
}
- @Async
- public void initializeAnubis(final @Nonnull String tenantIdentifier,
- final @Nonnull String applicationName,
- final @Nonnull String uri,
- final @Nonnull String keyTimestamp,
- final @Nonnull Signature signature) {
+ public ApplicationSignatureSet initializeAnubis(final @Nonnull String tenantIdentifier,
+ final @Nonnull String applicationName,
+ final @Nonnull String uri,
+ final @Nonnull String keyTimestamp,
+ final @Nonnull Signature signature) {
try (final AutoCloseable ignored
= this.applicationCallContextProvider.getApplicationCallContext(tenantIdentifier, applicationName))
{
final Anubis anubis = this.applicationCallContextProvider.getApplication(Anubis.class, uri);
- anubis.createSignatureSet(keyTimestamp, signature);
anubis.initializeResources();
- logger.info("Anubis initialization for io.mifos.provisioner.tenant '{}' and application '{}' succeeded with signature '{}'.",
- tenantIdentifier, applicationName, signature);
+ final ApplicationSignatureSet applicationSignatureSet = anubis.createSignatureSet(keyTimestamp, signature);
+ logger.info("Anubis initialization for io.mifos.provisioner.tenant '{}' and application '{}' succeeded with signature set '{}'.",
+ tenantIdentifier, applicationName, applicationSignatureSet);
+ return applicationSignatureSet;
} catch (final Exception e) {
throw new IllegalStateException(e);
diff --git a/service/src/main/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializer.java b/service/src/main/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializer.java
index 7df8945..a2b24db 100644
--- a/service/src/main/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializer.java
+++ b/service/src/main/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializer.java
@@ -17,14 +17,18 @@
import io.mifos.anubis.api.v1.client.Anubis;
+import io.mifos.anubis.api.v1.domain.AllowedOperation;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.api.v1.domain.PermittableEndpoint;
import io.mifos.core.api.util.InvalidTokenException;
import io.mifos.core.lang.ServiceException;
-import io.mifos.identity.api.v1.client.IdentityManager;
-import io.mifos.identity.api.v1.client.PermittableGroupAlreadyExistsException;
-import io.mifos.identity.api.v1.client.TenantAlreadyInitializedException;
+import io.mifos.core.lang.TenantContextHolder;
+import io.mifos.identity.api.v1.client.*;
+import io.mifos.identity.api.v1.domain.CallEndpointSet;
+import io.mifos.identity.api.v1.domain.Permission;
import io.mifos.identity.api.v1.domain.PermittableGroup;
+import io.mifos.permittedfeignclient.api.v1.client.ApplicationPermissionRequirements;
+import io.mifos.permittedfeignclient.api.v1.domain.ApplicationPermission;
import io.mifos.provisioner.config.ProvisionerConstants;
import io.mifos.tool.crypto.HashGenerator;
import org.apache.commons.lang.RandomStringUtils;
@@ -38,6 +42,7 @@
import javax.annotation.Nonnull;
import java.util.*;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Myrle Krantz
@@ -123,15 +128,20 @@
}
}
- public void postPermittableGroups(
+ public void postApplicationDetails(
final @Nonnull String tenantIdentifier,
final @Nonnull String identityManagerApplicationName,
final @Nonnull String identityManagerApplicationUri,
- final @Nonnull String applicationUri)
+ final @Nonnull String applicationName,
+ final @Nonnull String applicationUri,
+ final @Nonnull ApplicationSignatureSet applicationSignatureSet)
{
final List<PermittableEndpoint> permittables;
+ final List<ApplicationPermission> applicationPermissionRequirements;
try (final AutoCloseable ignored = applicationCallContextProvider.getApplicationCallGuestContext(tenantIdentifier)) {
permittables = getPermittables(applicationUri);
+ applicationPermissionRequirements = getApplicationPermissionRequirements(applicationName, applicationUri);
+
} catch (final Exception e) {
throw new IllegalStateException(e);
}
@@ -140,10 +150,16 @@
= applicationCallContextProvider.getApplicationCallContext(tenantIdentifier, identityManagerApplicationName))
{
final IdentityManager identityService = applicationCallContextProvider.getApplication(IdentityManager.class, identityManagerApplicationUri);
+ identityService.setApplicationSignature(applicationName, applicationSignatureSet.getTimestamp(), applicationSignatureSet.getApplicationSignature());
+ //TODO: I need to know when this is done. ActiveMQ. sigh.
- final List<PermittableGroup> permittableGroups = getPermittableGroups(permittables);
-
+ final Stream<PermittableGroup> permittableGroups = getPermittableGroups(permittables);
permittableGroups.forEach(x -> createOrFindPermittableGroup(identityService, x));
+
+ applicationPermissionRequirements.forEach(x -> createOrFindApplicationPermission(identityService, applicationName, x));
+
+ final Stream<CallEndpointSet> callEndpoints = getCallEndpointSets(applicationPermissionRequirements);
+ callEndpoints.forEach(x -> createOrFindApplicationCallEndpointSet(identityService, applicationName, x));
} catch (final Exception e) {
throw new IllegalStateException(e);
}
@@ -162,15 +178,44 @@
}
}
- static List<PermittableGroup> getPermittableGroups(final @Nonnull List<PermittableEndpoint> permittables)
+ private List<ApplicationPermission> getApplicationPermissionRequirements(final @Nonnull String applicationName,
+ final @Nonnull String applicationUri)
+ {
+ try {
+ final ApplicationPermissionRequirements anput
+ = this.applicationCallContextProvider.getApplication(ApplicationPermissionRequirements.class, applicationUri);
+ return anput.getRequiredPermissions();
+ }
+ catch (final RuntimeException unexpected)
+ {
+ logger.info("Get Required Permissions from application '{}' failed.", applicationName);
+ return Collections.emptyList();
+ }
+ }
+
+ static Stream<PermittableGroup> getPermittableGroups(final @Nonnull List<PermittableEndpoint> permittables)
{
final Map<String, Set<PermittableEndpoint>> groupedPermittables = new HashMap<>();
permittables.forEach(x -> groupedPermittables.computeIfAbsent(x.getGroupId(), y -> new LinkedHashSet<>()).add(x));
return groupedPermittables.entrySet().stream()
- .map(entry -> new PermittableGroup(entry.getKey(), entry.getValue().stream().collect(Collectors.toList())))
- .collect(Collectors.toList());
+ .map(entry -> new PermittableGroup(entry.getKey(), entry.getValue().stream().collect(Collectors.toList())));
+ }
+
+ private static Stream<CallEndpointSet> getCallEndpointSets(
+ final @Nonnull List<ApplicationPermission> applicationPermissionRequirements) {
+
+ final Map<String, List<String>> permissionsGroupedByEndpointSet = applicationPermissionRequirements.stream()
+ .collect(Collectors.groupingBy(ApplicationPermission::getEndpointSetIdentifier,
+ Collectors.mapping(x -> x.getPermission().getPermittableEndpointGroupIdentifier(), Collectors.toList())));
+
+ return permissionsGroupedByEndpointSet.entrySet().stream().map(entry -> {
+ final CallEndpointSet ret = new CallEndpointSet();
+ ret.setIdentifier(entry.getKey());
+ ret.setPermittableEndpointGroupIdentifiers(entry.getValue());
+ return ret;
+ });
}
void createOrFindPermittableGroup(
@@ -178,14 +223,14 @@
final @Nonnull PermittableGroup permittableGroup) {
try {
identityService.createPermittableGroup(permittableGroup);
- logger.info("Group '{}' successfully created in identity service.", permittableGroup.getIdentifier());
+ logger.info("Group '{}' successfully created in identity service for tenant {}.", permittableGroup.getIdentifier(), TenantContextHolder.checkedGetIdentifier());
}
catch (final PermittableGroupAlreadyExistsException groupAlreadyExistsException)
{
//if the group already exists, read out and compare. If the group is the same, there is nothing left to do.
final PermittableGroup existingGroup = identityService.getPermittableGroup(permittableGroup.getIdentifier());
if (!existingGroup.getIdentifier().equals(permittableGroup.getIdentifier())) {
- logger.error("Group '{}' already exists, but has a different name{} (strange).", permittableGroup.getIdentifier(), existingGroup.getIdentifier());
+ logger.error("Group '{}' already exists, but has a different name {} (strange).", permittableGroup.getIdentifier(), existingGroup.getIdentifier());
}
//Compare as sets because I'm not going to get into a hissy fit over order.
@@ -200,4 +245,63 @@
logger.error("Creating group '{}' failed.", permittableGroup.getIdentifier(), unexpected);
}
}
+
+ private void createOrFindApplicationPermission(
+ final @Nonnull IdentityManager identityService,
+ final @Nonnull String applicationName,
+ final @Nonnull ApplicationPermission applicationPermission) {
+ try {
+ identityService.createApplicationPermission(applicationName, applicationPermission.getPermission());
+ }
+ catch (final ApplicationPermissionAlreadyExistsException alreadyExistsException)
+ {
+ //if exists, read out and compare. If is the same, there is nothing left to do.
+ final Permission existing = identityService.getApplicationPermission(
+ applicationName, applicationPermission.getPermission().getPermittableEndpointGroupIdentifier());
+ if (!existing.getPermittableEndpointGroupIdentifier().equals(applicationPermission.getPermission().getPermittableEndpointGroupIdentifier())) {
+ logger.error("Application permission '{}' already exists, but has a different name {} (strange).",
+ applicationPermission.getPermission().getPermittableEndpointGroupIdentifier(), existing.getPermittableEndpointGroupIdentifier());
+ }
+
+ final Set<AllowedOperation> existingAllowedOperations = existing.getAllowedOperations();
+ final Set<AllowedOperation> newAllowedOperations = applicationPermission.getPermission().getAllowedOperations();
+ if (!existingAllowedOperations.equals(newAllowedOperations)) {
+ logger.error("Permission '{}' already exists, but has different contents.", applicationPermission.getPermission().getPermittableEndpointGroupIdentifier());
+ }
+ }
+ catch (final RuntimeException unexpected)
+ {
+ logger.error("Creating permission '{}' failed.", applicationPermission.getPermission().getPermittableEndpointGroupIdentifier(), unexpected);
+ }
+ }
+
+ private void createOrFindApplicationCallEndpointSet(
+ final @Nonnull IdentityManager identityService,
+ final @Nonnull String applicationName,
+ final @Nonnull CallEndpointSet callEndpointSet) {
+ try {
+ identityService.createApplicationCallEndpointSet(applicationName, callEndpointSet);
+ }
+ catch (final CallEndpointSetAlreadyExistsException alreadyExistsException)
+ {
+ //if already exists, read out and compare. If is the same, there is nothing left to do.
+ final CallEndpointSet existing = identityService.getApplicationCallEndpointSet(
+ applicationName, callEndpointSet.getIdentifier());
+ if (!existing.getIdentifier().equals(callEndpointSet.getIdentifier())) {
+ logger.error("Application call endpoint set '{}' already exists, but has a different name {} (strange).",
+ callEndpointSet.getIdentifier(), existing.getIdentifier());
+ }
+
+ //Compare as sets because I'm not going to get into a hissy fit over order.
+ final Set<String> existingPermittableEndpoints = new HashSet<>(existing.getPermittableEndpointGroupIdentifiers());
+ final Set<String> newPermittableEndpoints = new HashSet<>(callEndpointSet.getPermittableEndpointGroupIdentifiers());
+ if (!existingPermittableEndpoints.equals(newPermittableEndpoints)) {
+ logger.error("Application call endpoint set '{}' already exists, but has different contents.", callEndpointSet.getIdentifier());
+ }
+ }
+ catch (final RuntimeException unexpected)
+ {
+ logger.error("Creating application call endpoint set '{}' failed.", callEndpointSet.getIdentifier(), unexpected);
+ }
+ }
}
diff --git a/service/src/test/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializerTest.java b/service/src/test/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializerTest.java
index c32884c..ebe6e18 100644
--- a/service/src/test/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializerTest.java
+++ b/service/src/test/java/io/mifos/provisioner/internal/service/applications/IdentityServiceInitializerTest.java
@@ -28,6 +28,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.isA;
@@ -76,13 +77,13 @@
public void getPermittableGroups() throws Exception {
final List<PermittableEndpoint> permittableEndpoints = Arrays.asList(abcPost1, abcGet1, defGet1, abcPost2, abcGet2, defGet2, defGet3);
- final List<PermittableGroup> ret = IdentityServiceInitializer.getPermittableGroups(permittableEndpoints);
+ final List<PermittableGroup> ret = IdentityServiceInitializer.getPermittableGroups(permittableEndpoints).collect(Collectors.toList());
Assert.assertEquals(ret, Arrays.asList(group1, group2, group3));
}
@Test
public void getPermittableGroupsOnEmptyList() throws Exception {
- final List<PermittableGroup> ret = IdentityServiceInitializer.getPermittableGroups(Collections.emptyList());
+ final List<PermittableGroup> ret = IdentityServiceInitializer.getPermittableGroups(Collections.emptyList()).collect(Collectors.toList());
Assert.assertEquals(ret, Collections.emptyList());
}
diff --git a/shared.gradle b/shared.gradle
index 8a2c8dc..77669da 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -4,6 +4,7 @@
ext.versions = [
mifosidentityservice : '0.1.0-BUILD-SNAPSHOT',
frameworkanubis : '0.1.0-BUILD-SNAPSHOT',
+ frameworkanput : '0.1.0-BUILD-SNAPSHOT',
frameworkapi : '0.1.0-BUILD-SNAPSHOT',
frameworklang : '0.1.0-BUILD-SNAPSHOT',
frameworkasync : '0.1.0-BUILD-SNAPSHOT',