Skip to content
Permalink
Browse files
Adjusting provisioner to changes made in anubis and identity in prepa…
…ration for application key registration and key rotation.
  • Loading branch information
mifosio-04-04-2018 committed Apr 12, 2017
1 parent 14329d4 commit 2c578cc593c099ad9f80b20f1c2b5f07632293f9
Showing 7 changed files with 99 additions and 64 deletions.
@@ -16,6 +16,7 @@
package io.mifos.provisioner.tenant;

import io.mifos.anubis.api.v1.client.Anubis;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.api.v1.domain.PermittableEndpoint;
import io.mifos.anubis.api.v1.domain.Signature;
import io.mifos.anubis.provider.SystemRsaKeyProvider;
@@ -25,6 +26,7 @@
import io.mifos.core.api.util.ApiConstants;
import io.mifos.core.api.util.ApiFactory;
import io.mifos.core.lang.AutoTenantContext;
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.PermittableGroup;
@@ -107,7 +109,7 @@ public TokenProvider tokenProviderSpy(final @Qualifier("tokenProvider") TokenPro
private static ProvisionerMariaDBInitializer mariaDBInitializer = new ProvisionerMariaDBInitializer();
private static ProvisionerCassandraInitializer cassandraInitializer = new ProvisionerCassandraInitializer();
private static SystemSecurityEnvironment systemSecurityEnvironment
= new SystemSecurityEnvironment(testEnvironment.getSystemPublicKey(), testEnvironment.getSystemPrivateKey());
= new SystemSecurityEnvironment(testEnvironment.getSystemKeyTimestamp(), testEnvironment.getSystemPublicKey(), testEnvironment.getSystemPrivateKey());

@ClassRule
public static TestRule orderClassRules = RuleChain
@@ -168,27 +170,34 @@ public TokenSerializationResult answer(final InvocationOnMock invocation) throws
}
}

private class VerifyIsisInitializeContext implements Answer<Signature> {
private class VerifyIsisInitializeContext implements Answer<ApplicationSignatureSet> {

private final String keyTimestamp;
private final BigInteger modulus;
private final BigInteger exponent;

private boolean validSecurityContext = false;

VerifyIsisInitializeContext(final BigInteger modulus, final BigInteger exponent) {
VerifyIsisInitializeContext(final String keyTimestamp, final BigInteger modulus, final BigInteger exponent) {
this.keyTimestamp = keyTimestamp;
this.modulus = modulus;
this.exponent = exponent;
}

@Override
public Signature answer(final InvocationOnMock invocation) throws Throwable {
public ApplicationSignatureSet answer(final InvocationOnMock invocation) throws Throwable {
validSecurityContext = systemSecurityEnvironment.isValidSystemSecurityContext("identity", "1", Fixture.TENANT_IDENTIFIER);

final Signature fakeSignature = new Signature();
fakeSignature.setPublicKeyMod(modulus);
fakeSignature.setPublicKeyExp(exponent);

return fakeSignature;
final ApplicationSignatureSet ret = new ApplicationSignatureSet();
ret.setTimestamp(keyTimestamp);
ret.setApplicationSignature(fakeSignature);
ret.setIdentityManagerSignature(fakeSignature);

return ret;
}

boolean isValidSecurityContext() {
@@ -216,6 +225,32 @@ boolean isValidSecurityContext() {
}
}

private class VerifyCreateSignatureSetContext implements Answer<ApplicationSignatureSet> {

private boolean validSecurityContext = false;
final private String target;

private VerifyCreateSignatureSetContext(final String target) {
this.target = target;
}

@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();
return new ApplicationSignatureSet(
timestamp,
new Signature(keys.getPublicKeyMod(), keys.getPublicKeyExp()),
identityManagerSignature);
}

boolean isValidSecurityContext() {
return validSecurityContext;
}
}


private class VerifyAnubisPermittablesContext implements Answer<List<PermittableEndpoint>> {

@@ -265,6 +300,7 @@ public void testTenantApplicationAssignment() throws InterruptedException {
final VerifyIsisInitializeContext verifyInitializeContextAndReturnSignature;
try (final AutoTenantContext ignored = new AutoTenantContext(Fixture.TENANT_IDENTIFIER)) {
verifyInitializeContextAndReturnSignature = new VerifyIsisInitializeContext(
systemSecurityEnvironment.tenantKeyTimestamp(),
systemSecurityEnvironment.tenantPublicKey().getModulus(),
systemSecurityEnvironment.tenantPublicKey().getPublicExponent());
}
@@ -282,7 +318,7 @@ public void testTenantApplicationAssignment() throws InterruptedException {
Assert.assertNotNull(identityServiceAdminInitialization.getAdminPassword());
}

verify(applicationCallContextProviderSpy).getApplicationCallContext(Fixture.TENANT_IDENTIFIER, "identity-v1");
verify(applicationCallContextProviderSpy, atMost(2)).getApplicationCallContext(Fixture.TENANT_IDENTIFIER, "identity-v1");


//Create horus application.
@@ -309,12 +345,15 @@ public void testTenantApplicationAssignment() throws InterruptedException {
final PermittableEndpoint mPermittableEndpoint = new PermittableEndpoint("/m/n", "GET", "m");

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));
}
doAnswer(verifyAnubisInitializeContext).when(anubisMock).initialize(anyObject(), anyObject());
doAnswer(verifyAnubisInitializeContext).when(anubisMock).initializeResources();
doAnswer(verifyCreateSignatureSetContext).when(anubisMock).createSignatureSet(anyString(), anyObject());
doAnswer(verifyAnubisPermittablesContext).when(anubisMock).getPermittableEndpoints();

{
@@ -330,6 +369,7 @@ public void testTenantApplicationAssignment() throws InterruptedException {
verify(identityServiceMock).createPermittableGroup(new PermittableGroup("m", Collections.singletonList(mPermittableEndpoint)));

Assert.assertTrue(verifyAnubisInitializeContext.isValidSecurityContext());
Assert.assertTrue(verifyCreateSignatureSetContext.isValidSecurityContext());
Assert.assertTrue(verifyAnubisPermittablesContext.isValidSecurityContext());
}
}
@@ -16,14 +16,10 @@
package io.mifos.provisioner.config;

import io.mifos.anubis.config.EnableAnubis;
import io.mifos.anubis.config.TenantSignatureProvider;
import io.mifos.anubis.repository.TenantAuthorizationDataRepository;
import io.mifos.anubis.token.SystemAccessTokenSerializer;
import io.mifos.core.api.util.ApiFactory;
import io.mifos.core.async.config.EnableAsync;
import io.mifos.core.cassandra.config.EnableCassandra;
import io.mifos.core.cassandra.core.CassandraSessionProvider;
import io.mifos.core.lang.ApplicationName;
import io.mifos.core.lang.config.EnableApplicationName;
import io.mifos.core.lang.config.EnableServiceException;
import io.mifos.core.mariadb.config.EnableMariaDB;
@@ -50,7 +46,7 @@
})
@EnableCrypto
@EnableAsync
@EnableAnubis(storeTenantKeysAtInitialization = false)
@EnableAnubis(provideSignatureRestController = false)
@EnableMariaDB
@EnableCassandra
@EnableServiceException
@@ -70,6 +66,7 @@ public Logger logger() {
public TokenProvider tokenProvider(final Environment environment,
@SuppressWarnings("SpringJavaAutowiringInspection") final SystemAccessTokenSerializer tokenSerializer) {
return new TokenProvider(
environment.getProperty("system.publicKey.timestamp"),
new BigInteger(environment.getProperty("system.privateKey.modulus")),
new BigInteger(environment.getProperty("system.privateKey.exponent")), tokenSerializer);
}
@@ -78,20 +75,4 @@ public TokenProvider tokenProvider(final Environment environment,
public ApiFactory apiFactory(@Qualifier(ProvisionerConstants.LOGGER_NAME) final Logger logger) {
return new ApiFactory(logger);
}

@Bean
public TenantSignatureProvider tenantSignatureProvider()
{
return tenant -> {
throw new IllegalArgumentException("no io.mifos.provisioner.tenant signatures here.");
};
}

@Bean
public TenantAuthorizationDataRepository tenantAuthorizationDataRepository(
final ApplicationName applicationName,
final CassandraSessionProvider cassandraSessionProvider)
{
return new TenantAuthorizationDataRepository(applicationName, cassandraSessionProvider);
}
}
@@ -18,18 +18,16 @@
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.mapping.Mapper;
import com.datastax.driver.mapping.Result;

import io.mifos.anubis.api.v1.TokenConstants;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.api.v1.domain.Signature;
import io.mifos.anubis.repository.TenantAuthorizationDataRepository;
import io.mifos.anubis.config.TenantSignatureRepository;
import io.mifos.core.cassandra.core.CassandraSessionProvider;
import io.mifos.core.lang.AutoTenantContext;
import io.mifos.core.lang.ServiceException;
import io.mifos.provisioner.internal.repository.ApplicationEntity;
import io.mifos.provisioner.internal.repository.TenantCassandraRepository;
import io.mifos.provisioner.internal.repository.TenantApplicationEntity;
import io.mifos.provisioner.internal.repository.TenantCassandraRepository;
import io.mifos.provisioner.internal.repository.TenantEntity;

import io.mifos.provisioner.internal.service.applications.AnubisInitializer;
import io.mifos.provisioner.internal.service.applications.IdentityServiceInitializer;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,7 +36,10 @@
import org.springframework.util.Assert;

import javax.annotation.Nonnull;
import java.util.*;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@@ -47,20 +48,20 @@ public class TenantApplicationService {
private final CassandraSessionProvider cassandraSessionProvider;
private final AnubisInitializer anubisInitializer;
private final IdentityServiceInitializer identityServiceInitializer;
private final TenantAuthorizationDataRepository tenantAuthorizationDataRepository;
private final TenantSignatureRepository tenantSignatureRepository;
private final TenantCassandraRepository tenantCassandraRepository;

@Autowired
public TenantApplicationService(final CassandraSessionProvider cassandraSessionProvider,
final AnubisInitializer anubisInitializer,
final IdentityServiceInitializer identityServiceInitializer,
final TenantAuthorizationDataRepository tenantAuthorizationDataRepository,
@SuppressWarnings("SpringJavaAutowiringInspection") final TenantSignatureRepository tenantSignatureRepository,
final TenantCassandraRepository tenantCassandraRepository) {
super();
this.cassandraSessionProvider = cassandraSessionProvider;
this.anubisInitializer = anubisInitializer;
this.identityServiceInitializer = identityServiceInitializer;
this.tenantAuthorizationDataRepository = tenantAuthorizationDataRepository;
this.tenantSignatureRepository = tenantSignatureRepository;
this.tenantCassandraRepository = tenantCassandraRepository;
}

@@ -80,7 +81,7 @@ public void assign(final @Nonnull TenantApplicationEntity tenantApplicationEntit

initializeIsis(x, applicationNameToUriPairs);

getIsisSignature(x).ifPresent(y -> initializeAnubis(x, y, applicationNameToUriPairs));
getLatestIdentityManagerSignatureSet(x).ifPresent(y -> initializeAnubis(x, y.getTimestamp(), y.getIdentityManagerSignature(), applicationNameToUriPairs));
});

tenantEntity.orElseThrow(
@@ -127,9 +128,9 @@ public int hashCode() {
}
}

private Optional<Signature> getIsisSignature(final @Nonnull TenantEntity tenantEntity) {
private Optional<ApplicationSignatureSet> getLatestIdentityManagerSignatureSet(final @Nonnull TenantEntity tenantEntity) {
try (final AutoTenantContext ignored = new AutoTenantContext(tenantEntity.getIdentifier())) {
return tenantAuthorizationDataRepository.getSignature(TokenConstants.VERSION);
return tenantSignatureRepository.getLatestSignatureSet();
}
}

@@ -146,13 +147,15 @@ private void initializeIsis(

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)
);
}
@@ -15,20 +15,20 @@
*/
package io.mifos.provisioner.internal.service;

import io.mifos.anubis.api.v1.domain.Signature;
import io.mifos.anubis.api.v1.domain.ApplicationSignatureSet;
import io.mifos.anubis.repository.TenantAuthorizationDataRepository;
import io.mifos.core.lang.AutoTenantContext;
import io.mifos.core.lang.ServiceException;
import io.mifos.provisioner.internal.repository.TenantCassandraRepository;
import io.mifos.provisioner.internal.util.DataSourceUtils;
import io.mifos.provisioner.internal.util.DataStoreOption;
import io.mifos.provisioner.api.v1.domain.CassandraConnectionInfo;
import io.mifos.provisioner.api.v1.domain.DatabaseConnectionInfo;
import io.mifos.provisioner.api.v1.domain.Tenant;
import io.mifos.provisioner.config.ProvisionerConstants;
import io.mifos.provisioner.internal.repository.TenantCassandraRepository;
import io.mifos.provisioner.internal.repository.TenantDAO;
import io.mifos.provisioner.internal.repository.TenantEntity;
import io.mifos.provisioner.internal.service.applications.IdentityServiceInitializer;
import io.mifos.provisioner.internal.util.DataSourceUtils;
import io.mifos.provisioner.internal.util.DataStoreOption;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -60,7 +60,7 @@ public class TenantService {
public TenantService(@Qualifier(ProvisionerConstants.LOGGER_NAME) final Logger logger,
final Environment environment,
final TenantApplicationService tenantApplicationService,
final TenantAuthorizationDataRepository tenantAuthorizationDataRepository,
@SuppressWarnings("SpringJavaAutowiringInspection") final TenantAuthorizationDataRepository tenantAuthorizationDataRepository,
final TenantCassandraRepository tenantCassandraRepository,
final IdentityServiceInitializer identityServiceInitializer) {
super();
@@ -110,10 +110,10 @@ public Optional<String> assignIdentityManager(
});

IdentityServiceInitializer.IdentityServiceInitializationResult identityServiceInitializationResult = identityServiceInitializer.initializeIsis(tenantIdentifier, identityManagerAppName, identityManagerUri);
final Signature identityServiceTenantSignature = identityServiceInitializationResult.getSignature();
final ApplicationSignatureSet identityServiceTenantSignatureSet = identityServiceInitializationResult.getSignatureSet();

try (final AutoTenantContext ignored = new AutoTenantContext(tenantIdentifier)) {
tenantAuthorizationDataRepository.provisionTenant(identityServiceTenantSignature.getPublicKeyMod(), identityServiceTenantSignature.getPublicKeyExp());
tenantAuthorizationDataRepository.createSignatureSet(identityServiceTenantSignatureSet.getTimestamp(), identityServiceTenantSignatureSet.getIdentityManagerSignature());
}

return identityServiceInitializationResult.getAdminPassword();
@@ -46,12 +46,14 @@ public AnubisInitializer(
public void 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.initialize(signature.getPublicKeyMod(), signature.getPublicKeyExp());
anubis.createSignatureSet(keyTimestamp, signature);
anubis.initializeResources();
logger.info("Anubis initialization for io.mifos.provisioner.tenant '{}' and application '{}' succeeded with signature '{}'.",
tenantIdentifier, applicationName, signature);

0 comments on commit 2c578cc

Please sign in to comment.