Github user bbende commented on a diff in the pull request:

    https://github.com/apache/nifi-registry/pull/14#discussion_r142427496
  
    --- 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 --
    
    Should be fine to leave this out for now, but we may need to revisit this 
if/when we add support for Ranger... this was done so someone can configure 
additional libraries to be on the classpath of the authorizer, specifically for 
Ranger to know where the Hadoop client JARs were if wanting to send audit logs 
to HDFS.


---

Reply via email to