use of io.cdap.cdap.api.security.store.SecureStoreMetadata in project cdap by caskdata.
the class RemoteExecutionJobMain method initialize.
@VisibleForTesting
RemoteExecutionRuntimeJobEnvironment initialize(CConfiguration cConf) throws Exception {
zkServer = InMemoryZKServer.builder().build();
zkServer.startAndWait();
InetSocketAddress zkAddr = ResolvingDiscoverable.resolve(zkServer.getLocalAddress());
String zkConnectStr = String.format("%s:%d", zkAddr.getHostString(), zkAddr.getPort());
LOG.debug("In memory ZK started at {}", zkConnectStr);
cConf.set(Constants.Zookeeper.QUORUM, zkConnectStr);
Injector injector = Guice.createInjector(new ConfigModule(cConf), RemoteAuthenticatorModules.getDefaultModule(), new DFSLocationModule(), new InMemoryDiscoveryModule(), new TwillModule(), new AuthenticationContextModules().getProgramContainerModule(cConf), new AbstractModule() {
@Override
protected void configure() {
// don't need to perform any impersonation from within user programs
bind(UGIProvider.class).to(CurrentUGIProvider.class).in(Scopes.SINGLETON);
// Binds a no-op SecureStore for the TwillModule to setup TokenSecureStoreRenewer.
bind(SecureStore.class).toInstance(new SecureStore() {
@Override
public List<SecureStoreMetadata> list(String namespace) {
return Collections.emptyList();
}
@Override
public SecureStoreData get(String namespace, String name) throws Exception {
throw new NotFoundException("Secure key " + name + " not found in namespace " + namespace);
}
});
}
});
Map<String, String> properties = new HashMap<>();
properties.put(Constants.Zookeeper.QUORUM, zkConnectStr);
locationFactory = injector.getInstance(LocationFactory.class);
locationFactory.create("/").mkdirs();
twillRunnerService = injector.getInstance(TwillRunnerService.class);
twillRunnerService.start();
if (UserGroupInformation.isSecurityEnabled()) {
TokenSecureStoreRenewer secureStoreRenewer = injector.getInstance(TokenSecureStoreRenewer.class);
secureStoreUpdateCancellable = twillRunnerService.setSecureStoreRenewer(secureStoreRenewer, 30000L, secureStoreRenewer.getUpdateInterval(), 30000L, TimeUnit.MILLISECONDS);
}
return new RemoteExecutionRuntimeJobEnvironment(locationFactory, twillRunnerService, properties);
}
use of io.cdap.cdap.api.security.store.SecureStoreMetadata in project cdap by caskdata.
the class DefaultSecureStoreServiceTest method testSecureStoreAccess.
@Test
public void testSecureStoreAccess() throws Exception {
final SecureKeyId secureKeyId1 = NamespaceId.DEFAULT.secureKey(KEY1);
SecurityRequestContext.setUserId(ALICE.getName());
try {
secureStoreManager.put(NamespaceId.DEFAULT.getNamespace(), KEY1, VALUE1, DESCRIPTION1, Collections.<String, String>emptyMap());
Assert.fail("Alice should not be able to store a key since she does not have WRITE privileges on the namespace");
} catch (UnauthorizedException expected) {
// expected
}
// Grant ALICE admin access to the secure key
grantAndAssertSuccess(NamespaceId.DEFAULT, ALICE, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(Authorizable.fromEntityId(NamespaceId.DEFAULT, EntityType.SECUREKEY), ALICE, EnumSet.of(StandardPermission.LIST));
grantAndAssertSuccess(secureKeyId1, ALICE, EnumSet.allOf(StandardPermission.class));
// Write should succeed
secureStoreManager.put(NamespaceId.DEFAULT.getNamespace(), KEY1, VALUE1, DESCRIPTION1, Collections.<String, String>emptyMap());
// Listing should return the value just written
List<SecureStoreMetadata> metadatas = secureStore.list(NamespaceId.DEFAULT.getNamespace());
Assert.assertEquals(1, metadatas.size());
Assert.assertEquals(KEY1, metadatas.get(0).getName());
Assert.assertEquals(DESCRIPTION1, metadatas.get(0).getDescription());
revokeAndAssertSuccess(secureKeyId1, ALICE, EnumSet.allOf(StandardPermission.class));
// Should not be able to list the keys since ALICE does not have privilege on the secure key
try {
secureStore.list(NamespaceId.DEFAULT.getNamespace());
} catch (UnauthorizedException e) {
// expected
}
// Give BOB read access and verify that he can read the stored data
SecurityRequestContext.setUserId(BOB.getName());
grantAndAssertSuccess(NamespaceId.DEFAULT, BOB, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(secureKeyId1, BOB, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(Authorizable.fromEntityId(NamespaceId.DEFAULT, EntityType.SECUREKEY), BOB, EnumSet.of(StandardPermission.LIST));
Assert.assertEquals(VALUE1, new String(secureStore.get(NamespaceId.DEFAULT.getNamespace(), KEY1).get(), Charsets.UTF_8));
metadatas = secureStore.list(NamespaceId.DEFAULT.getNamespace());
Assert.assertEquals(1, metadatas.size());
// BOB should not be able to delete the key
try {
secureStoreManager.delete(NamespaceId.DEFAULT.getNamespace(), KEY1);
Assert.fail("Bob should not be able to delete a key since he does not have ADMIN privileges on the key");
} catch (UnauthorizedException expected) {
// expected
}
// Grant Bob ADMIN access and he should be able to delete the key
grantAndAssertSuccess(secureKeyId1, BOB, ImmutableSet.of(StandardPermission.DELETE));
secureStoreManager.delete(NamespaceId.DEFAULT.getNamespace(), KEY1);
Assert.assertEquals(0, secureStore.list(NamespaceId.DEFAULT.getNamespace()).size());
Predicate<GrantedPermission> secureKeyIdFilter = new Predicate<GrantedPermission>() {
@Override
public boolean apply(GrantedPermission input) {
return input.getAuthorizable().equals(Authorizable.fromEntityId(secureKeyId1));
}
};
}
use of io.cdap.cdap.api.security.store.SecureStoreMetadata in project cdap by caskdata.
the class KMSSecureStoreService method list.
/**
* List of all the entries in the secure store. No filtering or authentication is done here.
* This method makes two calls to the KMS provider, one to get the list of keys and then another call to
* get the metadata for all the keys in the requested namespace.
* @return A list of {@link SecureStoreMetadata} objects representing the data stored in the store.
* @param namespace The namespace this key belongs to.
* @throws NamespaceNotFoundException If the specified namespace does not exist.
* @throws ConcurrentModificationException If a key was deleted between the time we got the list of keys and when
* we got their metadata.
* @throws IOException If there was a problem getting the list from the underlying key provider.
*/
// Unfortunately KeyProvider does not specify the underlying cause except in the message, so we can not throw a
// more specific exception.
@Override
public List<SecureStoreMetadata> list(String namespace) throws Exception {
checkNamespaceExists(namespace);
String prefix = namespace + NAME_SEPARATOR;
List<String> keysInNamespace = new ArrayList<>();
KeyProvider.Metadata[] metadatas;
try {
for (String key : provider.getKeys()) {
if (key.startsWith(prefix)) {
keysInNamespace.add(key);
}
}
metadatas = provider.getKeysMetadata(keysInNamespace.toArray(new String[keysInNamespace.size()]));
} catch (IOException e) {
throw new IOException("Failed to get the list of elements from the secure store.", e);
}
// If a key was deleted between the time we get the list of keys and their metadatas then throw an exception
if (metadatas.length != keysInNamespace.size()) {
throw new ConcurrentModificationException("A key was deleted while listing was in progress. Please try again.");
}
List<SecureStoreMetadata> secureStoreMetadatas = new ArrayList<>(metadatas.length);
for (int i = 0; i < metadatas.length; i++) {
KeyProvider.Metadata metadata = metadatas[i];
secureStoreMetadatas.add(new SecureStoreMetadata(keysInNamespace.get(i).substring(prefix.length()), metadata.getDescription(), metadata.getCreated().getTime(), metadata.getAttributes()));
}
return secureStoreMetadatas;
}
use of io.cdap.cdap.api.security.store.SecureStoreMetadata in project cdap by caskdata.
the class FileSecureStoreService method serialize.
private byte[] serialize(SecureStoreData data) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (DataOutputStream dos = new DataOutputStream(bos)) {
// Writing the metadata
SecureStoreMetadata meta = data.getMetadata();
dos.writeUTF(meta.getName());
dos.writeBoolean(meta.getDescription() != null);
if (meta.getDescription() != null) {
dos.writeUTF(meta.getDescription());
}
dos.writeLong(meta.getLastModifiedTime());
Map<String, String> properties = meta.getProperties();
dos.writeInt(properties.size());
for (Map.Entry<String, String> entry : properties.entrySet()) {
dos.writeUTF(entry.getKey());
dos.writeUTF(entry.getValue());
}
byte[] secret = data.get();
dos.writeInt(secret.length);
dos.write(secret);
}
return bos.toByteArray();
}
use of io.cdap.cdap.api.security.store.SecureStoreMetadata in project cdap by caskdata.
the class FileSecureStoreService method list.
/**
* List of all the entries in the secure store belonging to the specified namespace. No filtering or authentication
* is done here.
* @return A list of {@link SecureStoreMetadata} objects representing the data stored in the store.
* @param namespace The namespace this key belongs to.
* @throws NamespaceNotFoundException If the specified namespace does not exist.
* @throws IOException If there was a problem reading from the keystore.
*/
@Override
public List<SecureStoreMetadata> list(String namespace) throws Exception {
checkNamespaceExists(namespace);
readLock.lock();
try {
Enumeration<String> aliases = keyStore.aliases();
List<SecureStoreMetadata> metadataList = new ArrayList<>();
String prefix = namespace + NAME_SEPARATOR;
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
// Filter out elements not in this namespace.
if (alias.startsWith(prefix)) {
metadataList.add(getSecureStoreMetadata(alias));
}
}
return metadataList;
} catch (KeyStoreException e) {
throw new IOException("Failed to get the list of elements from the secure store.", e);
} finally {
readLock.unlock();
}
}
Aggregations