mirror of https://github.com/apache/nifi.git
NIFI-1551:
- Starting to remove the AuthorityProvider. - This closes #330
This commit is contained in:
parent
2bcc31330c
commit
c4d06f203d
nifi-api/src/main/java/org/apache/nifi
authentication
authorization
nifi-assembly
nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util
nifi-nar-bundles
nifi-cassandra-bundle/nifi-cassandra-processors/src
main/java/org/apache/nifi/processors/cassandra
test/java/org/apache/nifi/processors/cassandra
nifi-framework-bundle/nifi-framework
nifi-administration/src
main
java/org/apache/nifi
admin
KeyDataSourceFactoryBean.javaUserDataSourceFactoryBean.java
dao
service
AccountDisabledException.javaAccountPendingException.javaUserService.java
action
AbstractUserAction.javaAddActionsAction.javaAdministrationAction.javaAuthorizeDownloadAction.javaAuthorizeUserAction.javaCreateUserAction.javaDeleteKeysAction.javaDeleteUserAction.javaDisableUserAction.javaDisableUserGroupAction.javaFindUserByDnAction.javaFindUserByIdAction.javaGetActionAction.javaGetActionsAction.javaGetKeyByIdAction.javaGetKeyByIdentityAction.javaGetOrCreateKeyAction.javaGetPreviousValues.javaGetUserGroupAction.javaGetUsersAction.javaHasPendingUserAccounts.javaInvalidateUserAccountAction.javaInvalidateUserGroupAccountsAction.javaPurgeActionsAction.javaRequestUserAccountAction.javaSeedUserAccountsAction.javaUngroupUserAction.javaUngroupUserGroupAction.javaUpdateUserAction.javaUpdateUserAuthoritiesCacheAction.javaUpdateUserCacheAction.javaUpdateUserGroupAction.java
impl
transaction/impl
authorization
AuthorityProviderFactoryBean.javaAuthorizerFactoryBean.javaStandardAuthorityProviderConfigurationContext.javaStandardAuthorityProviderInitializationContext.java
user
resources
xsd
test/java/org/apache/nifi/admin/service/action
nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status
nifi-cluster-authorization-provider
.gitignorepom.xml
src/main
java/org/apache/nifi/cluster/authorization
resources/META-INF/services
nifi-file-authorization-provider
nifi-nar-utils/src/main/java/org/apache/nifi/nar
nifi-resources/src/main/resources/conf
|
@ -18,8 +18,8 @@ package org.apache.nifi.authentication;
|
|||
|
||||
import org.apache.nifi.authentication.exception.IdentityAccessException;
|
||||
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* 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.
|
|
@ -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);
|
||||
}
|
|
@ -34,7 +34,6 @@ public class AuthorizationRequest {
|
|||
|
||||
private AuthorizationRequest(final Builder builder) {
|
||||
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");
|
||||
|
||||
this.resource = builder.resource;
|
||||
|
@ -54,7 +53,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
|
||||
*/
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
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.AuthorizerCreationException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
||||
|
@ -31,7 +30,7 @@ public interface Authorizer {
|
|||
*
|
||||
* @param request The authorization request
|
||||
* @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;
|
||||
|
||||
|
|
|
@ -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.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.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.database.directory>./database_repository</nifi.database.directory>
|
||||
|
||||
|
@ -413,9 +413,8 @@ language governing permissions and limitations under the License. -->
|
|||
<nifi.security.truststoreType />
|
||||
<nifi.security.truststorePasswd />
|
||||
<nifi.security.needClientAuth />
|
||||
<nifi.security.authorizedUsers.file>./conf/authorized-users.xml</nifi.security.authorizedUsers.file>
|
||||
<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.authorizer>file-provider</nifi.security.user.authorizer>
|
||||
<nifi.security.user.login.identity.provider />
|
||||
<nifi.security.x509.principal.extractor />
|
||||
<nifi.security.support.new.account.requests />
|
||||
|
|
|
@ -48,7 +48,7 @@ public class NiFiProperties extends Properties {
|
|||
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_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 REPOSITORY_DATABASE_DIRECTORY = "nifi.database.directory";
|
||||
public static final String RESTORE_DIRECTORY = "nifi.restore.directory";
|
||||
|
@ -131,7 +131,7 @@ public class NiFiProperties extends Properties {
|
|||
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_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_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";
|
||||
|
@ -504,10 +504,10 @@ public class NiFiProperties extends Properties {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the user authorities file
|
||||
* @return the user authorizers file
|
||||
*/
|
||||
public File getAuthorityProviderConfiguraitonFile() {
|
||||
final String value = getProperty(AUTHORITY_PROVIDER_CONFIGURATION_FILE);
|
||||
public File getAuthorizerConfiguraitonFile() {
|
||||
final String value = getProperty(AUTHORIZER_CONFIGURATION_FILE);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return new File(DEFAULT_AUTHORITY_PROVIDER_CONFIGURATION_FILE);
|
||||
} else {
|
||||
|
|
|
@ -26,7 +26,7 @@ import com.datastax.driver.core.Session;
|
|||
import org.apache.avro.Schema;
|
||||
import org.apache.avro.SchemaBuilder;
|
||||
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.PropertyValue;
|
||||
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.Row;
|
||||
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.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSession;
|
||||
|
|
|
@ -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 {
|
||||
|
||||
UserDAO getUserDAO();
|
||||
|
||||
ActionDAO getActionDAO();
|
||||
|
||||
AuthorityDAO getAuthorityDAO();
|
||||
|
||||
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 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.KeyDAO;
|
||||
import org.apache.nifi.admin.dao.UserDAO;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,16 +37,6 @@ public class DAOFactoryImpl implements DAOFactory {
|
|||
return new StandardActionDAO(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorityDAO getAuthorityDAO() {
|
||||
return new StandardAuthorityDAO(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDAO getUserDAO() {
|
||||
return new StandardUserDAO(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDAO getKeyDAO() {
|
||||
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 AccountDisabledException extends RuntimeException {
|
||||
|
||||
public AccountDisabledException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public AccountDisabledException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public AccountDisabledException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AccountDisabledException(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,144 +16,13 @@
|
|||
*/
|
||||
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.
|
||||
* Manages NiFi user keys.
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
@ -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.admin.dao.ActionDAO;
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -35,7 +34,7 @@ public class AddActionsAction implements AdministrationAction<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Void execute(DAOFactory daoFactory) {
|
||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||
|
||||
// add each action
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.apache.nifi.admin.service.action;
|
||||
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param daoFactory factory
|
||||
* @param authorityProvider provider
|
||||
* @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.DataAccessException;
|
||||
import org.apache.nifi.admin.dao.KeyDAO;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -38,7 +37,7 @@ public class DeleteKeysAction implements AdministrationAction<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException {
|
||||
public Void execute(DAOFactory daoFactory) throws DataAccessException {
|
||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||
keyDao.deleteKeys(identity);
|
||||
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.admin.dao.ActionDAO;
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
/**
|
||||
* Gets the action with the specified id.
|
||||
|
@ -33,7 +32,7 @@ public class GetActionAction implements AdministrationAction<Action> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Action execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Action execute(DAOFactory daoFactory) {
|
||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||
return actionDao.getAction(id);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
package org.apache.nifi.admin.service.action;
|
||||
|
||||
import java.util.Date;
|
||||
import org.apache.nifi.admin.dao.ActionDAO;
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.history.History;
|
||||
import org.apache.nifi.history.HistoryQuery;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Get all actions that match the specified query.
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ public class GetActionsAction implements AdministrationAction<History> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public History execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public History execute(DAOFactory daoFactory) {
|
||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||
|
||||
// find all matching history
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
package org.apache.nifi.admin.service.action;
|
||||
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
import org.apache.nifi.admin.dao.KeyDAO;
|
||||
import org.apache.nifi.key.Key;
|
||||
|
||||
|
@ -34,7 +32,7 @@ public class GetKeyByIdAction implements AdministrationAction<Key> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Key execute(DAOFactory daoFactory) {
|
||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||
return keyDao.findKeyById(id);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
package org.apache.nifi.admin.service.action;
|
||||
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
import org.apache.nifi.admin.dao.KeyDAO;
|
||||
import org.apache.nifi.key.Key;
|
||||
|
||||
|
@ -34,7 +32,7 @@ public class GetKeyByIdentityAction implements AdministrationAction<Key> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Key execute(DAOFactory daoFactory) {
|
||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||
return keyDao.findLatestKeyByIdentity(identity);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
package org.apache.nifi.admin.service.action;
|
||||
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
import org.apache.nifi.admin.dao.KeyDAO;
|
||||
import org.apache.nifi.key.Key;
|
||||
|
||||
|
@ -34,7 +32,7 @@ public class GetOrCreateKeyAction implements AdministrationAction<Key> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Key execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Key execute(DAOFactory daoFactory) {
|
||||
final KeyDAO keyDao = daoFactory.getKeyDAO();
|
||||
|
||||
Key key = keyDao.findLatestKeyByIdentity(identity);
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
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.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.history.PreviousValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Gets the action with the specified id.
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ public class GetPreviousValues implements AdministrationAction<Map<String, List<
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<PreviousValue>> execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Map<String, List<PreviousValue>> execute(DAOFactory daoFactory) {
|
||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||
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.admin.dao.ActionDAO;
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -37,7 +36,7 @@ public class PurgeActionsAction implements AdministrationAction<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
public Void execute(DAOFactory daoFactory) {
|
||||
ActionDAO actionDao = daoFactory.getActionDAO();
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
|
@ -16,53 +16,24 @@
|
|||
*/
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -71,553 +42,12 @@ 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 final Lock readLock = lock.readLock();
|
||||
private final Lock 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;
|
||||
|
|
|
@ -16,19 +16,19 @@
|
|||
*/
|
||||
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.dao.DAOFactory;
|
||||
import org.apache.nifi.admin.dao.impl.DAOFactoryImpl;
|
||||
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.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.admin.service.transaction.TransactionException;
|
||||
import org.slf4j.Logger;
|
||||
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
|
||||
* AuthorityProvider.
|
||||
|
@ -37,11 +37,9 @@ public class StandardTransaction implements Transaction {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StandardTransaction.class);
|
||||
|
||||
private final AuthorityProvider authorityProvider;
|
||||
private Connection connection;
|
||||
|
||||
public StandardTransaction(AuthorityProvider authorityProvider, Connection connection) {
|
||||
this.authorityProvider = authorityProvider;
|
||||
public StandardTransaction(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
@ -56,7 +54,7 @@ public class StandardTransaction implements Transaction {
|
|||
DAOFactory daoFactory = new DAOFactoryImpl(connection);
|
||||
|
||||
// execute the specified action
|
||||
return action.execute(daoFactory, authorityProvider);
|
||||
return action.execute(daoFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,6 @@ import javax.sql.DataSource;
|
|||
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.AuthorityProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -30,7 +29,6 @@ import org.apache.nifi.authorization.AuthorityProvider;
|
|||
public class StandardTransactionBuilder implements TransactionBuilder {
|
||||
|
||||
private DataSource dataSource;
|
||||
private AuthorityProvider authorityProvider;
|
||||
|
||||
@Override
|
||||
public Transaction start() throws TransactionException {
|
||||
|
@ -40,7 +38,7 @@ public class StandardTransactionBuilder implements TransactionBuilder {
|
|||
connection.setAutoCommit(false);
|
||||
|
||||
// create a new transaction
|
||||
return new StandardTransaction(authorityProvider, connection);
|
||||
return new StandardTransaction(connection);
|
||||
} catch (SQLException sqle) {
|
||||
throw new TransactionException(sqle.getMessage());
|
||||
}
|
||||
|
@ -50,8 +48,4 @@ public class StandardTransactionBuilder implements TransactionBuilder {
|
|||
public void setDataSource(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.AuthorizerCreationException;
|
||||
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.Property;
|
||||
import org.apache.nifi.nar.ExtensionManager;
|
||||
|
@ -83,7 +82,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
public Object getObject() throws Exception {
|
||||
if (authorizer == null) {
|
||||
// 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
|
||||
if (StringUtils.isBlank(authorizerIdentifier)) {
|
||||
|
@ -122,14 +121,14 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
}
|
||||
|
||||
private Authorizers loadAuthorizersConfiguration() throws Exception {
|
||||
final File authorizersConfigurationFile = properties.getAuthorityProviderConfiguraitonFile();
|
||||
final File authorizersConfigurationFile = properties.getAuthorizerConfiguraitonFile();
|
||||
|
||||
// load the authorizers from the specified file
|
||||
if (authorizersConfigurationFile.exists()) {
|
||||
try {
|
||||
// find the schema
|
||||
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
final Schema schema = schemaFactory.newSchema(AuthorityProviders.class.getResource(AUTHORIZERS_XSD));
|
||||
final Schema schema = schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
|
||||
|
||||
// attempt to unmarshal
|
||||
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
||||
|
@ -221,7 +220,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
}
|
||||
|
||||
final Class parentClass = authorizerClass.getSuperclass();
|
||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
||||
if (parentClass != null && Authorizer.class.isAssignableFrom(parentClass)) {
|
||||
performMethodInjection(instance, parentClass);
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +252,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
|
|||
}
|
||||
|
||||
final Class parentClass = authorizerClass.getSuperclass();
|
||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
||||
if (parentClass != null && Authorizer.class.isAssignableFrom(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,123 +17,52 @@
|
|||
package org.apache.nifi.user;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import org.apache.nifi.authorization.Authority;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* An NiFiUser.
|
||||
*/
|
||||
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 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;
|
||||
|
||||
/* getters / setters */
|
||||
public Date getCreation() {
|
||||
return creation;
|
||||
public NiFiUser(String identity) {
|
||||
this(identity, null, null);
|
||||
}
|
||||
|
||||
public void setCreation(Date creation) {
|
||||
this.creation = creation;
|
||||
public NiFiUser(String identity, String userName) {
|
||||
this(identity, userName, null);
|
||||
}
|
||||
|
||||
public NiFiUser(String identity, NiFiUser chain) {
|
||||
this(identity, null, chain);
|
||||
}
|
||||
|
||||
public NiFiUser(String identity, String userName, NiFiUser chain) {
|
||||
this.identity = identity;
|
||||
this.userName = userName;
|
||||
this.chain = chain;
|
||||
}
|
||||
|
||||
/* getters / setters */
|
||||
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setIdentity(String identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
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() {
|
||||
return chain;
|
||||
}
|
||||
|
||||
public void setChain(NiFiUser chain) {
|
||||
this.chain = chain;
|
||||
}
|
||||
|
||||
public Set<Authority> getAuthorities() {
|
||||
if (authorities == null) {
|
||||
authorities = EnumSet.noneOf(Authority.class);
|
||||
}
|
||||
return authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
|
@ -158,7 +87,7 @@ public class NiFiUser implements Serializable {
|
|||
|
||||
@Override
|
||||
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"
|
||||
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 -->
|
||||
<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"/>
|
||||
</bean>
|
||||
|
||||
<!-- initialize the user data source -->
|
||||
<bean id="userDataSource" class="org.apache.nifi.admin.UserDataSourceFactoryBean" destroy-method="shutdown">
|
||||
<!-- initialize the user key data source -->
|
||||
<bean id="keyDataSource" class="org.apache.nifi.admin.KeyDataSourceFactoryBean" destroy-method="shutdown">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
</bean>
|
||||
|
||||
<!-- initialize the data source -->
|
||||
<bean id="auditDataSource" class="org.apache.nifi.admin.AuditDataSourceFactoryBean" destroy-method="shutdown" depends-on="userDataSource">
|
||||
<!-- initialize the audit data source -->
|
||||
<bean id="auditDataSource" class="org.apache.nifi.admin.AuditDataSourceFactoryBean" destroy-method="shutdown">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
</bean>
|
||||
|
||||
<!-- initialize the user transaction builder -->
|
||||
<bean id="userTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
||||
<property name="authorityProvider" ref="authorityProvider"/>
|
||||
<property name="dataSource" ref="userDataSource"/>
|
||||
|
||||
<!-- initialize the user key transaction builder -->
|
||||
<bean id="keyTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
||||
<property name="dataSource" ref="keyDataSource"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- initialize the audit transaction builder -->
|
||||
<bean id="auditTransactionBuilder" class="org.apache.nifi.admin.service.transaction.impl.StandardTransactionBuilder">
|
||||
<property name="authorityProvider" ref="authorityProvider"/>
|
||||
<property name="dataSource" ref="auditDataSource"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- administration service -->
|
||||
<bean id="userService" class="org.apache.nifi.admin.service.impl.StandardUserService" init-method="seedUserAccounts">
|
||||
<property name="transactionBuilder" ref="userTransactionBuilder"/>
|
||||
<bean id="userService" class="org.apache.nifi.admin.service.impl.StandardUserService">
|
||||
<property name="transactionBuilder" ref="keyTransactionBuilder"/>
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
</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);
|
||||
}
|
||||
}
|
|
@ -38,8 +38,6 @@ public class ControllerStatusDTO implements Cloneable {
|
|||
private Integer connectedNodeCount = 0;
|
||||
private Integer totalNodeCount = 0;
|
||||
|
||||
private Boolean hasPendingAccounts;
|
||||
|
||||
private Integer runningCount = 0;
|
||||
private Integer stoppedCount = 0;
|
||||
private Integer invalidCount = 0;
|
||||
|
@ -126,18 +124,6 @@ public class ControllerStatusDTO implements Cloneable {
|
|||
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
|
||||
*/
|
||||
|
@ -256,7 +242,6 @@ public class ControllerStatusDTO implements Cloneable {
|
|||
other.setConnectedNodes(getConnectedNodes());
|
||||
other.setConnectedNodeCount(getConnectedNodeCount());
|
||||
other.setTotalNodeCount(getTotalNodeCount());
|
||||
other.setHasPendingAccounts(getHasPendingAccounts());
|
||||
other.setRunningCount(getRunningCount());
|
||||
other.setStoppedCount(getStoppedCount());
|
||||
other.setInvalidCount(getInvalidCount());
|
||||
|
|
|
@ -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,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.cluster.authorization.protocol.message;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*/
|
||||
@XmlRootElement(name = "getGroupForUserMessage")
|
||||
public class GetGroupForUserMessage extends ProtocolMessage {
|
||||
|
||||
private String dn;
|
||||
|
||||
private String response;
|
||||
|
||||
public GetGroupForUserMessage() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType getType() {
|
||||
return MessageType.GET_GROUP_FOR_USER;
|
||||
}
|
||||
|
||||
public String getDn() {
|
||||
return dn;
|
||||
}
|
||||
|
||||
public void setDn(String dn) {
|
||||
this.dn = dn;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(String 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
org.apache.nifi.cluster.authorization.ClusterManagerAuthorizationProvider
|
||||
org.apache.nifi.cluster.authorization.NodeAuthorizationProvider
|
|
@ -1,85 +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-file-authorization-provider</artifactId>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/xsd</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>jaxb2-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>xjc</id>
|
||||
<goals>
|
||||
<goal>xjc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<packageName>org.apache.nifi.user.generated</packageName>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>**/user/generated/*.java</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-properties</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,496 +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.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
||||
import org.apache.nifi.util.file.FileUtils;
|
||||
import org.apache.nifi.user.generated.ObjectFactory;
|
||||
import org.apache.nifi.user.generated.Role;
|
||||
import org.apache.nifi.user.generated.User;
|
||||
import org.apache.nifi.user.generated.Users;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Provides identity checks and grants authorities.
|
||||
*/
|
||||
public class FileAuthorizationProvider implements AuthorityProvider {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileAuthorizationProvider.class);
|
||||
private static final String USERS_XSD = "/users.xsd";
|
||||
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.user.generated";
|
||||
private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
|
||||
|
||||
/**
|
||||
* Load the JAXBContext.
|
||||
*/
|
||||
private static JAXBContext initializeJaxbContext() {
|
||||
try {
|
||||
return JAXBContext.newInstance(JAXB_GENERATED_PATH, FileAuthorizationProvider.class.getClassLoader());
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException("Unable to create JAXBContext.");
|
||||
}
|
||||
}
|
||||
|
||||
private NiFiProperties properties;
|
||||
private File usersFile;
|
||||
private File restoreUsersFile;
|
||||
private Users users;
|
||||
private final Set<String> defaultAuthorities = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void initialize(final AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(final AuthorityProviderConfigurationContext configurationContext) throws ProviderCreationException {
|
||||
try {
|
||||
final String usersFilePath = configurationContext.getProperty("Authorized Users File");
|
||||
if (usersFilePath == null || usersFilePath.trim().isEmpty()) {
|
||||
throw new ProviderCreationException("The authorized users file must be specified.");
|
||||
}
|
||||
|
||||
// the users file instance will never be null because a default is used
|
||||
usersFile = new File(usersFilePath);
|
||||
final File usersFileDirectory = usersFile.getParentFile();
|
||||
|
||||
// the restore directory is optional and may be null
|
||||
final File restoreDirectory = properties.getRestoreDirectory();
|
||||
|
||||
if (restoreDirectory != null) {
|
||||
|
||||
// sanity check that restore directory is a directory, creating it if necessary
|
||||
FileUtils.ensureDirectoryExistAndCanAccess(restoreDirectory);
|
||||
|
||||
// check that restore directory is not the same as the primary directory
|
||||
if (usersFileDirectory.getAbsolutePath().equals(restoreDirectory.getAbsolutePath())) {
|
||||
throw new ProviderCreationException(String.format("Authorized User's directory '%s' is the same as restore directory '%s' ",
|
||||
usersFileDirectory.getAbsolutePath(), restoreDirectory.getAbsolutePath()));
|
||||
}
|
||||
|
||||
// the restore copy will have same file name, but reside in a different directory
|
||||
restoreUsersFile = new File(restoreDirectory, usersFile.getName());
|
||||
|
||||
// sync the primary copy with the restore copy
|
||||
try {
|
||||
FileUtils.syncWithRestore(usersFile, restoreUsersFile, logger);
|
||||
} catch (final IOException | IllegalStateException ioe) {
|
||||
throw new ProviderCreationException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// load the users from the specified file
|
||||
if (usersFile.exists()) {
|
||||
// find the schema
|
||||
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
final Schema schema = schemaFactory.newSchema(FileAuthorizationProvider.class.getResource(USERS_XSD));
|
||||
|
||||
// attempt to unmarshal
|
||||
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
||||
unmarshaller.setSchema(schema);
|
||||
final JAXBElement<Users> element = unmarshaller.unmarshal(new StreamSource(usersFile), Users.class);
|
||||
users = element.getValue();
|
||||
} else {
|
||||
final ObjectFactory objFactory = new ObjectFactory();
|
||||
users = objFactory.createUsers();
|
||||
}
|
||||
|
||||
// attempt to load a default roles
|
||||
final String rawDefaultAuthorities = configurationContext.getProperty("Default User Roles");
|
||||
if (StringUtils.isNotBlank(rawDefaultAuthorities)) {
|
||||
final Set<String> invalidDefaultAuthorities = new HashSet<>();
|
||||
|
||||
// validate the specified authorities
|
||||
final String[] rawDefaultAuthorityList = rawDefaultAuthorities.split(",");
|
||||
for (String rawAuthority : rawDefaultAuthorityList) {
|
||||
rawAuthority = rawAuthority.trim();
|
||||
final Authority authority = Authority.valueOfAuthority(rawAuthority);
|
||||
if (authority == null) {
|
||||
invalidDefaultAuthorities.add(rawAuthority);
|
||||
} else {
|
||||
defaultAuthorities.add(rawAuthority);
|
||||
}
|
||||
}
|
||||
|
||||
// report any unrecognized authorities
|
||||
if (!invalidDefaultAuthorities.isEmpty()) {
|
||||
logger.warn(String.format("The following default role(s) '%s' were not recognized. Possible values: %s.",
|
||||
StringUtils.join(invalidDefaultAuthorities, ", "), StringUtils.join(Authority.getRawAuthorities(), ", ")));
|
||||
}
|
||||
}
|
||||
} catch (IOException | ProviderCreationException | SAXException | JAXBException e) {
|
||||
throw new ProviderCreationException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() {
|
||||
}
|
||||
|
||||
private boolean hasDefaultRoles() {
|
||||
return !defaultAuthorities.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesDnExist(String dn) throws AuthorityAccessException {
|
||||
if (hasDefaultRoles()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final User user = getUser(dn);
|
||||
return user != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Set<Authority> getAuthorities(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||
final Set<Authority> authorities = EnumSet.noneOf(Authority.class);
|
||||
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
if (hasDefaultRoles()) {
|
||||
logger.debug(String.format("User DN not found: %s. Creating new user with default roles.", dn));
|
||||
|
||||
// create the user (which will automatically add any default authorities)
|
||||
addUser(dn, null);
|
||||
|
||||
// get the authorities for the newly created user
|
||||
authorities.addAll(getAuthorities(dn));
|
||||
} else {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
} else {
|
||||
// create the authorities that this user has
|
||||
for (final Role role : user.getRole()) {
|
||||
authorities.add(Authority.valueOfAuthority(role.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setAuthorities(String dn, Set<Authority> authorities) throws UnknownIdentityException, AuthorityAccessException {
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
|
||||
// add the user authorities
|
||||
setUserAuthorities(user, authorities);
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUserAuthorities(final User user, final Set<Authority> authorities) {
|
||||
// clear the existing rules
|
||||
user.getRole().clear();
|
||||
|
||||
// set the new roles
|
||||
final ObjectFactory objFactory = new ObjectFactory();
|
||||
for (final Authority authority : authorities) {
|
||||
final Role role = objFactory.createRole();
|
||||
role.setName(authority.toString());
|
||||
|
||||
// add the new role
|
||||
user.getRole().add(role);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addUser(String dn, String group) throws IdentityAlreadyExistsException, AuthorityAccessException {
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user doesn't already exist
|
||||
if (user != null) {
|
||||
throw new IdentityAlreadyExistsException(String.format("User DN already exists: %s", dn));
|
||||
}
|
||||
|
||||
// create the new user
|
||||
final ObjectFactory objFactory = new ObjectFactory();
|
||||
final User newUser = objFactory.createUser();
|
||||
|
||||
// set the user properties
|
||||
newUser.setDn(dn);
|
||||
newUser.setGroup(group);
|
||||
|
||||
// add default roles if appropriate
|
||||
if (hasDefaultRoles()) {
|
||||
for (final String authority : defaultAuthorities) {
|
||||
Role role = objFactory.createRole();
|
||||
role.setName(authority);
|
||||
|
||||
// add the role
|
||||
newUser.getRole().add(role);
|
||||
}
|
||||
}
|
||||
|
||||
// add the user
|
||||
users.getUser().add(newUser);
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Set<String> getUsers(Authority authority) throws AuthorityAccessException {
|
||||
final Set<String> userSet = new HashSet<>();
|
||||
for (final User user : users.getUser()) {
|
||||
for (final Role role : user.getRole()) {
|
||||
if (role.getName().equals(authority.toString())) {
|
||||
userSet.add(user.getDn());
|
||||
}
|
||||
}
|
||||
}
|
||||
return userSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void revokeUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
|
||||
// remove the specified user
|
||||
users.getUser().remove(user);
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsersGroup(Set<String> dns, String group) throws UnknownIdentityException, AuthorityAccessException {
|
||||
final Collection<User> groupedUsers = new HashSet<>();
|
||||
|
||||
// get the specified users
|
||||
for (final String dn : dns) {
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
|
||||
groupedUsers.add(user);
|
||||
}
|
||||
|
||||
// update each user group
|
||||
for (final User user : groupedUsers) {
|
||||
user.setGroup(group);
|
||||
}
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ungroupUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
|
||||
// remove the users group
|
||||
user.setGroup(null);
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ungroup(String group) throws AuthorityAccessException {
|
||||
// get the user group
|
||||
final Collection<User> userGroup = getUserGroup(group);
|
||||
|
||||
// ensure the user group was located
|
||||
if (userGroup == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update each user group
|
||||
for (final User user : userGroup) {
|
||||
user.setGroup(null);
|
||||
}
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupForUser(String dn) throws UnknownIdentityException, AuthorityAccessException {
|
||||
// get the user
|
||||
final User user = getUser(dn);
|
||||
|
||||
// ensure the user was located
|
||||
if (user == null) {
|
||||
throw new UnknownIdentityException(String.format("User DN not found: %s.", dn));
|
||||
}
|
||||
|
||||
return user.getGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeGroup(String group) throws UnknownIdentityException, AuthorityAccessException {
|
||||
// get the user group
|
||||
final Collection<User> userGroup = getUserGroup(group);
|
||||
|
||||
// ensure the user group was located
|
||||
if (userGroup == null) {
|
||||
throw new UnknownIdentityException(String.format("User group not found: %s.", group));
|
||||
}
|
||||
|
||||
// remove each user in the group
|
||||
for (final User user : userGroup) {
|
||||
users.getUser().remove(user);
|
||||
}
|
||||
|
||||
try {
|
||||
// save the file
|
||||
save();
|
||||
} catch (Exception e) {
|
||||
throw new AuthorityAccessException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants access to download content regardless of FlowFile attributes.
|
||||
*/
|
||||
@Override
|
||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
||||
return DownloadAuthorization.approved();
|
||||
}
|
||||
|
||||
private User getUser(String dn) throws UnknownIdentityException {
|
||||
// ensure the DN was specified
|
||||
if (dn == null) {
|
||||
throw new UnknownIdentityException("User DN not specified.");
|
||||
}
|
||||
|
||||
// attempt to get the user and ensure it was located
|
||||
User desiredUser = null;
|
||||
for (final User user : users.getUser()) {
|
||||
if (dn.equalsIgnoreCase(user.getDn())) {
|
||||
desiredUser = user;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return desiredUser;
|
||||
}
|
||||
|
||||
private Collection<User> getUserGroup(String group) throws UnknownIdentityException {
|
||||
// ensure the DN was specified
|
||||
if (group == null) {
|
||||
throw new UnknownIdentityException("User group not specified.");
|
||||
}
|
||||
|
||||
// get all users with this group
|
||||
Collection<User> userGroup = null;
|
||||
for (final User user : users.getUser()) {
|
||||
if (group.equals(user.getGroup())) {
|
||||
if (userGroup == null) {
|
||||
userGroup = new HashSet<>();
|
||||
}
|
||||
userGroup.add(user);
|
||||
}
|
||||
}
|
||||
|
||||
return userGroup;
|
||||
}
|
||||
|
||||
private void save() throws Exception {
|
||||
final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
|
||||
// save users to restore directory before primary directory
|
||||
if (restoreUsersFile != null) {
|
||||
marshaller.marshal(users, restoreUsersFile);
|
||||
}
|
||||
|
||||
// save users to primary directory
|
||||
marshaller.marshal(users, usersFile);
|
||||
}
|
||||
|
||||
@AuthorityProviderContext
|
||||
public void setNiFiProperties(NiFiProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- role -->
|
||||
<xs:complexType name="Role">
|
||||
<xs:attribute name="name">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="ROLE_MONITOR"/>
|
||||
<xs:enumeration value="ROLE_PROVENANCE"/>
|
||||
<xs:enumeration value="ROLE_DFM"/>
|
||||
<xs:enumeration value="ROLE_ADMIN"/>
|
||||
<xs:enumeration value="ROLE_PROXY"/>
|
||||
<xs:enumeration value="ROLE_NIFI"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- user -->
|
||||
<xs:complexType name="User">
|
||||
<xs:sequence>
|
||||
<xs:element name="role" type="Role" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="dn">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
<xs:pattern value=".*[^\s].*"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="group">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
<xs:pattern value=".*[^\s].*"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- users -->
|
||||
<xs:element name="users">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="user" type="User" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
|
@ -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.authorization;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.util.file.FileUtils;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.junit.After;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.mockito.Mockito;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Ignore
|
||||
public class FileAuthorizationProviderTest {
|
||||
|
||||
private FileAuthorizationProvider provider;
|
||||
|
||||
private File primary;
|
||||
|
||||
private File restore;
|
||||
|
||||
private NiFiProperties mockProperties;
|
||||
|
||||
private AuthorityProviderConfigurationContext mockConfigurationContext;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
|
||||
primary = new File("target/primary/users.txt");
|
||||
restore = new File("target/restore/users.txt");
|
||||
|
||||
System.out.println("absolute path: " + primary.getAbsolutePath());
|
||||
|
||||
mockProperties = mock(NiFiProperties.class);
|
||||
when(mockProperties.getRestoreDirectory()).thenReturn(restore.getParentFile());
|
||||
|
||||
mockConfigurationContext = mock(AuthorityProviderConfigurationContext.class);
|
||||
when(mockConfigurationContext.getProperty(Mockito.eq("Authorized Users File"))).thenReturn(primary.getPath());
|
||||
|
||||
provider = new FileAuthorizationProvider();
|
||||
provider.setNiFiProperties(mockProperties);
|
||||
provider.initialize(null);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
deleteFile(primary);
|
||||
deleteFile(restore);
|
||||
}
|
||||
|
||||
private boolean deleteFile(final File file) {
|
||||
if (file.isDirectory()) {
|
||||
FileUtils.deleteFilesInDir(file, null, null, true, true);
|
||||
}
|
||||
return FileUtils.deleteFile(file, null, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostContructionWhenRestoreDoesNotExist() throws Exception {
|
||||
|
||||
byte[] primaryBytes = "<users/>".getBytes();
|
||||
FileOutputStream fos = new FileOutputStream(primary);
|
||||
fos.write(primaryBytes);
|
||||
fos.close();
|
||||
|
||||
provider.onConfigured(mockConfigurationContext);
|
||||
assertEquals(primary.length(), restore.length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostContructionWhenPrimaryDoesNotExist() throws Exception {
|
||||
|
||||
byte[] restoreBytes = "<users/>".getBytes();
|
||||
FileOutputStream fos = new FileOutputStream(restore);
|
||||
fos.write(restoreBytes);
|
||||
fos.close();
|
||||
|
||||
provider.onConfigured(mockConfigurationContext);
|
||||
assertEquals(restore.length(), primary.length());
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = ProviderCreationException.class)
|
||||
public void testPostContructionWhenPrimaryDifferentThanRestore() throws Exception {
|
||||
|
||||
byte[] primaryBytes = "<users></users>".getBytes();
|
||||
FileOutputStream fos = new FileOutputStream(primary);
|
||||
fos.write(primaryBytes);
|
||||
fos.close();
|
||||
|
||||
byte[] restoreBytes = "<users/>".getBytes();
|
||||
fos = new FileOutputStream(restore);
|
||||
fos.write(restoreBytes);
|
||||
fos.close();
|
||||
|
||||
provider.onConfigured(mockConfigurationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostContructionWhenPrimaryAndBackupDoNotExist() throws Exception {
|
||||
|
||||
provider.onConfigured(mockConfigurationContext);
|
||||
assertEquals(0, restore.length());
|
||||
assertEquals(restore.length(), primary.length());
|
||||
}
|
||||
|
||||
}
|
|
@ -16,15 +16,8 @@
|
|||
*/
|
||||
package org.apache.nifi.nar;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import org.apache.nifi.authentication.LoginIdentityProvider;
|
||||
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.controller.ControllerService;
|
||||
import org.apache.nifi.controller.repository.ContentRepository;
|
||||
import org.apache.nifi.controller.repository.FlowFileRepository;
|
||||
|
@ -34,10 +27,16 @@ import org.apache.nifi.flowfile.FlowFilePrioritizer;
|
|||
import org.apache.nifi.processor.Processor;
|
||||
import org.apache.nifi.provenance.ProvenanceEventRepository;
|
||||
import org.apache.nifi.reporting.ReportingTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Scans through the classpath to load all FlowFileProcessors, FlowFileComparators, and ReportingTasks using the service provider API and running through all classloaders (root, NARs).
|
||||
*
|
||||
|
@ -58,7 +57,7 @@ public class ExtensionManager {
|
|||
definitionMap.put(FlowFilePrioritizer.class, new HashSet<Class>());
|
||||
definitionMap.put(ReportingTask.class, new HashSet<Class>());
|
||||
definitionMap.put(ControllerService.class, new HashSet<Class>());
|
||||
definitionMap.put(AuthorityProvider.class, new HashSet<Class>());
|
||||
definitionMap.put(Authorizer.class, new HashSet<Class>());
|
||||
definitionMap.put(LoginIdentityProvider.class, new HashSet<Class>());
|
||||
definitionMap.put(ProvenanceEventRepository.class, new HashSet<Class>());
|
||||
definitionMap.put(ComponentStatusRepository.class, new HashSet<Class>());
|
||||
|
|
|
@ -16,16 +16,8 @@
|
|||
*/
|
||||
package org.apache.nifi.nar;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import org.apache.nifi.authentication.LoginIdentityProvider;
|
||||
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.components.Validator;
|
||||
import org.apache.nifi.controller.ControllerService;
|
||||
import org.apache.nifi.controller.repository.ContentRepository;
|
||||
|
@ -40,6 +32,14 @@ import org.apache.nifi.processor.io.StreamCallback;
|
|||
import org.apache.nifi.provenance.ProvenanceEventRepository;
|
||||
import org.apache.nifi.reporting.ReportingTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* THREAD SAFE
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ public class NarThreadContextClassLoader extends URLClassLoader {
|
|||
narSpecificClasses.add(OutputStreamCallback.class);
|
||||
narSpecificClasses.add(StreamCallback.class);
|
||||
narSpecificClasses.add(ControllerService.class);
|
||||
narSpecificClasses.add(AuthorityProvider.class);
|
||||
narSpecificClasses.add(Authorizer.class);
|
||||
narSpecificClasses.add(LoginIdentityProvider.class);
|
||||
narSpecificClasses.add(ProvenanceEventRepository.class);
|
||||
narSpecificClasses.add(ComponentStatusRepository.class);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
This file lists all authorized users for this NiFi instance when using
|
||||
the FileAuthorizationProvider or ClusterManagerAuthorizationProvider. If one of
|
||||
these providers is not in use then this file is not used. Refer to the properties
|
||||
file and authority-providers.xml for configuration details.
|
||||
file and authorizers.xml for configuration details.
|
||||
|
||||
Available roles:
|
||||
ROLE_MONITOR - for users - read only access to flow
|
||||
|
|
|
@ -18,26 +18,11 @@
|
|||
to use a specific provider it must be configured here and it's identifier
|
||||
must be specified in the nifi.properties file.
|
||||
-->
|
||||
<authorityProviders>
|
||||
<authorizers>
|
||||
<provider>
|
||||
<identifier>file-provider</identifier>
|
||||
<class>org.apache.nifi.authorization.FileAuthorizationProvider</class>
|
||||
<property name="Authorized Users File">./conf/authorized-users.xml</property>
|
||||
<property name="Default User Roles"></property>
|
||||
</provider>
|
||||
|
||||
<!--<provider>
|
||||
<identifier>cluster-ncm-provider</identifier>
|
||||
<class>org.apache.nifi.cluster.authorization.ClusterManagerAuthorizationProvider</class>
|
||||
<property name="Authority Provider Port"></property>
|
||||
<property name="Authority Provider Threads">10</property>
|
||||
<property name="Authorized Users File">./conf/authorized-users.xml</property>
|
||||
<property name="Default User Roles"></property>
|
||||
</provider>-->
|
||||
|
||||
<!--<provider>
|
||||
<identifier>cluster-node-provider</identifier>
|
||||
<class>org.apache.nifi.cluster.authorization.NodeAuthorizationProvider</class>
|
||||
<property name="Cluster Manager Authority Provider Port"></property>
|
||||
</provider>-->
|
||||
</authorityProviders>
|
||||
</authorizers>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue