mirror of
https://github.com/apache/nifi.git
synced 2025-02-10 03:55:22 +00:00
NIFI-655:
- Removing registration support. - Removing file based implementation.
This commit is contained in:
parent
efa1939fc5
commit
f250560474
@ -17,7 +17,6 @@
|
|||||||
package org.apache.nifi.authentication;
|
package org.apache.nifi.authentication;
|
||||||
|
|
||||||
import org.apache.nifi.authentication.exception.IdentityAccessException;
|
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.ProviderCreationException;
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||||
|
|
||||||
@ -26,25 +25,12 @@ import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
|||||||
*/
|
*/
|
||||||
public interface LoginIdentityProvider {
|
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.
|
* Authenticates the specified login credentials.
|
||||||
*
|
*
|
||||||
* @param credentials the 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;
|
boolean authenticate(LoginCredentials credentials) throws IdentityAccessException;
|
||||||
|
|
||||||
@ -52,6 +38,7 @@ public interface LoginIdentityProvider {
|
|||||||
* Called immediately after instance creation for implementers to perform additional setup
|
* Called immediately after instance creation for implementers to perform additional setup
|
||||||
*
|
*
|
||||||
* @param initializationContext in which to initialize
|
* @param initializationContext in which to initialize
|
||||||
|
* @throws ProviderCreationException Unable to initialize
|
||||||
*/
|
*/
|
||||||
void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException;
|
void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException;
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -35,10 +35,6 @@
|
|||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-file-authorization-provider</artifactId>
|
<artifactId>nifi-file-authorization-provider</artifactId>
|
||||||
</dependency>
|
</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 -->
|
<!-- mark these nifi artifacts as provided since it is included in the lib -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -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>
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,7 +26,6 @@ import javax.xml.bind.annotation.XmlType;
|
|||||||
public class LoginConfigurationDTO {
|
public class LoginConfigurationDTO {
|
||||||
|
|
||||||
private Boolean supportsLogin;
|
private Boolean supportsLogin;
|
||||||
private Boolean supportsRegistration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Indicates whether or not this NiFi supports user login.
|
* @return Indicates whether or not this NiFi supports user login.
|
||||||
@ -42,19 +41,4 @@ public class LoginConfigurationDTO {
|
|||||||
public void setSupportsLogin(Boolean supportsLogin) {
|
public void setSupportsLogin(Boolean supportsLogin) {
|
||||||
this.supportsLogin = 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,52 @@
|
|||||||
<version>0.3.1-SNAPSHOT</version>
|
<version>0.3.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>nifi-file-authorization-provider</artifactId>
|
<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>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-api</artifactId>
|
<artifactId>nifi-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-authorized-users</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-utils</artifactId>
|
<artifactId>nifi-utils</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
|
@ -16,34 +16,38 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.nifi.authorization;
|
package org.apache.nifi.authorization;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.Collection;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
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.annotation.AuthorityProviderContext;
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
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.ObjectFactory;
|
||||||
import org.apache.nifi.user.generated.Role;
|
import org.apache.nifi.user.generated.Role;
|
||||||
import org.apache.nifi.user.generated.User;
|
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.NiFiProperties;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides identity checks and grants authorities.
|
* Provides identity checks and grants authorities.
|
||||||
@ -51,26 +55,84 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class FileAuthorizationProvider implements AuthorityProvider {
|
public class FileAuthorizationProvider implements AuthorityProvider {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FileAuthorizationProvider.class);
|
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 NiFiProperties properties;
|
||||||
|
private File usersFile;
|
||||||
|
private File restoreUsersFile;
|
||||||
|
private Users users;
|
||||||
private final Set<String> defaultAuthorities = new HashSet<>();
|
private final Set<String> defaultAuthorities = new HashSet<>();
|
||||||
|
|
||||||
private AuthorizedUsers authorizedUsers;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
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 {
|
try {
|
||||||
// initialize the authorized users
|
final String usersFilePath = configurationContext.getProperty("Authorized Users File");
|
||||||
authorizedUsers = AuthorizedUsers.getInstance(usersFilePath, properties);
|
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
|
// attempt to load a default roles
|
||||||
final String rawDefaultAuthorities = configurationContext.getProperty("Default User 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(), ", ")));
|
StringUtils.join(invalidDefaultAuthorities, ", "), StringUtils.join(Authority.getRawAuthorities(), ", ")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException | IllegalStateException | ProviderCreationException e) {
|
} catch (IOException | ProviderCreationException | SAXException | JAXBException e) {
|
||||||
throw new ProviderCreationException(e);
|
throw new ProviderCreationException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,64 +172,67 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doesDnExist(final String dn) throws AuthorityAccessException {
|
public boolean doesDnExist(String dn) throws AuthorityAccessException {
|
||||||
if (hasDefaultRoles()) {
|
if (hasDefaultRoles()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return authorizedUsers.hasUser(new HasUserByIdentity(dn));
|
final User user = getUser(dn);
|
||||||
|
return user != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
final Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
||||||
|
|
||||||
// get the user
|
// get the user
|
||||||
final NiFiUser user = authorizedUsers.getUser(new FindUser() {
|
final User user = getUser(dn);
|
||||||
@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
|
// ensure the user was located
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
if (hasDefaultRoles()) {
|
if (hasDefaultRoles()) {
|
||||||
logger.debug(String.format("User identity not found: %s. Creating new user with default roles.", dn));
|
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)
|
// create the user (which will automatically add any default authorities)
|
||||||
addUser(dn, null);
|
addUser(dn, null);
|
||||||
|
|
||||||
// find the user that was just added
|
// get the authorities for the newly created user
|
||||||
user = byDn.findUser(users);
|
authorities.addAll(getAuthorities(dn));
|
||||||
} else {
|
} else {
|
||||||
throw new UnknownIdentityException(String.format("User identity not found: %s.", dn));
|
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// create the authorities that this user has
|
||||||
return user;
|
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;
|
return authorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAuthorities(final String dn, final Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
|
public synchronized void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
authorizedUsers.updateUser(new FindUserByIdentity(dn), new UpdateUser() {
|
// get the user
|
||||||
@Override
|
final User user = getUser(dn);
|
||||||
public void updateUser(NiFiUser user) {
|
|
||||||
// add the user authorities
|
// ensure the user was located
|
||||||
setUserAuthorities(user, authorities);
|
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
|
// clear the existing rules
|
||||||
user.getRole().clear();
|
user.getRole().clear();
|
||||||
|
|
||||||
@ -182,145 +248,186 @@ public class FileAuthorizationProvider implements AuthorityProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addUser(final String dn, final String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
public synchronized void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
||||||
authorizedUsers.createOrUpdateUser(new FindUser() {
|
final User user = getUser(dn);
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// user does not exist, will create
|
// ensure the user doesn't already exist
|
||||||
if (desiredUser == null) {
|
if (user != null) {
|
||||||
throw new UnknownIdentityException("This exception will trigger the creator to be invoked.");
|
throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn));
|
||||||
}
|
}
|
||||||
|
|
||||||
// user exists, verify its still pending
|
// create the new user
|
||||||
if (LoginUser.class.isAssignableFrom(desiredUser.getClass())) {
|
final ObjectFactory objFactory = new ObjectFactory();
|
||||||
if (((LoginUser) desiredUser).isPending()) {
|
final User newUser = objFactory.createUser();
|
||||||
return desiredUser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// user exists and account is valid... no good
|
// set the user properties
|
||||||
throw new IdentityAlreadyExistsException(String.format("User identity already exists: %s", dn));
|
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
|
// add the user
|
||||||
newUser.setDn(dn);
|
users.getUser().add(newUser);
|
||||||
newUser.setGroup(group);
|
|
||||||
|
|
||||||
// add default roles if appropriate
|
try {
|
||||||
if (hasDefaultRoles()) {
|
// save the file
|
||||||
for (final String authority : defaultAuthorities) {
|
save();
|
||||||
Role role = objFactory.createRole();
|
} catch (Exception e) {
|
||||||
role.setName(authority);
|
throw new AuthorityAccessException(e.getMessage(), e);
|
||||||
|
}
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getUsers(final Authority authority) throws AuthorityAccessException {
|
public synchronized Set<String> getUsers(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matchingUsers;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final Set<String> userSet = new HashSet<>();
|
final Set<String> userSet = new HashSet<>();
|
||||||
for (final NiFiUser user : matchingUsers) {
|
for (final User user : users.getUser()) {
|
||||||
userSet.add(authorizedUsers.getUserIdentity(user));
|
for (final Role role : user.getRole()) {
|
||||||
|
if (role.getName().equals(authority.toString())) {
|
||||||
|
userSet.add(user.getDn());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userSet;
|
return userSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void revokeUser(final String dn) throws UnknownIdentityException, AuthorityAccessException {
|
public synchronized void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
authorizedUsers.removeUser(new FindUserByIdentity(dn));
|
// 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
|
@Override
|
||||||
public void setUsersGroup(final Set<String> dns, final String group) throws UnknownIdentityException, AuthorityAccessException {
|
public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
authorizedUsers.updateUsers(new FindUsersByIdentity(dns), new UpdateUsers() {
|
final Collection<User> groupedUsers = new HashSet<>();
|
||||||
@Override
|
|
||||||
public void updateUsers(List<NiFiUser> users) {
|
// get the specified users
|
||||||
// update each user group
|
for (final String dn : dns) {
|
||||||
for (final NiFiUser user : users) {
|
// get the user
|
||||||
user.setGroup(group);
|
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
|
@Override
|
||||||
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
authorizedUsers.updateUser(new FindUserByIdentity(dn), new UpdateUser() {
|
// get the user
|
||||||
@Override
|
final User user = getUser(dn);
|
||||||
public void updateUser(NiFiUser user) {
|
|
||||||
// remove the users group
|
// ensure the user was located
|
||||||
user.setGroup(null);
|
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
|
@Override
|
||||||
public void ungroup(final String group) throws AuthorityAccessException {
|
public void ungroup(String group) throws AuthorityAccessException {
|
||||||
authorizedUsers.updateUsers(new FindUsersByGroup(group), new UpdateUsers() {
|
// get the user group
|
||||||
@Override
|
final Collection<User> userGroup = getUserGroup(group);
|
||||||
public void updateUsers(List<NiFiUser> users) {
|
|
||||||
// update each user group
|
// ensure the user group was located
|
||||||
for (final NiFiUser user : users) {
|
if (userGroup == null) {
|
||||||
user.setGroup(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
|
@Override
|
||||||
public String getGroupForUser(final String dn) throws UnknownIdentityException, AuthorityAccessException {
|
public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
final NiFiUser user = authorizedUsers.getUser(new FindUserByIdentity(dn));
|
// 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();
|
return user.getGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
||||||
authorizedUsers.removeUsers(new FindUsersByGroup(group));
|
// get the user group
|
||||||
|
final Collection<User> 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();
|
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<User> 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<User> 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
|
@AuthorityProviderContext
|
||||||
public void setNiFiProperties(NiFiProperties properties) {
|
public void setNiFiProperties(NiFiProperties properties) {
|
||||||
this.properties = 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<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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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<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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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<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.isEmpty()) {
|
|
||||||
throw new UnknownIdentityException(String.format("User group not found: %s.", group));
|
|
||||||
}
|
|
||||||
|
|
||||||
return userGroup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FindUsersByIdentity implements FindUsers {
|
|
||||||
|
|
||||||
private final Set<String> identities;
|
|
||||||
|
|
||||||
public FindUsersByIdentity(Set<String> identities) {
|
|
||||||
// ensure the group was specified
|
|
||||||
if (identities == null) {
|
|
||||||
throw new UnknownIdentityException("User identities not specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.identities = identities;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!copy.isEmpty()) {
|
|
||||||
throw new UnknownIdentityException("Unable to find users with identities: " + StringUtils.join(copy, ", "));
|
|
||||||
}
|
|
||||||
|
|
||||||
return userList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,19 @@
|
|||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:complexType name="NiFiUser">
|
<!-- user -->
|
||||||
|
<xs:complexType name="User">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/>
|
<xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
</xs:sequence>
|
</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:attribute name="group">
|
||||||
<xs:simpleType>
|
<xs:simpleType>
|
||||||
<xs:restriction base="xs:string">
|
<xs:restriction base="xs:string">
|
||||||
@ -44,53 +53,11 @@
|
|||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:complexType>
|
</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 -->
|
<!-- users -->
|
||||||
<xs:element name="users">
|
<xs:element name="users">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/>
|
<xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
<xs:element name="loginUser" type="LoginUser" minOccurs="0" maxOccurs="unbounded"/>
|
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
@ -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>
|
|
@ -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
|
|
@ -19,9 +19,4 @@
|
|||||||
must be specified in the nifi.properties file.
|
must be specified in the nifi.properties file.
|
||||||
-->
|
-->
|
||||||
<loginIdentityProviders>
|
<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>
|
</loginIdentityProviders>
|
@ -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.NiFiAuthenticationEntryPoint;
|
||||||
import org.apache.nifi.web.security.RegistrationStatusFilter;
|
import org.apache.nifi.web.security.RegistrationStatusFilter;
|
||||||
import org.apache.nifi.web.security.login.LoginAuthenticationFilter;
|
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.JwtAuthenticationFilter;
|
||||||
import org.apache.nifi.web.security.jwt.JwtService;
|
import org.apache.nifi.web.security.jwt.JwtService;
|
||||||
import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
|
import org.apache.nifi.web.security.node.NodeAuthorizedUserFilter;
|
||||||
@ -88,13 +87,6 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
|
|||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
.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
|
// login authentication for /token - exchanges for JWT for subsequent API usage
|
||||||
http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(buildLoginFilter("/token"), UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
@ -139,14 +131,6 @@ public class NiFiWebApiSecurityConfiguration extends WebSecurityConfigurerAdapte
|
|||||||
return loginFilter;
|
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) {
|
private Filter buildRegistrationStatusFilter(final String url) {
|
||||||
final RegistrationStatusFilter registrationStatusFilter = new RegistrationStatusFilter(url);
|
final RegistrationStatusFilter registrationStatusFilter = new RegistrationStatusFilter(url);
|
||||||
registrationStatusFilter.setCertificateExtractor(certificateExtractor);
|
registrationStatusFilter.setCertificateExtractor(certificateExtractor);
|
||||||
|
@ -2354,14 +2354,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||||||
public LoginConfigurationDTO getLoginConfiguration() {
|
public LoginConfigurationDTO getLoginConfiguration() {
|
||||||
final LoginConfigurationDTO loginConfiguration = new LoginConfigurationDTO();
|
final LoginConfigurationDTO loginConfiguration = new LoginConfigurationDTO();
|
||||||
|
|
||||||
// specify whether login/registration should be supported
|
// specify whether login should be supported
|
||||||
if (loginIdentityProvider == null) {
|
loginConfiguration.setSupportsLogin(loginIdentityProvider != null);
|
||||||
loginConfiguration.setSupportsLogin(false);
|
|
||||||
loginConfiguration.setSupportsRegistration(false);
|
|
||||||
} else {
|
|
||||||
loginConfiguration.setSupportsLogin(true);
|
|
||||||
loginConfiguration.setSupportsRegistration(loginIdentityProvider.supportsRegistration());
|
|
||||||
}
|
|
||||||
|
|
||||||
return loginConfiguration;
|
return loginConfiguration;
|
||||||
}
|
}
|
||||||
|
@ -688,7 +688,6 @@ public class ControllerResource extends ApplicationResource {
|
|||||||
|
|
||||||
// only support login/registration when running securely
|
// only support login/registration when running securely
|
||||||
loginConfig.setSupportsLogin(loginConfig.getSupportsLogin() && httpServletRequest.isSecure());
|
loginConfig.setSupportsLogin(loginConfig.getSupportsLogin() && httpServletRequest.isSecure());
|
||||||
loginConfig.setSupportsRegistration(loginConfig.getSupportsRegistration() && httpServletRequest.isSecure());
|
|
||||||
|
|
||||||
// create the revision
|
// create the revision
|
||||||
final RevisionDTO revision = new RevisionDTO();
|
final RevisionDTO revision = new RevisionDTO();
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -258,20 +258,6 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
|
|||||||
private LoginIdentityProvider withNarLoader(final LoginIdentityProvider baseProvider) {
|
private LoginIdentityProvider withNarLoader(final LoginIdentityProvider baseProvider) {
|
||||||
return new LoginIdentityProvider() {
|
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
|
@Override
|
||||||
public boolean authenticate(LoginCredentials credentials) {
|
public boolean authenticate(LoginCredentials credentials) {
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
<div id="login-contents-container">
|
<div id="login-contents-container">
|
||||||
<jsp:include page="/WEB-INF/partials/login/login-message.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/login-message.jsp"/>
|
||||||
<jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/login-form.jsp"/>
|
||||||
<jsp:include page="/WEB-INF/partials/login/user-registration-form.jsp"/>
|
|
||||||
<jsp:include page="/WEB-INF/partials/login/nifi-registration-form.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/nifi-registration-form.jsp"/>
|
||||||
<jsp:include page="/WEB-INF/partials/login/login-submission.jsp"/>
|
<jsp:include page="/WEB-INF/partials/login/login-submission.jsp"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,10 +27,6 @@
|
|||||||
<div class="setting-name">Password</div>
|
<div class="setting-name">Password</div>
|
||||||
<div class="setting-field">
|
<div class="setting-field">
|
||||||
<input type="password" id="password"/>
|
<input type="password" id="password"/>
|
||||||
<div id="create-account-message" class="hidden">
|
|
||||||
<div style="font-style: italic;">Don't have an account?</div>
|
|
||||||
<div><span id="create-account-link" class="link">Create one</span> to request access.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -30,10 +30,6 @@
|
|||||||
<div class="setting-field">
|
<div class="setting-field">
|
||||||
<textarea cols="30" rows="4" id="nifi-registration-justification" maxlength="500" class="setting-input"></textarea>
|
<textarea cols="30" rows="4" id="nifi-registration-justification" maxlength="500" class="setting-input"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div id="login-to-account-message" class="hidden">
|
|
||||||
<div style="font-style: italic;">Already have an account?</div>
|
|
||||||
<div style="margin-top: 2px;"><span id="login-to-account-link" class="link">Log in</span></div>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: right; color: #666; margin-top: 2px; float: right;">
|
<div style="text-align: right; color: #666; margin-top: 2px; float: right;">
|
||||||
<span id="remaining-characters"></span> characters remaining
|
<span id="remaining-characters"></span> characters remaining
|
||||||
</div>
|
</div>
|
||||||
|
@ -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" %>
|
|
||||||
<div id="user-registration-container" class="hidden">
|
|
||||||
<div class="login-title">Create Account</div>
|
|
||||||
<div class="setting">
|
|
||||||
<div class="setting-name">Username</div>
|
|
||||||
<div class="setting-field">
|
|
||||||
<input type="text" id="registration-username"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting">
|
|
||||||
<div class="setting-name">Password</div>
|
|
||||||
<div class="setting-field">
|
|
||||||
<input type="password" id="registration-password" style="margin-bottom: 5px;"/>
|
|
||||||
<br/>
|
|
||||||
<input type="password" id="registration-password-confirmation" placeholder="Confirm password"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -56,18 +56,6 @@ body.login-body input, body.login-body textarea {
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#create-account-message {
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#create-account-link {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
User Registration
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NiFi Registration
|
NiFi Registration
|
||||||
*/
|
*/
|
||||||
@ -88,15 +76,6 @@ body.login-body input, body.login-body textarea {
|
|||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#login-to-account-message {
|
|
||||||
float: left;
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#login-to-account-link {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Submission
|
Submission
|
||||||
*/
|
*/
|
||||||
|
@ -141,21 +141,15 @@ nf.CanvasHeader = (function () {
|
|||||||
nf.Shell.showPage(config.urls.helpDocument);
|
nf.Shell.showPage(config.urls.helpDocument);
|
||||||
});
|
});
|
||||||
|
|
||||||
// show the login link if supported and user is currently anonymous
|
// hide the login link if the user is already logged in
|
||||||
var isAnonymous = $('#current-user').text() === nf.Canvas.ANONYMOUS_USER_TEXT;
|
if ($('#current-user').text() !== nf.Canvas.ANONYMOUS_USER_TEXT) {
|
||||||
if (supportsLogin === true && isAnonymous) {
|
|
||||||
// login link
|
|
||||||
$('#login-link').click(function () {
|
|
||||||
nf.Shell.showPage('login', false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#login-link-container').css('display', 'none');
|
$('#login-link-container').css('display', 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
// if login is not supported, don't show the current user
|
// login link
|
||||||
if (supportsLogin !== true) {
|
$('#login-link').click(function () {
|
||||||
$('#current-user-container').css('display', 'none');
|
nf.Shell.showPage('login', false);
|
||||||
}
|
});
|
||||||
|
|
||||||
// logout link
|
// logout link
|
||||||
$('#logout-link').click(function () {
|
$('#logout-link').click(function () {
|
||||||
|
@ -1087,13 +1087,6 @@ nf.Canvas = (function () {
|
|||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
});
|
});
|
||||||
|
|
||||||
// get the login config
|
|
||||||
var loginXhr = $.ajax({
|
|
||||||
type: 'GET',
|
|
||||||
url: config.urls.loginConfig,
|
|
||||||
dataType: 'json'
|
|
||||||
});
|
|
||||||
|
|
||||||
// create the deferred cluster request
|
// create the deferred cluster request
|
||||||
var isClusteredRequest = $.Deferred(function (deferred) {
|
var isClusteredRequest = $.Deferred(function (deferred) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -1113,9 +1106,8 @@ nf.Canvas = (function () {
|
|||||||
}).promise();
|
}).promise();
|
||||||
|
|
||||||
// ensure the config requests are loaded
|
// 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 configResponse = configResult[0];
|
||||||
var loginResponse = loginResult[0];
|
|
||||||
|
|
||||||
// calculate the canvas offset
|
// calculate the canvas offset
|
||||||
var canvasContainer = $('#canvas-container');
|
var canvasContainer = $('#canvas-container');
|
||||||
@ -1123,7 +1115,6 @@ nf.Canvas = (function () {
|
|||||||
|
|
||||||
// get the config details
|
// get the config details
|
||||||
var configDetails = configResponse.config;
|
var configDetails = configResponse.config;
|
||||||
var loginDetails = loginResponse.config;
|
|
||||||
|
|
||||||
// when both request complete, load the application
|
// when both request complete, load the application
|
||||||
isClusteredRequest.done(function () {
|
isClusteredRequest.done(function () {
|
||||||
@ -1143,7 +1134,7 @@ nf.Canvas = (function () {
|
|||||||
nf.ContextMenu.init();
|
nf.ContextMenu.init();
|
||||||
nf.CanvasToolbar.init();
|
nf.CanvasToolbar.init();
|
||||||
nf.CanvasToolbox.init();
|
nf.CanvasToolbox.init();
|
||||||
nf.CanvasHeader.init(loginDetails.supportsLogin);
|
nf.CanvasHeader.init();
|
||||||
nf.GraphControl.init();
|
nf.GraphControl.init();
|
||||||
nf.Search.init();
|
nf.Search.init();
|
||||||
nf.Settings.init();
|
nf.Settings.init();
|
||||||
|
@ -40,20 +40,7 @@ nf.Login = (function () {
|
|||||||
$('#login-message-container').show();
|
$('#login-message-container').show();
|
||||||
};
|
};
|
||||||
|
|
||||||
var initializeLogin = function (supportsRegistration) {
|
var initializeLogin = function () {
|
||||||
// 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 showLogin = function () {
|
var showLogin = function () {
|
||||||
@ -82,7 +69,6 @@ nf.Login = (function () {
|
|||||||
|
|
||||||
$('div.nifi-submit-justification').hide();
|
$('div.nifi-submit-justification').hide();
|
||||||
$('#user-registration-container').show();
|
$('#user-registration-container').show();
|
||||||
$('#login-to-account-message').show();
|
|
||||||
$('#login-submission-button').text('Create');
|
$('#login-submission-button').text('Create');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -416,7 +402,7 @@ nf.Login = (function () {
|
|||||||
if (showMessage === true) {
|
if (showMessage === true) {
|
||||||
initializeMessage();
|
initializeMessage();
|
||||||
} else if (needsLogin === true) {
|
} else if (needsLogin === true) {
|
||||||
initializeLogin(loginConfig.supportsRegistration);
|
initializeLogin();
|
||||||
showLogin();
|
showLogin();
|
||||||
} else if (needsNiFiRegistration === true) {
|
} else if (needsNiFiRegistration === true) {
|
||||||
initializeNiFiRegistration();
|
initializeNiFiRegistration();
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
<module>nifi-web</module>
|
<module>nifi-web</module>
|
||||||
<module>nifi-resources</module>
|
<module>nifi-resources</module>
|
||||||
<module>nifi-documentation</module>
|
<module>nifi-documentation</module>
|
||||||
<module>nifi-authorized-users</module>
|
|
||||||
<module>nifi-file-identity-provider</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -43,11 +43,6 @@
|
|||||||
<artifactId>nifi-file-authorization-provider</artifactId>
|
<artifactId>nifi-file-authorization-provider</artifactId>
|
||||||
<version>0.3.1-SNAPSHOT</version>
|
<version>0.3.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-file-identity-provider</artifactId>
|
|
||||||
<version>0.3.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-cluster-authorization-provider</artifactId>
|
<artifactId>nifi-cluster-authorization-provider</artifactId>
|
||||||
@ -63,11 +58,6 @@
|
|||||||
<artifactId>nifi-runtime</artifactId>
|
<artifactId>nifi-runtime</artifactId>
|
||||||
<version>0.3.1-SNAPSHOT</version>
|
<version>0.3.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-authorized-users</artifactId>
|
|
||||||
<version>0.3.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-client-dto</artifactId>
|
<artifactId>nifi-client-dto</artifactId>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user