mirror of https://github.com/apache/nifi.git
NIFI-1551:
- Removing the AuthorityProvider. - Refactoring REST API in preparation for introduction of the Authorizer. - Updating UI accordingly. - Removing unneeded properties from nifi.properties. - Addressing comments from PR. - This closes #359.
This commit is contained in:
parent
7db78e87a5
commit
153f63ef43
|
@ -18,8 +18,8 @@ package org.apache.nifi.authentication;
|
||||||
|
|
||||||
import org.apache.nifi.authentication.exception.IdentityAccessException;
|
import org.apache.nifi.authentication.exception.IdentityAccessException;
|
||||||
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
|
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identity provider that is able to authentication a user with username/password credentials.
|
* Identity provider that is able to authentication a user with username/password credentials.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.authorization.exception;
|
package org.apache.nifi.authentication.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the exceptional case when an AuthorityProvider fails instantiated.
|
* Represents the exceptional case when an AuthorityProvider fails instantiated.
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.authorization.exception;
|
package org.apache.nifi.authentication.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the exceptional case when an AuthorityProvider fails destruction.
|
* Represents the exceptional case when an AuthorityProvider fails destruction.
|
|
@ -1,93 +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.authorization;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorities that can be assigned to NiFi users.
|
|
||||||
*/
|
|
||||||
public enum Authority {
|
|
||||||
|
|
||||||
ROLE_MONITOR,
|
|
||||||
ROLE_DFM,
|
|
||||||
ROLE_ADMIN,
|
|
||||||
ROLE_PROVENANCE,
|
|
||||||
ROLE_PROXY,
|
|
||||||
ROLE_NIFI;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param rawAuthority string form of authority
|
|
||||||
* @return the matching role or null if the specified role does not match
|
|
||||||
* any roles
|
|
||||||
*/
|
|
||||||
public static Authority valueOfAuthority(String rawAuthority) {
|
|
||||||
Authority desiredAuthority = null;
|
|
||||||
|
|
||||||
for (Authority authority : values()) {
|
|
||||||
if (authority.toString().equals(rawAuthority)) {
|
|
||||||
desiredAuthority = authority;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return desiredAuthority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the string value of each authority
|
|
||||||
*/
|
|
||||||
public static Set<String> getRawAuthorities() {
|
|
||||||
Set<String> authorities = new LinkedHashSet<>();
|
|
||||||
for (Authority authority : values()) {
|
|
||||||
authorities.add(authority.toString());
|
|
||||||
}
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<String> convertAuthorities(Set<Authority> authorities) {
|
|
||||||
if (authorities == null) {
|
|
||||||
throw new IllegalArgumentException("No authorities have been specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the set
|
|
||||||
Set<String> rawAuthorities = new HashSet<>(authorities.size());
|
|
||||||
for (Authority authority : authorities) {
|
|
||||||
rawAuthorities.add(authority.toString());
|
|
||||||
}
|
|
||||||
return rawAuthorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EnumSet<Authority> convertRawAuthorities(Set<String> rawAuthorities) {
|
|
||||||
if (rawAuthorities == null) {
|
|
||||||
throw new IllegalArgumentException("No authorities have been specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the set
|
|
||||||
EnumSet<Authority> authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
for (String rawAuthority : rawAuthorities) {
|
|
||||||
Authority authority = Authority.valueOfAuthority(rawAuthority);
|
|
||||||
if (authority != null) {
|
|
||||||
authorities.add(authority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,182 +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.authorization;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class allows clients to retrieve the authorities for a given DN.
|
|
||||||
*/
|
|
||||||
public interface AuthorityProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @return whether the user with the specified identity is known to this authority
|
|
||||||
* provider. It is not necessary for the user to have any authorities
|
|
||||||
*/
|
|
||||||
boolean doesDnExist(String identity) throws AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the authorities for the specified user. If the specified user exists
|
|
||||||
* but does not have any authorities, an empty set should be returned.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @return the authorities for the specified user. If the specified user
|
|
||||||
* exists but does not have any authorities, an empty set should be returned
|
|
||||||
* @throws UnknownIdentityException if identity is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access authorities
|
|
||||||
*/
|
|
||||||
Set<Authority> getAuthorities(String identity) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the specified authorities for the specified user.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @param authorities the new authorities for the user
|
|
||||||
* @throws UnknownIdentityException if identity is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access authorities
|
|
||||||
*/
|
|
||||||
void setAuthorities(String identity, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the users for the specified authority.
|
|
||||||
*
|
|
||||||
* @param authority for which to determine membership of
|
|
||||||
* @return all users with the specified authority
|
|
||||||
* @throws AuthorityAccessException if unable to access authorities
|
|
||||||
*/
|
|
||||||
Set<String> getUsers(Authority authority) throws AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revokes the specified user. Its up to the implementor to determine the
|
|
||||||
* semantics of revocation.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void revokeUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the specified user.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @param group Optional
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void addUser(String identity, String group) throws IdentityAlreadyExistsException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the group for the specified user. Return null if the user does not
|
|
||||||
* belong to a group.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @return the group of the given user
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
String getGroupForUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revokes all users for a specified group. Its up to the implementor to
|
|
||||||
* determine the semantics of revocation.
|
|
||||||
*
|
|
||||||
* @param group to revoke the users of
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the specified users to the specified group.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @param group to add users to
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void setUsersGroup(Set<String> identity, String group) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ungroups the specified user.
|
|
||||||
*
|
|
||||||
* @param identity of the user. The identity may be a dn, an email, a username, or any string that identities the user.
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void ungroupUser(String identity) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ungroups the specified group. Since the semantics of revocation is up to
|
|
||||||
* the implementor, this method should do nothing if the specified group
|
|
||||||
* does not exist. If an admin revoked this group before calling ungroup, it
|
|
||||||
* may or may not exist.
|
|
||||||
*
|
|
||||||
* @param group to ungroup
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
void ungroup(String group) throws AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the user in the specified dnChain should be able to
|
|
||||||
* download the content for the flowfile with the specified attributes.
|
|
||||||
*
|
|
||||||
* The first identity in the chain is the end user that the request was issued on
|
|
||||||
* behalf of. The subsequent identities in the chain represent entities proxying
|
|
||||||
* the user's request with the last being the proxy that sent the current
|
|
||||||
* request.
|
|
||||||
*
|
|
||||||
* @param proxyChain proxy chain of user identities that for the download request
|
|
||||||
* @param attributes of the flowfile being requested
|
|
||||||
* @return the authorization result
|
|
||||||
* @throws UnknownIdentityException if the user is not known
|
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
|
||||||
*/
|
|
||||||
DownloadAuthorization authorizeDownload(List<String> proxyChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called immediately after instance creation for implementers to perform
|
|
||||||
* additional setup
|
|
||||||
*
|
|
||||||
* @param initializationContext in which to initialize
|
|
||||||
*/
|
|
||||||
void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to configure the AuthorityProvider.
|
|
||||||
*
|
|
||||||
* @param configurationContext at the time of configuration
|
|
||||||
* @throws ProviderCreationException for any issues configuring the provider
|
|
||||||
*/
|
|
||||||
void onConfigured(AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called immediately before instance destruction for implementers to
|
|
||||||
* release resources.
|
|
||||||
*
|
|
||||||
* @throws ProviderDestructionException If pre-destruction fails.
|
|
||||||
*/
|
|
||||||
void preDestruction() throws ProviderDestructionException;
|
|
||||||
}
|
|
|
@ -1,48 +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.authorization;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface AuthorityProviderConfigurationContext {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return identifier for the authority provider
|
|
||||||
*/
|
|
||||||
String getIdentifier();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves all properties the component currently understands regardless
|
|
||||||
* of whether a value has been set for them or not. If no value is present
|
|
||||||
* then its value is null and thus any registered default for the property
|
|
||||||
* descriptor applies.
|
|
||||||
*
|
|
||||||
* @return Map of all properties
|
|
||||||
*/
|
|
||||||
Map<String, String> getProperties();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param property to lookup the descriptor and value of
|
|
||||||
* @return the value the component currently understands for the given
|
|
||||||
* PropertyDescriptor. This method does not substitute default
|
|
||||||
* PropertyDescriptor values, so the value returned will be null if not set
|
|
||||||
*/
|
|
||||||
String getProperty(String property);
|
|
||||||
}
|
|
|
@ -1,27 +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.authorization;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface AuthorityProviderInitializationContext {
|
|
||||||
|
|
||||||
public String getIdentifier();
|
|
||||||
|
|
||||||
public AuthorityProviderLookup getAuthorityProviderLookup();
|
|
||||||
}
|
|
|
@ -1,25 +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.authorization;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface AuthorityProviderLookup {
|
|
||||||
|
|
||||||
AuthorityProvider getAuthorityProvider(String identifier);
|
|
||||||
}
|
|
|
@ -29,17 +29,22 @@ public class AuthorizationRequest {
|
||||||
private final Resource resource;
|
private final Resource resource;
|
||||||
private final String identity;
|
private final String identity;
|
||||||
private final RequestAction action;
|
private final RequestAction action;
|
||||||
|
private final boolean isAccessAttempt;
|
||||||
|
private final boolean isAnonymous;
|
||||||
private final Map<String, String> context;
|
private final Map<String, String> context;
|
||||||
private final Map<String, String> eventAttributes;
|
private final Map<String, String> eventAttributes;
|
||||||
|
|
||||||
private AuthorizationRequest(final Builder builder) {
|
private AuthorizationRequest(final Builder builder) {
|
||||||
Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
|
Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
|
||||||
Objects.requireNonNull(builder.identity, "The identity of the user is required when creating an authorization request");
|
|
||||||
Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
|
Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
|
||||||
|
Objects.requireNonNull(builder.isAccessAttempt, "Whether this request is an access attempt is request");
|
||||||
|
Objects.requireNonNull(builder.isAnonymous, "Whether this request is being performed by an anonymous user is required");
|
||||||
|
|
||||||
this.resource = builder.resource;
|
this.resource = builder.resource;
|
||||||
this.identity = builder.identity;
|
this.identity = builder.identity;
|
||||||
this.action = builder.action;
|
this.action = builder.action;
|
||||||
|
this.isAccessAttempt = builder.isAccessAttempt;
|
||||||
|
this.isAnonymous = builder.isAnonymous;
|
||||||
this.context = builder.context == null ? null : Collections.unmodifiableMap(builder.context);
|
this.context = builder.context == null ? null : Collections.unmodifiableMap(builder.context);
|
||||||
this.eventAttributes = builder.context == null ? null : Collections.unmodifiableMap(builder.eventAttributes);
|
this.eventAttributes = builder.context == null ? null : Collections.unmodifiableMap(builder.eventAttributes);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +59,7 @@ public class AuthorizationRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identity accessing the Resource. Not null.
|
* The identity accessing the Resource. May be null if the user could not authenticate.
|
||||||
*
|
*
|
||||||
* @return The identity
|
* @return The identity
|
||||||
*/
|
*/
|
||||||
|
@ -62,6 +67,24 @@ public class AuthorizationRequest {
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this is a direct access attempt of the Resource if if it's being checked as part of another response.
|
||||||
|
*
|
||||||
|
* @return if this is a direct access attempt
|
||||||
|
*/
|
||||||
|
public boolean isAccessAttempt() {
|
||||||
|
return isAccessAttempt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the entity accessing is anonymous.
|
||||||
|
*
|
||||||
|
* @return whether the entity is anonymous
|
||||||
|
*/
|
||||||
|
public boolean isAnonymous() {
|
||||||
|
return isAnonymous;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The action being taken against the Resource. Not null.
|
* The action being taken against the Resource. Not null.
|
||||||
*
|
*
|
||||||
|
@ -96,6 +119,8 @@ public class AuthorizationRequest {
|
||||||
|
|
||||||
private Resource resource;
|
private Resource resource;
|
||||||
private String identity;
|
private String identity;
|
||||||
|
private Boolean isAnonymous;
|
||||||
|
private Boolean isAccessAttempt;
|
||||||
private RequestAction action;
|
private RequestAction action;
|
||||||
private Map<String, String> context;
|
private Map<String, String> context;
|
||||||
private Map<String, String> eventAttributes;
|
private Map<String, String> eventAttributes;
|
||||||
|
@ -110,6 +135,16 @@ public class AuthorizationRequest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder anonymous(final Boolean isAnonymous) {
|
||||||
|
this.isAnonymous = isAnonymous;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder accessAttempt(final Boolean isAccessAttempt) {
|
||||||
|
this.isAccessAttempt = isAccessAttempt;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder action(final RequestAction action) {
|
public Builder action(final RequestAction action) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.authorization;
|
package org.apache.nifi.authorization;
|
||||||
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||||
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
||||||
|
@ -31,7 +30,7 @@ public interface Authorizer {
|
||||||
*
|
*
|
||||||
* @param request The authorization request
|
* @param request The authorization request
|
||||||
* @return the authorization result
|
* @return the authorization result
|
||||||
* @throws AuthorityAccessException if unable to access the authorities
|
* @throws AuthorizationAccessException if unable to access the authorities
|
||||||
*/
|
*/
|
||||||
AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
|
AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
|
||||||
|
|
||||||
|
|
|
@ -1,83 +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.authorization;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a decision whether authorization is granted to download content.
|
|
||||||
*/
|
|
||||||
public class DownloadAuthorization {
|
|
||||||
|
|
||||||
private static enum Result {
|
|
||||||
|
|
||||||
Approved,
|
|
||||||
Denied;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final DownloadAuthorization APPROVED = new DownloadAuthorization(Result.Approved, null);
|
|
||||||
|
|
||||||
private final Result result;
|
|
||||||
private final String explanation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new DownloadAuthorization with the specified result and
|
|
||||||
* explanation.
|
|
||||||
*
|
|
||||||
* @param result of the authorization
|
|
||||||
* @param explanation for the authorization attempt
|
|
||||||
*/
|
|
||||||
private DownloadAuthorization(Result result, String explanation) {
|
|
||||||
if (Result.Denied.equals(result) && explanation == null) {
|
|
||||||
throw new IllegalArgumentException("An explanation is required when the download request is denied.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.result = result;
|
|
||||||
this.explanation = explanation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Whether or not the download request is approved
|
|
||||||
*/
|
|
||||||
public boolean isApproved() {
|
|
||||||
return Result.Approved.equals(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return If the download request is denied, the reason why. Null otherwise
|
|
||||||
*/
|
|
||||||
public String getExplanation() {
|
|
||||||
return explanation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a new approved DownloadAuthorization
|
|
||||||
*/
|
|
||||||
public static DownloadAuthorization approved() {
|
|
||||||
return APPROVED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new denied DownloadAuthorization with the specified
|
|
||||||
* explanation.
|
|
||||||
*
|
|
||||||
* @param explanation for why it was denied
|
|
||||||
* @return a new denied DownloadAuthorization with the specified explanation
|
|
||||||
* @throws IllegalArgumentException if explanation is null
|
|
||||||
*/
|
|
||||||
public static DownloadAuthorization denied(String explanation) {
|
|
||||||
return new DownloadAuthorization(Result.Denied, explanation);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +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.authorization.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Documented
|
|
||||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Inherited
|
|
||||||
public @interface AuthorityProviderContext {
|
|
||||||
}
|
|
|
@ -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.authorization.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the case when the DN could not be confirmed because it was unable
|
|
||||||
* to access the data store.
|
|
||||||
*/
|
|
||||||
public class AuthorityAccessException extends RuntimeException {
|
|
||||||
|
|
||||||
public AuthorityAccessException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthorityAccessException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +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.authorization.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the case when the user identity already exists.
|
|
||||||
*/
|
|
||||||
public class IdentityAlreadyExistsException extends RuntimeException {
|
|
||||||
|
|
||||||
public IdentityAlreadyExistsException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityAlreadyExistsException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +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.authorization.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the case when an identity cannot be confirmed.
|
|
||||||
*/
|
|
||||||
public class UnknownIdentityException extends RuntimeException {
|
|
||||||
|
|
||||||
public UnknownIdentityException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnknownIdentityException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -325,7 +325,7 @@ language governing permissions and limitations under the License. -->
|
||||||
<nifi.flow.configuration.file>./conf/flow.xml.gz</nifi.flow.configuration.file>
|
<nifi.flow.configuration.file>./conf/flow.xml.gz</nifi.flow.configuration.file>
|
||||||
<nifi.flow.configuration.archive.dir>./conf/archive/</nifi.flow.configuration.archive.dir>
|
<nifi.flow.configuration.archive.dir>./conf/archive/</nifi.flow.configuration.archive.dir>
|
||||||
<nifi.login.identity.provider.configuration.file>./conf/login-identity-providers.xml</nifi.login.identity.provider.configuration.file>
|
<nifi.login.identity.provider.configuration.file>./conf/login-identity-providers.xml</nifi.login.identity.provider.configuration.file>
|
||||||
<nifi.authority.provider.configuration.file>./conf/authority-providers.xml</nifi.authority.provider.configuration.file>
|
<nifi.authorizer.configuration.file>./conf/authorizers.xml</nifi.authorizer.configuration.file>
|
||||||
<nifi.templates.directory>./conf/templates</nifi.templates.directory>
|
<nifi.templates.directory>./conf/templates</nifi.templates.directory>
|
||||||
<nifi.database.directory>./database_repository</nifi.database.directory>
|
<nifi.database.directory>./database_repository</nifi.database.directory>
|
||||||
|
|
||||||
|
@ -413,13 +413,9 @@ language governing permissions and limitations under the License. -->
|
||||||
<nifi.security.truststoreType />
|
<nifi.security.truststoreType />
|
||||||
<nifi.security.truststorePasswd />
|
<nifi.security.truststorePasswd />
|
||||||
<nifi.security.needClientAuth />
|
<nifi.security.needClientAuth />
|
||||||
<nifi.security.authorizedUsers.file>./conf/authorized-users.xml</nifi.security.authorizedUsers.file>
|
<nifi.security.user.authorizer>file-provider</nifi.security.user.authorizer>
|
||||||
<nifi.security.user.credential.cache.duration>24 hours</nifi.security.user.credential.cache.duration>
|
|
||||||
<nifi.security.user.authority.provider>file-provider</nifi.security.user.authority.provider>
|
|
||||||
<nifi.security.user.login.identity.provider />
|
<nifi.security.user.login.identity.provider />
|
||||||
<nifi.security.x509.principal.extractor />
|
<nifi.security.x509.principal.extractor />
|
||||||
<nifi.security.support.new.account.requests />
|
|
||||||
<nifi.security.anonymous.authorities />
|
|
||||||
<nifi.security.ocsp.responder.url />
|
<nifi.security.ocsp.responder.url />
|
||||||
<nifi.security.ocsp.responder.certificate />
|
<nifi.security.ocsp.responder.certificate />
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,10 @@ import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class NiFiProperties extends Properties {
|
public class NiFiProperties extends Properties {
|
||||||
|
|
||||||
|
@ -48,7 +44,7 @@ public class NiFiProperties extends Properties {
|
||||||
public static final String PROPERTIES_FILE_PATH = "nifi.properties.file.path";
|
public static final String PROPERTIES_FILE_PATH = "nifi.properties.file.path";
|
||||||
public static final String FLOW_CONFIGURATION_FILE = "nifi.flow.configuration.file";
|
public static final String FLOW_CONFIGURATION_FILE = "nifi.flow.configuration.file";
|
||||||
public static final String FLOW_CONFIGURATION_ARCHIVE_FILE = "nifi.flow.configuration.archive.file";
|
public static final String FLOW_CONFIGURATION_ARCHIVE_FILE = "nifi.flow.configuration.archive.file";
|
||||||
public static final String AUTHORITY_PROVIDER_CONFIGURATION_FILE = "nifi.authority.provider.configuration.file";
|
public static final String AUTHORIZER_CONFIGURATION_FILE = "nifi.authorizer.configuration.file";
|
||||||
public static final String LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE = "nifi.login.identity.provider.configuration.file";
|
public static final String LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE = "nifi.login.identity.provider.configuration.file";
|
||||||
public static final String REPOSITORY_DATABASE_DIRECTORY = "nifi.database.directory";
|
public static final String REPOSITORY_DATABASE_DIRECTORY = "nifi.database.directory";
|
||||||
public static final String RESTORE_DIRECTORY = "nifi.restore.directory";
|
public static final String RESTORE_DIRECTORY = "nifi.restore.directory";
|
||||||
|
@ -131,13 +127,10 @@ public class NiFiProperties extends Properties {
|
||||||
public static final String SECURITY_TRUSTSTORE_TYPE = "nifi.security.truststoreType";
|
public static final String SECURITY_TRUSTSTORE_TYPE = "nifi.security.truststoreType";
|
||||||
public static final String SECURITY_TRUSTSTORE_PASSWD = "nifi.security.truststorePasswd";
|
public static final String SECURITY_TRUSTSTORE_PASSWD = "nifi.security.truststorePasswd";
|
||||||
public static final String SECURITY_NEED_CLIENT_AUTH = "nifi.security.needClientAuth";
|
public static final String SECURITY_NEED_CLIENT_AUTH = "nifi.security.needClientAuth";
|
||||||
public static final String SECURITY_USER_AUTHORITY_PROVIDER = "nifi.security.user.authority.provider";
|
public static final String SECURITY_USER_AUTHORIZER = "nifi.security.user.authorizer";
|
||||||
public static final String SECURITY_USER_LOGIN_IDENTITY_PROVIDER = "nifi.security.user.login.identity.provider";
|
public static final String SECURITY_USER_LOGIN_IDENTITY_PROVIDER = "nifi.security.user.login.identity.provider";
|
||||||
public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_PORT = "nifi.security.cluster.authority.provider.port";
|
public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_PORT = "nifi.security.cluster.authority.provider.port";
|
||||||
public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_THREADS = "nifi.security.cluster.authority.provider.threads";
|
public static final String SECURITY_CLUSTER_AUTHORITY_PROVIDER_THREADS = "nifi.security.cluster.authority.provider.threads";
|
||||||
public static final String SECURITY_USER_CREDENTIAL_CACHE_DURATION = "nifi.security.user.credential.cache.duration";
|
|
||||||
public static final String SECURITY_SUPPORT_NEW_ACCOUNT_REQUESTS = "nifi.security.support.new.account.requests";
|
|
||||||
public static final String SECURITY_ANONYMOUS_AUTHORITIES = "nifi.security.anonymous.authorities";
|
|
||||||
public static final String SECURITY_OCSP_RESPONDER_URL = "nifi.security.ocsp.responder.url";
|
public static final String SECURITY_OCSP_RESPONDER_URL = "nifi.security.ocsp.responder.url";
|
||||||
public static final String SECURITY_OCSP_RESPONDER_CERTIFICATE = "nifi.security.ocsp.responder.certificate";
|
public static final String SECURITY_OCSP_RESPONDER_CERTIFICATE = "nifi.security.ocsp.responder.certificate";
|
||||||
|
|
||||||
|
@ -504,10 +497,10 @@ public class NiFiProperties extends Properties {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the user authorities file
|
* @return the user authorizers file
|
||||||
*/
|
*/
|
||||||
public File getAuthorityProviderConfiguraitonFile() {
|
public File getAuthorizerConfiguraitonFile() {
|
||||||
final String value = getProperty(AUTHORITY_PROVIDER_CONFIGURATION_FILE);
|
final String value = getProperty(AUTHORIZER_CONFIGURATION_FILE);
|
||||||
if (StringUtils.isBlank(value)) {
|
if (StringUtils.isBlank(value)) {
|
||||||
return new File(DEFAULT_AUTHORITY_PROVIDER_CONFIGURATION_FILE);
|
return new File(DEFAULT_AUTHORITY_PROVIDER_CONFIGURATION_FILE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -541,40 +534,6 @@ public class NiFiProperties extends Properties {
|
||||||
return needClientAuth;
|
return needClientAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserCredentialCacheDuration() {
|
|
||||||
return getProperty(SECURITY_USER_CREDENTIAL_CACHE_DURATION,
|
|
||||||
DEFAULT_USER_CREDENTIAL_CACHE_DURATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getSupportNewAccountRequests() {
|
|
||||||
boolean shouldSupport = true;
|
|
||||||
String rawShouldSupport = getProperty(SECURITY_SUPPORT_NEW_ACCOUNT_REQUESTS);
|
|
||||||
if ("false".equalsIgnoreCase(rawShouldSupport)) {
|
|
||||||
shouldSupport = false;
|
|
||||||
}
|
|
||||||
return shouldSupport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Set<String> getAnonymousAuthorities() {
|
|
||||||
final Set<String> authorities;
|
|
||||||
|
|
||||||
final String rawAnonymousAuthorities = getProperty(SECURITY_ANONYMOUS_AUTHORITIES);
|
|
||||||
if (!StringUtils.isEmpty(rawAnonymousAuthorities)) {
|
|
||||||
authorities = new HashSet<>();
|
|
||||||
|
|
||||||
// parse the raw authorities and trim them
|
|
||||||
final List<String> authoritiesList = Arrays.asList(rawAnonymousAuthorities.split(","));
|
|
||||||
for (final String authority : authoritiesList) {
|
|
||||||
authorities.add(authority.trim());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
authorities = Collections.EMPTY_SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters for web properties //
|
// getters for web properties //
|
||||||
public Integer getPort() {
|
public Integer getPort() {
|
||||||
Integer port = null;
|
Integer port = null;
|
||||||
|
@ -922,7 +881,7 @@ public class NiFiProperties extends Properties {
|
||||||
* @return true if client certificates are required for access to the REST API
|
* @return true if client certificates are required for access to the REST API
|
||||||
*/
|
*/
|
||||||
public boolean isClientAuthRequiredForRestApi() {
|
public boolean isClientAuthRequiredForRestApi() {
|
||||||
return StringUtils.isBlank(getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && getAnonymousAuthorities().isEmpty() && !isKerberosServiceSupportEnabled();
|
return StringUtils.isBlank(getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && !isKerberosServiceSupportEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress getNodeApiAddress() {
|
public InetSocketAddress getNodeApiAddress() {
|
||||||
|
|
|
@ -83,11 +83,7 @@ nifi.security.truststore=
|
||||||
nifi.security.truststoreType=
|
nifi.security.truststoreType=
|
||||||
nifi.security.truststorePasswd=
|
nifi.security.truststorePasswd=
|
||||||
nifi.security.needClientAuth=
|
nifi.security.needClientAuth=
|
||||||
nifi.security.authorizedUsers.file=./target/conf/authorized-users.xml
|
nifi.security.user.authorizer=
|
||||||
nifi.security.user.credential.cache.duration=24 hours
|
|
||||||
nifi.security.user.authority.provider=nifi.authorization.FileAuthorizationProvider
|
|
||||||
nifi.security.support.new.account.requests=
|
|
||||||
nifi.security.default.user.roles=
|
|
||||||
|
|
||||||
# cluster common properties (cluster manager and nodes must have same values) #
|
# cluster common properties (cluster manager and nodes must have same values) #
|
||||||
nifi.cluster.protocol.heartbeat.interval=5 sec
|
nifi.cluster.protocol.heartbeat.interval=5 sec
|
||||||
|
|
|
@ -81,11 +81,7 @@ nifi.security.truststore=
|
||||||
nifi.security.truststoreType=
|
nifi.security.truststoreType=
|
||||||
nifi.security.truststorePasswd=
|
nifi.security.truststorePasswd=
|
||||||
nifi.security.needClientAuth=
|
nifi.security.needClientAuth=
|
||||||
nifi.security.authorizedUsers.file=./target/conf/authorized-users.xml
|
nifi.security.user.authorizer=
|
||||||
nifi.security.user.credential.cache.duration=24 hours
|
|
||||||
nifi.security.user.authority.provider=nifi.authorization.FileAuthorizationProvider
|
|
||||||
nifi.security.support.new.account.requests=
|
|
||||||
nifi.security.default.user.roles=
|
|
||||||
|
|
||||||
# cluster common properties (cluster manager and nodes must have same values) #
|
# cluster common properties (cluster manager and nodes must have same values) #
|
||||||
nifi.cluster.protocol.heartbeat.interval=5 sec
|
nifi.cluster.protocol.heartbeat.interval=5 sec
|
||||||
|
|
|
@ -83,11 +83,7 @@ nifi.security.truststore=
|
||||||
nifi.security.truststoreType=
|
nifi.security.truststoreType=
|
||||||
nifi.security.truststorePasswd=
|
nifi.security.truststorePasswd=
|
||||||
nifi.security.needClientAuth=
|
nifi.security.needClientAuth=
|
||||||
nifi.security.authorizedUsers.file=./target/conf/authorized-users.xml
|
nifi.security.user.authorizer=
|
||||||
nifi.security.user.credential.cache.duration=24 hours
|
|
||||||
nifi.security.user.authority.provider=nifi.authorization.FileAuthorizationProvider
|
|
||||||
nifi.security.support.new.account.requests=
|
|
||||||
nifi.security.default.user.roles=
|
|
||||||
|
|
||||||
# cluster common properties (cluster manager and nodes must have same values) #
|
# cluster common properties (cluster manager and nodes must have same values) #
|
||||||
nifi.cluster.protocol.heartbeat.interval=5 sec
|
nifi.cluster.protocol.heartbeat.interval=5 sec
|
||||||
|
|
|
@ -154,9 +154,6 @@ NiFi provides several different configuration options for security purposes. The
|
||||||
by the NiFi cluster protocol. If the Truststore properties are not set, this must be `false`. Otherwise, a value
|
by the NiFi cluster protocol. If the Truststore properties are not set, this must be `false`. Otherwise, a value
|
||||||
of `true` indicates that nodes in the cluster will be authenticated and must have certificates that are trusted
|
of `true` indicates that nodes in the cluster will be authenticated and must have certificates that are trusted
|
||||||
by the Truststores.
|
by the Truststores.
|
||||||
|`nifi.security.anonymous.authorities` | Specifies the roles that should be granted to users that connect over HTTPS anonymously. All users can make
|
|
||||||
use of anonymous access, however if they have been granted a particular level of access by an administrator
|
|
||||||
it will take precedence if they access NiFi using a client certificate or once they have logged in.
|
|
||||||
|==================================================================================================================================================
|
|==================================================================================================================================================
|
||||||
|
|
||||||
Once the above properties have been configured, we can enable the User Interface to be accessed over HTTPS instead of HTTP. This is accomplished
|
Once the above properties have been configured, we can enable the User Interface to be accessed over HTTPS instead of HTTP. This is accomplished
|
||||||
|
@ -167,10 +164,10 @@ be accessible from all network interfaces, a value of `0.0.0.0` should be used.
|
||||||
NOTE: It is important when enabling HTTPS that the `nifi.web.http.port` property be unset.
|
NOTE: It is important when enabling HTTPS that the `nifi.web.http.port` property be unset.
|
||||||
|
|
||||||
Similar to `nifi.security.needClientAuth`, the web server can be configured to require certificate based client authentication for users accessing
|
Similar to `nifi.security.needClientAuth`, the web server can be configured to require certificate based client authentication for users accessing
|
||||||
the User Interface. In order to do this it must be configured to not support username/password authentication (see below) and not grant access to
|
the User Interface. In order to do this it must be configured to not support username/password authentication (see below). Either of these options
|
||||||
anonymous users (see `nifi.security.anonymous.authorities` above). Either of these options will configure the web server to WANT certificate based client
|
will configure the web server to WANT certificate based client authentication. This will allow it to support users with certificates and those without
|
||||||
authentication. This will allow it to support users with certificates and those without that may be logging in with their credentials or those accessing
|
that may be logging in with their credentials or those accessing anonymously. If username/password authentication and anonymous access are not configured,
|
||||||
anonymously. If username/password authentication and anonymous access are not configured, the web server will REQUIRE certificate based client authentication.
|
the web server will REQUIRE certificate based client authentication.
|
||||||
|
|
||||||
Now that the User Interface has been secured, we can easily secure Site-to-Site connections and inner-cluster communications, as well. This is
|
Now that the User Interface has been secured, we can easily secure Site-to-Site connections and inner-cluster communications, as well. This is
|
||||||
accomplished by setting the `nifi.remote.input.secure` and `nifi.cluster.protocol.is.secure` properties, respectively, to `true`.
|
accomplished by setting the `nifi.remote.input.secure` and `nifi.cluster.protocol.is.secure` properties, respectively, to `true`.
|
||||||
|
@ -289,127 +286,6 @@ nifi.security.user.login.identity.provider=kerberos-provider
|
||||||
|
|
||||||
See also <<kerberos_service>> to allow single sign-on access via client Kerberos tickets.
|
See also <<kerberos_service>> to allow single sign-on access via client Kerberos tickets.
|
||||||
|
|
||||||
Controlling Levels of Access
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Once NiFi is configured to run securely and an authentication mechanism is configured, it is necessary
|
|
||||||
to configure who will have access to the system and what types of access those people will have.
|
|
||||||
NiFi controls this through the user of an 'Authority Provider.' The Authority Provider is a pluggable
|
|
||||||
mechanism for providing authorizations to different users. Which Authority Provider to use is configured
|
|
||||||
using two properties in the _nifi.properties_ file.
|
|
||||||
|
|
||||||
The `nifi.authority.provider.configuration.file` property specifies the configuration file for Authority Providers.
|
|
||||||
The `nifi.security.user.authority.provider` property indicates which of the configured Authority Providers should be
|
|
||||||
used.
|
|
||||||
|
|
||||||
By default, the `file-provider` Authority Provider is selected and is configured to use the permissions granted in
|
|
||||||
the _authorized-users.xml_ file. This is typically sufficient for instances of NiFi that are run in "standalone" mode.
|
|
||||||
If the NiFi instance is configured to run in a cluster, the node will typically use the `cluster-node-provider`
|
|
||||||
Provider and the Cluster Manager will typically use the `cluster-ncm-provider` Provider. Both of these Providers
|
|
||||||
have a default configuration in the _authority-providers.xml_ file but are commented out.
|
|
||||||
|
|
||||||
When using the `cluster-node-provider` Provider, all of the authorization is provided by the Cluster Manager. In this
|
|
||||||
way, the configuration only has to be maintained in one place and will be consistent across the entire cluster.
|
|
||||||
|
|
||||||
When configuring the Cluster Manager or a standalone node, it is necessary to manually designate an ADMIN user
|
|
||||||
in the _authorized-users.xml_ file, which is located in the root installation's conf directory.
|
|
||||||
After this ADMIN user has been added, s/he may grant access
|
|
||||||
to other users, systems, and other instances of NiFi, through the User Interface (UI) without having to manually edit the _authorized-users.xml_
|
|
||||||
file. If you are the administrator, you would add yourself as the ADMIN user in this file.
|
|
||||||
|
|
||||||
Open the _authorized-users.xml_ file in a text editor. You will notice that it includes a template
|
|
||||||
to guide you, with example entries that are commented out.
|
|
||||||
|
|
||||||
It is only necessary to manually add one user, the ADMIN user, to this file.
|
|
||||||
So, at a minimum, the following example entry should be included and contain the user Distinguished Name (DN)
|
|
||||||
in place of "user dn - read only and admin":
|
|
||||||
|
|
||||||
----
|
|
||||||
<users>
|
|
||||||
<user dn="[user dn - read only and admin]">
|
|
||||||
<role name="ROLE_ADMIN"/>
|
|
||||||
</user>
|
|
||||||
</users>
|
|
||||||
----
|
|
||||||
|
|
||||||
Here is an LDAP example entry using the name John Smith:
|
|
||||||
|
|
||||||
----
|
|
||||||
<users>
|
|
||||||
<user dn="cn=John Smith,ou=people,dc=example,dc=com">
|
|
||||||
<role name="ROLE_ADMIN"/>
|
|
||||||
</user>
|
|
||||||
</users>
|
|
||||||
----
|
|
||||||
|
|
||||||
Here is a Kerberos example entry using the name John Smith and realm `NIFI.APACHE.ORG`:
|
|
||||||
|
|
||||||
----
|
|
||||||
<users>
|
|
||||||
<user dn="johnsmith@NIFI.APACHE.ORG">
|
|
||||||
<role name="ROLE_ADMIN"/>
|
|
||||||
</user>
|
|
||||||
</users>
|
|
||||||
----
|
|
||||||
|
|
||||||
After the _authorized-users.xml_ file has been edited and saved, restart NiFi.
|
|
||||||
Once the application starts, the ADMIN user is
|
|
||||||
able to access the UI at the HTTPS URL that is configured in the _nifi.properties_ file.
|
|
||||||
|
|
||||||
From the UI, click on the Users icon ( image:iconUsers.png["Users", width=32] ) in the
|
|
||||||
Management Toolbar (upper-right corner of the UI), and the User Management Page opens.
|
|
||||||
|
|
||||||
The ADMIN user should be listed. Click on the pencil icon to see this user's role(s). You may edit the
|
|
||||||
roles by selecting the appropriate checkboxes.
|
|
||||||
|
|
||||||
The following roles are available in NiFi:
|
|
||||||
|
|
||||||
[options="header,footer"]
|
|
||||||
|========================================================================================================
|
|
||||||
| Role Name | Description
|
|
||||||
| Administrator | Administrator is able to configure thread pool sizes and user accounts as well as
|
|
||||||
purge the dataflow change history.
|
|
||||||
| Data Flow Manager | Data Flow Manager is given the ability to manipulate the dataflow. S/he is able to
|
|
||||||
add, remove, and manipulate components on the graph; add, remove, and manipulate
|
|
||||||
Controller Services and Reporting Tasks; create and manage templates;
|
|
||||||
view statistics; and view the bulletin board.
|
|
||||||
| Read Only | Users with Read Only access are able to view the dataflow but are unable to change anything.
|
|
||||||
| Provenance | Users with Provenance access are able to query the Data Provenance repository and view
|
|
||||||
the lineage of data. Additionally, this role provides the ability to view or download
|
|
||||||
the content of a FlowFile from a Provenance event (assuming that the content is still
|
|
||||||
available in the Content Repository and that the Authority Provider also grants access).
|
|
||||||
This access is not provided to users with Read Only
|
|
||||||
(unless the user has both Read Only and Provenance roles) because the information provided
|
|
||||||
to users with this role can potentially be very sensitive in nature, as all FlowFile attributes
|
|
||||||
and data are exposed. In order to Replay a Provenance event, a user is required to have both
|
|
||||||
the Provenance role as well as the Data Flow Manager role.
|
|
||||||
| NiFi | The NiFi Role is intended to be assigned to machines that will interact with an instance of NiFi
|
|
||||||
via Site-to-Site. This role provides the ability to send data to or retrieve data from Root
|
|
||||||
Group Ports (but only those that they are given permissions to interact with - see the User Guide
|
|
||||||
for more information on providing access to specific Ports) as well as obtain information about
|
|
||||||
which Ports exist. Note that this role allows the client to know only about the Ports that it
|
|
||||||
has permissions to interact with.
|
|
||||||
| Proxy | The Proxy Role is assigned to a system in order to grant that system permission to make requests
|
|
||||||
on behalf of a user. For instance, if an HTTP proxy service is used to gain access to the system,
|
|
||||||
the certificate being used by that service can be given the Proxy Role.
|
|
||||||
|========================================================================================================
|
|
||||||
|
|
||||||
|
|
||||||
When users want access to the NiFi UI, they navigate to the configured URL and are
|
|
||||||
prompted to request access. When someone has requested access, the ADMIN user sees a star
|
|
||||||
on the Users icon in the Management Toolbar, alerting the ADMIN to the fact that a request is
|
|
||||||
pending. Upon opening the User Management Page, the pending request is visible, and the ADMIN
|
|
||||||
can grant access and click on the pencil icon to set the user's roles appropriately.
|
|
||||||
|
|
||||||
The ADMIN may also select multiple users and add them to a "Group". Hold down the Shift key and select
|
|
||||||
multiple users, then click the `Group` button in the upper-right corner of the User Management Page.
|
|
||||||
Then, provide a name for the group.
|
|
||||||
|
|
||||||
The group feature is especially useful when a remote NiFi cluster is connecting to this NiFi using
|
|
||||||
a Remote Process Group. In that scenario, all the nodes
|
|
||||||
in the remote cluster can be included in the same group. When the ADMIN wants to grant port access to the remote
|
|
||||||
cluster, s/he can grant it to the group and avoid having to grant it individually to each node in the cluster.
|
|
||||||
|
|
||||||
[[encryption]]
|
[[encryption]]
|
||||||
Encryption Configuration
|
Encryption Configuration
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -1454,15 +1330,8 @@ Security Configuration section of this Administrator's Guide.
|
||||||
|nifi.security.truststoreType|The truststore type. It is blank by default.
|
|nifi.security.truststoreType|The truststore type. It is blank by default.
|
||||||
|nifi.security.truststorePasswd|The truststore password. It is blank by default.
|
|nifi.security.truststorePasswd|The truststore password. It is blank by default.
|
||||||
|nifi.security.needClientAuth|This indicates whether client authentication in the cluster protocol. It is blank by default.
|
|nifi.security.needClientAuth|This indicates whether client authentication in the cluster protocol. It is blank by default.
|
||||||
|nifi.security.user.credential.cache.duration|The length of time to cache user credentials. The default value is 24 hours.
|
|
||||||
|nifi.security.user.authority.provider|This indicates what type of authority provider to use. The default value is file-provider, which refers to the file
|
|
||||||
configured in the core property `nifi.authority.provider.configuration.file`. Another authority provider may be used, such as when the NiFi instance is part of a cluster. But the default value of file-provider is fine for a standalone instance of NiFi.
|
|
||||||
|nifi.security.user.login.identity.provider|This indicates what type of login identity provider to use. The default value is blank, can be set to the identifier from a provider
|
|nifi.security.user.login.identity.provider|This indicates what type of login identity provider to use. The default value is blank, can be set to the identifier from a provider
|
||||||
in the file specified in `nifi.login.identity.provider.configuration.file`. Setting this property will trigger NiFi to support username/password authentication.
|
in the file specified in `nifi.login.identity.provider.configuration.file`. Setting this property will trigger NiFi to support username/password authentication.
|
||||||
|nifi.security.support.new.account.requests|This indicates whether a secure NiFi is configured to allow users to request access. It is blank by default.
|
|
||||||
|nifi.security.anonymous.authorities|This indicates what roles to grant to anonymous users accessing NiFi over HTTPS. It is blank by default, but could be
|
|
||||||
set to any combination of ROLE_MONITOR, ROLE_DFM, ROLE_ADMIN, ROLE_PROVENANCE, ROLE_NIFI. Leaving this property blank will require that users accessing NiFi
|
|
||||||
over HTTPS be authenticated either using a client certificate or their credentials against the configured log identity provider.
|
|
||||||
|nifi.security.ocsp.responder.url|This is the URL for the Online Certificate Status Protocol (OCSP) responder if one is being used. It is blank by default.
|
|nifi.security.ocsp.responder.url|This is the URL for the Online Certificate Status Protocol (OCSP) responder if one is being used. It is blank by default.
|
||||||
|nifi.security.ocsp.responder.certificate|This is the location of the OCSP responder certificate if one is being used. It is blank by default.
|
|nifi.security.ocsp.responder.certificate|This is the location of the OCSP responder certificate if one is being used. It is blank by default.
|
||||||
|====
|
|====
|
||||||
|
|
|
@ -26,7 +26,7 @@ import com.datastax.driver.core.Session;
|
||||||
import org.apache.avro.Schema;
|
import org.apache.avro.Schema;
|
||||||
import org.apache.avro.SchemaBuilder;
|
import org.apache.avro.SchemaBuilder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
import org.apache.nifi.components.PropertyValue;
|
import org.apache.nifi.components.PropertyValue;
|
||||||
import org.apache.nifi.components.ValidationContext;
|
import org.apache.nifi.components.ValidationContext;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import com.datastax.driver.core.DataType;
|
||||||
import com.datastax.driver.core.Metadata;
|
import com.datastax.driver.core.Metadata;
|
||||||
import com.datastax.driver.core.Row;
|
import com.datastax.driver.core.Row;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
|
|
|
@ -31,14 +31,6 @@
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-jetty</artifactId>
|
<artifactId>nifi-jetty</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-cluster-authorization-provider</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-file-authorization-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>
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* 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.admin;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
|
import org.h2.jdbcx.JdbcConnectionPool;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
public class KeyDataSourceFactoryBean implements FactoryBean {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(KeyDataSourceFactoryBean.class);
|
||||||
|
private static final String NF_USERNAME_PASSWORD = "nf";
|
||||||
|
private static final int MAX_CONNECTIONS = 5;
|
||||||
|
|
||||||
|
// database file name
|
||||||
|
private static final String USER_KEYS_DATABASE_FILE_NAME = "nifi-user-keys";
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// keys table
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
private static final String CREATE_KEY_TABLE = "CREATE TABLE KEY ("
|
||||||
|
+ "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
|
||||||
|
+ "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
|
||||||
|
+ "KEY VARCHAR2(100) NOT NULL"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
private JdbcConnectionPool connectionPool;
|
||||||
|
|
||||||
|
private NiFiProperties properties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject() throws Exception {
|
||||||
|
if (connectionPool == null) {
|
||||||
|
|
||||||
|
// locate the repository directory
|
||||||
|
String repositoryDirectoryPath = properties.getProperty(NiFiProperties.REPOSITORY_DATABASE_DIRECTORY);
|
||||||
|
|
||||||
|
// ensure the repository directory is specified
|
||||||
|
if (repositoryDirectoryPath == null) {
|
||||||
|
throw new NullPointerException("Database directory must be specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a handle to the repository directory
|
||||||
|
File repositoryDirectory = new File(repositoryDirectoryPath);
|
||||||
|
|
||||||
|
// create a handle to the database directory and file
|
||||||
|
File databaseFile = new File(repositoryDirectory, USER_KEYS_DATABASE_FILE_NAME);
|
||||||
|
String databaseUrl = getDatabaseUrl(databaseFile);
|
||||||
|
|
||||||
|
// create the pool
|
||||||
|
connectionPool = JdbcConnectionPool.create(databaseUrl, NF_USERNAME_PASSWORD, NF_USERNAME_PASSWORD);
|
||||||
|
connectionPool.setMaxConnections(MAX_CONNECTIONS);
|
||||||
|
|
||||||
|
Connection connection = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
Statement statement = null;
|
||||||
|
try {
|
||||||
|
// get a connection
|
||||||
|
connection = connectionPool.getConnection();
|
||||||
|
connection.setAutoCommit(false);
|
||||||
|
|
||||||
|
// create a statement for creating/updating the database
|
||||||
|
statement = connection.createStatement();
|
||||||
|
|
||||||
|
// determine if the key table need to be created
|
||||||
|
rs = connection.getMetaData().getTables(null, null, "KEY", null);
|
||||||
|
if (!rs.next()) {
|
||||||
|
statement.execute(CREATE_KEY_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit any changes
|
||||||
|
connection.commit();
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
RepositoryUtils.rollback(connection, logger);
|
||||||
|
throw sqle;
|
||||||
|
} finally {
|
||||||
|
RepositoryUtils.closeQuietly(rs);
|
||||||
|
RepositoryUtils.closeQuietly(statement);
|
||||||
|
RepositoryUtils.closeQuietly(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectionPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDatabaseUrl(File databaseFile) {
|
||||||
|
String databaseUrl = "jdbc:h2:" + databaseFile + ";AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3";
|
||||||
|
String databaseUrlAppend = properties.getProperty(NiFiProperties.H2_URL_APPEND);
|
||||||
|
if (StringUtils.isNotBlank(databaseUrlAppend)) {
|
||||||
|
databaseUrl += databaseUrlAppend;
|
||||||
|
}
|
||||||
|
return databaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getObjectType() {
|
||||||
|
return JdbcConnectionPool.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(NiFiProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
// shutdown the connection pool
|
||||||
|
if (connectionPool != null) {
|
||||||
|
try {
|
||||||
|
connectionPool.dispose();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("Unable to dispose of connection pool: " + e.getMessage());
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.warn(StringUtils.EMPTY, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,244 +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.admin;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.h2.jdbcx.JdbcConnectionPool;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
|
|
||||||
public class UserDataSourceFactoryBean implements FactoryBean {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UserDataSourceFactoryBean.class);
|
|
||||||
private static final String NF_USERNAME_PASSWORD = "nf";
|
|
||||||
private static final int MAX_CONNECTIONS = 5;
|
|
||||||
|
|
||||||
// database file name
|
|
||||||
private static final String AUDIT_DATABASE_FILE_NAME = "nifi-users";
|
|
||||||
|
|
||||||
private static final String CREATE_USER_TABLE = "CREATE TABLE USER ("
|
|
||||||
+ "ID VARCHAR2(100) NOT NULL PRIMARY KEY, "
|
|
||||||
+ "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
|
|
||||||
+ "USER_NAME VARCHAR2(4096) NOT NULL, "
|
|
||||||
+ "USER_GROUP VARCHAR2(100), "
|
|
||||||
+ "CREATION TIMESTAMP NOT NULL, "
|
|
||||||
+ "LAST_ACCESSED TIMESTAMP, "
|
|
||||||
+ "LAST_VERIFIED TIMESTAMP, "
|
|
||||||
+ "JUSTIFICATION VARCHAR2(500) NOT NULL, "
|
|
||||||
+ "STATUS VARCHAR2(10) NOT NULL"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String CREATE_AUTHORITY_TABLE = "CREATE TABLE AUTHORITY ("
|
|
||||||
+ "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
|
|
||||||
+ "USER_ID VARCHAR2(100) NOT NULL, "
|
|
||||||
+ "ROLE VARCHAR2(50) NOT NULL, "
|
|
||||||
+ "FOREIGN KEY (USER_ID) REFERENCES USER (ID), "
|
|
||||||
+ "CONSTRAINT USER_ROLE_UNIQUE_CONSTRAINT UNIQUE (USER_ID, ROLE)"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String INSERT_ANONYMOUS_USER = "INSERT INTO USER ("
|
|
||||||
+ "ID, IDENTITY, USER_NAME, CREATION, LAST_VERIFIED, JUSTIFICATION, STATUS"
|
|
||||||
+ ") VALUES ("
|
|
||||||
+ "'" + UUID.randomUUID().toString() + "', "
|
|
||||||
+ "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
|
|
||||||
+ "'" + NiFiUser.ANONYMOUS_USER_IDENTITY + "', "
|
|
||||||
+ "NOW(), "
|
|
||||||
+ "NOW(), "
|
|
||||||
+ "'Anonymous user needs no justification', "
|
|
||||||
+ "'ACTIVE'"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String INSERT_ANONYMOUS_AUTHORITY = "INSERT INTO AUTHORITY ("
|
|
||||||
+ "USER_ID, ROLE"
|
|
||||||
+ ") VALUES ("
|
|
||||||
+ "(SELECT ID FROM USER WHERE IDENTITY = '" + NiFiUser.ANONYMOUS_USER_IDENTITY + "'), "
|
|
||||||
+ "'%s'"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String DELETE_ANONYMOUS_AUTHORITIES = "DELETE FROM AUTHORITY "
|
|
||||||
+ "WHERE USER_ID = (SELECT ID FROM USER WHERE IDENTITY = '" + NiFiUser.ANONYMOUS_USER_IDENTITY + "')";
|
|
||||||
|
|
||||||
private static final String RENAME_DN_COLUMN = "ALTER TABLE USER ALTER COLUMN DN RENAME TO IDENTITY";
|
|
||||||
private static final String RESIZE_IDENTITY_COLUMN = "ALTER TABLE USER MODIFY IDENTITY VARCHAR(4096)";
|
|
||||||
private static final String RESIZE_USER_NAME_COLUMN = "ALTER TABLE USER MODIFY USER_NAME VARCHAR(4096)";
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// keys table
|
|
||||||
// ----------
|
|
||||||
private static final String CREATE_KEY_TABLE = "CREATE TABLE KEY ("
|
|
||||||
+ "ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
|
|
||||||
+ "IDENTITY VARCHAR2(4096) NOT NULL UNIQUE, "
|
|
||||||
+ "KEY VARCHAR2(100) NOT NULL"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private JdbcConnectionPool connectionPool;
|
|
||||||
|
|
||||||
private NiFiProperties properties;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getObject() throws Exception {
|
|
||||||
if (connectionPool == null) {
|
|
||||||
|
|
||||||
// locate the repository directory
|
|
||||||
String repositoryDirectoryPath = properties.getProperty(NiFiProperties.REPOSITORY_DATABASE_DIRECTORY);
|
|
||||||
|
|
||||||
// ensure the repository directory is specified
|
|
||||||
if (repositoryDirectoryPath == null) {
|
|
||||||
throw new NullPointerException("Database directory must be specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the roles being granted to anonymous users
|
|
||||||
final Set<String> rawAnonymousAuthorities = new HashSet<>(properties.getAnonymousAuthorities());
|
|
||||||
final Set<Authority> anonymousAuthorities = Authority.convertRawAuthorities(rawAnonymousAuthorities);
|
|
||||||
|
|
||||||
// ensure every authorities was recognized
|
|
||||||
if (rawAnonymousAuthorities.size() != anonymousAuthorities.size()) {
|
|
||||||
final Set<String> validAuthorities = Authority.convertAuthorities(anonymousAuthorities);
|
|
||||||
rawAnonymousAuthorities.removeAll(validAuthorities);
|
|
||||||
throw new IllegalStateException(String.format("Invalid authorities specified for anonymous access: [%s]. Valid values are: [%s].",
|
|
||||||
StringUtils.join(rawAnonymousAuthorities, ", "), StringUtils.join(Authority.values(), ", ")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a handle to the repository directory
|
|
||||||
File repositoryDirectory = new File(repositoryDirectoryPath);
|
|
||||||
|
|
||||||
// create a handle to the database directory and file
|
|
||||||
File databaseFile = new File(repositoryDirectory, AUDIT_DATABASE_FILE_NAME);
|
|
||||||
String databaseUrl = getDatabaseUrl(databaseFile);
|
|
||||||
|
|
||||||
// create the pool
|
|
||||||
connectionPool = JdbcConnectionPool.create(databaseUrl, NF_USERNAME_PASSWORD, NF_USERNAME_PASSWORD);
|
|
||||||
connectionPool.setMaxConnections(MAX_CONNECTIONS);
|
|
||||||
|
|
||||||
Connection connection = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
Statement statement = null;
|
|
||||||
try {
|
|
||||||
// get a connection
|
|
||||||
connection = connectionPool.getConnection();
|
|
||||||
connection.setAutoCommit(false);
|
|
||||||
|
|
||||||
// create a statement for creating/updating the database
|
|
||||||
statement = connection.createStatement();
|
|
||||||
|
|
||||||
// determine if the tables need to be created
|
|
||||||
rs = connection.getMetaData().getTables(null, null, "USER", null);
|
|
||||||
if (!rs.next()) {
|
|
||||||
logger.info("Database not built for repository: " + databaseUrl + ". Building now...");
|
|
||||||
|
|
||||||
// create the tables
|
|
||||||
statement.execute(CREATE_USER_TABLE);
|
|
||||||
statement.execute(CREATE_AUTHORITY_TABLE);
|
|
||||||
|
|
||||||
// seed the anonymous user
|
|
||||||
statement.execute(INSERT_ANONYMOUS_USER);
|
|
||||||
} else {
|
|
||||||
logger.info("Existing database found and connected to at: " + databaseUrl);
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
|
|
||||||
// if the DN column exists, transform the table
|
|
||||||
rs = connection.getMetaData().getColumns(null, null, "USER", "DN");
|
|
||||||
if (rs.next()) {
|
|
||||||
statement.execute(RENAME_DN_COLUMN);
|
|
||||||
statement.execute(RESIZE_IDENTITY_COLUMN);
|
|
||||||
statement.execute(RESIZE_USER_NAME_COLUMN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all authorities for the anonymous user
|
|
||||||
statement.execute(DELETE_ANONYMOUS_AUTHORITIES);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add all authorities for the anonymous user
|
|
||||||
for (final Authority authority : anonymousAuthorities) {
|
|
||||||
statement.execute(String.format(INSERT_ANONYMOUS_AUTHORITY, authority.name()));
|
|
||||||
}
|
|
||||||
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
|
|
||||||
// determine if the key table need to be created
|
|
||||||
rs = connection.getMetaData().getTables(null, null, "KEY", null);
|
|
||||||
if (!rs.next()) {
|
|
||||||
statement.execute(CREATE_KEY_TABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// commit any changes
|
|
||||||
connection.commit();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
RepositoryUtils.rollback(connection, logger);
|
|
||||||
throw sqle;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
RepositoryUtils.closeQuietly(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return connectionPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDatabaseUrl(File databaseFile) {
|
|
||||||
String databaseUrl = "jdbc:h2:" + databaseFile + ";AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3";
|
|
||||||
String databaseUrlAppend = properties.getProperty(NiFiProperties.H2_URL_APPEND);
|
|
||||||
if (StringUtils.isNotBlank(databaseUrlAppend)) {
|
|
||||||
databaseUrl += databaseUrlAppend;
|
|
||||||
}
|
|
||||||
return databaseUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getObjectType() {
|
|
||||||
return JdbcConnectionPool.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSingleton() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProperties(NiFiProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
|
|
||||||
// shutdown the connection pool
|
|
||||||
if (connectionPool != null) {
|
|
||||||
try {
|
|
||||||
connectionPool.dispose();
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Unable to dispose of connection pool: " + e.getMessage());
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.warn(StringUtils.EMPTY, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,59 +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.admin.dao;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authority data access.
|
|
||||||
*/
|
|
||||||
public interface AuthorityDAO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all Authority for the specified user.
|
|
||||||
*
|
|
||||||
* @param userId identifier of user
|
|
||||||
* @return authorities
|
|
||||||
*/
|
|
||||||
Set<Authority> findAuthoritiesByUserId(String userId) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new Authorities for the specified user in addition to authorities
|
|
||||||
* they already have.
|
|
||||||
*
|
|
||||||
* @param authorities to add to the given user
|
|
||||||
* @param userId identifier of user
|
|
||||||
*/
|
|
||||||
void createAuthorities(Set<Authority> authorities, String userId) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all Authorities for the specified user.
|
|
||||||
*
|
|
||||||
* @param userId user identifier
|
|
||||||
* @throws DataAccessException if unable to access authorities
|
|
||||||
*/
|
|
||||||
void deleteAuthorities(String userId) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the specified Authority.
|
|
||||||
*
|
|
||||||
* @param authorities to remove
|
|
||||||
* @param userId user id
|
|
||||||
*/
|
|
||||||
void deleteAuthorities(Set<Authority> authorities, String userId) throws DataAccessException;
|
|
||||||
}
|
|
|
@ -21,11 +21,7 @@ package org.apache.nifi.admin.dao;
|
||||||
*/
|
*/
|
||||||
public interface DAOFactory {
|
public interface DAOFactory {
|
||||||
|
|
||||||
UserDAO getUserDAO();
|
|
||||||
|
|
||||||
ActionDAO getActionDAO();
|
ActionDAO getActionDAO();
|
||||||
|
|
||||||
AuthorityDAO getAuthorityDAO();
|
|
||||||
|
|
||||||
KeyDAO getKeyDAO();
|
KeyDAO getKeyDAO();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,128 +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.admin.dao;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the user data access object.
|
|
||||||
*/
|
|
||||||
public interface UserDAO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether there are any PENDING user accounts.
|
|
||||||
*
|
|
||||||
* @return true if pending
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
Boolean hasPendingUserAccounts() throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all users.
|
|
||||||
*
|
|
||||||
* @return all users
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
Set<NiFiUser> findUsers() throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all user groups.
|
|
||||||
*
|
|
||||||
* @return all group names
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
Set<String> findUserGroups() throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all users for the specified group.
|
|
||||||
*
|
|
||||||
* @param group group
|
|
||||||
* @return users in group
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
Set<NiFiUser> findUsersForGroup(String group) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the user with the specified id.
|
|
||||||
*
|
|
||||||
* @param id user id
|
|
||||||
* @return user for the given id
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
NiFiUser findUserById(String id) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the user with the specified DN.
|
|
||||||
*
|
|
||||||
* @param dn user dn
|
|
||||||
* @return user
|
|
||||||
*/
|
|
||||||
NiFiUser findUserByDn(String dn) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new user based off the specified NiFiUser.
|
|
||||||
*
|
|
||||||
* @param user to create
|
|
||||||
* @return the created user with it's id
|
|
||||||
*/
|
|
||||||
NiFiUser createUser(NiFiUser user) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the specified NiFiUser.
|
|
||||||
*
|
|
||||||
* @param user to update
|
|
||||||
*/
|
|
||||||
void updateUser(NiFiUser user) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the specified user.
|
|
||||||
*
|
|
||||||
* @param id user identifier
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
void deleteUser(String id) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the status of the specified group.
|
|
||||||
*
|
|
||||||
* @param group group
|
|
||||||
* @param status status
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
void updateGroupStatus(String group, AccountStatus status) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the last verified time for all users in the specified group.
|
|
||||||
*
|
|
||||||
* @param group group
|
|
||||||
* @param lastVerified date last verified
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
void updateGroupVerification(String group, Date lastVerified) throws DataAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ungroups the specified group.
|
|
||||||
*
|
|
||||||
* @param group to ungroup
|
|
||||||
* @throws DataAccessException dae
|
|
||||||
*/
|
|
||||||
void ungroup(String group) throws DataAccessException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -18,10 +18,8 @@ package org.apache.nifi.admin.dao.impl;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
import org.apache.nifi.admin.dao.KeyDAO;
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -39,16 +37,6 @@ public class DAOFactoryImpl implements DAOFactory {
|
||||||
return new StandardActionDAO(connection);
|
return new StandardActionDAO(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthorityDAO getAuthorityDAO() {
|
|
||||||
return new StandardAuthorityDAO(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserDAO getUserDAO() {
|
|
||||||
return new StandardUserDAO(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyDAO getKeyDAO() {
|
public KeyDAO getKeyDAO() {
|
||||||
return new StandardKeyDAO(connection);
|
return new StandardKeyDAO(connection);
|
||||||
|
|
|
@ -1,172 +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.admin.dao.impl;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.RepositoryUtils;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class StandardAuthorityDAO implements AuthorityDAO {
|
|
||||||
|
|
||||||
private static final String SELECT_AUTHORITIES_FOR_USER = "SELECT ID, ROLE "
|
|
||||||
+ "FROM AUTHORITY "
|
|
||||||
+ "WHERE USER_ID = ?";
|
|
||||||
|
|
||||||
private static final String INSERT_AUTHORITY = "INSERT INTO AUTHORITY ("
|
|
||||||
+ "USER_ID, ROLE"
|
|
||||||
+ ") VALUES ("
|
|
||||||
+ "?, ?"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String DELETE_AUTHORITY = "DELETE FROM AUTHORITY "
|
|
||||||
+ "WHERE USER_ID = ? AND ROLE = ?";
|
|
||||||
|
|
||||||
private static final String DELETE_AUTHORITIES_FOR_USER = "DELETE FROM AUTHORITY "
|
|
||||||
+ "WHERE USER_ID = ?";
|
|
||||||
|
|
||||||
private final Connection connection;
|
|
||||||
|
|
||||||
public StandardAuthorityDAO(Connection connection) {
|
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createAuthorities(Set<Authority> authorities, String userId) throws DataAccessException {
|
|
||||||
if (authorities == null) {
|
|
||||||
throw new IllegalArgumentException("Specified authorities cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there are some authorities to create
|
|
||||||
if (!authorities.isEmpty()) {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// add each authority for the specified user
|
|
||||||
statement = connection.prepareStatement(INSERT_AUTHORITY);
|
|
||||||
statement.setString(1, userId);
|
|
||||||
for (Authority authority : authorities) {
|
|
||||||
statement.setString(2, authority.toString());
|
|
||||||
statement.addBatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert the authorities
|
|
||||||
int[] updateCounts = statement.executeBatch();
|
|
||||||
for (int updateCount : updateCounts) {
|
|
||||||
if (updateCount != 1) {
|
|
||||||
throw new DataAccessException("Unable to insert user authorities.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteAuthorities(String userId) throws DataAccessException {
|
|
||||||
// ensure there are some authorities to create
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// add each authority for the specified user
|
|
||||||
statement = connection.prepareStatement(DELETE_AUTHORITIES_FOR_USER);
|
|
||||||
statement.setString(1, userId);
|
|
||||||
|
|
||||||
// insert the authorities
|
|
||||||
statement.executeUpdate();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteAuthorities(Set<Authority> authorities, String userId) throws DataAccessException {
|
|
||||||
if (authorities == null) {
|
|
||||||
throw new IllegalArgumentException("Specified authorities cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there are some authorities to create
|
|
||||||
if (!authorities.isEmpty()) {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// add each authority for the specified user
|
|
||||||
statement = connection.prepareStatement(DELETE_AUTHORITY);
|
|
||||||
statement.setString(1, userId);
|
|
||||||
for (Authority authority : authorities) {
|
|
||||||
statement.setString(2, authority.toString());
|
|
||||||
statement.addBatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert the authorities
|
|
||||||
int[] updateCounts = statement.executeBatch();
|
|
||||||
for (int updateCount : updateCounts) {
|
|
||||||
if (updateCount != 1) {
|
|
||||||
throw new DataAccessException("Unable to remove user authorities.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Authority> findAuthoritiesByUserId(String userId) throws DataAccessException {
|
|
||||||
Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// add each authority for the specified user
|
|
||||||
statement = connection.prepareStatement(SELECT_AUTHORITIES_FOR_USER);
|
|
||||||
statement.setString(1, userId);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// create each corresponding authority
|
|
||||||
while (rs.next()) {
|
|
||||||
authorities.add(Authority.valueOfAuthority(rs.getString("ROLE")));
|
|
||||||
}
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,641 +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.admin.dao.impl;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.sql.Types;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import org.apache.nifi.admin.RepositoryUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for loading and persisting NiFiUsers.
|
|
||||||
*/
|
|
||||||
public class StandardUserDAO implements UserDAO {
|
|
||||||
|
|
||||||
private static final String SELECT_PENDING_ACCOUNTS_COUNT = "SELECT "
|
|
||||||
+ "COUNT(*) as PENDING_ACCOUNTS "
|
|
||||||
+ "FROM USER U "
|
|
||||||
+ "WHERE U.STATUS = 'PENDING'";
|
|
||||||
|
|
||||||
private static final String SELECT_USER_BY_USER = "SELECT "
|
|
||||||
+ "U.ID, "
|
|
||||||
+ "U.IDENTITY, "
|
|
||||||
+ "U.USER_NAME, "
|
|
||||||
+ "U.USER_GROUP, "
|
|
||||||
+ "U.CREATION, "
|
|
||||||
+ "U.LAST_ACCESSED, "
|
|
||||||
+ "U.LAST_VERIFIED, "
|
|
||||||
+ "U.JUSTIFICATION, "
|
|
||||||
+ "U.STATUS, "
|
|
||||||
+ "A.ROLE "
|
|
||||||
+ "FROM USER U "
|
|
||||||
+ "LEFT JOIN AUTHORITY A " // ensures that users without authorities are still matched
|
|
||||||
+ "ON U.ID = A.USER_ID "
|
|
||||||
+ "WHERE U.IDENTITY = ?";
|
|
||||||
|
|
||||||
private static final String SELECT_USER_BY_ID = "SELECT "
|
|
||||||
+ "U.ID, "
|
|
||||||
+ "U.IDENTITY, "
|
|
||||||
+ "U.USER_NAME, "
|
|
||||||
+ "U.USER_GROUP, "
|
|
||||||
+ "U.CREATION, "
|
|
||||||
+ "U.LAST_ACCESSED, "
|
|
||||||
+ "U.LAST_VERIFIED, "
|
|
||||||
+ "U.JUSTIFICATION, "
|
|
||||||
+ "U.STATUS, "
|
|
||||||
+ "A.ROLE "
|
|
||||||
+ "FROM USER U "
|
|
||||||
+ "LEFT JOIN AUTHORITY A " // ensures that users without authorities are still matched
|
|
||||||
+ "ON U.ID = A.USER_ID "
|
|
||||||
+ "WHERE U.ID = ?";
|
|
||||||
|
|
||||||
private static final String SELECT_USERS = "SELECT "
|
|
||||||
+ "U.ID, "
|
|
||||||
+ "U.IDENTITY, "
|
|
||||||
+ "U.USER_NAME, "
|
|
||||||
+ "U.USER_GROUP, "
|
|
||||||
+ "U.CREATION, "
|
|
||||||
+ "U.LAST_ACCESSED, "
|
|
||||||
+ "U.LAST_VERIFIED, "
|
|
||||||
+ "U.JUSTIFICATION, "
|
|
||||||
+ "U.STATUS, "
|
|
||||||
+ "A.ROLE "
|
|
||||||
+ "FROM USER U "
|
|
||||||
+ "LEFT JOIN AUTHORITY A " // ensures that users without authorities are still matched
|
|
||||||
+ "ON U.ID = A.USER_ID "
|
|
||||||
+ "WHERE U.IDENTITY <> ?";
|
|
||||||
|
|
||||||
private static final String SELECT_USER_GROUPS = "SELECT DISTINCT "
|
|
||||||
+ "U.USER_GROUP "
|
|
||||||
+ "FROM USER U";
|
|
||||||
|
|
||||||
private static final String SELECT_USER_GROUP = "SELECT "
|
|
||||||
+ "U.ID, "
|
|
||||||
+ "U.IDENTITY, "
|
|
||||||
+ "U.USER_NAME, "
|
|
||||||
+ "U.USER_GROUP, "
|
|
||||||
+ "U.CREATION, "
|
|
||||||
+ "U.LAST_ACCESSED, "
|
|
||||||
+ "U.LAST_VERIFIED, "
|
|
||||||
+ "U.JUSTIFICATION, "
|
|
||||||
+ "U.STATUS, "
|
|
||||||
+ "A.ROLE "
|
|
||||||
+ "FROM USER U "
|
|
||||||
+ "LEFT JOIN AUTHORITY A " // ensures that users without authorities are still matched
|
|
||||||
+ "ON U.ID = A.USER_ID "
|
|
||||||
+ "WHERE U.IDENTITY <> ? AND U.USER_GROUP = ?";
|
|
||||||
|
|
||||||
private static final String INSERT_USER = "INSERT INTO USER ("
|
|
||||||
+ "ID, IDENTITY, USER_NAME, USER_GROUP, CREATION, LAST_VERIFIED, JUSTIFICATION, STATUS"
|
|
||||||
+ ") VALUES ("
|
|
||||||
+ "?, "
|
|
||||||
+ "?, "
|
|
||||||
+ "?, "
|
|
||||||
+ "?, "
|
|
||||||
+ "NOW(), "
|
|
||||||
+ "?, "
|
|
||||||
+ "?, "
|
|
||||||
+ "?"
|
|
||||||
+ ")";
|
|
||||||
|
|
||||||
private static final String UPDATE_USER = "UPDATE USER SET "
|
|
||||||
+ "IDENTITY = ?, "
|
|
||||||
+ "USER_NAME = ?, "
|
|
||||||
+ "USER_GROUP = ?, "
|
|
||||||
+ "LAST_ACCESSED = ?, "
|
|
||||||
+ "LAST_VERIFIED = ?, "
|
|
||||||
+ "JUSTIFICATION = ?, "
|
|
||||||
+ "STATUS = ? "
|
|
||||||
+ "WHERE ID = ?";
|
|
||||||
|
|
||||||
private static final String UPDATE_USER_GROUP_STATUS = "UPDATE USER SET "
|
|
||||||
+ "STATUS = ?,"
|
|
||||||
+ "USER_GROUP = NULL "
|
|
||||||
+ "WHERE USER_GROUP = ?";
|
|
||||||
|
|
||||||
private static final String UPDATE_USER_GROUP_VERIFICATION = "UPDATE USER SET "
|
|
||||||
+ "LAST_VERIFIED = ? "
|
|
||||||
+ "WHERE USER_GROUP = ?";
|
|
||||||
|
|
||||||
private static final String UNGROUP_GROUP = "UPDATE USER SET "
|
|
||||||
+ "USER_GROUP = NULL "
|
|
||||||
+ "WHERE USER_GROUP = ?";
|
|
||||||
|
|
||||||
private static final String DELETE_USER = "DELETE FROM USER "
|
|
||||||
+ "WHERE ID = ?";
|
|
||||||
|
|
||||||
private final Connection connection;
|
|
||||||
|
|
||||||
public StandardUserDAO(Connection connection) {
|
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean hasPendingUserAccounts() throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_PENDING_ACCOUNTS_COUNT);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// get the first row which will contain the number of pending accounts
|
|
||||||
if (rs.next()) {
|
|
||||||
int pendingAccounts = rs.getInt("PENDING_ACCOUNTS");
|
|
||||||
return pendingAccounts > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// query returned no results?
|
|
||||||
return false;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<NiFiUser> findUsers() throws DataAccessException {
|
|
||||||
Set<NiFiUser> users = new HashSet<>();
|
|
||||||
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_USERS);
|
|
||||||
statement.setString(1, NiFiUser.ANONYMOUS_USER_IDENTITY);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
NiFiUser user = null;
|
|
||||||
|
|
||||||
// go through the user and its roles
|
|
||||||
while (rs.next()) {
|
|
||||||
// get the user id for the current record
|
|
||||||
String userId = rs.getString("ID");
|
|
||||||
|
|
||||||
// create the user during the first iteration
|
|
||||||
if (user == null || !userId.equals(user.getId())) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(userId);
|
|
||||||
user.setIdentity(rs.getString("IDENTITY"));
|
|
||||||
user.setUserName(rs.getString("USER_NAME"));
|
|
||||||
user.setUserGroup(rs.getString("USER_GROUP"));
|
|
||||||
user.setJustification(rs.getString("JUSTIFICATION"));
|
|
||||||
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
|
|
||||||
|
|
||||||
// set the creation date
|
|
||||||
user.setCreation(new Date(rs.getTimestamp("CREATION").getTime()));
|
|
||||||
|
|
||||||
// get the last accessed date
|
|
||||||
if (rs.getTimestamp("LAST_ACCESSED") != null) {
|
|
||||||
user.setLastAccessed(new Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the last verified date
|
|
||||||
if (rs.getTimestamp("LAST_VERIFIED") != null) {
|
|
||||||
user.setLastVerified(new Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the user
|
|
||||||
users.add(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the select statement performs a left join since the desired
|
|
||||||
// user may not have any authorities
|
|
||||||
String authority = rs.getString("ROLE");
|
|
||||||
if (StringUtils.isNotBlank(authority)) {
|
|
||||||
user.getAuthorities().add(Authority.valueOfAuthority(authority));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return users;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> findUserGroups() throws DataAccessException {
|
|
||||||
Set<String> userGroups = new HashSet<>();
|
|
||||||
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_USER_GROUPS);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// get each user group
|
|
||||||
while (rs.next()) {
|
|
||||||
userGroups.add(rs.getString("USER_GROUP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return userGroups;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<NiFiUser> findUsersForGroup(String group) throws DataAccessException {
|
|
||||||
Set<NiFiUser> users = new HashSet<>();
|
|
||||||
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_USER_GROUP);
|
|
||||||
statement.setString(1, NiFiUser.ANONYMOUS_USER_IDENTITY);
|
|
||||||
statement.setString(2, group);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
NiFiUser user = null;
|
|
||||||
|
|
||||||
// go through the user and its roles
|
|
||||||
while (rs.next()) {
|
|
||||||
// get the user id for the current record
|
|
||||||
String userId = rs.getString("ID");
|
|
||||||
|
|
||||||
// create the user during the first iteration
|
|
||||||
if (user == null || !userId.equals(user.getId())) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(userId);
|
|
||||||
user.setIdentity(rs.getString("IDENTITY"));
|
|
||||||
user.setUserName(rs.getString("USER_NAME"));
|
|
||||||
user.setUserGroup(rs.getString("USER_GROUP"));
|
|
||||||
user.setJustification(rs.getString("JUSTIFICATION"));
|
|
||||||
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
|
|
||||||
|
|
||||||
// set the creation date
|
|
||||||
user.setCreation(new Date(rs.getTimestamp("CREATION").getTime()));
|
|
||||||
|
|
||||||
// get the last accessed date
|
|
||||||
if (rs.getTimestamp("LAST_ACCESSED") != null) {
|
|
||||||
user.setLastAccessed(new Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the last verified date
|
|
||||||
if (rs.getTimestamp("LAST_VERIFIED") != null) {
|
|
||||||
user.setLastVerified(new Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the user
|
|
||||||
users.add(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the select statement performs a left join since the desired
|
|
||||||
// user may not have any authorities
|
|
||||||
String authority = rs.getString("ROLE");
|
|
||||||
if (StringUtils.isNotBlank(authority)) {
|
|
||||||
user.getAuthorities().add(Authority.valueOfAuthority(authority));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return users;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser findUserById(String id) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_USER_BY_ID);
|
|
||||||
statement.setString(1, id);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
NiFiUser user = null;
|
|
||||||
|
|
||||||
// go through the user and its roles
|
|
||||||
while (rs.next()) {
|
|
||||||
// create the user during the first iteration
|
|
||||||
if (user == null) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(rs.getString("ID"));
|
|
||||||
user.setIdentity(rs.getString("IDENTITY"));
|
|
||||||
user.setUserName(rs.getString("USER_NAME"));
|
|
||||||
user.setUserGroup(rs.getString("USER_GROUP"));
|
|
||||||
user.setJustification(rs.getString("JUSTIFICATION"));
|
|
||||||
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
|
|
||||||
|
|
||||||
// set the creation date
|
|
||||||
user.setCreation(new Date(rs.getTimestamp("CREATION").getTime()));
|
|
||||||
|
|
||||||
// get the last accessed date
|
|
||||||
if (rs.getTimestamp("LAST_ACCESSED") != null) {
|
|
||||||
user.setLastAccessed(new Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the last verified date
|
|
||||||
if (rs.getTimestamp("LAST_VERIFIED") != null) {
|
|
||||||
user.setLastVerified(new Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the select statement performs a left join since the desired
|
|
||||||
// user may not have any authorities
|
|
||||||
String authority = rs.getString("ROLE");
|
|
||||||
if (StringUtils.isNotBlank(authority)) {
|
|
||||||
user.getAuthorities().add(Authority.valueOfAuthority(authority));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser findUserByDn(String dn) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// create the connection and obtain a statement
|
|
||||||
statement = connection.prepareStatement(SELECT_USER_BY_USER);
|
|
||||||
statement.setString(1, dn);
|
|
||||||
|
|
||||||
// execute the query
|
|
||||||
rs = statement.executeQuery();
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
NiFiUser user = null;
|
|
||||||
|
|
||||||
// go through the user and its roles
|
|
||||||
while (rs.next()) {
|
|
||||||
// create the user during the first iteration
|
|
||||||
if (user == null) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(rs.getString("ID"));
|
|
||||||
user.setIdentity(rs.getString("IDENTITY"));
|
|
||||||
user.setUserName(rs.getString("USER_NAME"));
|
|
||||||
user.setUserGroup(rs.getString("USER_GROUP"));
|
|
||||||
user.setJustification(rs.getString("JUSTIFICATION"));
|
|
||||||
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
|
|
||||||
|
|
||||||
// set the creation date
|
|
||||||
user.setCreation(new Date(rs.getTimestamp("CREATION").getTime()));
|
|
||||||
|
|
||||||
// get the last accessed date
|
|
||||||
if (rs.getTimestamp("LAST_ACCESSED") != null) {
|
|
||||||
user.setLastAccessed(new Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the last verified date
|
|
||||||
if (rs.getTimestamp("LAST_VERIFIED") != null) {
|
|
||||||
user.setLastVerified(new Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the select statement performs a left join since the desired
|
|
||||||
// user may not have any authorities
|
|
||||||
String authority = rs.getString("ROLE");
|
|
||||||
if (StringUtils.isNotBlank(authority)) {
|
|
||||||
user.getAuthorities().add(Authority.valueOfAuthority(authority));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser createUser(NiFiUser user) throws DataAccessException {
|
|
||||||
if (user.getIdentity() == null) {
|
|
||||||
throw new IllegalArgumentException("User identity must be specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the user identity is not too lengthy
|
|
||||||
if (user.getIdentity().length() > 4096) {
|
|
||||||
throw new IllegalArgumentException("User identity must be less than 4096 characters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
final String id = UUID.nameUUIDFromBytes(user.getIdentity().getBytes(StandardCharsets.UTF_8)).toString();
|
|
||||||
|
|
||||||
// create a statement
|
|
||||||
statement = connection.prepareStatement(INSERT_USER, Statement.RETURN_GENERATED_KEYS);
|
|
||||||
statement.setString(1, id);
|
|
||||||
statement.setString(2, StringUtils.left(user.getIdentity(), 4096));
|
|
||||||
statement.setString(3, StringUtils.left(user.getUserName(), 4096));
|
|
||||||
statement.setString(4, StringUtils.left(user.getUserGroup(), 100));
|
|
||||||
if (user.getLastVerified() != null) {
|
|
||||||
statement.setTimestamp(5, new java.sql.Timestamp(user.getLastVerified().getTime()));
|
|
||||||
} else {
|
|
||||||
statement.setTimestamp(5, null);
|
|
||||||
}
|
|
||||||
statement.setString(6, StringUtils.left(user.getJustification(), 500));
|
|
||||||
statement.setString(7, user.getStatus().toString());
|
|
||||||
|
|
||||||
// insert the user
|
|
||||||
int updateCount = statement.executeUpdate();
|
|
||||||
if (updateCount == 1) {
|
|
||||||
user.setId(id);
|
|
||||||
} else {
|
|
||||||
throw new DataAccessException("Unable to insert user.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(rs);
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteUser(String id) throws DataAccessException {
|
|
||||||
// ensure there are some authorities to create
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// add each authority for the specified user
|
|
||||||
statement = connection.prepareStatement(DELETE_USER);
|
|
||||||
statement.setString(1, id);
|
|
||||||
|
|
||||||
// insert the authorities
|
|
||||||
statement.executeUpdate();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateUser(NiFiUser user) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// create a statement
|
|
||||||
statement = connection.prepareStatement(UPDATE_USER);
|
|
||||||
statement.setString(1, StringUtils.left(user.getIdentity(), 4096));
|
|
||||||
statement.setString(2, StringUtils.left(user.getUserName(), 4096));
|
|
||||||
statement.setString(3, StringUtils.left(user.getUserGroup(), 100));
|
|
||||||
statement.setString(6, StringUtils.left(user.getJustification(), 500));
|
|
||||||
statement.setString(7, user.getStatus().toString());
|
|
||||||
statement.setString(8, user.getId());
|
|
||||||
|
|
||||||
// set the last accessed time accordingly
|
|
||||||
if (user.getLastAccessed() == null) {
|
|
||||||
statement.setNull(4, Types.TIMESTAMP);
|
|
||||||
} else {
|
|
||||||
statement.setTimestamp(4, new java.sql.Timestamp(user.getLastAccessed().getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the last verified time accordingly
|
|
||||||
if (user.getLastVerified() == null) {
|
|
||||||
statement.setNull(5, Types.TIMESTAMP);
|
|
||||||
} else {
|
|
||||||
statement.setTimestamp(5, new java.sql.Timestamp(user.getLastVerified().getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// perform the update
|
|
||||||
int updateCount = statement.executeUpdate();
|
|
||||||
if (updateCount != 1) {
|
|
||||||
throw new DataAccessException("Unable to update user.");
|
|
||||||
}
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateGroupStatus(String group, AccountStatus status) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// create a statement
|
|
||||||
statement = connection.prepareStatement(UPDATE_USER_GROUP_STATUS);
|
|
||||||
statement.setString(1, status.toString());
|
|
||||||
statement.setString(2, group);
|
|
||||||
|
|
||||||
// perform the update
|
|
||||||
statement.executeUpdate();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateGroupVerification(String group, Date lastVerified) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// create a statement
|
|
||||||
statement = connection.prepareStatement(UPDATE_USER_GROUP_VERIFICATION);
|
|
||||||
|
|
||||||
// set the last verified time accordingly
|
|
||||||
if (lastVerified == null) {
|
|
||||||
statement.setNull(1, Types.TIMESTAMP);
|
|
||||||
} else {
|
|
||||||
statement.setTimestamp(1, new java.sql.Timestamp(lastVerified.getTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the group
|
|
||||||
statement.setString(2, group);
|
|
||||||
|
|
||||||
// perform the update
|
|
||||||
statement.executeUpdate();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroup(String group) throws DataAccessException {
|
|
||||||
PreparedStatement statement = null;
|
|
||||||
try {
|
|
||||||
// create a statement
|
|
||||||
statement = connection.prepareStatement(UNGROUP_GROUP);
|
|
||||||
statement.setString(1, group);
|
|
||||||
|
|
||||||
// perform the update
|
|
||||||
statement.executeUpdate();
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
throw new DataAccessException(sqle);
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
throw dae;
|
|
||||||
} finally {
|
|
||||||
RepositoryUtils.closeQuietly(statement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +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.admin.service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception to indicate that the user account is disabled.
|
|
||||||
*/
|
|
||||||
public class AccountNotFoundException extends RuntimeException {
|
|
||||||
|
|
||||||
public AccountNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountNotFoundException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountNotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,41 +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.admin.service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception to indicate that the user has already submitting an account request
|
|
||||||
* and that request is still pending.
|
|
||||||
*/
|
|
||||||
public class AccountPendingException extends RuntimeException {
|
|
||||||
|
|
||||||
public AccountPendingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountPendingException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountPendingException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountPendingException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,25 +16,34 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.admin.service;
|
package org.apache.nifi.admin.service;
|
||||||
|
|
||||||
|
import org.apache.nifi.key.Key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception to indicate that the user account is disabled.
|
* Manages NiFi user keys.
|
||||||
*/
|
*/
|
||||||
public class AccountDisabledException extends RuntimeException {
|
public interface KeyService {
|
||||||
|
|
||||||
public AccountDisabledException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
/**
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
* Gets a key for the specified user identity. Returns null if the user has not had a key issued
|
||||||
}
|
*
|
||||||
|
* @param id The key id
|
||||||
|
* @return The key or null
|
||||||
|
*/
|
||||||
|
Key getKey(int id);
|
||||||
|
|
||||||
public AccountDisabledException(Throwable cause) {
|
/**
|
||||||
super(cause);
|
* Gets a key for the specified user identity. If a key does not exist, one will be created.
|
||||||
}
|
*
|
||||||
|
* @param identity The user identity
|
||||||
public AccountDisabledException(String message, Throwable cause) {
|
* @return The key
|
||||||
super(message, cause);
|
* @throws AdministrationException if it failed to get/create the key
|
||||||
}
|
*/
|
||||||
|
Key getOrCreateKey(String identity);
|
||||||
public AccountDisabledException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes keys for the specified identity.
|
||||||
|
*
|
||||||
|
* @param identity The user identity
|
||||||
|
*/
|
||||||
|
void deleteKey(String identity);
|
||||||
}
|
}
|
|
@ -1,180 +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.admin.service;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
|
||||||
import org.apache.nifi.key.Key;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.nifi.user.NiFiUserGroup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages NiFi user accounts.
|
|
||||||
*/
|
|
||||||
public interface UserService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new user account using the specified dn and justification.
|
|
||||||
*
|
|
||||||
* @param dn user dn
|
|
||||||
* @param justification why the account is necessary
|
|
||||||
* @return the created NiFiUser
|
|
||||||
*/
|
|
||||||
NiFiUser createPendingUserAccount(String dn, String justification);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Determines if there are any PENDING user accounts present
|
|
||||||
*/
|
|
||||||
Boolean hasPendingUserAccount();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dnChain user dn chain
|
|
||||||
* @param attributes attributes for authorization request
|
|
||||||
* @return Determines if the users in the dnChain are authorized to download content with the specified attributes
|
|
||||||
*/
|
|
||||||
DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a user group using the specified group comprised of the specified users. Returns all the users that are currently in the specified group.
|
|
||||||
*
|
|
||||||
* @param group group
|
|
||||||
* @param userIds users
|
|
||||||
* @param authorities auths
|
|
||||||
* @return a user group
|
|
||||||
*/
|
|
||||||
NiFiUserGroup updateGroup(String group, Set<String> userIds, Set<Authority> authorities);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorizes the user specified.
|
|
||||||
*
|
|
||||||
* @param dn user dn
|
|
||||||
* @return the user for the given dn if found
|
|
||||||
*/
|
|
||||||
NiFiUser checkAuthorization(String dn);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the user with the specified id.
|
|
||||||
*
|
|
||||||
* @param id user identifier
|
|
||||||
*/
|
|
||||||
void deleteUser(String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disables the specified users account.
|
|
||||||
*
|
|
||||||
* @param id user identifier
|
|
||||||
* @return user for the given identifier
|
|
||||||
*/
|
|
||||||
NiFiUser disable(String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disables the specified user group.
|
|
||||||
*
|
|
||||||
* @param group to disable
|
|
||||||
* @return user group
|
|
||||||
*/
|
|
||||||
NiFiUserGroup disableGroup(String group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the specified user with the specified authorities.
|
|
||||||
*
|
|
||||||
* @param id identifier of user
|
|
||||||
* @param authorities auths to set
|
|
||||||
* @return the updated user
|
|
||||||
*/
|
|
||||||
NiFiUser update(String id, Set<Authority> authorities);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates the specified user account.
|
|
||||||
*
|
|
||||||
* @param id identifier of user account to invalidate
|
|
||||||
*/
|
|
||||||
void invalidateUserAccount(String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates the user accounts associated with the specified user group.
|
|
||||||
*
|
|
||||||
* @param group to invalidate user accounts on
|
|
||||||
*/
|
|
||||||
void invalidateUserGroupAccount(String group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ungroups the specified group.
|
|
||||||
*
|
|
||||||
* @param group to split up
|
|
||||||
*/
|
|
||||||
void ungroup(String group);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ungroups the specified user.
|
|
||||||
*
|
|
||||||
* @param id user to ungroup
|
|
||||||
*/
|
|
||||||
void ungroupUser(String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a collection of all NiFiUsers.
|
|
||||||
*
|
|
||||||
* @return Collection of users
|
|
||||||
*/
|
|
||||||
Collection<NiFiUser> getUsers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the specified user by id.
|
|
||||||
*
|
|
||||||
* @param id of the user
|
|
||||||
* @return the user object
|
|
||||||
*/
|
|
||||||
NiFiUser getUserById(String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the specified user by dn.
|
|
||||||
*
|
|
||||||
* @param dn the user dn
|
|
||||||
* @return the newly created user
|
|
||||||
* @throws AdministrationException ae
|
|
||||||
*/
|
|
||||||
NiFiUser getUserByDn(String dn);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a key for the specified user identity. Returns null if the user has not had a key issued
|
|
||||||
*
|
|
||||||
* @param id The key id
|
|
||||||
* @return The key or null
|
|
||||||
*/
|
|
||||||
Key getKey(int id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a key for the specified user identity. If a key does not exist, one will be created.
|
|
||||||
*
|
|
||||||
* @param identity The user identity
|
|
||||||
* @return The key
|
|
||||||
* @throws AdministrationException if it failed to get/create the key
|
|
||||||
*/
|
|
||||||
Key getOrCreateKey(String identity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes keys for the specified identity.
|
|
||||||
*
|
|
||||||
* @param identity The user identity
|
|
||||||
*/
|
|
||||||
void deleteKey(String identity);
|
|
||||||
}
|
|
|
@ -1,97 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param <T> type of user action
|
|
||||||
*/
|
|
||||||
public abstract class AbstractUserAction<T> implements AdministrationAction<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the authorities that need to be added to the specified user.
|
|
||||||
*
|
|
||||||
* @param user user
|
|
||||||
* @param authorities auths
|
|
||||||
* @return authorities to add
|
|
||||||
*/
|
|
||||||
protected Set<Authority> determineAuthoritiesToAdd(NiFiUser user, Set<Authority> authorities) {
|
|
||||||
// not using copyOf since authorities may be empty and copyOf can throw an IllegalArgumentException when empty
|
|
||||||
Set<Authority> authoritiesToAdd = EnumSet.noneOf(Authority.class);
|
|
||||||
authoritiesToAdd.addAll(authorities);
|
|
||||||
|
|
||||||
// identify the authorities that need to be inserted
|
|
||||||
authoritiesToAdd.removeAll(user.getAuthorities());
|
|
||||||
|
|
||||||
// return the desired authorities
|
|
||||||
return authoritiesToAdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the authorities that need to be removed from the specified
|
|
||||||
* user.
|
|
||||||
*
|
|
||||||
* @param user user
|
|
||||||
* @param authorities auths
|
|
||||||
* @return auths to remove
|
|
||||||
*/
|
|
||||||
protected Set<Authority> determineAuthoritiesToRemove(NiFiUser user, Set<Authority> authorities) {
|
|
||||||
Set<Authority> authoritiesToRemove = EnumSet.copyOf(user.getAuthorities());
|
|
||||||
|
|
||||||
// identify the authorities that need to be removed
|
|
||||||
authoritiesToRemove.removeAll(authorities);
|
|
||||||
|
|
||||||
// return the desired authorities
|
|
||||||
return authoritiesToRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies the specified users account. Includes obtaining the authorities
|
|
||||||
* and group according to the specified authority provider.
|
|
||||||
*
|
|
||||||
* @param authorityProvider provider
|
|
||||||
* @param user user to verify
|
|
||||||
*/
|
|
||||||
protected void verifyAccount(AuthorityProvider authorityProvider, NiFiUser user) {
|
|
||||||
// load the roles for the user
|
|
||||||
Set<Authority> authorities = authorityProvider.getAuthorities(user.getIdentity());
|
|
||||||
|
|
||||||
// update the user's authorities
|
|
||||||
user.getAuthorities().clear();
|
|
||||||
user.getAuthorities().addAll(authorities);
|
|
||||||
|
|
||||||
// get the user group
|
|
||||||
user.setUserGroup(authorityProvider.getGroupForUser(user.getIdentity()));
|
|
||||||
|
|
||||||
// update the users status in case they were previously pending or disabled
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
|
|
||||||
// update the users last verified time - this timestampt shouldn't be record
|
|
||||||
// until the both the user's authorities and group have been synced
|
|
||||||
Date now = new Date();
|
|
||||||
user.setLastVerified(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.apache.nifi.admin.service.action;
|
||||||
import org.apache.nifi.action.Action;
|
import org.apache.nifi.action.Action;
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ public class AddActionsAction implements AdministrationAction<Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Void execute(DAOFactory daoFactory) {
|
||||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||||
|
|
||||||
// add each action
|
// add each action
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the administration action. Actions are provided a DAO factory and
|
* Defines the administration action. Actions are provided a DAO factory and
|
||||||
|
@ -31,8 +30,7 @@ public interface AdministrationAction<T> {
|
||||||
* Performs an action using the specified DAOFactory and AuthorityProvider.
|
* Performs an action using the specified DAOFactory and AuthorityProvider.
|
||||||
*
|
*
|
||||||
* @param daoFactory factory
|
* @param daoFactory factory
|
||||||
* @param authorityProvider provider
|
|
||||||
* @return action result
|
* @return action result
|
||||||
*/
|
*/
|
||||||
T execute(DAOFactory daoFactory, AuthorityProvider authorityProvider);
|
T execute(DAOFactory daoFactory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to obtain authorization to download the content with the specified
|
|
||||||
* attributes for the specified user.
|
|
||||||
*/
|
|
||||||
public class AuthorizeDownloadAction implements AdministrationAction<DownloadAuthorization> {
|
|
||||||
|
|
||||||
private final List<String> dnChain;
|
|
||||||
private final Map<String, String> attributes;
|
|
||||||
|
|
||||||
public AuthorizeDownloadAction(List<String> dnChain, Map<String, String> attributes) {
|
|
||||||
this.dnChain = dnChain;
|
|
||||||
this.attributes = attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DownloadAuthorization execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
|
||||||
try {
|
|
||||||
return authorityProvider.authorizeDownload(dnChain, attributes);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(uie.getMessage(), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(aae.getMessage(), aae);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,173 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
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.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.security.util.CertificateUtils;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AuthorizeUserAction extends AbstractUserAction<NiFiUser> {
|
|
||||||
|
|
||||||
private final String identity;
|
|
||||||
private final int cacheDurationSeconds;
|
|
||||||
|
|
||||||
public AuthorizeUserAction(String identity, int cacheDurationSeconds) {
|
|
||||||
this.identity = identity;
|
|
||||||
this.cacheDurationSeconds = cacheDurationSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// get the user
|
|
||||||
NiFiUser user = userDao.findUserByDn(identity);
|
|
||||||
|
|
||||||
// verify the user was found
|
|
||||||
if (user == null) {
|
|
||||||
// determine whether this users exists
|
|
||||||
boolean doesDnExist = false;
|
|
||||||
try {
|
|
||||||
doesDnExist = authorityProvider.doesDnExist(identity);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the authority provider has the details for this user, create the account
|
|
||||||
if (doesDnExist) {
|
|
||||||
// create the user
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setIdentity(identity);
|
|
||||||
user.setUserName(CertificateUtils.extractUsername(identity));
|
|
||||||
user.setJustification("User details specified by authority provider.");
|
|
||||||
|
|
||||||
try {
|
|
||||||
// verify the users account
|
|
||||||
verifyAccount(authorityProvider, user);
|
|
||||||
|
|
||||||
// get the date used for verification
|
|
||||||
Date now = user.getLastVerified();
|
|
||||||
|
|
||||||
// update the last accessed field
|
|
||||||
user.setLastAccessed(now);
|
|
||||||
user.setCreation(now);
|
|
||||||
|
|
||||||
// create the new user account
|
|
||||||
CreateUserAction createUser = new CreateUserAction(user);
|
|
||||||
createUser.execute(daoFactory, authorityProvider);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
// strange since the provider just reported this dn existed but handleing anyways...
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to verify access for %s.", identity));
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to verify access for %s.", identity));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Throwable providerError = null;
|
|
||||||
|
|
||||||
// verify the users account if necessary
|
|
||||||
if (isAccountVerificationRequired(user)) {
|
|
||||||
try {
|
|
||||||
// verify the users account
|
|
||||||
verifyAccount(authorityProvider, user);
|
|
||||||
|
|
||||||
// update the last accessed field
|
|
||||||
user.setLastAccessed(user.getLastVerified());
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
// check the account status before attempting to update the account - depending on the account
|
|
||||||
// status we might not need to update the account
|
|
||||||
checkAccountStatus(user);
|
|
||||||
|
|
||||||
// the user is currently active and they were not found in the providers - disable the account...
|
|
||||||
user.setStatus(AccountStatus.DISABLED);
|
|
||||||
|
|
||||||
// record the exception
|
|
||||||
providerError = uie;
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// verfiy the users account status before allowing access.
|
|
||||||
checkAccountStatus(user);
|
|
||||||
|
|
||||||
// update the users last accessed time
|
|
||||||
user.setLastAccessed(new Date());
|
|
||||||
}
|
|
||||||
|
|
||||||
// persist the user's updates
|
|
||||||
UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
|
|
||||||
updateUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// persist the user's authorities
|
|
||||||
UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user);
|
|
||||||
updateUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
if (providerError != null) {
|
|
||||||
throw new AccountDisabledException(String.format("User credentials for %s were not found. This account has been disabled.", user.getIdentity()), providerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Determines if account verification is required
|
|
||||||
*/
|
|
||||||
private boolean isAccountVerificationRequired(NiFiUser user) {
|
|
||||||
// accounts that have never been verified obviously needs to be re-verified
|
|
||||||
if (user.getLastVerified() == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a calendar and substract the threshold - anything
|
|
||||||
// before this time will need to be re-verified
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.add(Calendar.SECOND, -cacheDurationSeconds);
|
|
||||||
|
|
||||||
return user.getLastVerified().before(calendar.getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the account status of the specified user.
|
|
||||||
*
|
|
||||||
* @param user to check
|
|
||||||
*/
|
|
||||||
private void checkAccountStatus(NiFiUser user) {
|
|
||||||
if (AccountStatus.DISABLED.equals(user.getStatus())) {
|
|
||||||
throw new AccountDisabledException(String.format("The account for %s has been disabled.", user.getIdentity()));
|
|
||||||
} else if (AccountStatus.PENDING.equals(user.getStatus())) {
|
|
||||||
throw new AccountPendingException(String.format("The account for %s is currently pending approval.", user.getIdentity()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action for creating a NiFiUser account.
|
|
||||||
*/
|
|
||||||
public class CreateUserAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private final NiFiUser user;
|
|
||||||
|
|
||||||
public CreateUserAction(NiFiUser user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
AuthorityDAO authorityDao = daoFactory.getAuthorityDAO();
|
|
||||||
|
|
||||||
// create the user entry
|
|
||||||
userDao.createUser(user);
|
|
||||||
|
|
||||||
// create the authorities
|
|
||||||
Set<Authority> authorities = user.getAuthorities();
|
|
||||||
authorityDao.createAuthorities(authorities, user.getId());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.apache.nifi.admin.service.action;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
import org.apache.nifi.admin.dao.DataAccessException;
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
import org.apache.nifi.admin.dao.KeyDAO;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -38,7 +37,7 @@ public class DeleteKeysAction implements AdministrationAction<Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
public Void execute(DAOFactory daoFactory) throws DataAccessException {
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||||
keyDao.deleteKeys(identity);
|
keyDao.deleteKeys(identity);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,73 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DeleteUserAction implements AdministrationAction<Void> {
|
|
||||||
|
|
||||||
private final String userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new transactions for deleting the specified user.
|
|
||||||
*
|
|
||||||
* @param userId user identifier
|
|
||||||
*/
|
|
||||||
public DeleteUserAction(String userId) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
final AuthorityDAO authorityDAO = daoFactory.getAuthorityDAO();
|
|
||||||
final UserDAO userDAO = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// find the user and ensure they are currently revoked
|
|
||||||
final NiFiUser user = userDAO.findUserById(userId);
|
|
||||||
|
|
||||||
// ensure the user was found
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the user is in the appropriate state
|
|
||||||
if (AccountStatus.ACTIVE.equals(user.getStatus())) {
|
|
||||||
throw new IllegalStateException(String.format("An active user cannot be removed. Revoke user access before attempting to remove."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the user's keys
|
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
|
||||||
keyDao.deleteKeys(user.getIdentity());
|
|
||||||
|
|
||||||
// remove the user and their authorities
|
|
||||||
authorityDAO.deleteAuthorities(userId);
|
|
||||||
userDAO.deleteUser(userId);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DisableUserAction implements AdministrationAction<NiFiUser> {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DisableUserAction.class);
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public DisableUserAction(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// get the user
|
|
||||||
NiFiUser user = userDao.findUserById(id);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the account
|
|
||||||
user.setStatus(AccountStatus.DISABLED);
|
|
||||||
user.setUserGroup(null);
|
|
||||||
|
|
||||||
// update the user locally
|
|
||||||
userDao.updateUser(user);
|
|
||||||
|
|
||||||
// remove the user's keys
|
|
||||||
KeyDAO keyDao = daoFactory.getKeyDAO();
|
|
||||||
keyDao.deleteKeys(user.getIdentity());
|
|
||||||
|
|
||||||
try {
|
|
||||||
// revoke the user in the authority provider
|
|
||||||
authorityProvider.revokeUser(user.getIdentity());
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
// user identity is not known
|
|
||||||
logger.info(String.format("User %s has already been removed from the authority provider.", user.getIdentity()));
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to revoke user '%s': %s", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.nifi.user.NiFiUserGroup;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DisableUserGroupAction implements AdministrationAction<NiFiUserGroup> {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DisableUserGroupAction.class);
|
|
||||||
|
|
||||||
private final String group;
|
|
||||||
|
|
||||||
public DisableUserGroupAction(final String group) {
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUserGroup execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
final UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
final Set<NiFiUser> users = userDao.findUsersForGroup(group);
|
|
||||||
|
|
||||||
// delete the keys for each user
|
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
|
||||||
for (final NiFiUser user : users) {
|
|
||||||
keyDao.deleteKeys(user.getIdentity());
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the user group locally
|
|
||||||
userDao.updateGroupStatus(group, AccountStatus.DISABLED);
|
|
||||||
|
|
||||||
// populate the group details
|
|
||||||
final NiFiUserGroup userGroup = new NiFiUserGroup();
|
|
||||||
userGroup.setGroup(group);
|
|
||||||
userGroup.setUsers(userDao.findUsersForGroup(group));
|
|
||||||
|
|
||||||
try {
|
|
||||||
// revoke the user in the authority provider
|
|
||||||
authorityProvider.revokeGroup(group);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
// user identity is not known
|
|
||||||
logger.info(String.format("User group %s has already been removed from the authority provider.", group));
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to revoke user group '%s': %s", group, aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
return userGroup;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class FindUserByDnAction implements AdministrationAction<NiFiUser> {
|
|
||||||
|
|
||||||
private final String dn;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new transactions for getting a user with the specified DN.
|
|
||||||
*
|
|
||||||
* @param dn The DN of the user to obtain
|
|
||||||
*/
|
|
||||||
public FindUserByDnAction(String dn) {
|
|
||||||
this.dn = dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
// get a UserDAO
|
|
||||||
UserDAO userDAO = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// return the desired user
|
|
||||||
return userDAO.findUserByDn(dn);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
public class FindUserByIdAction implements AdministrationAction<NiFiUser> {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new transactions for getting a user with the specified id.
|
|
||||||
*
|
|
||||||
* @param id of user
|
|
||||||
*/
|
|
||||||
public FindUserByIdAction(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
// get a UserDAO
|
|
||||||
UserDAO userDAO = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// return the desired user
|
|
||||||
return userDAO.findUserById(id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.apache.nifi.admin.service.action;
|
||||||
import org.apache.nifi.action.Action;
|
import org.apache.nifi.action.Action;
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the action with the specified id.
|
* Gets the action with the specified id.
|
||||||
|
@ -33,7 +32,7 @@ public class GetActionAction implements AdministrationAction<Action> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Action execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Action execute(DAOFactory daoFactory) {
|
||||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||||
return actionDao.getAction(id);
|
return actionDao.getAction(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.history.History;
|
import org.apache.nifi.history.History;
|
||||||
import org.apache.nifi.history.HistoryQuery;
|
import org.apache.nifi.history.HistoryQuery;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all actions that match the specified query.
|
* Get all actions that match the specified query.
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ public class GetActionsAction implements AdministrationAction<History> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public History execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public History execute(DAOFactory daoFactory) {
|
||||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||||
|
|
||||||
// find all matching history
|
// find all matching history
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
import org.apache.nifi.admin.dao.KeyDAO;
|
||||||
import org.apache.nifi.key.Key;
|
import org.apache.nifi.key.Key;
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ public class GetKeyByIdAction implements AdministrationAction<Key> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Key execute(DAOFactory daoFactory) {
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||||
return keyDao.findKeyById(id);
|
return keyDao.findKeyById(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
import org.apache.nifi.admin.dao.KeyDAO;
|
||||||
import org.apache.nifi.key.Key;
|
import org.apache.nifi.key.Key;
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ public class GetKeyByIdentityAction implements AdministrationAction<Key> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Key execute(DAOFactory daoFactory) {
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||||
return keyDao.findLatestKeyByIdentity(identity);
|
return keyDao.findLatestKeyByIdentity(identity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
import org.apache.nifi.admin.dao.KeyDAO;
|
||||||
import org.apache.nifi.key.Key;
|
import org.apache.nifi.key.Key;
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ public class GetOrCreateKeyAction implements AdministrationAction<Key> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Key execute(DAOFactory daoFactory) {
|
||||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||||
|
|
||||||
Key key = keyDao.findLatestKeyByIdentity(identity);
|
Key key = keyDao.findLatestKeyByIdentity(identity);
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.admin.service.action;
|
package org.apache.nifi.admin.service.action;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.history.PreviousValue;
|
import org.apache.nifi.history.PreviousValue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the action with the specified id.
|
* Gets the action with the specified id.
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ public class GetPreviousValues implements AdministrationAction<Map<String, List<
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, List<PreviousValue>> execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Map<String, List<PreviousValue>> execute(DAOFactory daoFactory) {
|
||||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||||
return actionDao.getPreviousValues(componentId);
|
return actionDao.getPreviousValues(componentId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,50 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUserGroup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GetUserGroupAction implements AdministrationAction<NiFiUserGroup> {
|
|
||||||
|
|
||||||
private final String group;
|
|
||||||
|
|
||||||
public GetUserGroupAction(String group) {
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUserGroup execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
final UserDAO userDAO = daoFactory.getUserDAO();
|
|
||||||
final NiFiUserGroup userGroup = new NiFiUserGroup();
|
|
||||||
|
|
||||||
// set the group
|
|
||||||
userGroup.setGroup(group);
|
|
||||||
|
|
||||||
// get the users in this group
|
|
||||||
userGroup.setUsers(userDAO.findUsersForGroup(group));
|
|
||||||
|
|
||||||
// return the group
|
|
||||||
return userGroup;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GetUsersAction implements AdministrationAction<Collection<NiFiUser>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<NiFiUser> execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
// get a UserDAO
|
|
||||||
UserDAO userDAO = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// return the desired user
|
|
||||||
return userDAO.findUsers();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
package org.apache.nifi.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action for creating a NiFiUser account.
|
|
||||||
*/
|
|
||||||
public class HasPendingUserAccounts extends AbstractUserAction<Boolean> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
return userDao.hasPendingUserAccounts();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates a user account.
|
|
||||||
*/
|
|
||||||
public class InvalidateUserAccountAction implements AdministrationAction<Void> {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public InvalidateUserAccountAction(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// get the current user details
|
|
||||||
NiFiUser user = userDao.findUserById(id);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// invalidate the user account
|
|
||||||
user.setLastVerified(null);
|
|
||||||
|
|
||||||
// create the user entry
|
|
||||||
userDao.updateUser(user);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,45 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates a user account.
|
|
||||||
*/
|
|
||||||
public class InvalidateUserGroupAccountsAction implements AdministrationAction<Void> {
|
|
||||||
|
|
||||||
private final String group;
|
|
||||||
|
|
||||||
public InvalidateUserGroupAccountsAction(String group) {
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// create the user entry
|
|
||||||
userDao.updateGroupVerification(group, null);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.apache.nifi.admin.service.action;
|
||||||
import org.apache.nifi.action.Action;
|
import org.apache.nifi.action.Action;
|
||||||
import org.apache.nifi.admin.dao.ActionDAO;
|
import org.apache.nifi.admin.dao.ActionDAO;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ public class PurgeActionsAction implements AdministrationAction<Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
public Void execute(DAOFactory daoFactory) {
|
||||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||||
|
|
||||||
// remove the corresponding actions
|
// remove the corresponding actions
|
||||||
|
|
|
@ -1,67 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.security.util.CertificateUtils;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class RequestUserAccountAction implements AdministrationAction<NiFiUser> {
|
|
||||||
|
|
||||||
private final String identity;
|
|
||||||
private final String justification;
|
|
||||||
|
|
||||||
public RequestUserAccountAction(String identity, String justification) {
|
|
||||||
this.identity = identity;
|
|
||||||
this.justification = justification;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// determine if this user already exists
|
|
||||||
NiFiUser user = userDao.findUserByDn(identity);
|
|
||||||
if (user != null) {
|
|
||||||
throw new IllegalArgumentException(String.format("User account for %s already exists.", identity));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setIdentity(identity);
|
|
||||||
user.setUserName(CertificateUtils.extractUsername(identity));
|
|
||||||
user.setJustification(justification);
|
|
||||||
user.setStatus(AccountStatus.PENDING);
|
|
||||||
|
|
||||||
// update user timestamps
|
|
||||||
Date now = new Date();
|
|
||||||
user.setCreation(now);
|
|
||||||
|
|
||||||
// create the new user account
|
|
||||||
userDao.createUser(user);
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,164 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.security.util.CertificateUtils;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seeds the user accounts. This action is performed at start up because it
|
|
||||||
* takes the users specified in the authority provider and makes them available
|
|
||||||
* to be seen in the UI. This happens because the UI loads the users from the
|
|
||||||
* cache. Without pre loading the users, the table in the UI would only show a
|
|
||||||
* given user once they have visited the application.
|
|
||||||
*/
|
|
||||||
public class SeedUserAccountsAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SeedUserAccountsAction.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
Set<String> authorizedIdentities = new HashSet<>();
|
|
||||||
|
|
||||||
// get the current user cache
|
|
||||||
final Set<NiFiUser> existingUsers;
|
|
||||||
try {
|
|
||||||
existingUsers = userDao.findUsers();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// unable to access local cache... start up failure
|
|
||||||
logger.error(String.format("Unable to get existing user base. Cannot proceed until these users can be "
|
|
||||||
+ "verified against the current authority provider: %s", e));
|
|
||||||
throw new AdministrationException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// all users for all roles
|
|
||||||
for (final Authority authority : Authority.values()) {
|
|
||||||
authorizedIdentities.addAll(authorityProvider.getUsers(authority));
|
|
||||||
}
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
// unable to access the authority provider... honor the cache
|
|
||||||
logger.warn("Unable to access authority provider due to " + aae);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Set<NiFiUser> accountsToRevoke = new HashSet<>(existingUsers);
|
|
||||||
|
|
||||||
// persist the users
|
|
||||||
for (String identity : authorizedIdentities) {
|
|
||||||
NiFiUser user = null;
|
|
||||||
try {
|
|
||||||
// locate the user for this dn
|
|
||||||
user = userDao.findUserByDn(identity);
|
|
||||||
boolean newAccount = false;
|
|
||||||
|
|
||||||
// if the user does not exist, create a new account
|
|
||||||
if (user == null) {
|
|
||||||
logger.info(String.format("Creating user account: %s", identity));
|
|
||||||
newAccount = true;
|
|
||||||
|
|
||||||
// create the user
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setIdentity(identity);
|
|
||||||
user.setUserName(CertificateUtils.extractUsername(identity));
|
|
||||||
user.setJustification("User details specified by authority provider.");
|
|
||||||
} else {
|
|
||||||
logger.info(String.format("User account already created: %s. Updating authorities...", identity));
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify the account
|
|
||||||
verifyAccount(authorityProvider, user);
|
|
||||||
|
|
||||||
// persist the account accordingly
|
|
||||||
if (newAccount) {
|
|
||||||
CreateUserAction createUser = new CreateUserAction(user);
|
|
||||||
createUser.execute(daoFactory, authorityProvider);
|
|
||||||
} else {
|
|
||||||
// this is not a new user and we have just verified their
|
|
||||||
// account, do not revoke...
|
|
||||||
accountsToRevoke.remove(user);
|
|
||||||
|
|
||||||
// persist the user
|
|
||||||
UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
|
|
||||||
updateUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// persist the user's authorities
|
|
||||||
UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user);
|
|
||||||
updateUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
} catch (DataAccessException dae) {
|
|
||||||
if (user != null) {
|
|
||||||
logger.warn(String.format("Unable to access account details in local cache for user %s: %s", user, dae.getMessage()));
|
|
||||||
} else {
|
|
||||||
logger.warn(String.format("Unable to access account details in local cache: %s", dae.getMessage()));
|
|
||||||
}
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
if (user != null) {
|
|
||||||
logger.warn(String.format("Unable to find account details in authority provider for user %s: %s", user, uie.getMessage()));
|
|
||||||
} else {
|
|
||||||
logger.warn(String.format("Unable to find account details in authority provider: %s", uie.getMessage()));
|
|
||||||
}
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
logger.warn("Unable to access authority provider due to " + aae);
|
|
||||||
|
|
||||||
// unable to access authority provider for this user, honor the cache for now
|
|
||||||
accountsToRevoke.remove(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all users that are no longer in the provider
|
|
||||||
for (final NiFiUser user : accountsToRevoke) {
|
|
||||||
// allow pending requests to remain...
|
|
||||||
if (AccountStatus.PENDING.equals(user.getStatus())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
logger.info(String.format("User not authorized with configured provider: %s. Disabling account...", user.getIdentity()));
|
|
||||||
|
|
||||||
// disable the account and reset its last verified timestamp since it was not found
|
|
||||||
// in the current configured authority provider
|
|
||||||
user.setStatus(AccountStatus.DISABLED);
|
|
||||||
user.setLastVerified(null);
|
|
||||||
|
|
||||||
// update the user record
|
|
||||||
UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
|
|
||||||
updateUser.execute(daoFactory, authorityProvider);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// unable to revoke access for someone we know is not authorized... fail start up
|
|
||||||
logger.error(String.format("Unable to revoke access for user %s that is no longer authorized: %s", user, e));
|
|
||||||
throw new AdministrationException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class UngroupUserAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private final String userId;
|
|
||||||
|
|
||||||
public UngroupUserAction(String userId) {
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
|
||||||
final UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// get the user in question
|
|
||||||
final NiFiUser user = userDao.findUserById(userId);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the user group
|
|
||||||
user.setUserGroup(null);
|
|
||||||
|
|
||||||
// update the user locally
|
|
||||||
userDao.updateUser(user);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// update the authority provider
|
|
||||||
authorityProvider.ungroupUser(user.getIdentity());
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to ungroup user '%s': %s", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to ungroup user '%s': %s", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,57 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class UngroupUserGroupAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private final String group;
|
|
||||||
|
|
||||||
public UngroupUserGroupAction(String group) {
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
|
||||||
final UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// update the user locally
|
|
||||||
userDao.ungroup(group);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// update the authority provider
|
|
||||||
authorityProvider.ungroup(group);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to ungroup '%s': %s", group, uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to ungroup '%s': %s", group, aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,124 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets user authorities.
|
|
||||||
*/
|
|
||||||
public class UpdateUserAction extends AbstractUserAction<NiFiUser> {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UpdateUserAction.class);
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
private final Set<Authority> authorities;
|
|
||||||
|
|
||||||
public UpdateUserAction(String id, Set<Authority> authorities) {
|
|
||||||
this.id = id;
|
|
||||||
this.authorities = authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException, AdministrationException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// get the user
|
|
||||||
NiFiUser user = userDao.findUserById(id);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine whether this users exists
|
|
||||||
boolean doesIdentityExist = false;
|
|
||||||
try {
|
|
||||||
doesIdentityExist = authorityProvider.doesDnExist(user.getIdentity());
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the user already doesn't exist, add them
|
|
||||||
if (!doesIdentityExist) {
|
|
||||||
try {
|
|
||||||
// add the account account and group if necessary
|
|
||||||
authorityProvider.addUser(user.getIdentity(), user.getUserGroup());
|
|
||||||
} catch (final IdentityAlreadyExistsException iaee) {
|
|
||||||
logger.warn(String.format("User '%s' already exists in the authority provider. Continuing with user update.", user.getIdentity()));
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authorities for '%s': %s", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// update the authority provider as approprivate
|
|
||||||
authorityProvider.setAuthorities(user.getIdentity(), authorities);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to modify authorities for '%s': %s.", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// get the user group
|
|
||||||
user.setUserGroup(authorityProvider.getGroupForUser(user.getIdentity()));
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to determine the group for '%s': %s.", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access the group for '%s': %s.", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
// since all the authorities were updated accordingly, set the authorities
|
|
||||||
user.getAuthorities().clear();
|
|
||||||
user.getAuthorities().addAll(authorities);
|
|
||||||
|
|
||||||
// update the users status in case they were previously pending or disabled
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
|
|
||||||
// update the users last verified time - this timestamp shouldn't be recorded
|
|
||||||
// until the both the user's authorities and group have been synced
|
|
||||||
Date now = new Date();
|
|
||||||
user.setLastVerified(now);
|
|
||||||
|
|
||||||
// persist the user's updates
|
|
||||||
UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
|
|
||||||
updateUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// persist the user's authorities
|
|
||||||
UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user);
|
|
||||||
updateUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a NiFiUser's authorities. Prior to invoking this action, the user's
|
|
||||||
* authorities should be set according to the business logic of the service in
|
|
||||||
* question. This should not be invoked directly when attempting to set user
|
|
||||||
* authorities as the authorityProvider is not called from this action.
|
|
||||||
*/
|
|
||||||
public class UpdateUserAuthoritiesCacheAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private final NiFiUser user;
|
|
||||||
|
|
||||||
public UpdateUserAuthoritiesCacheAction(NiFiUser user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
AuthorityDAO authorityDao = daoFactory.getAuthorityDAO();
|
|
||||||
|
|
||||||
// get the user
|
|
||||||
NiFiUser currentUser = userDao.findUserById(user.getId());
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (currentUser == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", user.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine what authorities need to be added/removed
|
|
||||||
Set<Authority> authorities = user.getAuthorities();
|
|
||||||
Set<Authority> authoritiesToAdd = determineAuthoritiesToAdd(currentUser, authorities);
|
|
||||||
Set<Authority> authoritiesToRemove = determineAuthoritiesToRemove(currentUser, authorities);
|
|
||||||
|
|
||||||
// update the user authorities locally
|
|
||||||
if (CollectionUtils.isNotEmpty(authoritiesToAdd)) {
|
|
||||||
authorityDao.createAuthorities(authoritiesToAdd, user.getId());
|
|
||||||
}
|
|
||||||
if (CollectionUtils.isNotEmpty(authoritiesToRemove)) {
|
|
||||||
authorityDao.deleteAuthorities(authoritiesToRemove, user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,47 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a NiFiUser. This will not update the user authorities, they must be
|
|
||||||
* updated with the UpdateUserAuthoritiesAction.
|
|
||||||
*/
|
|
||||||
public class UpdateUserCacheAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private final NiFiUser user;
|
|
||||||
|
|
||||||
public UpdateUserCacheAction(NiFiUser user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// update the user
|
|
||||||
userDao.updateUser(user);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,171 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates all NiFiUser authorities in a specified group.
|
|
||||||
*/
|
|
||||||
public class UpdateUserGroupAction extends AbstractUserAction<Void> {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UpdateUserGroupAction.class);
|
|
||||||
|
|
||||||
private final String group;
|
|
||||||
private final Set<String> userIds;
|
|
||||||
private final Set<Authority> authorities;
|
|
||||||
|
|
||||||
public UpdateUserGroupAction(String group, Set<String> userIds, Set<Authority> authorities) {
|
|
||||||
this.group = group;
|
|
||||||
this.userIds = userIds;
|
|
||||||
this.authorities = authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
|
||||||
if (userIds == null && authorities == null) {
|
|
||||||
throw new IllegalArgumentException("Must specify user Ids or authorities.");
|
|
||||||
}
|
|
||||||
|
|
||||||
UserDAO userDao = daoFactory.getUserDAO();
|
|
||||||
|
|
||||||
// record the new users being added to this group
|
|
||||||
final Set<NiFiUser> newUsers = new HashSet<>();
|
|
||||||
final Set<String> newUserIdentities = new HashSet<>();
|
|
||||||
|
|
||||||
// if the user ids have been specified we need to create/update a group using the specified group name
|
|
||||||
if (userIds != null) {
|
|
||||||
if (userIds.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("When creating a group, at least one user id must be specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// going to create a group using the specified user ids
|
|
||||||
for (final String userId : userIds) {
|
|
||||||
// get the user in question
|
|
||||||
final NiFiUser user = userDao.findUserById(userId);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (user == null) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// if the user is unknown to the authority provider we cannot continue
|
|
||||||
if (!authorityProvider.doesDnExist(user.getIdentity()) || AccountStatus.DISABLED.equals(user.getStatus())) {
|
|
||||||
throw new IllegalStateException(String.format("Unable to group these users because access for '%s' is not %s.", user.getIdentity(), AccountStatus.ACTIVE.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// record the user being added to this group
|
|
||||||
newUsers.add(user);
|
|
||||||
newUserIdentities.add(user.getIdentity());
|
|
||||||
} catch (final AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// update the authority provider
|
|
||||||
authorityProvider.setUsersGroup(newUserIdentities, group);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to set user group '%s': %s", StringUtils.join(newUserIdentities, ", "), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to set user group '%s': %s", StringUtils.join(newUserIdentities, ", "), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all the users that need to be updated
|
|
||||||
final Set<NiFiUser> users = new HashSet<>(userDao.findUsersForGroup(group));
|
|
||||||
users.addAll(newUsers);
|
|
||||||
|
|
||||||
// ensure the user exists
|
|
||||||
if (users.isEmpty()) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to find user accounts with group id %s.", group));
|
|
||||||
}
|
|
||||||
|
|
||||||
// update each user in this group
|
|
||||||
for (final NiFiUser user : users) {
|
|
||||||
// if there are new authorities set them, otherwise refresh them according to the provider
|
|
||||||
if (authorities != null) {
|
|
||||||
try {
|
|
||||||
// update the authority provider as approprivate
|
|
||||||
authorityProvider.setAuthorities(user.getIdentity(), authorities);
|
|
||||||
|
|
||||||
// since all the authorities were updated accordingly, set the authorities
|
|
||||||
user.getAuthorities().clear();
|
|
||||||
user.getAuthorities().addAll(authorities);
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to modify authorities for '%s': %s.", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
// refresh the authorities according to the provider
|
|
||||||
user.getAuthorities().clear();
|
|
||||||
user.getAuthorities().addAll(authorityProvider.getAuthorities(user.getIdentity()));
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to determine the authorities for '%s': %s.", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// get the user group
|
|
||||||
user.setUserGroup(authorityProvider.getGroupForUser(user.getIdentity()));
|
|
||||||
} catch (UnknownIdentityException uie) {
|
|
||||||
throw new AccountNotFoundException(String.format("Unable to determine the group for '%s': %s.", user.getIdentity(), uie.getMessage()), uie);
|
|
||||||
} catch (AuthorityAccessException aae) {
|
|
||||||
throw new AdministrationException(String.format("Unable to access the group for '%s': %s.", user.getIdentity(), aae.getMessage()), aae);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the users status in case they were previously pending or disabled
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
|
|
||||||
// update the users last verified time - this timestamp shouldn't be recorded
|
|
||||||
// until the both the user's authorities and group have been synced
|
|
||||||
Date now = new Date();
|
|
||||||
user.setLastVerified(now);
|
|
||||||
|
|
||||||
// persist the user's updates
|
|
||||||
UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
|
|
||||||
updateUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// persist the user's authorities
|
|
||||||
UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user);
|
|
||||||
updateUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.service.impl;
|
||||||
|
|
||||||
|
import org.apache.nifi.admin.dao.DataAccessException;
|
||||||
|
import org.apache.nifi.admin.service.AdministrationException;
|
||||||
|
import org.apache.nifi.admin.service.KeyService;
|
||||||
|
import org.apache.nifi.admin.service.action.DeleteKeysAction;
|
||||||
|
import org.apache.nifi.admin.service.action.GetKeyByIdAction;
|
||||||
|
import org.apache.nifi.admin.service.action.GetOrCreateKeyAction;
|
||||||
|
import org.apache.nifi.admin.service.transaction.Transaction;
|
||||||
|
import org.apache.nifi.admin.service.transaction.TransactionBuilder;
|
||||||
|
import org.apache.nifi.admin.service.transaction.TransactionException;
|
||||||
|
import org.apache.nifi.key.Key;
|
||||||
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class StandardKeyService implements KeyService {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(StandardKeyService.class);
|
||||||
|
|
||||||
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
private final Lock readLock = lock.readLock();
|
||||||
|
private final Lock writeLock = lock.writeLock();
|
||||||
|
|
||||||
|
private TransactionBuilder transactionBuilder;
|
||||||
|
private NiFiProperties properties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Key getKey(int id) {
|
||||||
|
Transaction transaction = null;
|
||||||
|
Key key = null;
|
||||||
|
|
||||||
|
readLock.lock();
|
||||||
|
try {
|
||||||
|
// start the transaction
|
||||||
|
transaction = transactionBuilder.start();
|
||||||
|
|
||||||
|
// get the key
|
||||||
|
GetKeyByIdAction addActions = new GetKeyByIdAction(id);
|
||||||
|
key = transaction.execute(addActions);
|
||||||
|
|
||||||
|
// commit the transaction
|
||||||
|
transaction.commit();
|
||||||
|
} catch (TransactionException | DataAccessException te) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw new AdministrationException(te);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw t;
|
||||||
|
} finally {
|
||||||
|
closeQuietly(transaction);
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Key getOrCreateKey(String identity) {
|
||||||
|
Transaction transaction = null;
|
||||||
|
Key key = null;
|
||||||
|
|
||||||
|
writeLock.lock();
|
||||||
|
try {
|
||||||
|
// start the transaction
|
||||||
|
transaction = transactionBuilder.start();
|
||||||
|
|
||||||
|
// get or create a key
|
||||||
|
GetOrCreateKeyAction addActions = new GetOrCreateKeyAction(identity);
|
||||||
|
key = transaction.execute(addActions);
|
||||||
|
|
||||||
|
// commit the transaction
|
||||||
|
transaction.commit();
|
||||||
|
} catch (TransactionException | DataAccessException te) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw new AdministrationException(te);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw t;
|
||||||
|
} finally {
|
||||||
|
closeQuietly(transaction);
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKey(String identity) {
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
writeLock.lock();
|
||||||
|
try {
|
||||||
|
// start the transaction
|
||||||
|
transaction = transactionBuilder.start();
|
||||||
|
|
||||||
|
// delete the keys
|
||||||
|
DeleteKeysAction deleteKeys = new DeleteKeysAction(identity);
|
||||||
|
transaction.execute(deleteKeys);
|
||||||
|
|
||||||
|
// commit the transaction
|
||||||
|
transaction.commit();
|
||||||
|
} catch (TransactionException | DataAccessException te) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw new AdministrationException(te);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
rollback(transaction);
|
||||||
|
throw t;
|
||||||
|
} finally {
|
||||||
|
closeQuietly(transaction);
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rollback(final Transaction transaction) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeQuietly(final Transaction transaction) {
|
||||||
|
if (transaction != null) {
|
||||||
|
try {
|
||||||
|
transaction.close();
|
||||||
|
} catch (final IOException ioe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionBuilder(TransactionBuilder transactionBuilder) {
|
||||||
|
this.transactionBuilder = transactionBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(NiFiProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,731 +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.admin.service.impl;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.service.AccountDisabledException;
|
|
||||||
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.admin.service.action.AuthorizeDownloadAction;
|
|
||||||
import org.apache.nifi.admin.service.action.AuthorizeUserAction;
|
|
||||||
import org.apache.nifi.admin.service.action.DeleteKeysAction;
|
|
||||||
import org.apache.nifi.admin.service.action.DeleteUserAction;
|
|
||||||
import org.apache.nifi.admin.service.action.DisableUserAction;
|
|
||||||
import org.apache.nifi.admin.service.action.DisableUserGroupAction;
|
|
||||||
import org.apache.nifi.admin.service.action.FindUserByDnAction;
|
|
||||||
import org.apache.nifi.admin.service.action.FindUserByIdAction;
|
|
||||||
import org.apache.nifi.admin.service.action.GetKeyByIdAction;
|
|
||||||
import org.apache.nifi.admin.service.action.GetOrCreateKeyAction;
|
|
||||||
import org.apache.nifi.admin.service.action.GetUserGroupAction;
|
|
||||||
import org.apache.nifi.admin.service.action.GetUsersAction;
|
|
||||||
import org.apache.nifi.admin.service.action.HasPendingUserAccounts;
|
|
||||||
import org.apache.nifi.admin.service.action.InvalidateUserAccountAction;
|
|
||||||
import org.apache.nifi.admin.service.action.InvalidateUserGroupAccountsAction;
|
|
||||||
import org.apache.nifi.admin.service.action.RequestUserAccountAction;
|
|
||||||
import org.apache.nifi.admin.service.action.SeedUserAccountsAction;
|
|
||||||
import org.apache.nifi.admin.service.action.UpdateUserAction;
|
|
||||||
import org.apache.nifi.admin.service.action.UpdateUserGroupAction;
|
|
||||||
import org.apache.nifi.admin.service.action.UngroupUserAction;
|
|
||||||
import org.apache.nifi.admin.service.action.UngroupUserGroupAction;
|
|
||||||
import org.apache.nifi.admin.service.transaction.Transaction;
|
|
||||||
import org.apache.nifi.admin.service.transaction.TransactionBuilder;
|
|
||||||
import org.apache.nifi.admin.service.transaction.TransactionException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
|
||||||
import org.apache.nifi.key.Key;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.nifi.user.NiFiUserGroup;
|
|
||||||
import org.apache.nifi.util.FormatUtils;
|
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class StandardUserService implements UserService {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(StandardUserService.class);
|
|
||||||
|
|
||||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
|
||||||
private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
|
|
||||||
private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
|
|
||||||
|
|
||||||
private TransactionBuilder transactionBuilder;
|
|
||||||
private NiFiProperties properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seed any users from the authority provider that are not already present.
|
|
||||||
*/
|
|
||||||
public void seedUserAccounts() {
|
|
||||||
// do not seed node's user cache. when/if the node disconnects its
|
|
||||||
// cache will be populated lazily (as needed)
|
|
||||||
if (properties.isNode()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transaction transaction = null;
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// seed the accounts
|
|
||||||
SeedUserAccountsAction seedUserAccounts = new SeedUserAccountsAction();
|
|
||||||
transaction.execute(seedUserAccounts);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (AdministrationException ae) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw ae;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser createPendingUserAccount(String dn, String justification) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// create the account request
|
|
||||||
RequestUserAccountAction requestUserAccount = new RequestUserAccountAction(dn, justification);
|
|
||||||
NiFiUser user = transaction.execute(requestUserAccount);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the nifi user
|
|
||||||
return user;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUserGroup updateGroup(final String group, final Set<String> userIds, final Set<Authority> authorities) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// if user ids have been specified, invalidate the user accounts before performing
|
|
||||||
// the desired updates. if case of an error, this will ensure that these users are
|
|
||||||
// authorized the next time the access the application
|
|
||||||
if (userIds != null) {
|
|
||||||
for (final String userId : userIds) {
|
|
||||||
invalidateUserAccount(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// set the authorities for each user in this group if specified
|
|
||||||
final UpdateUserGroupAction updateUserGroup = new UpdateUserGroupAction(group, userIds, authorities);
|
|
||||||
transaction.execute(updateUserGroup);
|
|
||||||
|
|
||||||
// get all the users that are now in this group
|
|
||||||
final GetUserGroupAction getUserGroup = new GetUserGroupAction(group);
|
|
||||||
final NiFiUserGroup userGroup = transaction.execute(getUserGroup);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
return userGroup;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroupUser(String id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// ungroup the specified user
|
|
||||||
final UngroupUserAction ungroupUser = new UngroupUserAction(id);
|
|
||||||
transaction.execute(ungroupUser);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroup(String group) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// ungroup the specified user
|
|
||||||
final UngroupUserGroupAction ungroupUserGroup = new UngroupUserGroupAction(group);
|
|
||||||
transaction.execute(ungroupUserGroup);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser checkAuthorization(String dn) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// create the connection
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// determine how long the cache is valid for
|
|
||||||
final int cacheSeconds;
|
|
||||||
try {
|
|
||||||
cacheSeconds = (int) FormatUtils.getTimeDuration(properties.getUserCredentialCacheDuration(), TimeUnit.SECONDS);
|
|
||||||
} catch (IllegalArgumentException iae) {
|
|
||||||
throw new AdministrationException("User credential cache duration is not configured correctly.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to authorize the user
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(dn, cacheSeconds);
|
|
||||||
NiFiUser user = transaction.execute(authorizeUser);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the nifi user
|
|
||||||
return user;
|
|
||||||
} catch (DataAccessException | TransactionException dae) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(dae);
|
|
||||||
} catch (AccountDisabledException | AccountPendingException ade) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw ade;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteUser(String id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// create the connection
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// delete the user
|
|
||||||
DeleteUserAction deleteUser = new DeleteUserAction(id);
|
|
||||||
transaction.execute(deleteUser);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (DataAccessException | TransactionException dae) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(dae);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser disable(String id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// create the connection
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// disable the user
|
|
||||||
DisableUserAction disableUser = new DisableUserAction(id);
|
|
||||||
NiFiUser user = transaction.execute(disableUser);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return user;
|
|
||||||
} catch (DataAccessException | TransactionException dae) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(dae);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUserGroup disableGroup(String group) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// create the connection
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// disable the user
|
|
||||||
DisableUserGroupAction disableUser = new DisableUserGroupAction(group);
|
|
||||||
NiFiUserGroup userGroup = transaction.execute(disableUser);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return userGroup;
|
|
||||||
} catch (DataAccessException | TransactionException dae) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(dae);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser update(String id, Set<Authority> authorities) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
// may be empty but not null
|
|
||||||
if (authorities == null) {
|
|
||||||
throw new IllegalArgumentException("The specified authorities cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// invalidate the user account in preparation for potential subsequent errors
|
|
||||||
invalidateUserAccount(id);
|
|
||||||
|
|
||||||
// at this point the current user account has been invalidated so we will
|
|
||||||
// attempt to update the account. if any part fails we are assured the
|
|
||||||
// user will be need to be given approval before they access the system at
|
|
||||||
// a later time
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// update the user authorities
|
|
||||||
UpdateUserAction setUserAuthorities = new UpdateUserAction(id, authorities);
|
|
||||||
NiFiUser user = transaction.execute(setUserAuthorities);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return user;
|
|
||||||
} catch (TransactionException | DataAccessException e) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(e);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates the user with the specified id. This is done to ensure a user account will need to be re-validated in case an error occurs while modifying a user account. This method should only be
|
|
||||||
* invoked from within a write lock.
|
|
||||||
*
|
|
||||||
* @param id user account identifier
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void invalidateUserAccount(String id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// invalidate the user account
|
|
||||||
InvalidateUserAccountAction invalidateUserAccount = new InvalidateUserAccountAction(id);
|
|
||||||
transaction.execute(invalidateUserAccount);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateUserGroupAccount(String group) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// invalidate the user account
|
|
||||||
InvalidateUserGroupAccountsAction invalidateUserGroupAccounts = new InvalidateUserGroupAccountsAction(group);
|
|
||||||
transaction.execute(invalidateUserGroupAccounts);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------
|
|
||||||
// read only methods
|
|
||||||
// -----------------
|
|
||||||
@Override
|
|
||||||
public Boolean hasPendingUserAccount() {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
final HasPendingUserAccounts hasPendingAccounts = new HasPendingUserAccounts();
|
|
||||||
final Boolean hasPendingUserAccounts = transaction.execute(hasPendingAccounts);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
return hasPendingUserAccounts;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DownloadAuthorization authorizeDownload(final List<String> dnChain, final Map<String, String> attributes) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// authorize the download
|
|
||||||
AuthorizeDownloadAction authorizeDownload = new AuthorizeDownloadAction(dnChain, attributes);
|
|
||||||
DownloadAuthorization downloadAuthorization = transaction.execute(authorizeDownload);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the authorization
|
|
||||||
return downloadAuthorization;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<NiFiUser> getUsers() {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// get all users
|
|
||||||
GetUsersAction getUsers = new GetUsersAction();
|
|
||||||
Collection<NiFiUser> users = transaction.execute(getUsers);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the users
|
|
||||||
return users;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser getUserById(String id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// return the desired user
|
|
||||||
FindUserByIdAction findUserById = new FindUserByIdAction(id);
|
|
||||||
NiFiUser user = transaction.execute(findUserById);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return user;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NiFiUser getUserByDn(String dn) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// return the desired user
|
|
||||||
FindUserByDnAction findUserByDn = new FindUserByDnAction(dn);
|
|
||||||
NiFiUser user = transaction.execute(findUserByDn);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// return the user
|
|
||||||
return user;
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Key getKey(int id) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
Key key = null;
|
|
||||||
|
|
||||||
readLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// get the key
|
|
||||||
GetKeyByIdAction addActions = new GetKeyByIdAction(id);
|
|
||||||
key = transaction.execute(addActions);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Key getOrCreateKey(String identity) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
Key key = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// get or create a key
|
|
||||||
GetOrCreateKeyAction addActions = new GetOrCreateKeyAction(identity);
|
|
||||||
key = transaction.execute(addActions);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteKey(String identity) {
|
|
||||||
Transaction transaction = null;
|
|
||||||
|
|
||||||
writeLock.lock();
|
|
||||||
try {
|
|
||||||
// start the transaction
|
|
||||||
transaction = transactionBuilder.start();
|
|
||||||
|
|
||||||
// delete the keys
|
|
||||||
DeleteKeysAction deleteKeys = new DeleteKeysAction(identity);
|
|
||||||
transaction.execute(deleteKeys);
|
|
||||||
|
|
||||||
// commit the transaction
|
|
||||||
transaction.commit();
|
|
||||||
} catch (TransactionException | DataAccessException te) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw new AdministrationException(te);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
rollback(transaction);
|
|
||||||
throw t;
|
|
||||||
} finally {
|
|
||||||
closeQuietly(transaction);
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rollback(final Transaction transaction) {
|
|
||||||
if (transaction != null) {
|
|
||||||
transaction.rollback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void closeQuietly(final Transaction transaction) {
|
|
||||||
if (transaction != null) {
|
|
||||||
try {
|
|
||||||
transaction.close();
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionBuilder(TransactionBuilder transactionBuilder) {
|
|
||||||
this.transactionBuilder = transactionBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProperties(NiFiProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,19 +16,19 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.admin.service.transaction.impl;
|
package org.apache.nifi.admin.service.transaction.impl;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import org.apache.nifi.admin.RepositoryUtils;
|
import org.apache.nifi.admin.RepositoryUtils;
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
import org.apache.nifi.admin.dao.DAOFactory;
|
||||||
import org.apache.nifi.admin.dao.impl.DAOFactoryImpl;
|
import org.apache.nifi.admin.dao.impl.DAOFactoryImpl;
|
||||||
import org.apache.nifi.admin.service.action.AdministrationAction;
|
import org.apache.nifi.admin.service.action.AdministrationAction;
|
||||||
import org.apache.nifi.admin.service.transaction.TransactionException;
|
|
||||||
import org.apache.nifi.admin.service.transaction.Transaction;
|
import org.apache.nifi.admin.service.transaction.Transaction;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
import org.apache.nifi.admin.service.transaction.TransactionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction implementation that uses the specified SQL Connection and
|
* Transaction implementation that uses the specified SQL Connection and
|
||||||
* AuthorityProvider.
|
* AuthorityProvider.
|
||||||
|
@ -37,11 +37,9 @@ public class StandardTransaction implements Transaction {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(StandardTransaction.class);
|
private static final Logger logger = LoggerFactory.getLogger(StandardTransaction.class);
|
||||||
|
|
||||||
private final AuthorityProvider authorityProvider;
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
public StandardTransaction(AuthorityProvider authorityProvider, Connection connection) {
|
public StandardTransaction(Connection connection) {
|
||||||
this.authorityProvider = authorityProvider;
|
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +54,7 @@ public class StandardTransaction implements Transaction {
|
||||||
DAOFactory daoFactory = new DAOFactoryImpl(connection);
|
DAOFactory daoFactory = new DAOFactoryImpl(connection);
|
||||||
|
|
||||||
// execute the specified action
|
// execute the specified action
|
||||||
return action.execute(daoFactory, authorityProvider);
|
return action.execute(daoFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,7 +22,6 @@ import javax.sql.DataSource;
|
||||||
import org.apache.nifi.admin.service.transaction.Transaction;
|
import org.apache.nifi.admin.service.transaction.Transaction;
|
||||||
import org.apache.nifi.admin.service.transaction.TransactionBuilder;
|
import org.apache.nifi.admin.service.transaction.TransactionBuilder;
|
||||||
import org.apache.nifi.admin.service.transaction.TransactionException;
|
import org.apache.nifi.admin.service.transaction.TransactionException;
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -30,7 +29,6 @@ import org.apache.nifi.authorization.AuthorityProvider;
|
||||||
public class StandardTransactionBuilder implements TransactionBuilder {
|
public class StandardTransactionBuilder implements TransactionBuilder {
|
||||||
|
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Transaction start() throws TransactionException {
|
public Transaction start() throws TransactionException {
|
||||||
|
@ -40,7 +38,7 @@ public class StandardTransactionBuilder implements TransactionBuilder {
|
||||||
connection.setAutoCommit(false);
|
connection.setAutoCommit(false);
|
||||||
|
|
||||||
// create a new transaction
|
// create a new transaction
|
||||||
return new StandardTransaction(authorityProvider, connection);
|
return new StandardTransaction(connection);
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
throw new TransactionException(sqle.getMessage());
|
throw new TransactionException(sqle.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -50,8 +48,4 @@ public class StandardTransactionBuilder implements TransactionBuilder {
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthorityProvider(AuthorityProvider authorityProvider) {
|
|
||||||
this.authorityProvider = authorityProvider;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,491 +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.authorization;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.authorization.generated.AuthorityProviderProperty;
|
|
||||||
import org.apache.nifi.authorization.generated.AuthorityProviders;
|
|
||||||
import org.apache.nifi.authorization.generated.Provider;
|
|
||||||
import org.apache.nifi.nar.ExtensionManager;
|
|
||||||
import org.apache.nifi.nar.NarCloseable;
|
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBElement;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.transform.stream.StreamSource;
|
|
||||||
import javax.xml.validation.Schema;
|
|
||||||
import javax.xml.validation.SchemaFactory;
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory bean for loading the configured authority provider.
|
|
||||||
*/
|
|
||||||
public class AuthorityProviderFactoryBean implements FactoryBean, ApplicationContextAware, DisposableBean, AuthorityProviderLookup {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AuthorityProviderFactoryBean.class);
|
|
||||||
private static final String AUTHORITY_PROVIDERS_XSD = "/authority-providers.xsd";
|
|
||||||
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authorization.generated";
|
|
||||||
private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the JAXBContext.
|
|
||||||
*/
|
|
||||||
private static JAXBContext initializeJaxbContext() {
|
|
||||||
try {
|
|
||||||
return JAXBContext.newInstance(JAXB_GENERATED_PATH, AuthorityProviderFactoryBean.class.getClassLoader());
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
throw new RuntimeException("Unable to create JAXBContext.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
private NiFiProperties properties;
|
|
||||||
private final Map<String, AuthorityProvider> authorityProviders = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthorityProvider getAuthorityProvider(String identifier) {
|
|
||||||
return authorityProviders.get(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getObject() throws Exception {
|
|
||||||
if (authorityProvider == null) {
|
|
||||||
// look up the authority provider to use
|
|
||||||
final String authorityProviderIdentifier = properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORITY_PROVIDER);
|
|
||||||
|
|
||||||
// ensure the authority provider class name was specified
|
|
||||||
if (StringUtils.isBlank(authorityProviderIdentifier)) {
|
|
||||||
// if configured for ssl, the authority provider must be specified
|
|
||||||
if (properties.getSslPort() != null) {
|
|
||||||
throw new Exception("When running securely, the authority provider identifier must be specified in the nifi properties file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// use a default provider... only allowable when running not securely
|
|
||||||
authorityProvider = createDefaultProvider();
|
|
||||||
} else {
|
|
||||||
final AuthorityProviders authorityProviderConfiguration = loadAuthorityProvidersConfiguration();
|
|
||||||
|
|
||||||
// create each authority provider
|
|
||||||
for (final Provider provider : authorityProviderConfiguration.getProvider()) {
|
|
||||||
authorityProviders.put(provider.getIdentifier(), createAuthorityProvider(provider.getIdentifier(), provider.getClazz()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure each authority provider
|
|
||||||
for (final Provider provider : authorityProviderConfiguration.getProvider()) {
|
|
||||||
final AuthorityProvider instance = authorityProviders.get(provider.getIdentifier());
|
|
||||||
instance.onConfigured(loadAuthorityProviderConfiguration(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the authority provider instance
|
|
||||||
authorityProvider = getAuthorityProvider(authorityProviderIdentifier);
|
|
||||||
|
|
||||||
// ensure it was found
|
|
||||||
if (authorityProvider == null) {
|
|
||||||
throw new Exception(String.format("The specified authority provider '%s' could not be found.", authorityProviderIdentifier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorityProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthorityProviders loadAuthorityProvidersConfiguration() throws Exception {
|
|
||||||
final File authorityProvidersConfigurationFile = properties.getAuthorityProviderConfiguraitonFile();
|
|
||||||
|
|
||||||
// load the users from the specified file
|
|
||||||
if (authorityProvidersConfigurationFile.exists()) {
|
|
||||||
try {
|
|
||||||
// find the schema
|
|
||||||
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
|
||||||
final Schema schema = schemaFactory.newSchema(AuthorityProviders.class.getResource(AUTHORITY_PROVIDERS_XSD));
|
|
||||||
|
|
||||||
// attempt to unmarshal
|
|
||||||
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
|
||||||
unmarshaller.setSchema(schema);
|
|
||||||
final JAXBElement<AuthorityProviders> element = unmarshaller.unmarshal(new StreamSource(authorityProvidersConfigurationFile), AuthorityProviders.class);
|
|
||||||
return element.getValue();
|
|
||||||
} catch (SAXException | JAXBException e) {
|
|
||||||
throw new Exception("Unable to load the authority provider configuration file at: " + authorityProvidersConfigurationFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unable to find the authority provider configuration file at " + authorityProvidersConfigurationFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthorityProvider createAuthorityProvider(final String identifier, final String authorityProviderClassName) throws Exception {
|
|
||||||
// get the classloader for the specified authority provider
|
|
||||||
final ClassLoader authorityProviderClassLoader = ExtensionManager.getClassLoader(authorityProviderClassName);
|
|
||||||
if (authorityProviderClassLoader == null) {
|
|
||||||
throw new Exception(String.format("The specified authority provider class '%s' is not known to this nifi.", authorityProviderClassName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the current context classloader
|
|
||||||
final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
|
|
||||||
final AuthorityProvider instance;
|
|
||||||
try {
|
|
||||||
// set the appropriate class loader
|
|
||||||
Thread.currentThread().setContextClassLoader(authorityProviderClassLoader);
|
|
||||||
|
|
||||||
// attempt to load the class
|
|
||||||
Class<?> rawAuthorityProviderClass = Class.forName(authorityProviderClassName, true, authorityProviderClassLoader);
|
|
||||||
Class<? extends AuthorityProvider> authorityProviderClass = rawAuthorityProviderClass.asSubclass(AuthorityProvider.class);
|
|
||||||
|
|
||||||
// otherwise create a new instance
|
|
||||||
Constructor constructor = authorityProviderClass.getConstructor();
|
|
||||||
instance = (AuthorityProvider) constructor.newInstance();
|
|
||||||
|
|
||||||
// method injection
|
|
||||||
performMethodInjection(instance, authorityProviderClass);
|
|
||||||
|
|
||||||
// field injection
|
|
||||||
performFieldInjection(instance, authorityProviderClass);
|
|
||||||
|
|
||||||
// call post construction lifecycle event
|
|
||||||
instance.initialize(new StandardAuthorityProviderInitializationContext(identifier, this));
|
|
||||||
} finally {
|
|
||||||
if (currentClassLoader != null) {
|
|
||||||
Thread.currentThread().setContextClassLoader(currentClassLoader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return withNarLoader(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthorityProviderConfigurationContext loadAuthorityProviderConfiguration(final Provider provider) {
|
|
||||||
final Map<String, String> providerProperties = new HashMap<>();
|
|
||||||
|
|
||||||
for (final AuthorityProviderProperty property : provider.getProperty()) {
|
|
||||||
providerProperties.put(property.getName(), property.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new StandardAuthorityProviderConfigurationContext(provider.getIdentifier(), providerProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void performMethodInjection(final AuthorityProvider instance, final Class authorityProviderClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
|
||||||
for (final Method method : authorityProviderClass.getMethods()) {
|
|
||||||
if (method.isAnnotationPresent(AuthorityProviderContext.class)) {
|
|
||||||
// make the method accessible
|
|
||||||
final boolean isAccessible = method.isAccessible();
|
|
||||||
method.setAccessible(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Class<?>[] argumentTypes = method.getParameterTypes();
|
|
||||||
|
|
||||||
// look for setters (single argument)
|
|
||||||
if (argumentTypes.length == 1) {
|
|
||||||
final Class<?> argumentType = argumentTypes[0];
|
|
||||||
|
|
||||||
// look for well known types
|
|
||||||
if (NiFiProperties.class.isAssignableFrom(argumentType)) {
|
|
||||||
// nifi properties injection
|
|
||||||
method.invoke(instance, properties);
|
|
||||||
} else if (ApplicationContext.class.isAssignableFrom(argumentType)) {
|
|
||||||
// spring application context injection
|
|
||||||
method.invoke(instance, applicationContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
method.setAccessible(isAccessible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Class parentClass = authorityProviderClass.getSuperclass();
|
|
||||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
|
||||||
performMethodInjection(instance, parentClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void performFieldInjection(final AuthorityProvider instance, final Class authorityProviderClass) throws IllegalArgumentException, IllegalAccessException {
|
|
||||||
for (final Field field : authorityProviderClass.getDeclaredFields()) {
|
|
||||||
if (field.isAnnotationPresent(AuthorityProviderContext.class)) {
|
|
||||||
// make the method accessible
|
|
||||||
final boolean isAccessible = field.isAccessible();
|
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// get the type
|
|
||||||
final Class<?> fieldType = field.getType();
|
|
||||||
|
|
||||||
// only consider this field if it isn't set yet
|
|
||||||
if (field.get(instance) == null) {
|
|
||||||
// look for well known types
|
|
||||||
if (NiFiProperties.class.isAssignableFrom(fieldType)) {
|
|
||||||
// nifi properties injection
|
|
||||||
field.set(instance, properties);
|
|
||||||
} else if (ApplicationContext.class.isAssignableFrom(fieldType)) {
|
|
||||||
// spring application context injection
|
|
||||||
field.set(instance, applicationContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
field.setAccessible(isAccessible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Class parentClass = authorityProviderClass.getSuperclass();
|
|
||||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
|
||||||
performFieldInjection(instance, parentClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a default provider to use when running unsecurely with no
|
|
||||||
* provider configured
|
|
||||||
*/
|
|
||||||
private AuthorityProvider createDefaultProvider() {
|
|
||||||
return new AuthorityProvider() {
|
|
||||||
@Override
|
|
||||||
public boolean doesDnExist(String dn) throws AuthorityAccessException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
return EnumSet.noneOf(Authority.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getUsers(Authority authority) throws AuthorityAccessException {
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUsersGroup(Set<String> dn, String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroup(String group) throws AuthorityAccessException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
return DownloadAuthorization.approved();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigured(AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preDestruction() throws ProviderDestructionException {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decorates the base provider to ensure the nar context classloader is used
|
|
||||||
* when invoking the underlying methods.
|
|
||||||
*
|
|
||||||
* @param baseProvider base provider
|
|
||||||
* @return provider
|
|
||||||
*/
|
|
||||||
public AuthorityProvider withNarLoader(final AuthorityProvider baseProvider) {
|
|
||||||
return new AuthorityProvider() {
|
|
||||||
@Override
|
|
||||||
public boolean doesDnExist(String dn) throws AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
return baseProvider.doesDnExist(dn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
return baseProvider.getAuthorities(dn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.setAuthorities(dn, authorities);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getUsers(Authority authority) throws AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
return baseProvider.getUsers(authority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.revokeUser(dn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.addUser(dn, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
return baseProvider.getGroupForUser(dn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.revokeGroup(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.setUsersGroup(dns, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.ungroupUser(dn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroup(String group) throws AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.ungroup(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
return baseProvider.authorizeDownload(dnChain, attributes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.initialize(initializationContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigured(AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.onConfigured(configurationContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preDestruction() throws ProviderDestructionException {
|
|
||||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
|
||||||
baseProvider.preDestruction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getObjectType() {
|
|
||||||
return AuthorityProvider.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSingleton() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() throws Exception {
|
|
||||||
if (authorityProvider != null) {
|
|
||||||
authorityProvider.preDestruction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProperties(NiFiProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ import org.apache.nifi.authorization.annotation.AuthorizerContext;
|
||||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||||
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
||||||
import org.apache.nifi.authorization.generated.AuthorityProviders;
|
|
||||||
import org.apache.nifi.authorization.generated.Authorizers;
|
import org.apache.nifi.authorization.generated.Authorizers;
|
||||||
import org.apache.nifi.authorization.generated.Property;
|
import org.apache.nifi.authorization.generated.Property;
|
||||||
import org.apache.nifi.nar.ExtensionManager;
|
import org.apache.nifi.nar.ExtensionManager;
|
||||||
|
@ -83,7 +82,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
||||||
public Object getObject() throws Exception {
|
public Object getObject() throws Exception {
|
||||||
if (authorizer == null) {
|
if (authorizer == null) {
|
||||||
// look up the authorizer to use
|
// look up the authorizer to use
|
||||||
final String authorizerIdentifier = properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORITY_PROVIDER);
|
final String authorizerIdentifier = properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORIZER);
|
||||||
|
|
||||||
// ensure the authorizer class name was specified
|
// ensure the authorizer class name was specified
|
||||||
if (StringUtils.isBlank(authorizerIdentifier)) {
|
if (StringUtils.isBlank(authorizerIdentifier)) {
|
||||||
|
@ -122,14 +121,14 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
||||||
}
|
}
|
||||||
|
|
||||||
private Authorizers loadAuthorizersConfiguration() throws Exception {
|
private Authorizers loadAuthorizersConfiguration() throws Exception {
|
||||||
final File authorizersConfigurationFile = properties.getAuthorityProviderConfiguraitonFile();
|
final File authorizersConfigurationFile = properties.getAuthorizerConfiguraitonFile();
|
||||||
|
|
||||||
// load the authorizers from the specified file
|
// load the authorizers from the specified file
|
||||||
if (authorizersConfigurationFile.exists()) {
|
if (authorizersConfigurationFile.exists()) {
|
||||||
try {
|
try {
|
||||||
// find the schema
|
// find the schema
|
||||||
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
final Schema schema = schemaFactory.newSchema(AuthorityProviders.class.getResource(AUTHORIZERS_XSD));
|
final Schema schema = schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
|
||||||
|
|
||||||
// attempt to unmarshal
|
// attempt to unmarshal
|
||||||
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
||||||
|
@ -221,7 +220,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
||||||
}
|
}
|
||||||
|
|
||||||
final Class parentClass = authorizerClass.getSuperclass();
|
final Class parentClass = authorizerClass.getSuperclass();
|
||||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
if (parentClass != null && Authorizer.class.isAssignableFrom(parentClass)) {
|
||||||
performMethodInjection(instance, parentClass);
|
performMethodInjection(instance, parentClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +252,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
||||||
}
|
}
|
||||||
|
|
||||||
final Class parentClass = authorizerClass.getSuperclass();
|
final Class parentClass = authorizerClass.getSuperclass();
|
||||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
if (parentClass != null && Authorizer.class.isAssignableFrom(parentClass)) {
|
||||||
performFieldInjection(instance, parentClass);
|
performFieldInjection(instance, parentClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +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.authorization;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class StandardAuthorityProviderConfigurationContext implements AuthorityProviderConfigurationContext {
|
|
||||||
|
|
||||||
private final String identifier;
|
|
||||||
private final Map<String, String> properties;
|
|
||||||
|
|
||||||
public StandardAuthorityProviderConfigurationContext(String identifier, Map<String, String> properties) {
|
|
||||||
this.identifier = identifier;
|
|
||||||
this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getProperties() {
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProperty(String property) {
|
|
||||||
return properties.get(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +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.authorization;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class StandardAuthorityProviderInitializationContext implements AuthorityProviderInitializationContext {
|
|
||||||
|
|
||||||
private final String identifier;
|
|
||||||
private final AuthorityProviderLookup authorityProviderLookup;
|
|
||||||
|
|
||||||
public StandardAuthorityProviderInitializationContext(String identifier, AuthorityProviderLookup authorityProviderLookup) {
|
|
||||||
this.identifier = identifier;
|
|
||||||
this.authorityProviderLookup = authorityProviderLookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthorityProviderLookup getAuthorityProviderLookup() {
|
|
||||||
return authorityProviderLookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,47 +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.user;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the status of a user's account.
|
|
||||||
*/
|
|
||||||
public enum AccountStatus {
|
|
||||||
|
|
||||||
ACTIVE,
|
|
||||||
PENDING,
|
|
||||||
DISABLED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the matching status or null if the specified status does not
|
|
||||||
* match any statuses.
|
|
||||||
*
|
|
||||||
* @param rawStatus string form of status
|
|
||||||
* @return account status object
|
|
||||||
*/
|
|
||||||
public static AccountStatus valueOfStatus(String rawStatus) {
|
|
||||||
AccountStatus desiredStatus = null;
|
|
||||||
|
|
||||||
for (AccountStatus status : values()) {
|
|
||||||
if (status.toString().equals(rawStatus)) {
|
|
||||||
desiredStatus = status;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return desiredStatus;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,121 +17,54 @@
|
||||||
package org.apache.nifi.user;
|
package org.apache.nifi.user;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An NiFiUser.
|
* An NiFiUser.
|
||||||
*/
|
*/
|
||||||
public class NiFiUser implements Serializable {
|
public class NiFiUser implements Serializable {
|
||||||
|
|
||||||
public static final String ANONYMOUS_USER_IDENTITY = "anonymous";
|
public static final NiFiUser ANONYMOUS = new NiFiUser("anonymous");
|
||||||
|
|
||||||
private String id;
|
|
||||||
private String identity;
|
private String identity;
|
||||||
private String userName;
|
private String userName;
|
||||||
private String userGroup;
|
|
||||||
private String justification;
|
|
||||||
|
|
||||||
private Date creation;
|
|
||||||
private Date lastVerified;
|
|
||||||
private Date lastAccessed;
|
|
||||||
|
|
||||||
private AccountStatus status;
|
|
||||||
private EnumSet<Authority> authorities;
|
|
||||||
|
|
||||||
private NiFiUser chain;
|
private NiFiUser chain;
|
||||||
|
|
||||||
/* getters / setters */
|
public NiFiUser(String identity) {
|
||||||
public Date getCreation() {
|
this(identity, identity, null);
|
||||||
return creation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreation(Date creation) {
|
public NiFiUser(String identity, String userName) {
|
||||||
this.creation = creation;
|
this(identity, userName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NiFiUser(String identity, NiFiUser chain) {
|
||||||
|
this(identity, identity, chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NiFiUser(String identity, String userName, NiFiUser chain) {
|
||||||
|
this.identity = identity;
|
||||||
|
this.userName = userName;
|
||||||
|
this.chain = chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* getters / setters */
|
||||||
|
|
||||||
public String getIdentity() {
|
public String getIdentity() {
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIdentity(String identity) {
|
|
||||||
this.identity = identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserName() {
|
public String getUserName() {
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserName(String userName) {
|
|
||||||
this.userName = userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserGroup() {
|
|
||||||
return userGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserGroup(String userGroup) {
|
|
||||||
this.userGroup = userGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJustification() {
|
|
||||||
return justification;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJustification(String justification) {
|
|
||||||
this.justification = justification;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountStatus getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(AccountStatus status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastVerified() {
|
|
||||||
return lastVerified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastVerified(Date lastVerified) {
|
|
||||||
this.lastVerified = lastVerified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastAccessed() {
|
|
||||||
return lastAccessed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastAccessed(Date lastAccessed) {
|
|
||||||
this.lastAccessed = lastAccessed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NiFiUser getChain() {
|
public NiFiUser getChain() {
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChain(NiFiUser chain) {
|
public boolean isAnonymous() {
|
||||||
this.chain = chain;
|
return this == ANONYMOUS;
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Authority> getAuthorities() {
|
|
||||||
if (authorities == null) {
|
|
||||||
authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
}
|
|
||||||
return authorities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,7 +91,7 @@ public class NiFiUser implements Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("identity[%s], userName[%s], justification[%s], authorities[%s]", getIdentity(), getUserName(), getJustification(), StringUtils.join(getAuthorities(), ", "));
|
return String.format("identity[%s], userName[%s]", getIdentity(), getUserName(), ", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,41 +18,34 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||||
|
|
||||||
<!-- user authority provider -->
|
|
||||||
<bean id="authorityProvider" class="org.apache.nifi.authorization.AuthorityProviderFactoryBean" depends-on="clusterManager">
|
|
||||||
<property name="properties" ref="nifiProperties"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- user/entity authorizer -->
|
<!-- user/entity authorizer -->
|
||||||
<bean id="authorizer" class="org.apache.nifi.authorization.AuthorizerFactoryBean" depends-on="clusterManager">
|
<bean id="authorizer" class="org.apache.nifi.authorization.AuthorizerFactoryBean">
|
||||||
<property name="properties" ref="nifiProperties"/>
|
<property name="properties" ref="nifiProperties"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- initialize the user data source -->
|
<!-- initialize the user key data source -->
|
||||||
<bean id="userDataSource" class="org.apache.nifi.admin.UserDataSourceFactoryBean" destroy-method="shutdown">
|
<bean id="keyDataSource" class="org.apache.nifi.admin.KeyDataSourceFactoryBean" destroy-method="shutdown">
|
||||||
<property name="properties" ref="nifiProperties"/>
|
<property name="properties" ref="nifiProperties"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- initialize the data source -->
|
<!-- initialize the audit data source -->
|
||||||
<bean id="auditDataSource" class="org.apache.nifi.admin.AuditDataSourceFactoryBean" destroy-method="shutdown" depends-on="userDataSource">
|
<bean id="auditDataSource" class="org.apache.nifi.admin.AuditDataSourceFactoryBean" destroy-method="shutdown">
|
||||||
<property name="properties" ref="nifiProperties"/>
|
<property name="properties" ref="nifiProperties"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- initialize the user transaction builder -->
|
<!-- initialize the user key transaction builder -->
|
||||||
<bean id="userTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
<bean id="keyTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
||||||
<property name="authorityProvider" ref="authorityProvider"/>
|
<property name="dataSource" ref="keyDataSource"/>
|
||||||
<property name="dataSource" ref="userDataSource"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- initialize the audit transaction builder -->
|
<!-- initialize the audit transaction builder -->
|
||||||
<bean id="auditTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
<bean id="auditTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
||||||
<property name="authorityProvider" ref="authorityProvider"/>
|
|
||||||
<property name="dataSource" ref="auditDataSource"/>
|
<property name="dataSource" ref="auditDataSource"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- administration service -->
|
<!-- administration service -->
|
||||||
<bean id="userService" class="org.apache.nifi.admin.service.impl.StandardUserService" init-method="seedUserAccounts">
|
<bean id="keyService" class="org.apache.nifi.admin.service.impl.StandardKeyService">
|
||||||
<property name="transactionBuilder" ref="userTransactionBuilder"/>
|
<property name="transactionBuilder" ref="keyTransactionBuilder"/>
|
||||||
<property name="properties" ref="nifiProperties"/>
|
<property name="properties" ref="nifiProperties"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
|
||||||
this work for additional information regarding copyright ownership.
|
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
(the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
||||||
<!-- role -->
|
|
||||||
<xs:complexType name="Provider">
|
|
||||||
<xs:sequence>
|
|
||||||
<xs:element name="identifier" type="AuthorityProviderNonEmptyStringType"/>
|
|
||||||
<xs:element name="class" type="AuthorityProviderNonEmptyStringType"/>
|
|
||||||
<xs:element name="property" type="AuthorityProviderProperty" minOccurs="0" maxOccurs="unbounded" />
|
|
||||||
</xs:sequence>
|
|
||||||
</xs:complexType>
|
|
||||||
|
|
||||||
<!-- Name/Value properties-->
|
|
||||||
<xs:complexType name="AuthorityProviderProperty">
|
|
||||||
<xs:simpleContent>
|
|
||||||
<xs:extension base="xs:string">
|
|
||||||
<xs:attribute name="name" type="AuthorityProviderNonEmptyStringType"></xs:attribute>
|
|
||||||
</xs:extension>
|
|
||||||
</xs:simpleContent>
|
|
||||||
</xs:complexType>
|
|
||||||
|
|
||||||
<xs:simpleType name="AuthorityProviderNonEmptyStringType">
|
|
||||||
<xs:restriction base="xs:string">
|
|
||||||
<xs:minLength value="1"/>
|
|
||||||
</xs:restriction>
|
|
||||||
</xs:simpleType>
|
|
||||||
|
|
||||||
<!-- users -->
|
|
||||||
<xs:element name="authorityProviders">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:sequence>
|
|
||||||
<xs:element name="provider" type="Provider" minOccurs="0" maxOccurs="unbounded"/>
|
|
||||||
</xs:sequence>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:schema>
|
|
|
@ -1,433 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
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.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AuthorizeUserActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_6 = "6";
|
|
||||||
private static final String USER_ID_7 = "7";
|
|
||||||
private static final String USER_ID_8 = "8";
|
|
||||||
private static final String USER_ID_9 = "9";
|
|
||||||
private static final String USER_ID_10 = "10";
|
|
||||||
private static final String USER_ID_11 = "11";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_1 = "authority access exception while searching for user";
|
|
||||||
private static final String USER_IDENTITY_2 = "unknown user";
|
|
||||||
private static final String USER_IDENTITY_3 = "user removed after checking existence";
|
|
||||||
private static final String USER_IDENTITY_4 = "access exception getting authorities";
|
|
||||||
private static final String USER_IDENTITY_5 = "error creating user account";
|
|
||||||
private static final String USER_IDENTITY_6 = "create user general sequence";
|
|
||||||
private static final String USER_IDENTITY_7 = "existing user requires verification";
|
|
||||||
private static final String USER_IDENTITY_8 = "existing user does not require verification";
|
|
||||||
private static final String USER_IDENTITY_9 = "existing pending user";
|
|
||||||
private static final String USER_IDENTITY_10 = "existing disabled user";
|
|
||||||
private static final String USER_IDENTITY_11 = "existing user is now unknown in the authority provider";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
private AuthorityDAO authorityDao;
|
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String id = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_ID_7.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_7);
|
|
||||||
user.setIdentity(USER_IDENTITY_7);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
} else if (USER_ID_8.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_8);
|
|
||||||
user.setIdentity(USER_IDENTITY_8);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setLastVerified(new Date());
|
|
||||||
} else if (USER_ID_11.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_11);
|
|
||||||
user.setIdentity(USER_IDENTITY_11);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserById(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
switch (dn) {
|
|
||||||
case USER_IDENTITY_7:
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_7);
|
|
||||||
user.setIdentity(USER_IDENTITY_7);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_8:
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_8);
|
|
||||||
user.setIdentity(USER_IDENTITY_8);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setLastVerified(new Date());
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_9:
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_9);
|
|
||||||
user.setIdentity(USER_IDENTITY_9);
|
|
||||||
user.setStatus(AccountStatus.PENDING);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_10:
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_10);
|
|
||||||
user.setIdentity(USER_IDENTITY_10);
|
|
||||||
user.setStatus(AccountStatus.DISABLED);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_11:
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_11);
|
|
||||||
user.setIdentity(USER_IDENTITY_11);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserByDn(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
switch (user.getIdentity()) {
|
|
||||||
case USER_IDENTITY_5:
|
|
||||||
throw new DataAccessException();
|
|
||||||
case USER_IDENTITY_6:
|
|
||||||
user.setId(USER_ID_6);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).createUser(Mockito.any(NiFiUser.class));
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).updateUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the authority dao
|
|
||||||
authorityDao = Mockito.mock(AuthorityDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Set<Authority> authorities = (Set<Authority>) args[0];
|
|
||||||
String id = (String) args[1];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityDao).createAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Set<Authority> authorities = (Set<Authority>) args[0];
|
|
||||||
String id = (String) args[1];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityDao).deleteAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
Mockito.when(daoFactory.getAuthorityDAO()).thenReturn(authorityDao);
|
|
||||||
|
|
||||||
// mock the authority provider
|
|
||||||
authorityProvider = Mockito.mock(AuthorityProvider.class);
|
|
||||||
Mockito.doAnswer(new Answer<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
switch (dn) {
|
|
||||||
case USER_IDENTITY_1:
|
|
||||||
throw new AuthorityAccessException(StringUtils.EMPTY);
|
|
||||||
case USER_IDENTITY_2:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).doesDnExist(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Set<Authority>>() {
|
|
||||||
@Override
|
|
||||||
public Set<Authority> answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
switch (dn) {
|
|
||||||
case USER_IDENTITY_3:
|
|
||||||
throw new UnknownIdentityException(StringUtils.EMPTY);
|
|
||||||
case USER_IDENTITY_4:
|
|
||||||
throw new AuthorityAccessException(StringUtils.EMPTY);
|
|
||||||
case USER_IDENTITY_6:
|
|
||||||
authorities.add(Authority.ROLE_MONITOR);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_7:
|
|
||||||
authorities.add(Authority.ROLE_DFM);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_9:
|
|
||||||
throw new UnknownIdentityException(StringUtils.EMPTY);
|
|
||||||
case USER_IDENTITY_10:
|
|
||||||
throw new UnknownIdentityException(StringUtils.EMPTY);
|
|
||||||
case USER_IDENTITY_11:
|
|
||||||
throw new UnknownIdentityException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).getAuthorities(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
Set<Authority> authorites = (Set<Authority>) args[1];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).setAuthorities(Mockito.anyString(), Mockito.anySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests AuthorityAccessException in doesDnExist.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AdministrationException.class)
|
|
||||||
public void testAuthorityAccessExceptionInDoesDnExist() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_1, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test unknown user in the authority provider.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountNotFoundException.class)
|
|
||||||
public void testUnknownUser() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_2, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test a user thats been removed after checking their existence.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountNotFoundException.class)
|
|
||||||
public void testUserRemovedAfterCheckingExistence() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_3, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Testing AuthorityAccessException when getting authorities.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AdministrationException.class)
|
|
||||||
public void testAuthorityAccessException() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_4, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Testing DataAccessException while creating user accounts.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testErrorCreatingUserAccount() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_5, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case when a user account is created.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testAccountCreation() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_6, 0);
|
|
||||||
NiFiUser user = authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
Assert.assertEquals(USER_IDENTITY_6, user.getIdentity());
|
|
||||||
Assert.assertEquals(1, user.getAuthorities().size());
|
|
||||||
Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
|
|
||||||
|
|
||||||
// verify interaction with dao and provider
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).createUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case when there is an existing user account that
|
|
||||||
* requires verification.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExistingUserRequiresVerification() throws Exception {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_7, 0);
|
|
||||||
NiFiUser user = authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
Assert.assertEquals(USER_IDENTITY_7, user.getIdentity());
|
|
||||||
Assert.assertEquals(1, user.getAuthorities().size());
|
|
||||||
Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_DFM));
|
|
||||||
|
|
||||||
// verify interaction with dao and provider
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(user);
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_DFM), USER_ID_7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case when there is an existing user account that does
|
|
||||||
* not require verification.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExistingUserNoVerification() throws Exception {
|
|
||||||
// disabling verification by passing in a large cache duration
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_8, Integer.MAX_VALUE);
|
|
||||||
NiFiUser user = authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
Assert.assertEquals(USER_IDENTITY_8, user.getIdentity());
|
|
||||||
Assert.assertEquals(1, user.getAuthorities().size());
|
|
||||||
Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
|
|
||||||
|
|
||||||
// verify interaction with dao and provider
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(user);
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).createAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_8));
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).deleteAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests existing users whose accounts are in a pending status.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountPendingException.class)
|
|
||||||
public void testExistingPendingUser() throws Exception {
|
|
||||||
// disabling verification by passing in a large cache duration
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_9, Integer.MAX_VALUE);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests existing users whose accounts are in a disabled status.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountDisabledException.class)
|
|
||||||
public void testExistingDisabledUser() throws Exception {
|
|
||||||
// disabling verification by passing in a large cache duration
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_10, Integer.MAX_VALUE);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case where there is an active user that has been
|
|
||||||
* removed from the authority provider.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testExistingActiveUserNotFoundInProvider() throws Exception {
|
|
||||||
try {
|
|
||||||
AuthorizeUserAction authorizeUser = new AuthorizeUserAction(USER_IDENTITY_11, 0);
|
|
||||||
authorizeUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
Assert.fail();
|
|
||||||
} catch (AccountDisabledException ade) {
|
|
||||||
ArgumentCaptor<NiFiUser> user = ArgumentCaptor.forClass(NiFiUser.class);
|
|
||||||
|
|
||||||
// verify interaction with dao
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(user.capture());
|
|
||||||
|
|
||||||
// verify user
|
|
||||||
Assert.assertEquals(AccountStatus.DISABLED, user.getValue().getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,144 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test cases for creating a user.
|
|
||||||
*/
|
|
||||||
public class CreateUserActionTest {
|
|
||||||
|
|
||||||
private final String USER_ID_2 = "2";
|
|
||||||
private final String USER_ID_3 = "3";
|
|
||||||
|
|
||||||
private final String USER_IDENTITY_1 = "data access exception when creating user";
|
|
||||||
private final String USER_IDENTITY_3 = "general create user case";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
private AuthorityDAO authorityDao;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
if (USER_IDENTITY_1.equals(user.getIdentity())) {
|
|
||||||
throw new DataAccessException();
|
|
||||||
} else if (USER_IDENTITY_3.equals(user.getIdentity())) {
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).createUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the authority dao
|
|
||||||
authorityDao = Mockito.mock(AuthorityDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Set<Authority> authorities = (Set<Authority>) args[0];
|
|
||||||
String id = (String) args[1];
|
|
||||||
|
|
||||||
if (USER_ID_2.equals(id)) {
|
|
||||||
throw new DataAccessException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityDao).createAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
Mockito.when(daoFactory.getAuthorityDAO()).thenReturn(authorityDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests DataAccessExceptions that occur while creating user accounts.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testExceptionCreatingUser() throws Exception {
|
|
||||||
NiFiUser user = new NiFiUser();
|
|
||||||
user.setIdentity(USER_IDENTITY_1);
|
|
||||||
|
|
||||||
CreateUserAction createUser = new CreateUserAction(user);
|
|
||||||
createUser.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests DataAccessExceptions that occur while create user authorities.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testExceptionCreatingAuthoroties() throws Exception {
|
|
||||||
NiFiUser user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_2);
|
|
||||||
|
|
||||||
CreateUserAction createUser = new CreateUserAction(user);
|
|
||||||
createUser.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General case for creating a user.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreateUserAccount() throws Exception {
|
|
||||||
NiFiUser user = new NiFiUser();
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_DFM, Authority.ROLE_ADMIN));
|
|
||||||
|
|
||||||
CreateUserAction createUser = new CreateUserAction(user);
|
|
||||||
createUser.execute(daoFactory, null);
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
Assert.assertEquals(USER_ID_3, user.getId());
|
|
||||||
|
|
||||||
// verify interaction with dao
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).createUser(user);
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(user.getAuthorities(), USER_ID_3);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,176 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.admin.dao.KeyDAO;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Matchers;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
public class DisableUserActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_1 = "1";
|
|
||||||
private static final String USER_ID_2 = "2";
|
|
||||||
private static final String USER_ID_3 = "3";
|
|
||||||
private static final String USER_ID_4 = "4";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_3 = "authority access exception";
|
|
||||||
private static final String USER_IDENTITY_4 = "general disable user case";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
private KeyDAO keyDao;
|
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String id = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_ID_1.equals(id)) {
|
|
||||||
// leave user uninitialized
|
|
||||||
} else if (USER_ID_2.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(id);
|
|
||||||
} else if (USER_ID_3.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(id);
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
} else if (USER_ID_4.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(id);
|
|
||||||
user.setIdentity(USER_IDENTITY_4);
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserById(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
if (USER_ID_2.equals(user.getId())) {
|
|
||||||
throw new DataAccessException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).updateUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
keyDao = Mockito.mock(KeyDAO.class);
|
|
||||||
Mockito.doNothing().when(keyDao).deleteKeys(Matchers.anyString());
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
Mockito.when(daoFactory.getKeyDAO()).thenReturn(keyDao);
|
|
||||||
|
|
||||||
// mock the authority provider
|
|
||||||
authorityProvider = Mockito.mock(AuthorityProvider.class);
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
if (USER_IDENTITY_3.equals(dn)) {
|
|
||||||
throw new AuthorityAccessException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).revokeUser(Mockito.anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the case when the user account is unknown.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountNotFoundException.class)
|
|
||||||
public void testUnknownUserAccount() throws Exception {
|
|
||||||
DisableUserAction disableUser = new DisableUserAction(USER_ID_1);
|
|
||||||
disableUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the case when a DataAccessException is thrown by the userDao.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testDataAccessExceptionInUserDao() throws Exception {
|
|
||||||
DisableUserAction disableUser = new DisableUserAction(USER_ID_2);
|
|
||||||
disableUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the case when a AuthorityAccessException is thrown by the provider.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AdministrationException.class)
|
|
||||||
public void testAuthorityAccessExceptionInProvider() throws Exception {
|
|
||||||
DisableUserAction disableUser = new DisableUserAction(USER_ID_3);
|
|
||||||
disableUser.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case when the user is disabled.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testDisableUser() throws Exception {
|
|
||||||
DisableUserAction disableUser = new DisableUserAction(USER_ID_4);
|
|
||||||
NiFiUser user = disableUser.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
Assert.assertEquals(USER_ID_4, user.getId());
|
|
||||||
Assert.assertEquals(USER_IDENTITY_4, user.getIdentity());
|
|
||||||
Assert.assertEquals(AccountStatus.DISABLED, user.getStatus());
|
|
||||||
|
|
||||||
// verify the interaction with the dao and provider
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(user);
|
|
||||||
Mockito.verify(authorityProvider, Mockito.times(1)).revokeUser(USER_IDENTITY_4);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,126 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test case for InvalidateUserAccountAction.
|
|
||||||
*/
|
|
||||||
public class InvalidateUserAccountActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_1 = "1";
|
|
||||||
private static final String USER_ID_2 = "2";
|
|
||||||
private static final String USER_ID_3 = "3";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String id = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_ID_1.equals(id)) {
|
|
||||||
// leave uninitialized
|
|
||||||
} else if (USER_ID_2.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_2);
|
|
||||||
} else if (USER_ID_3.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
user.setLastVerified(new Date());
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserById(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
if (USER_ID_2.equals(user.getId())) {
|
|
||||||
throw new DataAccessException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).updateUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AccountNotFoundException.class)
|
|
||||||
public void testAccountNotFoundException() throws Exception {
|
|
||||||
InvalidateUserAccountAction invalidateUserAccount = new InvalidateUserAccountAction(USER_ID_1);
|
|
||||||
invalidateUserAccount.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests when a data access exception occurs when updating the user record.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testDataAccessException() throws Exception {
|
|
||||||
InvalidateUserAccountAction invalidateUserAccount = new InvalidateUserAccountAction(USER_ID_2);
|
|
||||||
invalidateUserAccount.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case of invalidating a user.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testInvalidateUser() throws Exception {
|
|
||||||
InvalidateUserAccountAction invalidateUserAccount = new InvalidateUserAccountAction(USER_ID_3);
|
|
||||||
invalidateUserAccount.execute(daoFactory, null);
|
|
||||||
|
|
||||||
// verify the interaction with the dao
|
|
||||||
ArgumentCaptor<NiFiUser> userCaptor = ArgumentCaptor.forClass(NiFiUser.class);
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(userCaptor.capture());
|
|
||||||
|
|
||||||
// verify the user
|
|
||||||
NiFiUser user = userCaptor.getValue();
|
|
||||||
Assert.assertEquals(USER_ID_3, user.getId());
|
|
||||||
Assert.assertNull(user.getLastVerified());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,127 +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.admin.service.action;
|
|
||||||
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.DataAccessException;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test case for RequestUserAccountAction.
|
|
||||||
*/
|
|
||||||
public class RequestUserAccountActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_3 = "3";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_1 = "existing user account";
|
|
||||||
private static final String USER_IDENTITY_2 = "data access exception";
|
|
||||||
private static final String USER_IDENTITY_3 = "new account request";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_IDENTITY_1.equals(dn)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserByDn(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
switch (user.getIdentity()) {
|
|
||||||
case USER_IDENTITY_2:
|
|
||||||
throw new DataAccessException();
|
|
||||||
case USER_IDENTITY_3:
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).createUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests when a user account already exists.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
|
||||||
public void testExistingAccount() throws Exception {
|
|
||||||
RequestUserAccountAction requestUserAccount = new RequestUserAccountAction(USER_IDENTITY_1, StringUtils.EMPTY);
|
|
||||||
requestUserAccount.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests when a DataAccessException occurs while saving the new account
|
|
||||||
* request.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = DataAccessException.class)
|
|
||||||
public void testDataAccessException() throws Exception {
|
|
||||||
RequestUserAccountAction requestUserAccount = new RequestUserAccountAction(USER_IDENTITY_2, StringUtils.EMPTY);
|
|
||||||
requestUserAccount.execute(daoFactory, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the general case for requesting a new user account.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testRequestUserAccountAction() throws Exception {
|
|
||||||
RequestUserAccountAction requestUserAccount = new RequestUserAccountAction(USER_IDENTITY_3, StringUtils.EMPTY);
|
|
||||||
NiFiUser user = requestUserAccount.execute(daoFactory, null);
|
|
||||||
|
|
||||||
// verfiy the user
|
|
||||||
Assert.assertEquals(USER_ID_3, user.getId());
|
|
||||||
Assert.assertEquals(USER_IDENTITY_3, user.getIdentity());
|
|
||||||
Assert.assertEquals(AccountStatus.PENDING, user.getStatus());
|
|
||||||
|
|
||||||
// verify interaction with dao
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).createUser(user);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,262 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.hamcrest.Matcher;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.ArgumentMatcher;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SeedUserAccountsActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_1 = "1";
|
|
||||||
private static final String USER_ID_2 = "2";
|
|
||||||
private static final String USER_ID_3 = "3";
|
|
||||||
private static final String USER_ID_4 = "4";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_1 = "user 1 - active user - remove monitor and operator, add dfm";
|
|
||||||
private static final String USER_IDENTITY_2 = "user 2 - active user - no action";
|
|
||||||
private static final String USER_IDENTITY_3 = "user 3 - pending user - add operator";
|
|
||||||
private static final String USER_IDENTITY_4 = "user 4 - new user - add monitor";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
private AuthorityDAO authorityDao;
|
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String id = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_ID_1.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_1);
|
|
||||||
user.setIdentity(USER_IDENTITY_1);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
} else if (USER_ID_2.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_2);
|
|
||||||
user.setIdentity(USER_IDENTITY_2);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
} else if (USER_ID_3.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
user.setStatus(AccountStatus.PENDING);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserById(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_IDENTITY_1.equals(dn)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_1);
|
|
||||||
user.setIdentity(USER_IDENTITY_1);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
} else if (USER_IDENTITY_2.equals(dn)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_2);
|
|
||||||
user.setIdentity(USER_IDENTITY_2);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
} else if (USER_IDENTITY_3.equals(dn)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
user.setStatus(AccountStatus.PENDING);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserByDn(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
if (USER_IDENTITY_4.equals(user.getIdentity())) {
|
|
||||||
user.setId(USER_ID_4);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).createUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the authority dao
|
|
||||||
authorityDao = Mockito.mock(AuthorityDAO.class);
|
|
||||||
|
|
||||||
// mock the authority provider
|
|
||||||
authorityProvider = Mockito.mock(AuthorityProvider.class);
|
|
||||||
Mockito.doAnswer(new Answer<Set<String>>() {
|
|
||||||
@Override
|
|
||||||
public Set<String> answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Authority role = (Authority) args[0];
|
|
||||||
|
|
||||||
Set<String> users = new HashSet<>();
|
|
||||||
if (Authority.ROLE_DFM.equals(role)) {
|
|
||||||
users.add(USER_IDENTITY_1);
|
|
||||||
} else if (Authority.ROLE_ADMIN.equals(role)) {
|
|
||||||
users.add(USER_IDENTITY_2);
|
|
||||||
} else if (Authority.ROLE_PROXY.equals(role)) {
|
|
||||||
users.add(USER_IDENTITY_3);
|
|
||||||
} else if (Authority.ROLE_MONITOR.equals(role)) {
|
|
||||||
users.add(USER_IDENTITY_4);
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).getUsers(Mockito.any(Authority.class));
|
|
||||||
Mockito.doAnswer(new Answer<Set<Authority>>() {
|
|
||||||
@Override
|
|
||||||
public Set<Authority> answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
switch (dn) {
|
|
||||||
case USER_IDENTITY_1:
|
|
||||||
authorities.add(Authority.ROLE_DFM);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_2:
|
|
||||||
authorities.add(Authority.ROLE_ADMIN);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_3:
|
|
||||||
authorities.add(Authority.ROLE_PROXY);
|
|
||||||
break;
|
|
||||||
case USER_IDENTITY_4:
|
|
||||||
authorities.add(Authority.ROLE_MONITOR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).getAuthorities(Mockito.anyString());
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
Mockito.when(daoFactory.getAuthorityDAO()).thenReturn(authorityDao);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests seeding the user accounts.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSeedUsers() throws Exception {
|
|
||||||
SeedUserAccountsAction seedUserAccounts = new SeedUserAccountsAction();
|
|
||||||
seedUserAccounts.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// matcher for user 1
|
|
||||||
Matcher<NiFiUser> matchesUser1 = new ArgumentMatcher<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object argument) {
|
|
||||||
NiFiUser user = (NiFiUser) argument;
|
|
||||||
return USER_ID_1.equals(user.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify user 1 - active existing user - remove monitor, operator, add dfm
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(Mockito.argThat(matchesUser1));
|
|
||||||
Mockito.verify(userDao, Mockito.never()).createUser(Mockito.argThat(matchesUser1));
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_DFM), USER_ID_1);
|
|
||||||
|
|
||||||
// matcher for user 2
|
|
||||||
Matcher<NiFiUser> matchesUser2 = new ArgumentMatcher<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object argument) {
|
|
||||||
NiFiUser user = (NiFiUser) argument;
|
|
||||||
return USER_ID_2.equals(user.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify user 2 - active existing user - no actions
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(Mockito.argThat(matchesUser2));
|
|
||||||
Mockito.verify(userDao, Mockito.never()).createUser(Mockito.argThat(matchesUser2));
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).createAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_2));
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).deleteAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_2));
|
|
||||||
|
|
||||||
// matchers for user 3
|
|
||||||
Matcher<NiFiUser> matchesPendingUser3 = new ArgumentMatcher<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object argument) {
|
|
||||||
NiFiUser user = (NiFiUser) argument;
|
|
||||||
return USER_ID_3.equals(user.getId()) && AccountStatus.ACTIVE.equals(user.getStatus());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Matcher<NiFiUser> matchesUser3 = new ArgumentMatcher<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object argument) {
|
|
||||||
NiFiUser user = (NiFiUser) argument;
|
|
||||||
return USER_ID_3.equals(user.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify user 3 - pending user - add operator
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(Mockito.argThat(matchesPendingUser3));
|
|
||||||
Mockito.verify(userDao, Mockito.never()).createUser(Mockito.argThat(matchesUser3));
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_PROXY), USER_ID_3);
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).deleteAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_3));
|
|
||||||
|
|
||||||
// matcher for user 4
|
|
||||||
Matcher<NiFiUser> matchesUser4 = new ArgumentMatcher<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object argument) {
|
|
||||||
NiFiUser user = (NiFiUser) argument;
|
|
||||||
return USER_ID_4.equals(user.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify user 4 - new user - add monitor
|
|
||||||
Mockito.verify(userDao, Mockito.never()).updateUser(Mockito.argThat(matchesUser4));
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).createUser(Mockito.argThat(matchesUser4));
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_MONITOR), USER_ID_4);
|
|
||||||
Mockito.verify(authorityDao, Mockito.never()).deleteAuthorities(Mockito.anySet(), Mockito.eq(USER_ID_4));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,223 +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.admin.service.action;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.apache.nifi.admin.dao.AuthorityDAO;
|
|
||||||
import org.apache.nifi.admin.dao.DAOFactory;
|
|
||||||
import org.apache.nifi.admin.dao.UserDAO;
|
|
||||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
|
||||||
import org.apache.nifi.admin.service.AdministrationException;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.user.AccountStatus;
|
|
||||||
import org.apache.nifi.user.NiFiUser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test case for SetUserAuthoritiesAction.
|
|
||||||
*/
|
|
||||||
public class SetUserAuthoritiesActionTest {
|
|
||||||
|
|
||||||
private static final String USER_ID_1 = "1";
|
|
||||||
private static final String USER_ID_2 = "2";
|
|
||||||
private static final String USER_ID_3 = "3";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_2 = "user 2";
|
|
||||||
private static final String USER_IDENTITY_3 = "user 3";
|
|
||||||
|
|
||||||
private DAOFactory daoFactory;
|
|
||||||
private UserDAO userDao;
|
|
||||||
private AuthorityDAO authorityDao;
|
|
||||||
private AuthorityProvider authorityProvider;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
// mock the user dao
|
|
||||||
userDao = Mockito.mock(UserDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String id = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_ID_1.equals(id)) {
|
|
||||||
// leave user uninitialized
|
|
||||||
} else if (USER_ID_2.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_2);
|
|
||||||
user.setIdentity(USER_IDENTITY_2);
|
|
||||||
} else if (USER_ID_3.equals(id)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserById(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<NiFiUser>() {
|
|
||||||
@Override
|
|
||||||
public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
NiFiUser user = null;
|
|
||||||
if (USER_IDENTITY_3.equals(dn)) {
|
|
||||||
user = new NiFiUser();
|
|
||||||
user.setId(USER_ID_3);
|
|
||||||
user.setIdentity(USER_IDENTITY_3);
|
|
||||||
user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
|
|
||||||
user.setStatus(AccountStatus.ACTIVE);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}).when(userDao).findUserByDn(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
NiFiUser user = (NiFiUser) args[0];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(userDao).updateUser(Mockito.any(NiFiUser.class));
|
|
||||||
|
|
||||||
// mock the authority dao
|
|
||||||
authorityDao = Mockito.mock(AuthorityDAO.class);
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Set<Authority> authorities = (Set<Authority>) args[0];
|
|
||||||
String id = (String) args[1];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityDao).createAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
Set<Authority> authorities = (Set<Authority>) args[0];
|
|
||||||
String id = (String) args[1];
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityDao).deleteAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
|
|
||||||
|
|
||||||
// mock the dao factory
|
|
||||||
daoFactory = Mockito.mock(DAOFactory.class);
|
|
||||||
Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
|
|
||||||
Mockito.when(daoFactory.getAuthorityDAO()).thenReturn(authorityDao);
|
|
||||||
|
|
||||||
// mock the authority provider
|
|
||||||
authorityProvider = Mockito.mock(AuthorityProvider.class);
|
|
||||||
Mockito.doAnswer(new Answer<Set<Authority>>() {
|
|
||||||
@Override
|
|
||||||
public Set<Authority> answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
|
|
||||||
Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
|
||||||
if (USER_IDENTITY_3.equals(dn)) {
|
|
||||||
authorities.add(Authority.ROLE_DFM);
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).getAuthorities(Mockito.anyString());
|
|
||||||
Mockito.doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
Object[] args = invocation.getArguments();
|
|
||||||
String dn = (String) args[0];
|
|
||||||
Set<Authority> authorites = (Set<Authority>) args[1];
|
|
||||||
|
|
||||||
if (USER_IDENTITY_2.equals(dn)) {
|
|
||||||
throw new AuthorityAccessException(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do nothing
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(authorityProvider).setAuthorities(Mockito.anyString(), Mockito.anySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test activating an unknown user account. User accounts are unknown then
|
|
||||||
* there is no pending account for the user.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AccountNotFoundException.class)
|
|
||||||
public void testUnknownUser() throws Exception {
|
|
||||||
UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_1, Collections.EMPTY_SET);
|
|
||||||
setUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Testing case then an AuthorityAccessException occurs while setting a
|
|
||||||
* users authorities.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test(expected = AdministrationException.class)
|
|
||||||
public void testAuthorityAccessException() throws Exception {
|
|
||||||
UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_2, Collections.EMPTY_SET);
|
|
||||||
setUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests general case of setting user authorities.
|
|
||||||
*
|
|
||||||
* @throws Exception ex
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSetAuthorities() throws Exception {
|
|
||||||
UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_3, EnumSet.of(Authority.ROLE_ADMIN));
|
|
||||||
NiFiUser user = setUserAuthorities.execute(daoFactory, authorityProvider);
|
|
||||||
|
|
||||||
// verify user
|
|
||||||
Assert.assertEquals(USER_ID_3, user.getId());
|
|
||||||
Assert.assertEquals(1, user.getAuthorities().size());
|
|
||||||
Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_ADMIN));
|
|
||||||
|
|
||||||
// verify interaction with dao
|
|
||||||
Mockito.verify(userDao, Mockito.times(1)).updateUser(user);
|
|
||||||
Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_ADMIN), USER_ID_3);
|
|
||||||
|
|
||||||
Set<Authority> authoritiesAddedToProvider = EnumSet.of(Authority.ROLE_ADMIN);
|
|
||||||
|
|
||||||
// verify interaction with provider
|
|
||||||
Mockito.verify(authorityProvider, Mockito.times(1)).setAuthorities(USER_IDENTITY_3, authoritiesAddedToProvider);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,6 +18,7 @@ package org.apache.nifi.web.api.dto;
|
||||||
|
|
||||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current revision for this NiFi.
|
* Current revision for this NiFi.
|
||||||
|
@ -41,6 +42,9 @@ public class RevisionDTO {
|
||||||
+ "nature of requests/responses this was implemented to allow the client to make numerous requests without having to wait for the previous response to come back"
|
+ "nature of requests/responses this was implemented to allow the client to make numerous requests without having to wait for the previous response to come back"
|
||||||
)
|
)
|
||||||
public String getClientId() {
|
public String getClientId() {
|
||||||
|
if (clientId == null || clientId.trim().isEmpty()) {
|
||||||
|
clientId = UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,6 @@ public class ControllerStatusDTO implements Cloneable {
|
||||||
private Integer connectedNodeCount = 0;
|
private Integer connectedNodeCount = 0;
|
||||||
private Integer totalNodeCount = 0;
|
private Integer totalNodeCount = 0;
|
||||||
|
|
||||||
private Boolean hasPendingAccounts;
|
|
||||||
|
|
||||||
private Integer runningCount = 0;
|
private Integer runningCount = 0;
|
||||||
private Integer stoppedCount = 0;
|
private Integer stoppedCount = 0;
|
||||||
private Integer invalidCount = 0;
|
private Integer invalidCount = 0;
|
||||||
|
@ -126,18 +124,6 @@ public class ControllerStatusDTO implements Cloneable {
|
||||||
this.reportingTaskBulletins = reportingTaskBulletins;
|
this.reportingTaskBulletins = reportingTaskBulletins;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether or not there are pending user requests
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("Whether there are any pending user account requests.")
|
|
||||||
public Boolean getHasPendingAccounts() {
|
|
||||||
return hasPendingAccounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasPendingAccounts(Boolean hasPendingAccounts) {
|
|
||||||
this.hasPendingAccounts = hasPendingAccounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return number of running components in this controller
|
* @return number of running components in this controller
|
||||||
*/
|
*/
|
||||||
|
@ -256,7 +242,6 @@ public class ControllerStatusDTO implements Cloneable {
|
||||||
other.setConnectedNodes(getConnectedNodes());
|
other.setConnectedNodes(getConnectedNodes());
|
||||||
other.setConnectedNodeCount(getConnectedNodeCount());
|
other.setConnectedNodeCount(getConnectedNodeCount());
|
||||||
other.setTotalNodeCount(getTotalNodeCount());
|
other.setTotalNodeCount(getTotalNodeCount());
|
||||||
other.setHasPendingAccounts(getHasPendingAccounts());
|
|
||||||
other.setRunningCount(getRunningCount());
|
other.setRunningCount(getRunningCount());
|
||||||
other.setStoppedCount(getStoppedCount());
|
other.setStoppedCount(getStoppedCount());
|
||||||
other.setInvalidCount(getInvalidCount());
|
other.setInvalidCount(getInvalidCount());
|
||||||
|
|
|
@ -35,7 +35,11 @@ public class Entity {
|
||||||
value = "The revision for this request/response. The revision is required for any mutable flow requests and is included in all responses."
|
value = "The revision for this request/response. The revision is required for any mutable flow requests and is included in all responses."
|
||||||
)
|
)
|
||||||
public RevisionDTO getRevision() {
|
public RevisionDTO getRevision() {
|
||||||
return revision;
|
if (revision == null) {
|
||||||
|
return new RevisionDTO();
|
||||||
|
} else {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRevision(RevisionDTO revision) {
|
public void setRevision(RevisionDTO revision) {
|
||||||
|
|
|
@ -14,41 +14,41 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.cluster.authorization.protocol.message;
|
package org.apache.nifi.web.api.entity;
|
||||||
|
|
||||||
|
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A serialized representation of this class can be placed in the entity body of a request to the API.
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name = "getGroupForUserMessage")
|
@XmlRootElement(name = "updateControllerServiceReferenceRequestEntity")
|
||||||
public class GetGroupForUserMessage extends ProtocolMessage {
|
public class UpdateControllerServiceReferenceRequestEntity extends Entity {
|
||||||
|
|
||||||
private String dn;
|
private String id;
|
||||||
|
private String state;
|
||||||
|
|
||||||
private String response;
|
@ApiModelProperty(
|
||||||
|
value = "The identifier of the Controller Service."
|
||||||
public GetGroupForUserMessage() {
|
)
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setId(String id) {
|
||||||
public MessageType getType() {
|
this.id = id;
|
||||||
return MessageType.GET_GROUP_FOR_USER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDn() {
|
@ApiModelProperty(
|
||||||
return dn;
|
value = "The new state of the references for the controller service.",
|
||||||
|
allowableValues = "ENABLED, DISABLED, RUNNING, STOPPED"
|
||||||
|
)
|
||||||
|
public String getState() {
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDn(String dn) {
|
public void setState(String state) {
|
||||||
this.dn = dn;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResponse() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResponse(String response) {
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1 +0,0 @@
|
||||||
/target
|
|
|
@ -1,46 +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>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>nifi-cluster-authorization-provider</artifactId>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-file-authorization-provider</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-framework-cluster-protocol</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-framework-cluster</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.nifi</groupId>
|
|
||||||
<artifactId>nifi-socket-utils</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
|
@ -1,225 +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.cluster.authorization;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProviderConfigurationContext;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProviderInitializationContext;
|
|
||||||
import org.apache.nifi.authorization.FileAuthorizationProvider;
|
|
||||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.DoesDnExistMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetAuthoritiesMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetGroupForUserMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage;
|
|
||||||
import static org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage.MessageType.DOES_DN_EXIST;
|
|
||||||
import static org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage.MessageType.GET_AUTHORITIES;
|
|
||||||
import static org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage.MessageType.GET_GROUP_FOR_USER;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.jaxb.JaxbProtocolUtils;
|
|
||||||
import org.apache.nifi.cluster.manager.impl.WebClusterManager;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolContext;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolMessageMarshaller;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolMessageUnmarshaller;
|
|
||||||
import org.apache.nifi.cluster.protocol.jaxb.JaxbProtocolContext;
|
|
||||||
import org.apache.nifi.io.socket.ServerSocketConfiguration;
|
|
||||||
import org.apache.nifi.io.socket.SocketListener;
|
|
||||||
import org.apache.nifi.io.socket.SocketUtils;
|
|
||||||
import org.apache.nifi.io.socket.multicast.DiscoverableService;
|
|
||||||
import org.apache.nifi.io.socket.multicast.DiscoverableServiceImpl;
|
|
||||||
import org.apache.nifi.logging.NiFiLog;
|
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import static org.apache.nifi.util.NiFiProperties.CLUSTER_MANAGER_ADDRESS;
|
|
||||||
import org.apache.nifi.util.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides authorities for the NCM in clustered environments. Communication
|
|
||||||
* occurs over TCP/IP sockets. All method calls are deferred to the
|
|
||||||
* FileAuthorizationProvider.
|
|
||||||
*/
|
|
||||||
public class ClusterManagerAuthorizationProvider extends FileAuthorizationProvider implements AuthorityProvider, ApplicationContextAware {
|
|
||||||
|
|
||||||
public static final String AUTHORITY_PROVIDER_SERVIVE_NAME = "cluster-authority-provider";
|
|
||||||
|
|
||||||
private static final Logger logger = new NiFiLog(LoggerFactory.getLogger(ClusterManagerAuthorizationProvider.class));
|
|
||||||
private static final String CLUSTER_MANAGER_AUTHORITY_PROVIDER_PORT = "Authority Provider Port";
|
|
||||||
private static final String CLUSTER_MANAGER_AUTHORITY_PROVIDER_THREADS = "Authority Provider Threads";
|
|
||||||
private static final int DEFAULT_CLUSTER_MANAGER_AUTHORITY_PROVIDER_THREADS = 10;
|
|
||||||
|
|
||||||
private WebClusterManager clusterManager;
|
|
||||||
private ProtocolContext<ProtocolMessage> authorityProviderProtocolContext;
|
|
||||||
private SocketListener socketListener;
|
|
||||||
private NiFiProperties properties;
|
|
||||||
private ApplicationContext applicationContext;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
|
||||||
super.initialize(initializationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
|
||||||
super.onConfigured(configurationContext);
|
|
||||||
|
|
||||||
// get the socket address of the cluster authority provider
|
|
||||||
final InetSocketAddress clusterAuthorityProviderAddress = getClusterManagerAuthorityProviderAddress(configurationContext);
|
|
||||||
|
|
||||||
// get the cluster manager
|
|
||||||
clusterManager = applicationContext.getBean("clusterManager", WebClusterManager.class);
|
|
||||||
|
|
||||||
// if using multicast, then the authority provider's service is broadcasted
|
|
||||||
if (properties.getClusterProtocolUseMulticast()) {
|
|
||||||
|
|
||||||
// create the authority provider service for discovery
|
|
||||||
final DiscoverableService clusterAuthorityProviderService = new DiscoverableServiceImpl(AUTHORITY_PROVIDER_SERVIVE_NAME, clusterAuthorityProviderAddress);
|
|
||||||
|
|
||||||
// register the authority provider service with the cluster manager
|
|
||||||
clusterManager.addBroadcastedService(clusterAuthorityProviderService);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the number of protocol listening thread
|
|
||||||
final int numThreads = getClusterManagerAuthorityProviderThreads(configurationContext);
|
|
||||||
|
|
||||||
// the server socket configuration
|
|
||||||
final ServerSocketConfiguration configuration = applicationContext.getBean("protocolServerSocketConfiguration", ServerSocketConfiguration.class);
|
|
||||||
|
|
||||||
// the authority provider listens for node messages
|
|
||||||
socketListener = new SocketListener(numThreads, clusterAuthorityProviderAddress.getPort(), configuration) {
|
|
||||||
@Override
|
|
||||||
public void dispatchRequest(final Socket socket) {
|
|
||||||
ClusterManagerAuthorizationProvider.this.dispatchRequest(socket);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// start the socket listener
|
|
||||||
if (socketListener != null && !socketListener.isRunning()) {
|
|
||||||
try {
|
|
||||||
socketListener.start();
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new ProviderCreationException("Failed to start Cluster Manager Authorization Provider due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the protocol context
|
|
||||||
authorityProviderProtocolContext = new JaxbProtocolContext<ProtocolMessage>(JaxbProtocolUtils.JAXB_CONTEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preDestruction() throws ProviderDestructionException {
|
|
||||||
if (socketListener != null && socketListener.isRunning()) {
|
|
||||||
try {
|
|
||||||
socketListener.stop();
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new ProviderDestructionException("Failed to stop Cluster Manager Authorization Provider due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.preDestruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getClusterManagerAuthorityProviderThreads(final AuthorityProviderConfigurationContext configurationContext) {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(configurationContext.getProperty(CLUSTER_MANAGER_AUTHORITY_PROVIDER_THREADS));
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
return DEFAULT_CLUSTER_MANAGER_AUTHORITY_PROVIDER_THREADS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private InetSocketAddress getClusterManagerAuthorityProviderAddress(final AuthorityProviderConfigurationContext configurationContext) {
|
|
||||||
try {
|
|
||||||
String socketAddress = properties.getProperty(CLUSTER_MANAGER_ADDRESS);
|
|
||||||
if (StringUtils.isBlank(socketAddress)) {
|
|
||||||
socketAddress = "localhost";
|
|
||||||
}
|
|
||||||
return InetSocketAddress.createUnresolved(socketAddress, getClusterManagerAuthorityProviderPort(configurationContext));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new RuntimeException("Invalid manager authority provider address/port due to: " + ex, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer getClusterManagerAuthorityProviderPort(final AuthorityProviderConfigurationContext configurationContext) {
|
|
||||||
final String authorityProviderPort = configurationContext.getProperty(CLUSTER_MANAGER_AUTHORITY_PROVIDER_PORT);
|
|
||||||
if (authorityProviderPort == null || authorityProviderPort.trim().isEmpty()) {
|
|
||||||
throw new ProviderCreationException("The authority provider port must be specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Integer.parseInt(authorityProviderPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatchRequest(final Socket socket) {
|
|
||||||
try {
|
|
||||||
// unmarshall message
|
|
||||||
final ProtocolMessageUnmarshaller<ProtocolMessage> unmarshaller = authorityProviderProtocolContext.createUnmarshaller();
|
|
||||||
final ProtocolMessage request = unmarshaller.unmarshal(socket.getInputStream());
|
|
||||||
final ProtocolMessage response = request;
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (request.getType()) {
|
|
||||||
case DOES_DN_EXIST: {
|
|
||||||
final DoesDnExistMessage castedMsg = (DoesDnExistMessage) request;
|
|
||||||
castedMsg.setResponse(doesDnExist(castedMsg.getDn()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GET_AUTHORITIES: {
|
|
||||||
final GetAuthoritiesMessage castedMsg = (GetAuthoritiesMessage) request;
|
|
||||||
castedMsg.setResponse(getAuthorities(castedMsg.getDn()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GET_GROUP_FOR_USER: {
|
|
||||||
final GetGroupForUserMessage castedMsg = (GetGroupForUserMessage) request;
|
|
||||||
castedMsg.setResponse(getGroupForUser(castedMsg.getDn()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new Exception("Unsupported Message Type: " + request.getType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
response.setExceptionClass(ex.getClass().getName());
|
|
||||||
response.setExceptionMessage(ex.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
final ProtocolMessageMarshaller<ProtocolMessage> marshaller = authorityProviderProtocolContext.createMarshaller();
|
|
||||||
marshaller.marshal(response, socket.getOutputStream());
|
|
||||||
|
|
||||||
} catch (final Exception e) {
|
|
||||||
logger.warn("Failed processing Socket Authorization Provider protocol message due to " + e, e);
|
|
||||||
} finally {
|
|
||||||
SocketUtils.closeQuietly(socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@AuthorityProviderContext
|
|
||||||
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@AuthorityProviderContext
|
|
||||||
public void setNiFiProperties(NiFiProperties properties) {
|
|
||||||
super.setNiFiProperties(properties);
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,389 +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.cluster.authorization;
|
|
||||||
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.DoesDnExistMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetAuthoritiesMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProvider;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProviderConfigurationContext;
|
|
||||||
import org.apache.nifi.authorization.AuthorityProviderInitializationContext;
|
|
||||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
|
||||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
|
||||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
|
||||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
|
||||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
|
||||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetGroupForUserMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.jaxb.JaxbProtocolUtils;
|
|
||||||
import org.apache.nifi.io.socket.SocketConfiguration;
|
|
||||||
import org.apache.nifi.io.socket.SocketUtils;
|
|
||||||
import org.apache.nifi.io.socket.multicast.DiscoverableService;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolContext;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolMessageMarshaller;
|
|
||||||
import org.apache.nifi.cluster.protocol.ProtocolMessageUnmarshaller;
|
|
||||||
import org.apache.nifi.cluster.protocol.impl.ClusterServiceDiscovery;
|
|
||||||
import org.apache.nifi.cluster.protocol.impl.ClusterServiceLocator;
|
|
||||||
import org.apache.nifi.cluster.protocol.jaxb.JaxbProtocolContext;
|
|
||||||
import org.apache.nifi.io.socket.multicast.DiscoverableServiceImpl;
|
|
||||||
import org.apache.nifi.io.socket.multicast.MulticastConfiguration;
|
|
||||||
import org.apache.nifi.logging.NiFiLog;
|
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import static org.apache.nifi.util.NiFiProperties.CLUSTER_NODE_UNICAST_MANAGER_ADDRESS;
|
|
||||||
import org.apache.nifi.util.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides authorities for nodes in clustered environments. Communication
|
|
||||||
* occurs over TCP/IP sockets. All method calls are communicated to the cluster
|
|
||||||
* manager provider via socket.
|
|
||||||
*/
|
|
||||||
public class NodeAuthorizationProvider implements AuthorityProvider, ApplicationContextAware {
|
|
||||||
|
|
||||||
private static final Logger logger = new NiFiLog(LoggerFactory.getLogger(NodeAuthorizationProvider.class));
|
|
||||||
private static final String CLUSTER_NODE_MANAGER_AUTHORITY_PROVIDER_PORT = "Cluster Manager Authority Provider Port";
|
|
||||||
|
|
||||||
private ProtocolContext<ProtocolMessage> authorityProviderProtocolContext;
|
|
||||||
private SocketConfiguration socketConfiguration;
|
|
||||||
private ClusterServiceLocator serviceLocator;
|
|
||||||
private ApplicationContext applicationContext;
|
|
||||||
private NiFiProperties properties;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
|
||||||
// TODO clear user cache?
|
|
||||||
|
|
||||||
// if using multicast, then the authority provider's service is broadcasted
|
|
||||||
if (properties.getClusterProtocolUseMulticast()) {
|
|
||||||
// create the service discovery
|
|
||||||
final ClusterServiceDiscovery serviceDiscovery = new ClusterServiceDiscovery(
|
|
||||||
ClusterManagerAuthorizationProvider.AUTHORITY_PROVIDER_SERVIVE_NAME,
|
|
||||||
properties.getClusterProtocolMulticastAddress(),
|
|
||||||
applicationContext.getBean("protocolMulticastConfiguration", MulticastConfiguration.class),
|
|
||||||
applicationContext.getBean("protocolContext", ProtocolContext.class));
|
|
||||||
|
|
||||||
// create service location configuration
|
|
||||||
final ClusterServiceLocator.AttemptsConfig config = new ClusterServiceLocator.AttemptsConfig();
|
|
||||||
config.setNumAttempts(3);
|
|
||||||
config.setTimeBetweenAttempts(1);
|
|
||||||
config.setTimeBetweenAttempsUnit(TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
serviceLocator = new ClusterServiceLocator(serviceDiscovery);
|
|
||||||
serviceLocator.setAttemptsConfig(config);
|
|
||||||
} else {
|
|
||||||
final InetSocketAddress serviceAddress = getClusterNodeManagerAuthorityProviderAddress(configurationContext);
|
|
||||||
final DiscoverableService service = new DiscoverableServiceImpl(ClusterManagerAuthorizationProvider.AUTHORITY_PROVIDER_SERVIVE_NAME, serviceAddress);
|
|
||||||
serviceLocator = new ClusterServiceLocator(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// start the service locator
|
|
||||||
serviceLocator.start();
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new ProviderCreationException(ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the socket configuration
|
|
||||||
socketConfiguration = applicationContext.getBean("protocolSocketConfiguration", SocketConfiguration.class);
|
|
||||||
|
|
||||||
// initialize the protocol context
|
|
||||||
authorityProviderProtocolContext = new JaxbProtocolContext<ProtocolMessage>(JaxbProtocolUtils.JAXB_CONTEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private InetSocketAddress getClusterNodeManagerAuthorityProviderAddress(final AuthorityProviderConfigurationContext configurationContext) {
|
|
||||||
try {
|
|
||||||
String socketAddress = properties.getProperty(CLUSTER_NODE_UNICAST_MANAGER_ADDRESS);
|
|
||||||
if (StringUtils.isBlank(socketAddress)) {
|
|
||||||
socketAddress = "localhost";
|
|
||||||
}
|
|
||||||
return InetSocketAddress.createUnresolved(socketAddress, getClusterNodeManagerAuthorityProviderPort(configurationContext));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new ProviderCreationException("Invalid cluster manager authority provider address/port due to: " + ex, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer getClusterNodeManagerAuthorityProviderPort(final AuthorityProviderConfigurationContext configurationContext) {
|
|
||||||
final String nodeAuthorityProviderPort = configurationContext.getProperty(CLUSTER_NODE_MANAGER_AUTHORITY_PROVIDER_PORT);
|
|
||||||
if (nodeAuthorityProviderPort == null || nodeAuthorityProviderPort.trim().isEmpty()) {
|
|
||||||
throw new ProviderCreationException("The cluster manager authority provider port must be specified.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Integer.parseInt(nodeAuthorityProviderPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthorities(String dn, Set<Authority> authorities) throws AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to set user authorities.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to add users.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doesDnExist(String dn) throws AuthorityAccessException {
|
|
||||||
// create message
|
|
||||||
final DoesDnExistMessage msg = new DoesDnExistMessage();
|
|
||||||
msg.setDn(dn);
|
|
||||||
|
|
||||||
Socket socket = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
final InetSocketAddress socketAddress = getServiceAddress();
|
|
||||||
if (socketAddress == null) {
|
|
||||||
throw new AuthorityAccessException("Cluster Authority Provider's address is not known.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// create a socket
|
|
||||||
socket = SocketUtils.createSocket(socketAddress, socketConfiguration);
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed to create socket due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// marshal message to output stream
|
|
||||||
final ProtocolMessageMarshaller marshaller = authorityProviderProtocolContext.createMarshaller();
|
|
||||||
marshaller.marshal(msg, socket.getOutputStream());
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed marshalling '" + msg.getType() + "' protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// unmarshall response and return
|
|
||||||
final ProtocolMessageUnmarshaller<ProtocolMessage> unmarshaller = authorityProviderProtocolContext.createUnmarshaller();
|
|
||||||
final DoesDnExistMessage response = (DoesDnExistMessage) unmarshaller.unmarshal(socket.getInputStream());
|
|
||||||
|
|
||||||
// check if there was an exception
|
|
||||||
if (response.wasException()) {
|
|
||||||
throw new AuthorityAccessException(response.getExceptionMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
// return provider's response
|
|
||||||
return response.getResponse();
|
|
||||||
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed unmarshalling '" + msg.getType() + "' response protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
SocketUtils.closeQuietly(socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
// create message
|
|
||||||
final GetAuthoritiesMessage msg = new GetAuthoritiesMessage();
|
|
||||||
msg.setDn(dn);
|
|
||||||
|
|
||||||
Socket socket = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
final InetSocketAddress socketAddress = getServiceAddress();
|
|
||||||
if (socketAddress == null) {
|
|
||||||
throw new AuthorityAccessException("Cluster Authority Provider's address is not known.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// create a socket
|
|
||||||
socket = SocketUtils.createSocket(socketAddress, socketConfiguration);
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed to create socket due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// marshal message to output stream
|
|
||||||
final ProtocolMessageMarshaller marshaller = authorityProviderProtocolContext.createMarshaller();
|
|
||||||
marshaller.marshal(msg, socket.getOutputStream());
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed marshalling '" + msg.getType() + "' protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// unmarshall response and return
|
|
||||||
final ProtocolMessageUnmarshaller<ProtocolMessage> unmarshaller = authorityProviderProtocolContext.createUnmarshaller();
|
|
||||||
final GetAuthoritiesMessage response = (GetAuthoritiesMessage) unmarshaller.unmarshal(socket.getInputStream());
|
|
||||||
|
|
||||||
// check if there was an exception
|
|
||||||
if (response.wasException()) {
|
|
||||||
if (isException(UnknownIdentityException.class, response)) {
|
|
||||||
throw new UnknownIdentityException(response.getExceptionMessage());
|
|
||||||
} else {
|
|
||||||
throw new AuthorityAccessException(response.getExceptionMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return provider's response
|
|
||||||
return response.getResponse();
|
|
||||||
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed unmarshalling '" + msg.getType() + "' response protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
SocketUtils.closeQuietly(socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getUsers(Authority authority) throws AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to get users for a given authority.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to revoke users.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to set user groups.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to ungroup users.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ungroup(String group) throws AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to ungroup.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
return DownloadAuthorization.approved();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
// create message
|
|
||||||
final GetGroupForUserMessage msg = new GetGroupForUserMessage();
|
|
||||||
msg.setDn(dn);
|
|
||||||
|
|
||||||
Socket socket = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
final InetSocketAddress socketAddress = getServiceAddress();
|
|
||||||
if (socketAddress == null) {
|
|
||||||
throw new AuthorityAccessException("Cluster Authority Provider's address is not known.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// create a socket
|
|
||||||
socket = SocketUtils.createSocket(socketAddress, socketConfiguration);
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed to create socket due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// marshal message to output stream
|
|
||||||
final ProtocolMessageMarshaller marshaller = authorityProviderProtocolContext.createMarshaller();
|
|
||||||
marshaller.marshal(msg, socket.getOutputStream());
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed marshalling '" + msg.getType() + "' protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// unmarshall response and return
|
|
||||||
final ProtocolMessageUnmarshaller<ProtocolMessage> unmarshaller = authorityProviderProtocolContext.createUnmarshaller();
|
|
||||||
final GetGroupForUserMessage response = (GetGroupForUserMessage) unmarshaller.unmarshal(socket.getInputStream());
|
|
||||||
|
|
||||||
// check if there was an exception
|
|
||||||
if (response.wasException()) {
|
|
||||||
if (isException(UnknownIdentityException.class, response)) {
|
|
||||||
throw new UnknownIdentityException(response.getExceptionMessage());
|
|
||||||
} else {
|
|
||||||
throw new AuthorityAccessException(response.getExceptionMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.getResponse();
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new AuthorityAccessException("Failed unmarshalling '" + msg.getType() + "' response protocol message due to: " + ioe, ioe);
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
SocketUtils.closeQuietly(socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
|
||||||
throw new AuthorityAccessException("Nodes are not allowed to revoke groups.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preDestruction() throws ProviderDestructionException {
|
|
||||||
try {
|
|
||||||
if (serviceLocator != null && serviceLocator.isRunning()) {
|
|
||||||
serviceLocator.stop();
|
|
||||||
}
|
|
||||||
} catch (final IOException ioe) {
|
|
||||||
throw new ProviderDestructionException(ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@AuthorityProviderContext
|
|
||||||
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AuthorityProviderContext
|
|
||||||
public void setNiFiProperties(NiFiProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private InetSocketAddress getServiceAddress() {
|
|
||||||
final DiscoverableService service = serviceLocator.getService();
|
|
||||||
if (service != null) {
|
|
||||||
return service.getServiceAddress();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isException(final Class<? extends Exception> exception, final ProtocolMessage protocolMessage) {
|
|
||||||
if (protocolMessage.wasException()) {
|
|
||||||
return exception.getName().equals(protocolMessage.getExceptionClass());
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +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.cluster.authorization.protocol.message;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.ProtocolMessage.MessageType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
@XmlRootElement(name = "doesDnExistMessage")
|
|
||||||
public class DoesDnExistMessage extends ProtocolMessage {
|
|
||||||
|
|
||||||
private String dn;
|
|
||||||
|
|
||||||
private boolean response;
|
|
||||||
|
|
||||||
public DoesDnExistMessage() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MessageType getType() {
|
|
||||||
return MessageType.DOES_DN_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDn() {
|
|
||||||
return dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDn(String dn) {
|
|
||||||
this.dn = dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getResponse() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResponse(boolean response) {
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,57 +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.cluster.authorization.protocol.message;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import org.apache.nifi.authorization.Authority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
@XmlRootElement(name = "getAuthoritiesMessage")
|
|
||||||
public class GetAuthoritiesMessage extends ProtocolMessage {
|
|
||||||
|
|
||||||
private String dn;
|
|
||||||
|
|
||||||
private Set<Authority> response = new HashSet<>();
|
|
||||||
|
|
||||||
public GetAuthoritiesMessage() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MessageType getType() {
|
|
||||||
return MessageType.GET_AUTHORITIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDn() {
|
|
||||||
return dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDn(String dn) {
|
|
||||||
this.dn = dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Authority> getResponse() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResponse(Set<Authority> response) {
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +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.cluster.authorization.protocol.message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public abstract class ProtocolMessage {
|
|
||||||
|
|
||||||
private String exceptionClass;
|
|
||||||
private String exceptionMessage;
|
|
||||||
|
|
||||||
public static enum MessageType {
|
|
||||||
|
|
||||||
DOES_DN_EXIST,
|
|
||||||
GET_AUTHORITIES,
|
|
||||||
GET_USERS,
|
|
||||||
GET_GROUP_FOR_USER
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract MessageType getType();
|
|
||||||
|
|
||||||
public boolean wasException() {
|
|
||||||
return exceptionClass != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExceptionMessage() {
|
|
||||||
return exceptionMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExceptionMessage(final String exceptionMessage) {
|
|
||||||
this.exceptionMessage = exceptionMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExceptionClass() {
|
|
||||||
return exceptionClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExceptionClass(String exceptionClass) {
|
|
||||||
this.exceptionClass = exceptionClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,41 +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.cluster.authorization.protocol.message.jaxb;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public final class JaxbProtocolUtils {
|
|
||||||
|
|
||||||
public static final String JAXB_CONTEXT_PATH = ObjectFactory.class.getPackage().getName();
|
|
||||||
|
|
||||||
public static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the JAXBContext version.
|
|
||||||
*/
|
|
||||||
private static JAXBContext initializeJaxbContext() {
|
|
||||||
try {
|
|
||||||
return JAXBContext.newInstance(JAXB_CONTEXT_PATH);
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
throw new RuntimeException("Unable to create JAXBContext.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,44 +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.cluster.authorization.protocol.message.jaxb;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRegistry;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.DoesDnExistMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetAuthoritiesMessage;
|
|
||||||
import org.apache.nifi.cluster.authorization.protocol.message.GetGroupForUserMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
@XmlRegistry
|
|
||||||
public class ObjectFactory {
|
|
||||||
|
|
||||||
public ObjectFactory() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public DoesDnExistMessage createDoesDnExistMessage() {
|
|
||||||
return new DoesDnExistMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GetAuthoritiesMessage createGetAuthoritiesMessage() {
|
|
||||||
return new GetAuthoritiesMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GetGroupForUserMessage createGetGroupForUserMessage() {
|
|
||||||
return new GetGroupForUserMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue