@Override protected void shutDown() throws Exception { secureStoreService.stopAndWait(); } }
@Override protected void startUp() throws Exception { secureStoreService.startAndWait(); }
/** * Adds extra dependency classes based on the given configuration. */ private Set<Class<?>> addExtraDependencies(CConfiguration cConf, Set<Class<?>> dependencies) { // Only support HBase and KMS when running on premise if (clusterMode == ClusterMode.ON_PREMISE) { dependencies.add(HBaseTableUtilFactory.getHBaseTableUtilClass(cConf)); if (SecureStoreUtils.isKMSBacked(cConf) && SecureStoreUtils.isKMSCapable()) { dependencies.add(SecureStoreUtils.getKMSSecureStore()); } } return dependencies; } }
@Test public void testCreate() throws Exception { SecureKeyCreateRequest secureKeyCreateRequest = new SecureKeyCreateRequest(DESCRIPTION, DATA, PROPERTIES); HttpResponse response = create(KEY, secureKeyCreateRequest); Assert.assertEquals(200, response.getResponseCode()); response = get(KEY); Assert.assertEquals(200, response.getResponseCode()); Assert.assertEquals(DATA, response.getResponseBodyAsString()); response = delete(KEY); Assert.assertEquals(200, response.getResponseCode()); }
@Test(expected = SecureKeyNotFoundException.class) public void testKeyNotFound() throws Exception { secureStoreService.get(NAMESPACE1, "nonexistingkey"); } }
/** * Deletes the element with the given name. An IOException is thrown if the key does not exist. We can not check the * existence of the key and then delete it atomically. So, there is no easy way to disambiguate between the key * not existing or a failure to delete because of some other reason apart from the message in the exception. * @param namespace The namespace this key belongs to. * @param name Name of the element to be deleted. * @throws NamespaceNotFoundException If the specified namespace does not exist. * @throws IOException If it failed to delete the key in the store. Unfortunately KeyProvider does not specify * the underlying cause except in the message, so we can not throw a more specific exception. */ @Override public void delete(String namespace, String name) throws Exception { checkNamespaceExists(namespace); try { provider.deleteKey(getKeyName(namespace, name)); } catch (IOException e) { throw new IOException("Failed to delete the key " + name + " under namespace " + namespace, e); } }
/** * Persist the keystore on the file system. * * During the flush the steps are * 1. Delete the _NEW file if it exists, it will exist only if something had failed in the last run. * 2. Try to write the current keystore in a _NEW file. * 3. If something fails then revert the key store to the old state and throw IOException. * 4. If everything is OK then rename the _NEW to the main file. * */ private void flush() throws IOException { Path newPath = constructNewPath(path); writeLock.lock(); try { // Might exist if a backup has been restored etc. Files.deleteIfExists(newPath); // Flush the keystore, write the _NEW file first writeToKeyStore(newPath); // Do Atomic rename _NEW to CURRENT Files.move(newPath, path, ATOMIC_MOVE, REPLACE_EXISTING); } finally { writeLock.unlock(); } }
/** * Deletes the key if the user has ADMIN privileges to the key. * * @throws UnauthorizedException If the user does not have admin privileges required to delete the secure key. * @throws NamespaceNotFoundException If the specified namespace does not exist. * @throws NotFoundException If the key to be deleted is not found. * @throws IOException If there was a problem deleting it from the underlying provider. */ @Override public final void delete(String namespace, String name) throws Exception { Principal principal = authenticationContext.getPrincipal(); SecureKeyId secureKeyId = new SecureKeyId(namespace, name); authorizationEnforcer.enforce(secureKeyId, principal, Action.ADMIN); secureStoreService.delete(namespace, name); }
@Test public void testList() throws Exception { populateStore(); List<SecureStoreMetadata> metadatas = secureStore.list(NAMESPACE1); metadatas.sort(Comparator.comparing(SecureStoreMetadata::getName)); verifyList(metadatas, ImmutableMap.of(KEY1, DESCRIPTION1, KEY2, DESCRIPTION2)); }
/** * Puts the user provided data in the secure store, if the user has admin access to the key. * * @throws UnauthorizedException If the user does not have write permissions on the namespace. * @throws NamespaceNotFoundException If the specified namespace does not exist. * @throws IOException If there was a problem storing the key to underlying provider. */ @Override public final synchronized void put(String namespace, String name, String value, @Nullable String description, Map<String, String> properties) throws Exception { Principal principal = authenticationContext.getPrincipal(); NamespaceId namespaceId = new NamespaceId(namespace); SecureKeyId secureKeyId = namespaceId.secureKey(name); authorizationEnforcer.enforce(secureKeyId, principal, Action.ADMIN); secureStoreService.put(namespace, name, value, description, properties); }
/** * Lists all the secure keys in the given namespace that the user has access to. * Returns an empty list if the user does not have access to any of the keys in the namespace. * * @return A map of key names accessible by the user and their descriptions. * @throws NamespaceNotFoundException If the specified namespace does not exist. * @throws IOException If there was a problem reading from the store. * */ @Override public final List<SecureStoreMetadata> list(final String namespace) throws Exception { Principal principal = authenticationContext.getPrincipal(); List<SecureStoreMetadata> metadatas = secureStoreService.list(namespace); return AuthorizationUtil.isVisible(metadatas, authorizationEnforcer, principal, input -> new SecureKeyId(namespace, input.getName()), null); }
public HttpResponse list() throws Exception { return HttpRequests.execute(HttpRequest.get(getURL("/v3/namespaces/default/securekeys")).build()); } }
@Override public AuthorizationContext create(Properties extensionProperties) { return new DefaultAuthorizationContext(extensionProperties, new NoOpDatasetContext(), new NoopAdmin(), new NoOpTransactional(), new AuthenticationTestContext(), new DummySecureStoreService()); }
/** * Adds extra dependency classes based on the given configuration. */ private Set<Class<?>> addExtraDependencies(CConfiguration cConf, Set<Class<?>> dependencies) { // Only support HBase and KMS when running on premise if (clusterMode == ClusterMode.ON_PREMISE) { dependencies.add(HBaseTableUtilFactory.getHBaseTableUtilClass(cConf)); if (SecureStoreUtils.isKMSBacked(cConf) && SecureStoreUtils.isKMSCapable()) { dependencies.add(SecureStoreUtils.getKMSSecureStore()); } } return dependencies; } }
@AfterClass public static void cleanUp() { secureStoreService.stopAndWait(); }
/** * Checks if the user has access to read the secure key and returns the {@link SecureStoreData} associated * with the key if they do. * * @return Data associated with the key if the user has read access. * @throws NamespaceNotFoundException If the specified namespace does not exist. * @throws NotFoundException If the key is not found in the store. * @throws IOException If there was a problem reading from the store. * @throws UnauthorizedException If the user does not have READ permissions on the secure key. */ @Override public final SecureStoreData get(String namespace, String name) throws Exception { Principal principal = authenticationContext.getPrincipal(); SecureKeyId secureKeyId = new SecureKeyId(namespace, name); authorizationEnforcer.enforce(secureKeyId, principal, Action.READ); return secureStoreService.get(namespace, name); }
public HttpResponse delete(String key) throws Exception { return HttpRequests.execute(HttpRequest.delete(getURL("/v3/namespaces/default/securekeys/" + key)).build()); }
public HttpResponse get(String key) throws Exception { return HttpRequests.execute(HttpRequest.get(getURL("/v3/namespaces/default/securekeys/" + key)).build()); }
public HttpResponse create(String key, SecureKeyCreateRequest keyCreateRequest) throws Exception { return HttpRequests.execute(HttpRequest.put(getURL("/v3/namespaces/default/securekeys/" + key)) .withBody(GSON.toJson(keyCreateRequest)).build()); }