[
https://issues.apache.org/jira/browse/NIFIREG-9?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16190322#comment-16190322
]
ASF GitHub Bot commented on NIFIREG-9:
--------------------------------------
Github user kevdoran commented on a diff in the pull request:
https://github.com/apache/nifi-registry/pull/14#discussion_r142517215
--- Diff:
nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/StandardAuthorizerFactory.java
---
@@ -0,0 +1,791 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.registry.authorization;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.registry.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.registry.authorization.generated.Authorizers;
+import org.apache.nifi.registry.authorization.generated.Prop;
+import org.apache.nifi.registry.properties.NiFiRegistryProperties;
+import org.apache.nifi.registry.provider.StandardProviderFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This implementation of AuthorizerFactory in NiFi Registry is based on a
combination of
+ * NiFi's AuthorizerFactory and AuthorizerFactoryBean.
+ */
+public class StandardAuthorizerFactory implements AuthorizerFactory,
UserGroupProviderLookup, AccessPolicyProviderLookup, AuthorizerLookup{
+
+ private static final Logger logger =
LoggerFactory.getLogger(StandardProviderFactory.class);
+
+ private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
+ private static final String JAXB_GENERATED_PATH =
"org.apache.nifi.registry.authorization.generated";
+ private static final JAXBContext JAXB_CONTEXT =
initializeJaxbContext();
+
+ /**
+ * Load the JAXBContext.
+ */
+ private static JAXBContext initializeJaxbContext() {
+ try {
+ return JAXBContext.newInstance(JAXB_GENERATED_PATH,
StandardAuthorizerFactory.class.getClassLoader());
+ } catch (JAXBException e) {
+ throw new RuntimeException("Unable to create JAXBContext.", e);
+ }
+ }
+
+ private final NiFiRegistryProperties properties;
+ private Authorizer authorizer;
+ private final Map<String, UserGroupProvider> userGroupProviders = new
HashMap<>();
+ private final Map<String, AccessPolicyProvider> accessPolicyProviders
= new HashMap<>();
+ private final Map<String, Authorizer> authorizers = new HashMap<>();
+
+ public StandardAuthorizerFactory(final NiFiRegistryProperties
properties) {
+ this.properties = properties;
+
+ if (this.properties == null) {
+ throw new IllegalStateException("NiFiRegistryProperties cannot
be null");
+ }
+ }
+
+ /***** UserGroupProviderLookup *****/
+
+ @Override
+ public UserGroupProvider getUserGroupProvider(String identifier) {
+ return userGroupProviders.get(identifier);
+ }
+
+ /***** AccessPolicyProviderLookup *****/
+
+ @Override
+ public AccessPolicyProvider getAccessPolicyProvider(String identifier)
{
+ return accessPolicyProviders.get(identifier);
+ }
+
+
+ /***** AuthorizerLookup *****/
+
+ @Override
+ public Authorizer getAuthorizer(String identifier) {
+ return authorizers.get(identifier);
+ }
+
+
+ /***** AuthorizerFactory *****/
+
+ @Override
+ public void initialize() throws AuthorizerFactoryException {
+// if (authorizerHolder.get() == null) {
+// final File authorizersConfigFile =
properties.getAuthorizersConfigurationFile();
+// if (authorizersConfigFile.exists()) {
+// try {
+// // find the schema
+// final SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+// final Schema schema =
schemaFactory.newSchema(StandardProviderFactory.class.getResource(AUTHORIZERS_XSD));
+//
+// // attempt to unmarshal
+// final Unmarshaller unmarshaller =
JAXB_CONTEXT.createUnmarshaller();
+// unmarshaller.setSchema(schema);
+//
+// // set the holder for later use
+// final JAXBElement<Authorizers> element =
unmarshaller.unmarshal(new StreamSource(authorizersConfigFile),
Authorizers.class);
+// authorizerHolder.set(element.getValue());
+// } catch (SAXException | JAXBException e) {
+// throw new AuthorizerFactoryException("Unable to load
the authorizer configuration file at: " +
authorizersConfigFile.getAbsolutePath(), e);
+// }
+// } else {
+// throw new AuthorizerFactoryException("Unable to find the
providers configuration file at " + authorizersConfigFile.getAbsolutePath());
+// }
+// }
+ }
+
+ @Override
+ public Authorizer getAuthorizer() throws AuthorizerFactoryException {
+ if (authorizer == null) {
+ if (properties.getSslPort() == null) {
+ // use a default authorizer... only allowable when running
not securely
+ authorizer = createDefaultAuthorizer();
+ } else {
+ // look up the authorizer to use
+ final String authorizerIdentifier =
properties.getProperty(NiFiRegistryProperties.SECURITY_USER_AUTHORIZER);
+
+ // ensure the authorizer class name was specified
+ if (StringUtils.isBlank(authorizerIdentifier)) {
+ throw new AuthorizerFactoryException("When running
securely, the authorizer identifier must be specified in the nifi properties
file.");
+ } else {
+
+ try {
+ final Authorizers authorizerConfiguration =
loadAuthorizersConfiguration();
+
+ // create each user group provider
+ for (final
org.apache.nifi.registry.authorization.generated.UserGroupProvider
userGroupProvider : authorizerConfiguration.getUserGroupProvider()) {
+
userGroupProviders.put(userGroupProvider.getIdentifier(),
createUserGroupProvider(userGroupProvider.getIdentifier(),
userGroupProvider.getClazz()));
+ }
+
+ // configure each user group provider
+ for (final
org.apache.nifi.registry.authorization.generated.UserGroupProvider provider :
authorizerConfiguration.getUserGroupProvider()) {
+ final UserGroupProvider instance =
userGroupProviders.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // create each access policy provider
+ for (final
org.apache.nifi.registry.authorization.generated.AccessPolicyProvider
accessPolicyProvider : authorizerConfiguration.getAccessPolicyProvider()) {
+
accessPolicyProviders.put(accessPolicyProvider.getIdentifier(),
createAccessPolicyProvider(accessPolicyProvider.getIdentifier(),
accessPolicyProvider.getClazz()));
+ }
+
+ // configure each access policy provider
+ for (final
org.apache.nifi.registry.authorization.generated.AccessPolicyProvider provider
: authorizerConfiguration.getAccessPolicyProvider()) {
+ final AccessPolicyProvider instance =
accessPolicyProviders.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // create each authorizer
+ for (final
org.apache.nifi.registry.authorization.generated.Authorizer authorizer :
authorizerConfiguration.getAuthorizer()) {
+ authorizers.put(authorizer.getIdentifier(),
createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz(),
authorizer.getClasspath()));
+ }
+
+ // configure each authorizer
+ for (final
org.apache.nifi.registry.authorization.generated.Authorizer provider :
authorizerConfiguration.getAuthorizer()) {
+ final Authorizer instance =
authorizers.get(provider.getIdentifier());
+
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(),
provider.getProperty()));
+ }
+
+ // get the authorizer instance
+ authorizer = getAuthorizer(authorizerIdentifier);
+
+ // ensure it was found
+ if (authorizer == null) {
+ throw new
AuthorizerFactoryException(String.format("The specified authorizer '%s' could
not be found.", authorizerIdentifier));
+ }
+ } catch (Exception e) {
+ throw new AuthorizerFactoryException("Failed to
construct Authorizer.", e);
+ }
+ }
+ }
+ }
+ return authorizer;
+ }
+
+ private Authorizers loadAuthorizersConfiguration() throws Exception {
+ final File authorizersConfigurationFile =
properties.getAuthorizersConfigurationFile();
+
+ // load the authorizers from the specified file
+ if (authorizersConfigurationFile.exists()) {
+ try {
+ // find the schema
+ final SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ final Schema schema =
schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
+
+ // attempt to unmarshal
+ final Unmarshaller unmarshaller =
JAXB_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ final JAXBElement<Authorizers> element =
unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile),
Authorizers.class);
+ return element.getValue();
+ } catch (SAXException | JAXBException e) {
+ throw new Exception("Unable to load the authorizer
configuration file at: " + authorizersConfigurationFile.getAbsolutePath(), e);
+ }
+ } else {
+ throw new Exception("Unable to find the authorizer
configuration file at " + authorizersConfigurationFile.getAbsolutePath());
+ }
+ }
+
+ private AuthorizerConfigurationContext
loadAuthorizerConfiguration(final String identifier, final List<Prop>
properties) {
+ final Map<String, String> authorizerProperties = new HashMap<>();
+
+ for (final Prop property : properties) {
+ authorizerProperties.put(property.getName(),
property.getValue());
+ }
+ return new StandardAuthorizerConfigurationContext(identifier,
authorizerProperties);
+ }
+
+ private UserGroupProvider createUserGroupProvider(final String
identifier, final String userGroupProviderClassName) throws Exception {
+
+ final UserGroupProvider instance;
+
+ // attempt to load the class
+ Class<?> rawUserGroupProviderClass =
Class.forName(userGroupProviderClassName);
+ Class<? extends UserGroupProvider> userGroupProviderClass =
rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = userGroupProviderClass.getConstructor();
+ instance = (UserGroupProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, userGroupProviderClass);
+
+ // field injection
+ performFieldInjection(instance, userGroupProviderClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+ return instance;
+ }
+
+ private AccessPolicyProvider createAccessPolicyProvider(final String
identifier, final String accessPolicyProviderClassName) throws Exception {
+ final AccessPolicyProvider instance;
+
+ // attempt to load the class
+ Class<?> rawAccessPolicyProviderClass =
Class.forName(accessPolicyProviderClassName);
+ Class<? extends AccessPolicyProvider> accessPolicyClass =
rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
+
+ // otherwise create a new instance
+ Constructor constructor = accessPolicyClass.getConstructor();
+ instance = (AccessPolicyProvider) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, accessPolicyClass);
+
+ // field injection
+ performFieldInjection(instance, accessPolicyClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+ return instance;
+ }
+
+ private Authorizer createAuthorizer(final String identifier, final
String authorizerClassName, final String classpathResources) throws Exception {
+ final Authorizer instance;
+ // attempt to load the class
+ Class<?> rawAuthorizerClass = Class.forName(authorizerClassName);
+ Class<? extends Authorizer> authorizerClass =
rawAuthorizerClass.asSubclass(Authorizer.class);
+
+ // otherwise create a new instance
+ Constructor constructor = authorizerClass.getConstructor();
+ instance = (Authorizer) constructor.newInstance();
+
+ // method injection
+ performMethodInjection(instance, authorizerClass);
+
+ // field injection
+ performFieldInjection(instance, authorizerClass);
+
+ // call post construction lifecycle event
+ instance.initialize(new
StandardAuthorizerInitializationContext(identifier, this, this, this));
+
+// if (StringUtils.isNotEmpty(classpathResources)) {
--- End diff --
Yeah hadn't gotten that far :)
Its a good point. I'll capture the outstanding work in a JIRA ticket and
some in-line TODOs.
> Define web REST API endpoints for user, group, and policy management
> --------------------------------------------------------------------
>
> Key: NIFIREG-9
> URL: https://issues.apache.org/jira/browse/NIFIREG-9
> Project: NiFi Registry
> Issue Type: New Feature
> Reporter: Kevin Doran
> Assignee: Kevin Doran
> Fix For: 0.0.1
>
>
> NIFIREG-8 defined web REST API endpoints for domain objects such as buckets
> and flows.
> This ticket scopes work to build on that by adding endpoints for additional
> resources to facilitate user, group, and policy management.
> The interface for user, group, and policy management will be based on the
> NiFi API so as to minimize the effort for NiFi API clients to be reused for
> NiFi Registry.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)