NIFI-655: - Removing registration support. - Removing file based implementation.
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/f2505604 Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/f2505604 Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/f2505604 Branch: refs/heads/NIFI-655 Commit: f2505604744f92b1da8bf761bd9027f2fbd03efc Parents: efa1939 Author: Matt Gilman <matt.c.gil...@gmail.com> Authored: Mon Nov 9 15:00:33 2015 -0500 Committer: Matt Gilman <matt.c.gil...@gmail.com> Committed: Mon Nov 9 15:00:33 2015 -0500 ---------------------------------------------------------------------- .../authentication/LoginIdentityProvider.java | 19 +- .../IdentityRegistrationException.java | 33 -- .../nifi-framework-nar/pom.xml | 4 - .../nifi-authorized-users/pom.xml | 75 --- .../nifi/authorized/users/AuthorizedUsers.java | 445 -------------- .../src/main/xsd/users.xsd | 97 --- .../nifi/web/api/dto/LoginConfigurationDTO.java | 16 - .../nifi-file-authorization-provider/pom.xml | 43 +- .../FileAuthorizationProvider.java | 583 ++++++++++--------- .../src/main/xsd/users.xsd | 64 ++ .../nifi-file-identity-provider/pom.xml | 39 -- ...he.nifi.authentication.LoginIdentityProvider | 15 - .../resources/conf/login-identity-providers.xml | 5 - .../web/NiFiWebApiSecurityConfiguration.java | 16 - .../nifi/web/StandardNiFiServiceFacade.java | 10 +- .../apache/nifi/web/api/ControllerResource.java | 1 - .../web/security/login/RegistrationFilter.java | 163 ------ .../LoginIdentityProviderFactoryBean.java | 14 - .../src/main/webapp/WEB-INF/pages/login.jsp | 1 - .../WEB-INF/partials/login/login-form.jsp | 4 - .../partials/login/nifi-registration-form.jsp | 4 - .../partials/login/user-registration-form.jsp | 34 -- .../nifi-web-ui/src/main/webapp/css/login.css | 21 - .../webapp/js/nf/canvas/nf-canvas-header.js | 18 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 13 +- .../src/main/webapp/js/nf/login/nf-login.js | 18 +- .../nifi-framework/pom.xml | 2 - nifi-nar-bundles/nifi-framework-bundle/pom.xml | 10 - 28 files changed, 420 insertions(+), 1347 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java index 290b694..95f2efa 100644 --- a/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java +++ b/nifi-api/src/main/java/org/apache/nifi/authentication/LoginIdentityProvider.java @@ -17,7 +17,6 @@ package org.apache.nifi.authentication; import org.apache.nifi.authentication.exception.IdentityAccessException; -import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException; import org.apache.nifi.authorization.exception.ProviderCreationException; import org.apache.nifi.authorization.exception.ProviderDestructionException; @@ -27,24 +26,11 @@ import org.apache.nifi.authorization.exception.ProviderDestructionException; public interface LoginIdentityProvider { /** - * Returns whether this provider supports user registration. - * - * @return whether user registration is supported - */ - boolean supportsRegistration(); - - /** - * Invoked to register the user with the specified login credentials. - * - * @param credentials the login credentials - */ - void register(LoginCredentials credentials) throws IdentityAlreadyExistsException, IdentityAccessException; - - /** * Authenticates the specified login credentials. * * @param credentials the credentials - * @return whether the user was authenticated + * @return was able to check the user credentials and returns whether the user was authenticated + * @throws IdentityAccessException Unable to register the user due to an issue accessing the underlying storage */ boolean authenticate(LoginCredentials credentials) throws IdentityAccessException; @@ -52,6 +38,7 @@ public interface LoginIdentityProvider { * Called immediately after instance creation for implementers to perform additional setup * * @param initializationContext in which to initialize + * @throws ProviderCreationException Unable to initialize */ void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException; http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityRegistrationException.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityRegistrationException.java b/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityRegistrationException.java deleted file mode 100644 index 4b80c61..0000000 --- a/nifi-api/src/main/java/org/apache/nifi/authentication/exception/IdentityRegistrationException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.authentication.exception; - -/** - * Represents the case when the identity could not be registered for some reason. - * Like the credentials did not meet the minimum requirements - */ -public class IdentityRegistrationException extends RuntimeException { - - public IdentityRegistrationException(String message, Throwable cause) { - super(message, cause); - } - - public IdentityRegistrationException(String message) { - super(message); - } - -} http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml index 3773ac7..fcfcfe7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml @@ -35,10 +35,6 @@ <groupId>org.apache.nifi</groupId> <artifactId>nifi-file-authorization-provider</artifactId> </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-file-identity-provider</artifactId> - </dependency> <!-- mark these nifi artifacts as provided since it is included in the lib --> <dependency> http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml deleted file mode 100644 index 6ec8236..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-framework</artifactId> - <version>0.3.1-SNAPSHOT</version> - </parent> - <artifactId>nifi-authorized-users</artifactId> - <build> - <resources> - <resource> - <directory>src/main/resources</directory> - </resource> - <resource> - <directory>src/main/xsd</directory> - </resource> - </resources> - <plugins> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>jaxb2-maven-plugin</artifactId> - <executions> - <execution> - <id>xjc</id> - <goals> - <goal>xjc</goal> - </goals> - <configuration> - <packageName>org.apache.nifi.user.generated</packageName> - </configuration> - </execution> - </executions> - <configuration> - <generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-checkstyle-plugin</artifactId> - <configuration> - <excludes>**/user/generated/*.java</excludes> - </configuration> - </plugin> - </plugins> - </build> - <dependencies> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-api</artifactId> - </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-properties</artifactId> - </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-utils</artifactId> - </dependency> - </dependencies> -</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java deleted file mode 100644 index abdd48e..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/java/org/apache/nifi/authorized/users/AuthorizedUsers.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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.authorized.users; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import org.apache.nifi.authorization.exception.AuthorityAccessException; -import org.apache.nifi.authorization.exception.ProviderCreationException; -import org.apache.nifi.authorization.exception.UnknownIdentityException; -import org.apache.nifi.user.generated.LoginUser; -import org.apache.nifi.user.generated.NiFiUser; -import org.apache.nifi.user.generated.User; -import org.apache.nifi.user.generated.Users; -import org.apache.nifi.util.NiFiProperties; -import org.apache.nifi.util.file.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.SAXException; - -/** - * Access to the configured Authorized Users. - */ -public final class AuthorizedUsers { - - private static final Logger logger = LoggerFactory.getLogger(AuthorizedUsers.class); - - private static final String USERS_XSD = "/users.xsd"; - private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated"; - private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext(); - - private static final Map<String, AuthorizedUsers> instances = new HashMap<>(); - - private File usersFile; - private File restoreFile; - - /** - * Load the JAXBContext. - */ - private static JAXBContext initializeJaxbContext() { - try { - return JAXBContext.newInstance(JAXB_GENERATED_PATH, AuthorizedUsers.class.getClassLoader()); - } catch (JAXBException e) { - throw new RuntimeException("Unable to create JAXBContext."); - } - } - - private AuthorizedUsers(final File usersFile, final NiFiProperties properties) throws IOException, IllegalStateException { - this.usersFile = usersFile; - - // the restore directory is optional and may be null - final File restoreDirectory = properties.getRestoreDirectory(); - if (restoreDirectory != null) { - - // sanity check that restore directory is a directory, creating it if necessary - FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory); - - // check that restore directory is not the same as the primary directory - final File usersFileDirectory = usersFile.getParentFile(); - if (usersFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath())) { - throw new IllegalStateException(String.format("Directory of users file '%s' is the same as restore directory '%s' ", - usersFileDirectory.getAbsolutePath(), restoreDirectory.getAbsolutePath())); - } - - // the restore copy will have same file name, but reside in a different directory - restoreFile = new File(restoreDirectory, usersFile.getName()); - - // sync the primary copy with the restore copy - try { - FileUtils.syncWithRestore(usersFile, restoreFile, logger); - } catch (final IOException | IllegalStateException ioe) { - throw new ProviderCreationException(ioe); - } - } - } - - public static AuthorizedUsers getInstance(final String usersFilePath, final NiFiProperties properties) throws IOException, IllegalStateException { - final File usersFile = new File(usersFilePath); - - // see if an authorizedUsers has already been created using this filename - AuthorizedUsers authorizedUsers = instances.get(usersFile.getName()); - - if (authorizedUsers == null) { - // create a new authorizedUsers - authorizedUsers = new AuthorizedUsers(usersFile, properties); - - // store it for later - instances.put(usersFile.getName(), authorizedUsers); - } else { - // ensure the file paths are the same, the restore capability cannot support different files with the same name - if (!authorizedUsers.usersFile.equals(usersFile)) { - throw new IllegalStateException(String.format("A users file with this name has already been initialized. The name must be unique given the constraints of " - + "the restore directory. The paths in question are '%s' and '%s'", authorizedUsers.usersFile.getAbsolutePath(), usersFile.getAbsolutePath())); - } - } - - return authorizedUsers; - } - - /** - * Gets the user identity. - * - * @param user The user - * @return The user identity - */ - public String getUserIdentity(final NiFiUser user) { - if (user instanceof User) { - return ((User) user).getDn(); - } else { - return ((LoginUser) user).getUsername(); - } - } - - /** - * Gets all users from configured file. - * - * @return The Users - */ - public synchronized Users getUsers() { - try { - // ensure the directory exists and it can be created - if (!usersFile.exists() && !usersFile.mkdirs()) { - throw new IllegalStateException("The users file does not exist and could not be created."); - } - - // find the schema - final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - final Schema schema = schemaFactory.newSchema(AuthorizedUsers.class.getResource(USERS_XSD)); - - // attempt to unmarshal - final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller(); - unmarshaller.setSchema(schema); - final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class); - return element.getValue(); - } catch (SAXException | JAXBException e) { - throw new AuthorityAccessException(e.getMessage(), e); - } - } - - /** - * Determines if a user exists through the specified HasUser. - * - * @param finder The finder - * @return Whether the user exists - */ - public synchronized boolean hasUser(final HasUser finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - return finder.hasUser(nifiUsers); - } - - /** - * Gets the desired user. - * - * @param finder The finder - * @return The NiFiUser - * @throws UnknownIdentityException If the desired user could not be found - */ - public synchronized NiFiUser getUser(final FindUser finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - return finder.findUser(nifiUsers); - } - - /** - * Gets the desired users. - * - * @param finder The finder - * @return The NiFiUsers - * @throws UnknownIdentityException If the users could not be found - */ - public synchronized List<NiFiUser> getUsers(final FindUsers finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - return finder.findUsers(nifiUsers); - } - - /** - * Creates the user via the specified CreateUser. - * - * @param creator The creator - */ - public synchronized void createUser(final CreateUser creator) { - // add the user - final Users users = getUsers(); - - // create the user - final NiFiUser newUser = creator.createUser(); - if (newUser instanceof User) { - users.getUser().add((User) newUser); - } else { - users.getLoginUser().add((LoginUser) newUser); - } - - // save the users - saveUsers(users); - } - - /** - * Creates or Updates a user identified by the finder. If the user exists, it's updated otherwise it's created. - * - * @param finder The finder - * @param creator The creator - * @param updater The updater - */ - public synchronized void createOrUpdateUser(final FindUser finder, final CreateUser creator, final UpdateUser updater) { - try { - updateUser(finder, updater); - } catch (final UnknownIdentityException uie) { - createUser(creator); - } - } - - /** - * Updates the user identified by the finder. - * - * @param finder The finder - * @param updater The updater - */ - public synchronized void updateUser(final FindUser finder, final UpdateUser updater) { - // update the user - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the user to update - final NiFiUser user = finder.findUser(nifiUsers); - - // update the user - updater.updateUser(user); - - // save the users - saveUsers(users); - } - - /** - * Updates the users identified by the finder. - * - * @param finder The finder - * @param updater The updater - */ - public synchronized void updateUsers(final FindUsers finder, final UpdateUsers updater) { - // update the user - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - final List<NiFiUser> userToUpdate = finder.findUsers(nifiUsers); - - // update the user - updater.updateUsers(userToUpdate); - - // save the users - saveUsers(users); - } - - /** - * Removes the user identified by the finder. - * - * @param finder The finder - */ - public synchronized void removeUser(final FindUser finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - final NiFiUser user = finder.findUser(nifiUsers); - if (user instanceof User) { - users.getUser().remove((User) user); - } else { - users.getLoginUser().remove((LoginUser) user); - } - - // save the users - saveUsers(users); - } - - /** - * Removes the users identified by the finder. - * - * @param finder The finder - */ - public synchronized void removeUsers(final FindUsers finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List<NiFiUser> nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - final List<NiFiUser> usersToRemove = finder.findUsers(nifiUsers); - for (final NiFiUser user : usersToRemove) { - if (user instanceof User) { - users.getUser().remove((User) user); - } else { - users.getLoginUser().remove((LoginUser) user); - } - } - - // save the users - saveUsers(users); - } - - private synchronized void saveUsers(final Users users) { - try { - final Marshaller marshaller = JAXB_CONTEXT.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - // save users to restore directory before primary directory - if (restoreFile != null) { - marshaller.marshal(users, restoreFile); - } - - // save users to primary directory - marshaller.marshal(users, usersFile); - } catch (JAXBException e) { - throw new AuthorityAccessException(e.getMessage(), e); - } - } - - public static interface HasUser { - - /** - * Determines if a user exists. Returns whether this user exists and will never through an UnknownIdentityException. - * - * @param users the users - * @return whether the desired user exists - */ - boolean hasUser(List<NiFiUser> users); - } - - public static interface FindUser { - - /** - * Finds the desired user. If the user cannot be found throws an UnknownIdentityException. Never returns null. - * - * @param users the users - * @return the desired user - * @throws UnknownIdentityException if the user cannot be found - */ - NiFiUser findUser(List<NiFiUser> users) throws UnknownIdentityException; - } - - public static interface FindUsers { - - /** - * Finds the specified users. - * - * @param users the userss - * @return the desired users - * @throws UnknownIdentityException if the users cannot be found - */ - List<NiFiUser> findUsers(List<NiFiUser> users) throws UnknownIdentityException; - } - - public static interface CreateUser { - - /** - * Creates the user to add. - * - * @return the users to add - */ - NiFiUser createUser(); - } - - public static interface UpdateUser { - - /** - * Updates the specified user. - * - * @param user the user - */ - void updateUser(NiFiUser user); - } - - public static interface UpdateUsers { - - /** - * Updates the specified users. - * - * @param users the users to update - */ - void updateUsers(List<NiFiUser> users); - } -} http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd deleted file mode 100644 index 509f97b..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd +++ /dev/null @@ -1,97 +0,0 @@ -<?xml version="1.0"?> -<!-- - 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. ---> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> - <!-- role --> - <xs:complexType name="Role"> - <xs:attribute name="name"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="ROLE_MONITOR"/> - <xs:enumeration value="ROLE_PROVENANCE"/> - <xs:enumeration value="ROLE_DFM"/> - <xs:enumeration value="ROLE_ADMIN"/> - <xs:enumeration value="ROLE_PROXY"/> - <xs:enumeration value="ROLE_NIFI"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - </xs:complexType> - - <xs:complexType name="NiFiUser"> - <xs:sequence> - <xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - <xs:attribute name="group"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - <xs:pattern value=".*[^\s].*"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - </xs:complexType> - - <!-- preauthenticated user --> - <xs:complexType name="User"> - <xs:complexContent> - <xs:extension base="NiFiUser"> - <xs:attribute name="dn" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - <xs:pattern value=".*[^\s].*"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> - - <!-- login user --> - <xs:complexType name="LoginUser"> - <xs:complexContent> - <xs:extension base="NiFiUser"> - <xs:attribute name="username" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - <xs:pattern value=".*[^\s].*"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="password" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - <xs:pattern value=".*[^\s].*"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="pending" type="xs:boolean" use="required"/> - </xs:extension> - </xs:complexContent> - </xs:complexType> - - <!-- users --> - <xs:element name="users"> - <xs:complexType> - <xs:sequence> - <xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/> - <xs:element name="loginUser" type="LoginUser" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - </xs:complexType> - </xs:element> -</xs:schema> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java index e4452c0..60f644b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/LoginConfigurationDTO.java @@ -26,7 +26,6 @@ import javax.xml.bind.annotation.XmlType; public class LoginConfigurationDTO { private Boolean supportsLogin; - private Boolean supportsRegistration; /** * @return Indicates whether or not this NiFi supports user login. @@ -42,19 +41,4 @@ public class LoginConfigurationDTO { public void setSupportsLogin(Boolean supportsLogin) { this.supportsLogin = supportsLogin; } - - /** - * @return If this NiFi supports login, indicates whether or not registration is supported. - */ - @ApiModelProperty( - value = "If this NiFi supports login, indicates whether or not registration is supported.", - readOnly = true - ) - public Boolean getSupportsRegistration() { - return supportsRegistration; - } - - public void setSupportsRegistration(Boolean supportsRegistration) { - this.supportsRegistration = supportsRegistration; - } } http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml index 50fa105..d014262 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml @@ -21,6 +21,44 @@ <version>0.3.1-SNAPSHOT</version> </parent> <artifactId>nifi-file-authorization-provider</artifactId> + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>src/main/xsd</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>jaxb2-maven-plugin</artifactId> + <executions> + <execution> + <id>xjc</id> + <goals> + <goal>xjc</goal> + </goals> + <configuration> + <packageName>org.apache.nifi.user.generated</packageName> + </configuration> + </execution> + </executions> + <configuration> + <generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <configuration> + <excludes>**/user/generated/*.java</excludes> + </configuration> + </plugin> + + </plugins> + </build> <dependencies> <dependency> <groupId>org.apache.nifi</groupId> @@ -28,12 +66,7 @@ </dependency> <dependency> <groupId>org.apache.nifi</groupId> - <artifactId>nifi-authorized-users</artifactId> - </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> <artifactId>nifi-utils</artifactId> - <scope>test</scope> </dependency> <dependency> <groupId>org.apache.nifi</groupId> http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java index 3400ce8..9c2cad5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/java/org/apache/nifi/authorization/FileAuthorizationProvider.java @@ -16,34 +16,38 @@ */ package org.apache.nifi.authorization; +import java.io.File; import java.io.IOException; -import java.util.ArrayList; +import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; import org.apache.nifi.authorization.annotation.AuthorityProviderContext; import org.apache.nifi.authorization.exception.AuthorityAccessException; import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException; import org.apache.nifi.authorization.exception.ProviderCreationException; import org.apache.nifi.authorization.exception.UnknownIdentityException; +import org.apache.nifi.util.file.FileUtils; import org.apache.nifi.user.generated.ObjectFactory; import org.apache.nifi.user.generated.Role; import org.apache.nifi.user.generated.User; +import org.apache.nifi.user.generated.Users; import org.apache.nifi.util.NiFiProperties; import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.authorized.users.AuthorizedUsers; -import org.apache.nifi.authorized.users.AuthorizedUsers.CreateUser; -import org.apache.nifi.authorized.users.AuthorizedUsers.FindUser; -import org.apache.nifi.authorized.users.AuthorizedUsers.FindUsers; -import org.apache.nifi.authorized.users.AuthorizedUsers.HasUser; -import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUser; -import org.apache.nifi.authorized.users.AuthorizedUsers.UpdateUsers; -import org.apache.nifi.user.generated.LoginUser; -import org.apache.nifi.user.generated.NiFiUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; /** * Provides identity checks and grants authorities. @@ -51,26 +55,84 @@ import org.slf4j.LoggerFactory; public class FileAuthorizationProvider implements AuthorityProvider { private static final Logger logger = LoggerFactory.getLogger(FileAuthorizationProvider.class); + private static final String USERS_XSD = "/users.xsd"; + private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated"; + private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext(); + + /** + * Load the JAXBContext. + */ + private static JAXBContext initializeJaxbContext() { + try { + return JAXBContext.newInstance(JAXB_GENERATED_PATH, FileAuthorizationProvider.class.getClassLoader()); + } catch (JAXBException e) { + throw new RuntimeException("Unable to create JAXBContext."); + } + } private NiFiProperties properties; + private File usersFile; + private File restoreUsersFile; + private Users users; private final Set<String> defaultAuthorities = new HashSet<>(); - private AuthorizedUsers authorizedUsers; - @Override public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException { } @Override public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException { - final String usersFilePath = configurationContext.getProperty("Authorized Users File"); - if (usersFilePath == null || usersFilePath.trim().isEmpty()) { - throw new ProviderCreationException("The authorized users file must be specified."); - } - try { - // initialize the authorized users - authorizedUsers = AuthorizedUsers.getInstance(usersFilePath, properties); + final String usersFilePath = configurationContext.getProperty("Authorized Users File"); + if (usersFilePath == null || usersFilePath.trim().isEmpty()) { + throw new ProviderCreationException("The authorized users file must be specified."); + } + + // the users file instance will never be null because a default is used + usersFile = new File(usersFilePath); + final File usersFileDirectory = usersFile.getParentFile(); + + // the restore directory is optional and may be null + final File restoreDirectory = properties.getRestoreDirectory(); + + if (restoreDirectory != null) { + + // sanity check that restore directory is a directory, creating it if necessary + FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory); + + // check that restore directory is not the same as the primary directory + if (usersFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath())) { + throw new ProviderCreationException(String.format("Authorized User's directory '%s' is the same as restore directory '%s' ", + usersFileDirectory.getAbsolutePath(), restoreDirectory.getAbsolutePath())); + } + + // the restore copy will have same file name, but reside in a different directory + restoreUsersFile = new File(restoreDirectory, usersFile.getName()); + + // sync the primary copy with the restore copy + try { + FileUtils.syncWithRestore(usersFile, restoreUsersFile, logger); + } catch (final IOException | IllegalStateException ioe) { + throw new ProviderCreationException(ioe); + } + + } + + // load the users from the specified file + if (usersFile.exists()) { + // find the schema + final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final Schema schema = schemaFactory.newSchema(FileAuthorizationProvider.class.getResource(USERS_XSD)); + + // attempt to unmarshal + final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller(); + unmarshaller.setSchema(schema); + final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class); + users = element.getValue(); + } else { + final ObjectFactory objFactory = new ObjectFactory(); + users = objFactory.createUsers(); + } // attempt to load a default roles final String rawDefaultAuthorities = configurationContext.getProperty("Default User Roles"); @@ -95,9 +157,10 @@ public class FileAuthorizationProvider implements AuthorityProvider { StringUtils.join(invalidDefaultAuthorities, ", "), StringUtils.join(Authority.getRawAuthorities(), ", "))); } } - } catch (IOException | IllegalStateException | ProviderCreationException e) { + } catch (IOException | ProviderCreationException | SAXException | JAXBException e) { throw new ProviderCreationException(e); } + } @Override @@ -109,64 +172,67 @@ public class FileAuthorizationProvider implements AuthorityProvider { } @Override - public boolean doesDnExist(final String dn) throws AuthorityAccessException { + public boolean doesDnExist(String dn) throws AuthorityAccessException { if (hasDefaultRoles()) { return true; } - return authorizedUsers.hasUser(new HasUserByIdentity(dn)); + final User user = getUser(dn); + return user != null; } @Override - public Set<Authority> getAuthorities(final String dn) throws UnknownIdentityException, AuthorityAccessException { + public synchronized Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException { final Set<Authority> authorities = EnumSet.noneOf(Authority.class); // get the user - final NiFiUser user = authorizedUsers.getUser(new FindUser() { - @Override - public NiFiUser findUser(List<NiFiUser> users) { - final FindUser byDn = new FindUserByIdentity(dn); - NiFiUser user = byDn.findUser(users); - - // if the user is not found, add them and locate them - if (user == null) { - if (hasDefaultRoles()) { - logger.debug(String.format("User identity not found: %s. Creating new user with default roles.", dn)); - - // create the user (which will automatically add any default authorities) - addUser(dn, null); - - // find the user that was just added - user = byDn.findUser(users); - } else { - throw new UnknownIdentityException(String.format("User identity not found: %s.", dn)); - } - } + final User user = getUser(dn); - return user; - } - }); + // ensure the user was located + if (user == null) { + if (hasDefaultRoles()) { + logger.debug(String.format("User DN not found: %s. Creating new user with default roles.", dn)); + + // create the user (which will automatically add any default authorities) + addUser(dn, null); - // create the authorities that this user has - for (final Role role : user.getRole()) { - authorities.add(Authority.valueOfAuthority(role.getName())); + // get the authorities for the newly created user + authorities.addAll(getAuthorities(dn)); + } else { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); + } + } else { + // create the authorities that this user has + for (final Role role : user.getRole()) { + authorities.add(Authority.valueOfAuthority(role.getName())); + } } return authorities; } @Override - public void setAuthorities(final String dn, final Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.updateUser(new FindUserByIdentity(dn), new UpdateUser() { - @Override - public void updateUser(NiFiUser user) { - // add the user authorities - setUserAuthorities(user, authorities); - } - }); + public synchronized void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException { + // get the user + final User user = getUser(dn); + + // ensure the user was located + if (user == null) { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); + } + + // add the user authorities + setUserAuthorities(user, authorities); + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } - private void setUserAuthorities(final NiFiUser user, final Set<Authority> authorities) { + private void setUserAuthorities(final User user, final Set<Authority> authorities) { // clear the existing rules user.getRole().clear(); @@ -182,292 +248,249 @@ public class FileAuthorizationProvider implements AuthorityProvider { } @Override - public void addUser(final String dn, final String group) throws IdentityAlreadyExistsException, AuthorityAccessException { - authorizedUsers.createOrUpdateUser(new FindUser() { - @Override - public NiFiUser findUser(final List<NiFiUser> users) throws UnknownIdentityException { - // attempt to get the user and ensure it was located - NiFiUser desiredUser = null; - for (final NiFiUser user : users) { - if (dn.equalsIgnoreCase(authorizedUsers.getUserIdentity(user))) { - desiredUser = user; - break; - } - } + public synchronized void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException { + final User user = getUser(dn); - // user does not exist, will create - if (desiredUser == null) { - throw new UnknownIdentityException("This exception will trigger the creator to be invoked."); - } + // ensure the user doesn't already exist + if (user != null) { + throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn)); + } - // user exists, verify its still pending - if (LoginUser.class.isAssignableFrom(desiredUser.getClass())) { - if (((LoginUser) desiredUser).isPending()) { - return desiredUser; - } - } + // create the new user + final ObjectFactory objFactory = new ObjectFactory(); + final User newUser = objFactory.createUser(); - // user exists and account is valid... no good - throw new IdentityAlreadyExistsException(String.format("User identity already exists: %s", dn)); - } - }, new CreateUser() { - @Override - public NiFiUser createUser() { - // only support adding PreAuthenticated User's via this API - LoginUser's are added - // via the LoginIdentityProvider - final ObjectFactory objFactory = new ObjectFactory(); - final User newUser = objFactory.createUser(); + // set the user properties + newUser.setDn(dn); + newUser.setGroup(group); - // set the user properties - newUser.setDn(dn); - newUser.setGroup(group); + // add default roles if appropriate + if (hasDefaultRoles()) { + for (final String authority : defaultAuthorities) { + Role role = objFactory.createRole(); + role.setName(authority); - // add default roles if appropriate - if (hasDefaultRoles()) { - for (final String authority : defaultAuthorities) { - Role role = objFactory.createRole(); - role.setName(authority); + // add the role + newUser.getRole().add(role); + } + } - // add the role - newUser.getRole().add(role); - } - } + // add the user + users.getUser().add(newUser); - return newUser; - } - }, new UpdateUser() { - @Override - public void updateUser(final NiFiUser user) { - // only support updating Login Users's via this API - need to mark the account as non pending - LoginUser loginUser = (LoginUser) user; - loginUser.setPending(false); - } - }); + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @Override - public Set<String> getUsers(final Authority authority) throws AuthorityAccessException { - final List<NiFiUser> matchingUsers = authorizedUsers.getUsers(new FindUsers() { - @Override - public List<NiFiUser> findUsers(List<NiFiUser> users) throws UnknownIdentityException { - final List<NiFiUser> matchingUsers = new ArrayList<>(); - for (final NiFiUser user : users) { - for (final Role role : user.getRole()) { - if (role.getName().equals(authority.toString())) { - matchingUsers.add(user); - } - } + public synchronized Set<String> getUsers(Authority authority) throws AuthorityAccessException { + final Set<String> userSet = new HashSet<>(); + for (final User user : users.getUser()) { + for (final Role role : user.getRole()) { + if (role.getName().equals(authority.toString())) { + userSet.add(user.getDn()); } - return matchingUsers; } - }); - - final Set<String> userSet = new HashSet<>(); - for (final NiFiUser user : matchingUsers) { - userSet.add(authorizedUsers.getUserIdentity(user)); } - return userSet; } @Override - public void revokeUser(final String dn) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.removeUser(new FindUserByIdentity(dn)); - } - - @Override - public void setUsersGroup(final Set<String> dns, final String group) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.updateUsers(new FindUsersByIdentity(dns), new UpdateUsers() { - @Override - public void updateUsers(List<NiFiUser> users) { - // update each user group - for (final NiFiUser user : users) { - user.setGroup(group); - } - } - }); - } + public synchronized void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException { + // get the user + final User user = getUser(dn); - @Override - public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.updateUser(new FindUserByIdentity(dn), new UpdateUser() { - @Override - public void updateUser(NiFiUser user) { - // remove the users group - user.setGroup(null); - } - }); - } + // ensure the user was located + if (user == null) { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); + } - @Override - public void ungroup(final String group) throws AuthorityAccessException { - authorizedUsers.updateUsers(new FindUsersByGroup(group), new UpdateUsers() { - @Override - public void updateUsers(List<NiFiUser> users) { - // update each user group - for (final NiFiUser user : users) { - user.setGroup(null); - } - } - }); - } + // remove the specified user + users.getUser().remove(user); - @Override - public String getGroupForUser(final String dn) throws UnknownIdentityException, AuthorityAccessException { - final NiFiUser user = authorizedUsers.getUser(new FindUserByIdentity(dn)); - return user.getGroup(); + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @Override - public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.removeUsers(new FindUsersByGroup(group)); - } + public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException { + final Collection<User> groupedUsers = new HashSet<>(); - /** - * Grants access to download content regardless of FlowFile attributes. - */ - @Override - public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException { - return DownloadAuthorization.approved(); - } + // get the specified users + for (final String dn : dns) { + // get the user + final User user = getUser(dn); - @AuthorityProviderContext - public void setNiFiProperties(NiFiProperties properties) { - this.properties = properties; - } + // ensure the user was located + if (user == null) { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); + } - private boolean isPendingLoginUser(final NiFiUser user) { - if (LoginUser.class.isAssignableFrom(user.getClass())) { - return ((LoginUser) user).isPending(); + groupedUsers.add(user); } - return false; - } - public class HasUserByIdentity implements HasUser { + // update each user group + for (final User user : groupedUsers) { + user.setGroup(group); + } - private final String identity; + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } + } - public HasUserByIdentity(String identity) { - // ensure the identity was specified - if (identity == null) { - throw new UnknownIdentityException("User identity not specified."); - } + @Override + public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException { + // get the user + final User user = getUser(dn); - this.identity = identity; + // ensure the user was located + if (user == null) { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); } - @Override - public boolean hasUser(List<NiFiUser> users) { - // attempt to get the user and ensure it was located - NiFiUser desiredUser = null; - for (final NiFiUser user : users) { - if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user)) && !isPendingLoginUser(user)) { - desiredUser = user; - break; - } - } + // remove the users group + user.setGroup(null); - return desiredUser != null; + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); } } - public class FindUserByIdentity implements FindUser { - - private final String identity; - - public FindUserByIdentity(String identity) { - // ensure the identity was specified - if (identity == null) { - throw new UnknownIdentityException("User identity not specified."); - } + @Override + public void ungroup(String group) throws AuthorityAccessException { + // get the user group + final Collection<User> userGroup = getUserGroup(group); - this.identity = identity; + // ensure the user group was located + if (userGroup == null) { + return; } - @Override - public NiFiUser findUser(List<NiFiUser> users) { - // attempt to get the user and ensure it was located - NiFiUser desiredUser = null; - for (final NiFiUser user : users) { - if (identity.equalsIgnoreCase(authorizedUsers.getUserIdentity(user)) && !isPendingLoginUser(user)) { - desiredUser = user; - break; - } - } - - if (desiredUser == null) { - throw new UnknownIdentityException(String.format("User identity not found: %s.", identity)); - } + // update each user group + for (final User user : userGroup) { + user.setGroup(null); + } - return desiredUser; + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); } } - public class FindUsersByGroup implements FindUsers { + @Override + public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException { + // get the user + final User user = getUser(dn); - private final String group; + // ensure the user was located + if (user == null) { + throw new UnknownIdentityException(String.format("User DN not found: %s.", dn)); + } - public FindUsersByGroup(String group) { - // ensure the group was specified - if (group == null) { - throw new UnknownIdentityException("User group not specified."); - } + return user.getGroup(); + } - this.group = group; - } + @Override + public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException { + // get the user group + final Collection<User> userGroup = getUserGroup(group); - @Override - public List<NiFiUser> findUsers(List<NiFiUser> users) throws UnknownIdentityException { - // get all users with this group - List<NiFiUser> userGroup = new ArrayList<>(); - for (final NiFiUser user : users) { - if (group.equals(user.getGroup()) && !isPendingLoginUser(user)) { - userGroup.add(user); - } - } + // ensure the user group was located + if (userGroup == null) { + throw new UnknownIdentityException(String.format("User group not found: %s.", group)); + } - // ensure the user group was located - if (userGroup.isEmpty()) { - throw new UnknownIdentityException(String.format("User group not found: %s.", group)); - } + // remove each user in the group + for (final User user : userGroup) { + users.getUser().remove(user); + } - return userGroup; + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); } } - public class FindUsersByIdentity implements FindUsers { + /** + * Grants access to download content regardless of FlowFile attributes. + */ + @Override + public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException { + return DownloadAuthorization.approved(); + } - private final Set<String> identities; + private User getUser(String dn) throws UnknownIdentityException { + // ensure the DN was specified + if (dn == null) { + throw new UnknownIdentityException("User DN not specified."); + } - public FindUsersByIdentity(Set<String> identities) { - // ensure the group was specified - if (identities == null) { - throw new UnknownIdentityException("User identities not specified."); + // attempt to get the user and ensure it was located + User desiredUser = null; + for (final User user : users.getUser()) { + if (dn.equalsIgnoreCase(user.getDn())) { + desiredUser = user; + break; } + } + + return desiredUser; + } - this.identities = identities; + private Collection<User> getUserGroup(String group) throws UnknownIdentityException { + // ensure the DN was specified + if (group == null) { + throw new UnknownIdentityException("User group not specified."); } - @Override - public List<NiFiUser> findUsers(List<NiFiUser> users) throws UnknownIdentityException { - final Set<String> copy = new HashSet<>(identities); - - // get all users with this group - List<NiFiUser> userList = new ArrayList<>(); - for (final NiFiUser user : users) { - final String userIdentity = authorizedUsers.getUserIdentity(user); - if (copy.contains(userIdentity) && !isPendingLoginUser(user)) { - copy.remove(userIdentity); - userList.add(user); + // get all users with this group + Collection<User> userGroup = null; + for (final User user : users.getUser()) { + if (group.equals(user.getGroup())) { + if (userGroup == null) { + userGroup = new HashSet<>(); } + userGroup.add(user); } + } - if (!copy.isEmpty()) { - throw new UnknownIdentityException("Unable to find users with identities: " + StringUtils.join(copy, ", ")); - } + return userGroup; + } - return userList; + private void save() throws Exception { + final Marshaller marshaller = JAXB_CONTEXT.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + // save users to restore directory before primary directory + if (restoreUsersFile != null) { + marshaller.marshal(users, restoreUsersFile); } + + // save users to primary directory + marshaller.marshal(users, usersFile); } + @AuthorityProviderContext + public void setNiFiProperties(NiFiProperties properties) { + this.properties = properties; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/xsd/users.xsd ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/xsd/users.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/xsd/users.xsd new file mode 100644 index 0000000..4ee1e17 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/xsd/users.xsd @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- + 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. +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <!-- role --> + <xs:complexType name="Role"> + <xs:attribute name="name"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="ROLE_MONITOR"/> + <xs:enumeration value="ROLE_PROVENANCE"/> + <xs:enumeration value="ROLE_DFM"/> + <xs:enumeration value="ROLE_ADMIN"/> + <xs:enumeration value="ROLE_PROXY"/> + <xs:enumeration value="ROLE_NIFI"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + + <!-- user --> + <xs:complexType name="User"> + <xs:sequence> + <xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="dn"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + <xs:pattern value=".*[^\s].*"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="group"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + <xs:pattern value=".*[^\s].*"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + + <!-- users --> + <xs:element name="users"> + <xs:complexType> + <xs:sequence> + <xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/pom.xml deleted file mode 100644 index 9dc5d02..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-framework</artifactId> - <version>0.3.1-SNAPSHOT</version> - </parent> - <artifactId>nifi-file-identity-provider</artifactId> - <packaging>jar</packaging> - <dependencies> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-api</artifactId> - </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-properties</artifactId> - </dependency> - <dependency> - <groupId>org.apache.nifi</groupId> - <artifactId>nifi-authorized-users</artifactId> - </dependency> - </dependencies> -</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider deleted file mode 100644 index 3dc6354..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider +++ /dev/null @@ -1,15 +0,0 @@ -# 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. -org.apache.nifi.authentication.FileLoginIdentityProvider http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml index 5b4cf88..191637b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml @@ -19,9 +19,4 @@ must be specified in the nifi.properties file. --> <loginIdentityProviders> - <provider> - <identifier>file-provider</identifier> - <class>org.apache.nifi.authentication.FileLoginIdentityProvider</class> - <property name="Authenticated Users File">./conf/authorized-users.xml</property> - </provider> </loginIdentityProviders> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java index 4fb3501..ed58a01 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiSecurityConfiguration.java @@ -25,7 +25,6 @@ import org.apache.nifi.web.security.anonymous.NiFiAnonymousUserFilter; import org.apache.nifi.web.security.NiFiAuthenticationEntryPoint; import org.apache.nifi.web.security.RegistrationStatusFilter; import org.apache.nifi.web.security.login.LoginAuthenticationFilter; -import org.apache.nifi.web.security.login.RegistrationFilter; import org.apache.nifi.web.security.jwt.JwtAuthenticationFilter; import org.apache.nifi.web.security.jwt.JwtService; import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter; @@ -88,13 +87,6 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - if (loginIdentityProvider != null) { - // verify the configured login authenticator supports user login registration - if (loginIdentityProvider.supportsRegistration()) { - http.addFilterBefore(buildRegistrationFilter("/registration"), UsernamePasswordAuthenticationFilter.class); - } - } - // login authentication for /token - exchanges for JWT for subsequent API usage http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class); @@ -139,14 +131,6 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte return loginFilter; } - private Filter buildRegistrationFilter(final String url) { - final RegistrationFilter registrationFilter = new RegistrationFilter(url); - registrationFilter.setJwtService(jwtService); - registrationFilter.setLoginIdentityProvider(loginIdentityProvider); - registrationFilter.setUserService(userService); - return registrationFilter; - } - private Filter buildRegistrationStatusFilter(final String url) { final RegistrationStatusFilter registrationStatusFilter = new RegistrationStatusFilter(url); registrationStatusFilter.setCertificateExtractor(certificateExtractor); http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index b4b5188..324be87 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -2354,14 +2354,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { public LoginConfigurationDTO getLoginConfiguration() { final LoginConfigurationDTO loginConfiguration = new LoginConfigurationDTO(); - // specify whether login/registration should be supported - if (loginIdentityProvider == null) { - loginConfiguration.setSupportsLogin(false); - loginConfiguration.setSupportsRegistration(false); - } else { - loginConfiguration.setSupportsLogin(true); - loginConfiguration.setSupportsRegistration(loginIdentityProvider.supportsRegistration()); - } + // specify whether login should be supported + loginConfiguration.setSupportsLogin(loginIdentityProvider != null); return loginConfiguration; } http://git-wip-us.apache.org/repos/asf/nifi/blob/f2505604/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index 78e7d94..93f21b2 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -688,7 +688,6 @@ public class ControllerResource extends ApplicationResource { // only support login/registration when running securely loginConfig.setSupportsLogin(loginConfig.getSupportsLogin() && httpServletRequest.isSecure()); - loginConfig.setSupportsRegistration(loginConfig.getSupportsRegistration() && httpServletRequest.isSecure()); // create the revision final RevisionDTO revision = new RevisionDTO();