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 290b6945ba..95f2efae8a 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; @@ -26,25 +25,12 @@ 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; 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 4b80c619d6..0000000000 --- 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); - } - -} 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 3773ac7330..fcfcfe75cd 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 @@ org.apache.nifi nifi-file-authorization-provider - - org.apache.nifi - nifi-file-identity-provider - 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 6ec82361da..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - 4.0.0 - - org.apache.nifi - nifi-framework - 0.3.1-SNAPSHOT - - nifi-authorized-users - - - - src/main/resources - - - src/main/xsd - - - - - org.codehaus.mojo - jaxb2-maven-plugin - - - xjc - - xjc - - - org.apache.nifi.user.generated - - - - - ${project.build.directory}/generated-sources/jaxb - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - **/user/generated/*.java - - - - - - - org.apache.nifi - nifi-api - - - org.apache.nifi - nifi-properties - - - org.apache.nifi - nifi-utils - - - \ No newline at end of file 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 abdd48e844..0000000000 --- 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 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 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 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 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 getUsers(final FindUsers finder) { - // load the users - final Users users = getUsers(); - - // combine the user lists - final List 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 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 nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - final List 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 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 nifiUsers = new ArrayList<>(); - nifiUsers.addAll(users.getUser()); - nifiUsers.addAll(users.getLoginUser()); - - // find the desired user - final List 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 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 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 findUsers(List 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 users); - } -} 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 e4452c0f60..60f644bbaf 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; - } } 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 50fa105d66..d014262e08 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,19 +21,52 @@ 0.3.1-SNAPSHOT nifi-file-authorization-provider + + + + src/main/resources + + + src/main/xsd + + + + + org.codehaus.mojo + jaxb2-maven-plugin + + + xjc + + xjc + + + org.apache.nifi.user.generated + + + + + ${project.build.directory}/generated-sources/jaxb + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + **/user/generated/*.java + + + + + org.apache.nifi nifi-api - - org.apache.nifi - nifi-authorized-users - org.apache.nifi nifi-utils - test org.apache.nifi 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 3400ce8d86..9c2cad5fdb 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 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 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 getAuthorities(final String dn) throws UnknownIdentityException, AuthorityAccessException { + public synchronized Set getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException { final Set authorities = EnumSet.noneOf(Authority.class); // get the user - final NiFiUser user = authorizedUsers.getUser(new FindUser() { - @Override - public NiFiUser findUser(List users) { - final FindUser byDn = new FindUserByIdentity(dn); - NiFiUser user = byDn.findUser(users); + final User user = getUser(dn); - // 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)); + // 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 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)); - } - } - - return user; + // 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())); } - }); - - // 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 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 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 authorities) { + private void setUserAuthorities(final User user, final Set authorities) { // clear the existing rules user.getRole().clear(); @@ -182,145 +248,186 @@ 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 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)); + // 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 the role + newUser.getRole().add(role); } - }, 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); + // add the user + users.getUser().add(newUser); - // 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); - } - } - - 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 getUsers(final Authority authority) throws AuthorityAccessException { - final List matchingUsers = authorizedUsers.getUsers(new FindUsers() { - @Override - public List findUsers(List users) throws UnknownIdentityException { - final List matchingUsers = new ArrayList<>(); - for (final NiFiUser user : users) { - for (final Role role : user.getRole()) { - if (role.getName().equals(authority.toString())) { - matchingUsers.add(user); - } - } - } - return matchingUsers; - } - }); - + public synchronized Set getUsers(Authority authority) throws AuthorityAccessException { final Set userSet = new HashSet<>(); - for (final NiFiUser user : matchingUsers) { - userSet.add(authorizedUsers.getUserIdentity(user)); + for (final User user : users.getUser()) { + for (final Role role : user.getRole()) { + if (role.getName().equals(authority.toString())) { + userSet.add(user.getDn()); + } + } } - return userSet; } @Override - public void revokeUser(final String dn) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.removeUser(new FindUserByIdentity(dn)); + public synchronized void revokeUser(String dn) 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)); + } + + // remove the specified user + users.getUser().remove(user); + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @Override - public void setUsersGroup(final Set dns, final String group) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.updateUsers(new FindUsersByIdentity(dns), new UpdateUsers() { - @Override - public void updateUsers(List users) { - // update each user group - for (final NiFiUser user : users) { - user.setGroup(group); - } + public void setUsersGroup(Set dns, String group) throws UnknownIdentityException, AuthorityAccessException { + final Collection groupedUsers = new HashSet<>(); + + // get the specified users + for (final String dn : dns) { + // 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)); } - }); + + groupedUsers.add(user); + } + + // update each user group + for (final User user : groupedUsers) { + user.setGroup(group); + } + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @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); - } - }); + // 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)); + } + + // remove the users group + user.setGroup(null); + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @Override - public void ungroup(final String group) throws AuthorityAccessException { - authorizedUsers.updateUsers(new FindUsersByGroup(group), new UpdateUsers() { - @Override - public void updateUsers(List users) { - // update each user group - for (final NiFiUser user : users) { - user.setGroup(null); - } - } - }); + public void ungroup(String group) throws AuthorityAccessException { + // get the user group + final Collection userGroup = getUserGroup(group); + + // ensure the user group was located + if (userGroup == null) { + return; + } + + // update each user group + for (final User user : userGroup) { + user.setGroup(null); + } + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } @Override - public String getGroupForUser(final String dn) throws UnknownIdentityException, AuthorityAccessException { - final NiFiUser user = authorizedUsers.getUser(new FindUserByIdentity(dn)); + public String getGroupForUser(String dn) 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)); + } + return user.getGroup(); } @Override public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException { - authorizedUsers.removeUsers(new FindUsersByGroup(group)); + // get the user group + final Collection userGroup = getUserGroup(group); + + // ensure the user group was located + if (userGroup == null) { + 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); + } + + try { + // save the file + save(); + } catch (Exception e) { + throw new AuthorityAccessException(e.getMessage(), e); + } } /** @@ -331,143 +438,59 @@ public class FileAuthorizationProvider implements AuthorityProvider { return DownloadAuthorization.approved(); } + private User getUser(String dn) throws UnknownIdentityException { + // ensure the DN was specified + if (dn == null) { + throw new UnknownIdentityException("User DN 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; + } + + private Collection getUserGroup(String group) throws UnknownIdentityException { + // ensure the DN was specified + if (group == null) { + throw new UnknownIdentityException("User group not specified."); + } + + // get all users with this group + Collection userGroup = null; + for (final User user : users.getUser()) { + if (group.equals(user.getGroup())) { + if (userGroup == null) { + userGroup = new HashSet<>(); + } + userGroup.add(user); + } + } + + return userGroup; + } + + 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; } - - private boolean isPendingLoginUser(final NiFiUser user) { - if (LoginUser.class.isAssignableFrom(user.getClass())) { - return ((LoginUser) user).isPending(); - } - return false; - } - - public class HasUserByIdentity implements HasUser { - - private final String identity; - - public HasUserByIdentity(String identity) { - // ensure the identity was specified - if (identity == null) { - throw new UnknownIdentityException("User identity not specified."); - } - - this.identity = identity; - } - - @Override - public boolean hasUser(List 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; - } - } - - return desiredUser != null; - } - } - - 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."); - } - - this.identity = identity; - } - - @Override - public NiFiUser findUser(List 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)); - } - - return desiredUser; - } - } - - public class FindUsersByGroup implements FindUsers { - - private final String group; - - public FindUsersByGroup(String group) { - // ensure the group was specified - if (group == null) { - throw new UnknownIdentityException("User group not specified."); - } - - this.group = group; - } - - @Override - public List findUsers(List users) throws UnknownIdentityException { - // get all users with this group - List 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.isEmpty()) { - throw new UnknownIdentityException(String.format("User group not found: %s.", group)); - } - - return userGroup; - } - } - - public class FindUsersByIdentity implements FindUsers { - - private final Set identities; - - public FindUsersByIdentity(Set identities) { - // ensure the group was specified - if (identities == null) { - throw new UnknownIdentityException("User identities not specified."); - } - - this.identities = identities; - } - - @Override - public List findUsers(List users) throws UnknownIdentityException { - final Set copy = new HashSet<>(identities); - - // get all users with this group - List 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); - } - } - - if (!copy.isEmpty()) { - throw new UnknownIdentityException("Unable to find users with identities: " + StringUtils.join(copy, ", ")); - } - - return userList; - } - } - } 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-file-authorization-provider/src/main/xsd/users.xsd similarity index 56% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorized-users/src/main/xsd/users.xsd rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/src/main/xsd/users.xsd index 509f97bc0b..4ee1e17226 100644 --- 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-file-authorization-provider/src/main/xsd/users.xsd @@ -30,10 +30,19 @@ - + + + + + + + + + + @@ -44,53 +53,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 9dc5d0234a..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-identity-provider/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - 4.0.0 - - org.apache.nifi - nifi-framework - 0.3.1-SNAPSHOT - - nifi-file-identity-provider - jar - - - org.apache.nifi - nifi-api - - - org.apache.nifi - nifi-properties - - - org.apache.nifi - nifi-authorized-users - - - \ No newline at end of file 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 3dc6354afa..0000000000 --- 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 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 5b4cf883a2..191637b785 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. --> - - file-provider - org.apache.nifi.authentication.FileLoginIdentityProvider - ./conf/authorized-users.xml - \ No newline at end of file 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 4fb35014f2..ed58a0198e 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); 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 b4b5188c6d..324be87efb 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; } 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 78e7d94cb3..93f21b2e6b 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(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/RegistrationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/RegistrationFilter.java deleted file mode 100644 index 8a3f02e281..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/RegistrationFilter.java +++ /dev/null @@ -1,163 +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.web.security.login; - -import java.io.IOException; -import java.io.PrintWriter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.nifi.admin.service.AccountDisabledException; -import org.apache.nifi.admin.service.AccountNotFoundException; -import org.apache.nifi.admin.service.AccountPendingException; -import org.apache.nifi.admin.service.AdministrationException; -import org.apache.nifi.admin.service.UserService; -import org.apache.nifi.authentication.LoginCredentials; -import org.apache.nifi.authentication.LoginIdentityProvider; -import org.apache.nifi.authentication.exception.IdentityAccessException; -import org.apache.nifi.authentication.exception.IdentityRegistrationException; -import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException; -import org.apache.nifi.util.StringUtils; -import org.apache.nifi.web.security.jwt.JwtService; -import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.authentication.AccountStatusException; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; - -/** - * Exchanges a successful login with the configured provider for a ID token for accessing the API. - */ -public class RegistrationFilter extends AbstractAuthenticationProcessingFilter { - - private static final Logger logger = LoggerFactory.getLogger(RegistrationFilter.class); - - private LoginIdentityProvider loginIdentityProvider; - private JwtService jwtService; - private UserService userService; - - public RegistrationFilter(final String defaultFilterProcessesUrl) { - super(defaultFilterProcessesUrl); - - // do not continue filter chain... simply exchanging authentication for token - setContinueChainBeforeSuccessfulAuthentication(false); - } - - @Override - public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticationException, IOException, ServletException { - // only suppport registration when running securely - if (!request.isSecure()) { - return null; - } - - // look for the credentials in the request - final LoginCredentials credentials = getLoginCredentials(request); - - // if the credentials were not part of the request, attempt to log in with the certificate in the request - if (credentials == null) { - throw new UsernameNotFoundException("User login credentials not found in request."); - } else { - try { - // attempt to register the user - loginIdentityProvider.register(credentials); - } catch (final IdentityAlreadyExistsException iaee) { - // if the identity already exists, try to create the nifi account request - } catch (final IdentityRegistrationException ire) { - // the credentials are not acceptable for some reason - throw new BadCredentialsException(ire.getMessage(), ire); - } catch (final IdentityAccessException iae) { - throw new AuthenticationServiceException(iae.getMessage(), iae); - } - - try { - // see if the account already exists so we're able to return the current status - userService.checkAuthorization(credentials.getUsername()); - - // account exists and is valid - throw new AccountStatusException(String.format("An account for %s already exists.", credentials.getUsername())) { - }; - } catch (AdministrationException ase) { - throw new AuthenticationServiceException(ase.getMessage(), ase); - } catch (AccountDisabledException | AccountPendingException e) { - throw new AccountStatusException(e.getMessage(), e) { - }; - } catch (AccountNotFoundException anfe) { - // create the pending user account - userService.createPendingUserAccount(credentials.getUsername(), request.getParameter("justification")); - - // create the login token - return new LoginAuthenticationToken(credentials); - } - } - } - - private LoginCredentials getLoginCredentials(HttpServletRequest request) { - final String username = request.getParameter("username"); - final String password = request.getParameter("password"); - - if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { - return null; - } else { - return new LoginCredentials(username, password); - } - } - - @Override - protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain, final Authentication authentication) - throws IOException, ServletException { - - // generate JWT for response - jwtService.addToken(response, authentication); - } - - @Override - protected void unsuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException failed) throws IOException, ServletException { - response.setContentType("text/plain"); - - final PrintWriter out = response.getWriter(); - out.println(failed.getMessage()); - - // set the appropriate response status - if (failed instanceof UsernameNotFoundException || failed instanceof BadCredentialsException) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - } else if (failed instanceof AccountStatusException) { - // account exists (maybe valid, pending, revoked) - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - } else { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - - public void setJwtService(JwtService jwtService) { - this.jwtService = jwtService; - } - - public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) { - this.loginIdentityProvider = loginIdentityProvider; - } - - public void setUserService(UserService userService) { - this.userService = userService; - } - -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java index 9a51e85ea7..27e94575a4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java @@ -258,20 +258,6 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable private LoginIdentityProvider withNarLoader(final LoginIdentityProvider baseProvider) { return new LoginIdentityProvider() { - @Override - public boolean supportsRegistration() { - try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { - return baseProvider.supportsRegistration(); - } - } - - @Override - public void register(LoginCredentials credentials) { - try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { - baseProvider.register(credentials); - } - } - @Override public boolean authenticate(LoginCredentials credentials) { try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp index a4967b1f3e..da2ae00f03 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/login.jsp @@ -43,7 +43,6 @@
-
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp index 8480501faa..f8f06f3e3e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/login-form.jsp @@ -27,10 +27,6 @@
Password
-
\ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp index 101119c2fa..f1b73c099c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/nifi-registration-form.jsp @@ -30,10 +30,6 @@
-
 characters remaining
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp deleted file mode 100644 index 7930e39d1a..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/login/user-registration-form.jsp +++ /dev/null @@ -1,34 +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. ---%> -<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> - \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css index f055d1a5fc..62f6118c8f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/login.css @@ -56,18 +56,6 @@ body.login-body input, body.login-body textarea { width: 400px; } -#create-account-message { - margin-top: 2px; -} - -#create-account-link { - text-decoration: underline; -} - -/* - User Registration -*/ - /* NiFi Registration */ @@ -88,15 +76,6 @@ body.login-body input, body.login-body textarea { height: 200px; } -#login-to-account-message { - float: left; - margin-top: 2px; -} - -#login-to-account-link { - text-decoration: underline; -} - /* Submission */ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js index 9e7bce1c70..62b576488b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js @@ -141,21 +141,15 @@ nf.CanvasHeader = (function () { nf.Shell.showPage(config.urls.helpDocument); }); - // show the login link if supported and user is currently anonymous - var isAnonymous = $('#current-user').text() === nf.Canvas.ANONYMOUS_USER_TEXT; - if (supportsLogin === true && isAnonymous) { - // login link - $('#login-link').click(function () { - nf.Shell.showPage('login', false); - }); - } else { + // hide the login link if the user is already logged in + if ($('#current-user').text() !== nf.Canvas.ANONYMOUS_USER_TEXT) { $('#login-link-container').css('display', 'none'); } - // if login is not supported, don't show the current user - if (supportsLogin !== true) { - $('#current-user-container').css('display', 'none'); - } + // login link + $('#login-link').click(function () { + nf.Shell.showPage('login', false); + }); // logout link $('#logout-link').click(function () { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js index c316ef28dd..5d7efcbaad 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js @@ -1087,13 +1087,6 @@ nf.Canvas = (function () { dataType: 'json' }); - // get the login config - var loginXhr = $.ajax({ - type: 'GET', - url: config.urls.loginConfig, - dataType: 'json' - }); - // create the deferred cluster request var isClusteredRequest = $.Deferred(function (deferred) { $.ajax({ @@ -1113,9 +1106,8 @@ nf.Canvas = (function () { }).promise(); // ensure the config requests are loaded - $.when(configXhr, loginXhr, userXhr).done(function (configResult, loginResult) { + $.when(configXhr, userXhr).done(function (configResult) { var configResponse = configResult[0]; - var loginResponse = loginResult[0]; // calculate the canvas offset var canvasContainer = $('#canvas-container'); @@ -1123,7 +1115,6 @@ nf.Canvas = (function () { // get the config details var configDetails = configResponse.config; - var loginDetails = loginResponse.config; // when both request complete, load the application isClusteredRequest.done(function () { @@ -1143,7 +1134,7 @@ nf.Canvas = (function () { nf.ContextMenu.init(); nf.CanvasToolbar.init(); nf.CanvasToolbox.init(); - nf.CanvasHeader.init(loginDetails.supportsLogin); + nf.CanvasHeader.init(); nf.GraphControl.init(); nf.Search.init(); nf.Settings.init(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js index 88156ef541..2da60e3619 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js @@ -40,20 +40,7 @@ nf.Login = (function () { $('#login-message-container').show(); }; - var initializeLogin = function (supportsRegistration) { - // if this nifi supports registration, render the registration form - if (supportsRegistration === true) { - initializeUserRegistration(); - initializeNiFiRegistration(); - - // show the create account message - $('#create-account-message').show(); - - // toggle between login and signup - $('#create-account-link').on('click', function () { - showUserRegistration(); - }); - } + var initializeLogin = function () { }; var showLogin = function () { @@ -82,7 +69,6 @@ nf.Login = (function () { $('div.nifi-submit-justification').hide(); $('#user-registration-container').show(); - $('#login-to-account-message').show(); $('#login-submission-button').text('Create'); }; @@ -416,7 +402,7 @@ nf.Login = (function () { if (showMessage === true) { initializeMessage(); } else if (needsLogin === true) { - initializeLogin(loginConfig.supportsRegistration); + initializeLogin(); showLogin(); } else if (needsNiFiRegistration === true) { initializeNiFiRegistration(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml index 6709e84151..b6f3f9c93e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml @@ -40,8 +40,6 @@ nifi-web nifi-resources nifi-documentation - nifi-authorized-users - nifi-file-identity-provider diff --git a/nifi-nar-bundles/nifi-framework-bundle/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/pom.xml index a81a832372..f78e497cb0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/pom.xml @@ -43,11 +43,6 @@ nifi-file-authorization-provider 0.3.1-SNAPSHOT - - org.apache.nifi - nifi-file-identity-provider - 0.3.1-SNAPSHOT - org.apache.nifi nifi-cluster-authorization-provider @@ -63,11 +58,6 @@ nifi-runtime 0.3.1-SNAPSHOT - - org.apache.nifi - nifi-authorized-users - 0.3.1-SNAPSHOT - org.apache.nifi nifi-client-dto