blob: 6581e89480c391a02ab1f8e271134f9894f5a3bb [file] [log] [blame]
/*
* 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.registry.security.authorization;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.registry.security.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.registry.security.authorization.exception.UninheritableAuthorizationsException;
import org.apache.nifi.registry.security.exception.SecurityProviderCreationException;
import org.apache.nifi.registry.security.exception.SecurityProviderDestructionException;
import org.apache.nifi.registry.util.PropertyValue;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
public class CompositeConfigurableUserGroupProvider extends CompositeUserGroupProvider implements ConfigurableUserGroupProvider {
static final String PROP_CONFIGURABLE_USER_GROUP_PROVIDER = "Configurable User Group Provider";
private UserGroupProviderLookup userGroupProviderLookup;
private ConfigurableUserGroupProvider configurableUserGroupProvider;
public CompositeConfigurableUserGroupProvider() {
super(true);
}
@Override
public void initialize(UserGroupProviderInitializationContext initializationContext) throws SecurityProviderCreationException {
userGroupProviderLookup = initializationContext.getUserGroupProviderLookup();
// initialize the CompositeUserGroupProvider
super.initialize(initializationContext);
}
@Override
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws SecurityProviderCreationException {
final PropertyValue configurableUserGroupProviderKey = configurationContext.getProperty(PROP_CONFIGURABLE_USER_GROUP_PROVIDER);
if (!configurableUserGroupProviderKey.isSet()) {
throw new SecurityProviderCreationException("The Configurable User Group Provider must be set.");
}
final UserGroupProvider userGroupProvider = userGroupProviderLookup.getUserGroupProvider(configurableUserGroupProviderKey.getValue());
if (userGroupProvider == null) {
throw new SecurityProviderCreationException(String.format("Unable to locate the Configurable User Group Provider: %s", configurableUserGroupProviderKey));
}
if (!(userGroupProvider instanceof ConfigurableUserGroupProvider)) {
throw new SecurityProviderCreationException(String.format("The Configurable User Group Provider is not configurable: %s", configurableUserGroupProviderKey));
}
// Ensure that the ConfigurableUserGroupProvider is not also listed as one of the providers for the CompositeUserGroupProvider
for (Map.Entry<String,String> entry : configurationContext.getProperties().entrySet()) {
Matcher matcher = USER_GROUP_PROVIDER_PATTERN.matcher(entry.getKey());
if (matcher.matches() && !StringUtils.isBlank(entry.getValue())) {
final String userGroupProviderKey = entry.getValue();
if (userGroupProviderKey.equals(configurableUserGroupProviderKey.getValue())) {
throw new SecurityProviderCreationException(String.format("Duplicate provider in Composite Configurable User Group Provider configuration: %s", userGroupProviderKey));
}
}
}
configurableUserGroupProvider = (ConfigurableUserGroupProvider) userGroupProvider;
// configure the CompositeUserGroupProvider
super.onConfigured(configurationContext);
}
@Override
public String getFingerprint() throws AuthorizationAccessException {
return configurableUserGroupProvider.getFingerprint();
}
@Override
public void inheritFingerprint(String fingerprint) throws AuthorizationAccessException {
configurableUserGroupProvider.inheritFingerprint(fingerprint);
}
@Override
public void checkInheritability(String proposedFingerprint) throws AuthorizationAccessException, UninheritableAuthorizationsException {
configurableUserGroupProvider.checkInheritability(proposedFingerprint);
}
@Override
public User addUser(User user) throws AuthorizationAccessException {
return configurableUserGroupProvider.addUser(user);
}
@Override
public boolean isConfigurable(User user) {
return configurableUserGroupProvider.isConfigurable(user);
}
@Override
public User updateUser(User user) throws AuthorizationAccessException {
return configurableUserGroupProvider.updateUser(user);
}
@Override
public User deleteUser(User user) throws AuthorizationAccessException {
return configurableUserGroupProvider.deleteUser(user);
}
@Override
public User deleteUser(String userIdentifier) throws AuthorizationAccessException {
return configurableUserGroupProvider.deleteUser(userIdentifier);
}
@Override
public Group addGroup(Group group) throws AuthorizationAccessException {
return configurableUserGroupProvider.addGroup(group);
}
@Override
public boolean isConfigurable(Group group) {
return configurableUserGroupProvider.isConfigurable(group);
}
@Override
public Group updateGroup(Group group) throws AuthorizationAccessException {
return configurableUserGroupProvider.updateGroup(group);
}
@Override
public Group deleteGroup(Group group) throws AuthorizationAccessException {
return configurableUserGroupProvider.deleteGroup(group);
}
@Override
public Group deleteGroup(String groupIdentifier) throws AuthorizationAccessException {
return configurableUserGroupProvider.deleteGroup(groupIdentifier);
}
@Override
public Set<User> getUsers() throws AuthorizationAccessException {
final Set<User> users = new HashSet<>(configurableUserGroupProvider.getUsers());
users.addAll(super.getUsers());
return users;
}
@Override
public User getUser(String identifier) throws AuthorizationAccessException {
User user = configurableUserGroupProvider.getUser(identifier);
if (user == null) {
user = super.getUser(identifier);
}
return user;
}
@Override
public User getUserByIdentity(String identity) throws AuthorizationAccessException {
User user = configurableUserGroupProvider.getUserByIdentity(identity);
if (user == null) {
user = super.getUserByIdentity(identity);
}
return user;
}
@Override
public Set<Group> getGroups() throws AuthorizationAccessException {
final Set<Group> groups = new HashSet<>(configurableUserGroupProvider.getGroups());
groups.addAll(super.getGroups());
return groups;
}
@Override
public Group getGroup(String identifier) throws AuthorizationAccessException {
Group group = configurableUserGroupProvider.getGroup(identifier);
if (group == null) {
group = super.getGroup(identifier);
}
return group;
}
@Override
public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException {
final CompositeUserAndGroups combinedResult;
// First, lookup user and groups by identity and combine data from all providers
UserAndGroups configurableProviderResult = configurableUserGroupProvider.getUserAndGroups(identity);
UserAndGroups compositeProvidersResult = super.getUserAndGroups(identity);
if (configurableProviderResult.getUser() != null && compositeProvidersResult.getUser() != null) {
throw new IllegalStateException("Multiple UserGroupProviders claim to provide user " + identity);
} else if (configurableProviderResult.getUser() != null) {
combinedResult = new CompositeUserAndGroups(configurableProviderResult.getUser(), configurableProviderResult.getGroups());
combinedResult.addAllGroups(compositeProvidersResult.getGroups());
} else if (compositeProvidersResult.getUser() != null) {
combinedResult = new CompositeUserAndGroups(compositeProvidersResult.getUser(), compositeProvidersResult.getGroups());
combinedResult.addAllGroups(configurableProviderResult.getGroups());
} else {
return UserAndGroups.EMPTY;
}
// Second, lookup groups containing the user identifier
String userIdentifier = combinedResult.getUser().getIdentifier();
for (final Group group : configurableUserGroupProvider.getGroups()) {
if (group.getUsers() != null && group.getUsers().contains(userIdentifier)) {
combinedResult.addGroup(group);
}
}
for (final Group group : super.getGroups()) {
if (group.getUsers() != null && group.getUsers().contains(userIdentifier)) {
combinedResult.addGroup(group);
}
}
return combinedResult;
}
@Override
public void preDestruction() throws SecurityProviderDestructionException {
super.preDestruction();
}
}