| /* |
| * 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.druid.security.basic.authorization.db.updater; |
| |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.google.common.base.Preconditions; |
| import com.google.inject.Inject; |
| import org.apache.druid.common.config.ConfigManager; |
| import org.apache.druid.concurrent.LifecycleLock; |
| import org.apache.druid.guice.ManageLifecycle; |
| import org.apache.druid.guice.annotations.Smile; |
| import org.apache.druid.java.util.common.ISE; |
| import org.apache.druid.java.util.common.StringUtils; |
| import org.apache.druid.java.util.common.concurrent.Execs; |
| import org.apache.druid.java.util.common.concurrent.ScheduledExecutors; |
| import org.apache.druid.java.util.common.lifecycle.LifecycleStart; |
| import org.apache.druid.java.util.common.lifecycle.LifecycleStop; |
| import org.apache.druid.java.util.emitter.EmittingLogger; |
| import org.apache.druid.metadata.MetadataCASUpdate; |
| import org.apache.druid.metadata.MetadataStorageConnector; |
| import org.apache.druid.metadata.MetadataStorageTablesConfig; |
| import org.apache.druid.security.basic.BasicAuthCommonCacheConfig; |
| import org.apache.druid.security.basic.BasicAuthDBConfig; |
| import org.apache.druid.security.basic.BasicAuthUtils; |
| import org.apache.druid.security.basic.BasicSecurityDBResourceException; |
| import org.apache.druid.security.basic.authorization.BasicRoleBasedAuthorizer; |
| import org.apache.druid.security.basic.authorization.db.cache.BasicAuthorizerCacheNotifier; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerGroupMapping; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerGroupMappingMapBundle; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerPermission; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerRole; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerRoleMapBundle; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerUser; |
| import org.apache.druid.security.basic.authorization.entity.BasicAuthorizerUserMapBundle; |
| import org.apache.druid.security.basic.authorization.entity.GroupMappingAndRoleMap; |
| import org.apache.druid.security.basic.authorization.entity.UserAndRoleMap; |
| import org.apache.druid.server.security.AuthorizationUtils; |
| import org.apache.druid.server.security.Authorizer; |
| import org.apache.druid.server.security.AuthorizerMapper; |
| import org.apache.druid.server.security.ResourceAction; |
| import org.joda.time.Duration; |
| |
| import javax.annotation.Nonnull; |
| import javax.annotation.Nullable; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ScheduledExecutorService; |
| import java.util.concurrent.ThreadLocalRandom; |
| import java.util.concurrent.TimeUnit; |
| |
| @ManageLifecycle |
| public class CoordinatorBasicAuthorizerMetadataStorageUpdater implements BasicAuthorizerMetadataStorageUpdater |
| { |
| private static final EmittingLogger LOG = |
| new EmittingLogger(CoordinatorBasicAuthorizerMetadataStorageUpdater.class); |
| |
| private static final long UPDATE_RETRY_DELAY = 1000; |
| |
| private static final String USERS = "users"; |
| private static final String GROUP_MAPPINGS = "groupMappings"; |
| private static final String ROLES = "roles"; |
| |
| public static final List<ResourceAction> SUPERUSER_PERMISSIONS = AuthorizationUtils.makeSuperUserPermissions(); |
| |
| private final AuthorizerMapper authorizerMapper; |
| private final MetadataStorageConnector connector; |
| private final MetadataStorageTablesConfig connectorConfig; |
| private final BasicAuthorizerCacheNotifier cacheNotifier; |
| private final BasicAuthCommonCacheConfig commonCacheConfig; |
| private final ObjectMapper objectMapper; |
| private final int numRetries = 5; |
| |
| private final Map<String, BasicAuthorizerUserMapBundle> cachedUserMaps; |
| private final Map<String, BasicAuthorizerGroupMappingMapBundle> cachedGroupMappingMaps; |
| private final Map<String, BasicAuthorizerRoleMapBundle> cachedRoleMaps; |
| |
| private final Set<String> authorizerNames; |
| private final LifecycleLock lifecycleLock = new LifecycleLock(); |
| |
| private final ScheduledExecutorService exec; |
| private volatile boolean stopped = false; |
| |
| @Inject |
| public CoordinatorBasicAuthorizerMetadataStorageUpdater( |
| AuthorizerMapper authorizerMapper, |
| MetadataStorageConnector connector, |
| MetadataStorageTablesConfig connectorConfig, |
| BasicAuthCommonCacheConfig commonCacheConfig, |
| @Smile ObjectMapper objectMapper, |
| BasicAuthorizerCacheNotifier cacheNotifier, |
| ConfigManager configManager // -V6022: ConfigManager creates the db table we need, set a dependency here |
| ) |
| { |
| this.exec = Execs.scheduledSingleThreaded("CoordinatorBasicAuthorizerMetadataStorageUpdater-Exec--%d"); |
| this.authorizerMapper = authorizerMapper; |
| this.connector = connector; |
| this.connectorConfig = connectorConfig; |
| this.commonCacheConfig = commonCacheConfig; |
| this.objectMapper = objectMapper; |
| this.cacheNotifier = cacheNotifier; |
| this.cachedUserMaps = new ConcurrentHashMap<>(); |
| this.cachedGroupMappingMaps = new ConcurrentHashMap<>(); |
| this.cachedRoleMaps = new ConcurrentHashMap<>(); |
| this.authorizerNames = new HashSet<>(); |
| } |
| |
| @LifecycleStart |
| public void start() |
| { |
| if (!lifecycleLock.canStart()) { |
| throw new ISE("can't start."); |
| } |
| |
| if (authorizerMapper == null || authorizerMapper.getAuthorizerMap() == null) { |
| return; |
| } |
| |
| try { |
| LOG.info("Starting CoordinatorBasicAuthorizerMetadataStorageUpdater"); |
| BasicAuthUtils.maybeInitialize( |
| () -> { |
| for (Map.Entry<String, Authorizer> entry : authorizerMapper.getAuthorizerMap().entrySet()) { |
| Authorizer authorizer = entry.getValue(); |
| if (authorizer instanceof BasicRoleBasedAuthorizer) { |
| BasicRoleBasedAuthorizer basicRoleBasedAuthorizer = (BasicRoleBasedAuthorizer) authorizer; |
| BasicAuthDBConfig dbConfig = basicRoleBasedAuthorizer.getDbConfig(); |
| String authorizerName = entry.getKey(); |
| authorizerNames.add(authorizerName); |
| |
| byte[] userMapBytes = getCurrentUserMapBytes(authorizerName); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap( |
| objectMapper, |
| userMapBytes |
| ); |
| cachedUserMaps.put(authorizerName, new BasicAuthorizerUserMapBundle(userMap, userMapBytes)); |
| |
| byte[] groupMappingMapBytes = getCurrentGroupMappingMapBytes(authorizerName); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap( |
| objectMapper, |
| groupMappingMapBytes |
| ); |
| cachedGroupMappingMaps.put( |
| authorizerName, |
| new BasicAuthorizerGroupMappingMapBundle( |
| groupMappingMap, |
| groupMappingMapBytes |
| ) |
| ); |
| |
| byte[] roleMapBytes = getCurrentRoleMapBytes(authorizerName); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| roleMapBytes |
| ); |
| cachedRoleMaps.put(authorizerName, new BasicAuthorizerRoleMapBundle(roleMap, roleMapBytes)); |
| |
| initSuperUsersAndGroupMapping(authorizerName, userMap, roleMap, groupMappingMap, |
| dbConfig.getInitialAdminUser(), |
| dbConfig.getInitialAdminRole(), |
| dbConfig.getInitialAdminGroupMapping() |
| ); |
| } |
| } |
| return true; |
| }); |
| |
| ScheduledExecutors.scheduleWithFixedDelay( |
| exec, |
| new Duration(commonCacheConfig.getPollingPeriod()), |
| new Duration(commonCacheConfig.getPollingPeriod()), |
| () -> { |
| if (stopped) { |
| return ScheduledExecutors.Signal.STOP; |
| } |
| try { |
| LOG.debug("Scheduled db poll is running"); |
| for (String authorizerName : authorizerNames) { |
| |
| byte[] userMapBytes = getCurrentUserMapBytes(authorizerName); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap( |
| objectMapper, |
| userMapBytes |
| ); |
| if (userMapBytes != null) { |
| synchronized (cachedUserMaps) { |
| cachedUserMaps.put(authorizerName, new BasicAuthorizerUserMapBundle(userMap, userMapBytes)); |
| } |
| } |
| |
| byte[] groupMappingMapBytes = getCurrentGroupMappingMapBytes(authorizerName); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap( |
| objectMapper, |
| groupMappingMapBytes |
| ); |
| if (groupMappingMapBytes != null) { |
| synchronized (cachedGroupMappingMaps) { |
| cachedGroupMappingMaps.put(authorizerName, new BasicAuthorizerGroupMappingMapBundle(groupMappingMap, groupMappingMapBytes)); |
| } |
| } |
| |
| byte[] roleMapBytes = getCurrentRoleMapBytes(authorizerName); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| roleMapBytes |
| ); |
| if (roleMapBytes != null) { |
| synchronized (cachedRoleMaps) { |
| cachedRoleMaps.put(authorizerName, new BasicAuthorizerRoleMapBundle(roleMap, roleMapBytes)); |
| } |
| } |
| } |
| LOG.debug("Scheduled db poll is done"); |
| } |
| catch (Throwable t) { |
| LOG.makeAlert(t, "Error occured while polling for cachedUserMaps, cachedGroupMappingMaps, cachedRoleMaps.").emit(); |
| } |
| return ScheduledExecutors.Signal.REPEAT; |
| } |
| ); |
| |
| lifecycleLock.started(); |
| } |
| finally { |
| lifecycleLock.exitStart(); |
| } |
| } |
| |
| @LifecycleStop |
| public void stop() |
| { |
| if (!lifecycleLock.canStop()) { |
| throw new ISE("can't stop."); |
| } |
| |
| LOG.info("CoordinatorBasicAuthorizerMetadataStorageUpdater is stopping."); |
| stopped = true; |
| LOG.info("CoordinatorBasicAuthorizerMetadataStorageUpdater is stopped."); |
| } |
| |
| |
| private static String getPrefixedKeyColumn(String keyPrefix, String keyName) |
| { |
| return StringUtils.format("basic_authorization_%s_%s", keyPrefix, keyName); |
| } |
| |
| private boolean tryUpdateUserMap( |
| String prefix, |
| Map<String, BasicAuthorizerUser> userMap, |
| byte[] oldUserMapValue, |
| byte[] newUserMapValue |
| ) |
| { |
| try { |
| List<MetadataCASUpdate> updates = new ArrayList<>(); |
| if (userMap != null) { |
| updates.add( |
| createMetadataCASUpdate(prefix, oldUserMapValue, newUserMapValue, USERS) |
| ); |
| |
| boolean succeeded = connector.compareAndSwap(updates); |
| if (succeeded) { |
| cachedUserMaps.put(prefix, new BasicAuthorizerUserMapBundle(userMap, newUserMapValue)); |
| |
| byte[] serializedUserAndRoleMap = getCurrentUserAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateUser(prefix, serializedUserAndRoleMap); |
| |
| return true; |
| } else { |
| return false; |
| } |
| } |
| return false; |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private boolean tryUpdateGroupMappingMap( |
| String prefix, |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap, |
| byte[] oldGroupMappingMapValue, |
| byte[] newGroupMappingMapValue |
| ) |
| { |
| try { |
| List<MetadataCASUpdate> updates = new ArrayList<>(); |
| if (groupMappingMap != null) { |
| updates.add( |
| createMetadataCASUpdate(prefix, oldGroupMappingMapValue, newGroupMappingMapValue, GROUP_MAPPINGS) |
| ); |
| |
| |
| boolean succeeded = connector.compareAndSwap(updates); |
| if (succeeded) { |
| cachedGroupMappingMaps.put(prefix, |
| new BasicAuthorizerGroupMappingMapBundle( |
| groupMappingMap, |
| newGroupMappingMapValue |
| ) |
| ); |
| |
| byte[] serializedGroupMappingAndRoleMap = getCurrentGroupMappingAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateGroupMapping(prefix, serializedGroupMappingAndRoleMap); |
| |
| return true; |
| } else { |
| return false; |
| } |
| } |
| return false; |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private boolean tryUpdateRoleMap( |
| String prefix, |
| Map<String, BasicAuthorizerRole> roleMap, |
| byte[] oldRoleMapValue, |
| byte[] newRoleMapValue |
| ) |
| { |
| try { |
| List<MetadataCASUpdate> updates = new ArrayList<>(); |
| if (roleMap != null) { |
| updates.add( |
| createMetadataCASUpdate(prefix, oldRoleMapValue, newRoleMapValue, ROLES) |
| ); |
| |
| boolean succeeded = connector.compareAndSwap(updates); |
| if (succeeded) { |
| |
| cachedRoleMaps.put(prefix, new BasicAuthorizerRoleMapBundle(roleMap, newRoleMapValue)); |
| |
| byte[] serializedUserAndRoleMap = getCurrentUserAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateUser(prefix, serializedUserAndRoleMap); |
| byte[] serializedGroupMappingAndRoleMap = getCurrentGroupMappingAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateGroupMapping(prefix, serializedGroupMappingAndRoleMap); |
| |
| return true; |
| } else { |
| return false; |
| } |
| } |
| return false; |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private boolean tryUpdateUserAndRoleMap( |
| String prefix, |
| Map<String, BasicAuthorizerUser> userMap, |
| byte[] oldUserMapValue, |
| byte[] newUserMapValue, |
| Map<String, BasicAuthorizerRole> roleMap, |
| byte[] oldRoleMapValue, |
| byte[] newRoleMapValue |
| ) |
| { |
| try { |
| List<MetadataCASUpdate> updates = new ArrayList<>(); |
| if (userMap != null && roleMap != null) { |
| updates.add( |
| createMetadataCASUpdate(prefix, oldUserMapValue, newUserMapValue, USERS) |
| ); |
| updates.add( |
| createMetadataCASUpdate(prefix, oldRoleMapValue, newRoleMapValue, ROLES) |
| ); |
| |
| boolean succeeded = connector.compareAndSwap(updates); |
| if (succeeded) { |
| cachedUserMaps.put(prefix, new BasicAuthorizerUserMapBundle(userMap, newUserMapValue)); |
| cachedRoleMaps.put(prefix, new BasicAuthorizerRoleMapBundle(roleMap, newRoleMapValue)); |
| |
| byte[] serializedUserAndRoleMap = getCurrentUserAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateUser(prefix, serializedUserAndRoleMap); |
| |
| return true; |
| } else { |
| return false; |
| } |
| } |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| return false; |
| } |
| |
| private boolean tryUpdateGroupMappingAndRoleMap( |
| String prefix, |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap, |
| byte[] oldGroupMappingMapValue, |
| byte[] newGroupMappingMapValue, |
| Map<String, BasicAuthorizerRole> roleMap, |
| byte[] oldRoleMapValue, |
| byte[] newRoleMapValue |
| ) |
| { |
| try { |
| List<MetadataCASUpdate> updates = new ArrayList<>(); |
| if (groupMappingMap != null && roleMap != null) { |
| updates.add( |
| createMetadataCASUpdate(prefix, oldGroupMappingMapValue, newGroupMappingMapValue, GROUP_MAPPINGS) |
| ); |
| updates.add( |
| createMetadataCASUpdate(prefix, oldRoleMapValue, newRoleMapValue, ROLES) |
| ); |
| } |
| |
| boolean succeeded = connector.compareAndSwap(updates); |
| if (succeeded) { |
| cachedGroupMappingMaps.put(prefix, new BasicAuthorizerGroupMappingMapBundle(groupMappingMap, newGroupMappingMapValue)); |
| cachedRoleMaps.put(prefix, new BasicAuthorizerRoleMapBundle(roleMap, newRoleMapValue)); |
| |
| byte[] serializedGroupMappingAndRoleMap = getCurrentGroupMappingAndRoleMapSerialized(prefix); |
| cacheNotifier.addUpdateGroupMapping(prefix, serializedGroupMappingAndRoleMap); |
| |
| return true; |
| } else { |
| return false; |
| } |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| @Nonnull |
| private MetadataCASUpdate createMetadataCASUpdate( |
| String prefix, |
| byte[] oldValue, |
| byte[] newValue, |
| String columnName |
| ) |
| { |
| return new MetadataCASUpdate( |
| connectorConfig.getConfigTable(), |
| MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, |
| MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, |
| getPrefixedKeyColumn(prefix, columnName), |
| oldValue, |
| newValue |
| ); |
| } |
| |
| @Override |
| public void createUser(String prefix, String userName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| createUserInternal(prefix, userName); |
| } |
| |
| @Override |
| public void deleteUser(String prefix, String userName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| deleteUserInternal(prefix, userName); |
| } |
| |
| @Override |
| public void createGroupMapping(String prefix, BasicAuthorizerGroupMapping groupMapping) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| createGroupMappingInternal(prefix, groupMapping); |
| |
| } |
| |
| @Override |
| public void deleteGroupMapping(String prefix, String groupMappingName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| deleteGroupMappingInternal(prefix, groupMappingName); |
| } |
| |
| @Override |
| public void createRole(String prefix, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| createRoleInternal(prefix, roleName); |
| } |
| |
| @Override |
| public void deleteRole(String prefix, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| deleteRoleInternal(prefix, roleName); |
| } |
| |
| @Override |
| public void assignUserRole(String prefix, String userName, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| assignUserRoleInternal(prefix, userName, roleName); |
| } |
| |
| @Override |
| public void unassignUserRole(String prefix, String userName, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| unassignUserRoleInternal(prefix, userName, roleName); |
| } |
| |
| @Override |
| public void assignGroupMappingRole(String prefix, String groupMappingName, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| assignGroupMappingRoleInternal(prefix, groupMappingName, roleName); |
| } |
| |
| @Override |
| public void unassignGroupMappingRole(String prefix, String groupMappingName, String roleName) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| unassignGroupMappingRoleInternal(prefix, groupMappingName, roleName); |
| } |
| |
| @Override |
| public void setPermissions(String prefix, String roleName, List<ResourceAction> permissions) |
| { |
| Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)); |
| setPermissionsInternal(prefix, roleName, permissions); |
| } |
| |
| @Override |
| @Nullable |
| public Map<String, BasicAuthorizerUser> getCachedUserMap(String prefix) |
| { |
| BasicAuthorizerUserMapBundle userMapBundle = cachedUserMaps.get(prefix); |
| return userMapBundle == null ? null : userMapBundle.getUserMap(); |
| } |
| |
| @Override |
| public Map<String, BasicAuthorizerGroupMapping> getCachedGroupMappingMap(String prefix) |
| { |
| BasicAuthorizerGroupMappingMapBundle groupMapBundle = cachedGroupMappingMaps.get(prefix); |
| return groupMapBundle == null ? null : groupMapBundle.getGroupMappingMap(); |
| } |
| |
| @Override |
| @Nullable |
| public Map<String, BasicAuthorizerRole> getCachedRoleMap(String prefix) |
| { |
| BasicAuthorizerRoleMapBundle roleMapBundle = cachedRoleMaps.get(prefix); |
| return roleMapBundle == null ? null : roleMapBundle.getRoleMap(); |
| } |
| |
| @Override |
| public byte[] getCurrentUserMapBytes(String prefix) |
| { |
| return connector.lookup( |
| connectorConfig.getConfigTable(), |
| MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, |
| MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, |
| getPrefixedKeyColumn(prefix, USERS) |
| ); |
| } |
| |
| @Override |
| public byte[] getCurrentGroupMappingMapBytes(String prefix) |
| { |
| return connector.lookup( |
| connectorConfig.getConfigTable(), |
| MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, |
| MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, |
| getPrefixedKeyColumn(prefix, GROUP_MAPPINGS) |
| ); |
| } |
| |
| @Override |
| public byte[] getCurrentRoleMapBytes(String prefix) |
| { |
| return connector.lookup( |
| connectorConfig.getConfigTable(), |
| MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, |
| MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, |
| getPrefixedKeyColumn(prefix, ROLES) |
| ); |
| } |
| |
| @Override |
| public void refreshAllNotification() |
| { |
| authorizerNames.forEach( |
| (authorizerName) -> { |
| try { |
| byte[] serializedUserAndRoleMap = getCurrentUserAndRoleMapSerialized(authorizerName); |
| cacheNotifier.addUpdateUser(authorizerName, serializedUserAndRoleMap); |
| |
| byte[] serializeGroupAndRoleMap = getCurrentGroupMappingAndRoleMapSerialized(authorizerName); |
| cacheNotifier.addUpdateGroupMapping(authorizerName, serializeGroupAndRoleMap); |
| } |
| catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| ); |
| } |
| |
| private byte[] getCurrentUserAndRoleMapSerialized(String prefix) throws IOException |
| { |
| BasicAuthorizerUserMapBundle userMapBundle = cachedUserMaps.get(prefix); |
| BasicAuthorizerRoleMapBundle roleMapBundle = cachedRoleMaps.get(prefix); |
| |
| UserAndRoleMap userAndRoleMap = new UserAndRoleMap( |
| userMapBundle == null ? null : userMapBundle.getUserMap(), |
| roleMapBundle == null ? null : roleMapBundle.getRoleMap() |
| ); |
| |
| return objectMapper.writeValueAsBytes(userAndRoleMap); |
| } |
| |
| private byte[] getCurrentGroupMappingAndRoleMapSerialized(String prefix) throws IOException |
| { |
| BasicAuthorizerGroupMappingMapBundle groupMappingMapBundle = cachedGroupMappingMaps.get(prefix); |
| BasicAuthorizerRoleMapBundle roleMapBundle = cachedRoleMaps.get(prefix); |
| |
| GroupMappingAndRoleMap groupMappingAndRoleMap = new GroupMappingAndRoleMap( |
| groupMappingMapBundle == null ? null : groupMappingMapBundle.getGroupMappingMap(), |
| roleMapBundle == null ? null : roleMapBundle.getRoleMap() |
| ); |
| |
| return objectMapper.writeValueAsBytes(groupMappingAndRoleMap); |
| } |
| |
| private void createUserInternal(String prefix, String userName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (createUserOnce(prefix, userName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not create user [%s] due to concurrent update contention.", userName); |
| } |
| |
| private void deleteUserInternal(String prefix, String userName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (deleteUserOnce(prefix, userName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not delete user [%s] due to concurrent update contention.", userName); |
| } |
| |
| private void createGroupMappingInternal(String prefix, BasicAuthorizerGroupMapping groupMapping) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (createGroupMappingOnce(prefix, groupMapping)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not create group mapping [%s] due to concurrent update contention.", groupMapping); |
| } |
| |
| private void deleteGroupMappingInternal(String prefix, String groupMappingName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (deleteGroupMappingOnce(prefix, groupMappingName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not delete group mapping [%s] due to concurrent update contention.", groupMappingName); |
| } |
| |
| private void createRoleInternal(String prefix, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (createRoleOnce(prefix, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not create role [%s] due to concurrent update contention.", roleName); |
| } |
| |
| private void deleteRoleInternal(String prefix, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (deleteRoleOnce(prefix, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not delete role [%s] due to concurrent update contention.", roleName); |
| } |
| |
| private void assignUserRoleInternal(String prefix, String userName, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (assignUserRoleOnce(prefix, userName, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not assign role [%s] to user [%s] due to concurrent update contention.", roleName, userName); |
| } |
| |
| private void unassignUserRoleInternal(String prefix, String userName, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (unassignUserRoleOnce(prefix, userName, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not unassign role [%s] from user [%s] due to concurrent update contention.", roleName, userName); |
| } |
| |
| private void assignGroupMappingRoleInternal(String prefix, String groupMappingName, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (assignGroupMappingRoleOnce(prefix, groupMappingName, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not assign role [%s] to group mapping [%s] due to concurrent update contention.", |
| roleName, |
| groupMappingName |
| ); |
| } |
| |
| private void unassignGroupMappingRoleInternal(String prefix, String groupMappingName, String roleName) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (unassignGroupMappingRoleOnce(prefix, groupMappingName, roleName)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not unassign role [%s] from group mapping [%s] due to concurrent update contention.", roleName, |
| groupMappingName |
| ); |
| } |
| |
| private void setPermissionsInternal(String prefix, String roleName, List<ResourceAction> permissions) |
| { |
| int attempts = 0; |
| while (attempts < numRetries) { |
| if (setPermissionsOnce(prefix, roleName, permissions)) { |
| return; |
| } else { |
| attempts++; |
| } |
| try { |
| Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY)); |
| } |
| catch (InterruptedException ie) { |
| throw new RuntimeException(ie); |
| } |
| } |
| throw new ISE("Could not set permissions for role [%s] due to concurrent update contention.", roleName); |
| } |
| |
| private boolean deleteUserOnce(String prefix, String userName) |
| { |
| byte[] oldValue = getCurrentUserMapBytes(prefix); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap(objectMapper, oldValue); |
| if (userMap.get(userName) == null) { |
| throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName); |
| } else { |
| userMap.remove(userName); |
| } |
| byte[] newValue = BasicAuthUtils.serializeAuthorizerUserMap(objectMapper, userMap); |
| return tryUpdateUserMap(prefix, userMap, oldValue, newValue); |
| } |
| |
| private boolean createUserOnce(String prefix, String userName) |
| { |
| byte[] oldValue = getCurrentUserMapBytes(prefix); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap(objectMapper, oldValue); |
| if (userMap.get(userName) != null) { |
| throw new BasicSecurityDBResourceException("User [%s] already exists.", userName); |
| } else { |
| userMap.put(userName, new BasicAuthorizerUser(userName, null)); |
| } |
| byte[] newValue = BasicAuthUtils.serializeAuthorizerUserMap(objectMapper, userMap); |
| return tryUpdateUserMap(prefix, userMap, oldValue, newValue); |
| } |
| |
| private boolean deleteGroupMappingOnce(String prefix, String groupMappingName) |
| { |
| byte[] oldValue = getCurrentGroupMappingMapBytes(prefix); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap(objectMapper, oldValue); |
| if (groupMappingMap.get(groupMappingName) == null) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] does not exist.", groupMappingName); |
| } else { |
| groupMappingMap.remove(groupMappingName); |
| } |
| byte[] newValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap); |
| return tryUpdateGroupMappingMap(prefix, groupMappingMap, oldValue, newValue); |
| } |
| |
| private boolean createGroupMappingOnce(String prefix, BasicAuthorizerGroupMapping groupMapping) |
| { |
| byte[] oldValue = getCurrentGroupMappingMapBytes(prefix); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap(objectMapper, oldValue); |
| if (groupMappingMap.get(groupMapping.getName()) != null) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] already exists.", groupMapping.getName()); |
| } else { |
| groupMappingMap.put(groupMapping.getName(), groupMapping); |
| } |
| byte[] newValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap); |
| return tryUpdateGroupMappingMap(prefix, groupMappingMap, oldValue, newValue); |
| } |
| |
| private boolean createRoleOnce(String prefix, String roleName) |
| { |
| byte[] oldValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap(objectMapper, oldValue); |
| if (roleMap.get(roleName) != null) { |
| throw new BasicSecurityDBResourceException("Role [%s] already exists.", roleName); |
| } else { |
| roleMap.put(roleName, new BasicAuthorizerRole(roleName, null)); |
| } |
| byte[] newValue = BasicAuthUtils.serializeAuthorizerRoleMap(objectMapper, roleMap); |
| return tryUpdateRoleMap(prefix, roleMap, oldValue, newValue); |
| } |
| |
| private boolean deleteRoleOnce(String prefix, String roleName) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } else { |
| roleMap.remove(roleName); |
| } |
| |
| byte[] oldUserMapValue = getCurrentUserMapBytes(prefix); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap( |
| objectMapper, |
| oldUserMapValue |
| ); |
| for (BasicAuthorizerUser user : userMap.values()) { |
| user.getRoles().remove(roleName); |
| } |
| byte[] newUserMapValue = BasicAuthUtils.serializeAuthorizerUserMap(objectMapper, userMap); |
| |
| byte[] oldGroupMapValue = getCurrentGroupMappingMapBytes(prefix); |
| Map<String, BasicAuthorizerGroupMapping> groupMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap( |
| objectMapper, |
| oldGroupMapValue |
| ); |
| for (BasicAuthorizerGroupMapping group : groupMap.values()) { |
| group.getRoles().remove(roleName); |
| } |
| byte[] newGroupMapValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMap); |
| |
| byte[] newRoleMapValue = BasicAuthUtils.serializeAuthorizerRoleMap(objectMapper, roleMap); |
| |
| return tryUpdateUserAndRoleMap( |
| prefix, |
| userMap, oldUserMapValue, newUserMapValue, |
| roleMap, oldRoleMapValue, newRoleMapValue |
| ) && tryUpdateGroupMappingAndRoleMap( |
| prefix, |
| groupMap, oldGroupMapValue, newGroupMapValue, |
| roleMap, newRoleMapValue, newRoleMapValue |
| ); |
| } |
| |
| private boolean assignUserRoleOnce(String prefix, String userName, String roleName) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } |
| |
| byte[] oldUserMapValue = getCurrentUserMapBytes(prefix); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap( |
| objectMapper, |
| oldUserMapValue |
| ); |
| BasicAuthorizerUser user = userMap.get(userName); |
| if (userMap.get(userName) == null) { |
| throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName); |
| } |
| |
| if (user.getRoles().contains(roleName)) { |
| throw new BasicSecurityDBResourceException("User [%s] already has role [%s].", userName, roleName); |
| } |
| |
| user.getRoles().add(roleName); |
| byte[] newUserMapValue = BasicAuthUtils.serializeAuthorizerUserMap(objectMapper, userMap); |
| |
| // Role map is unchanged, but submit as an update to ensure that the table didn't change (e.g., role deleted) |
| return tryUpdateUserAndRoleMap( |
| prefix, |
| userMap, oldUserMapValue, newUserMapValue, |
| roleMap, oldRoleMapValue, oldRoleMapValue |
| ); |
| } |
| |
| private boolean unassignUserRoleOnce(String prefix, String userName, String roleName) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } |
| |
| byte[] oldUserMapValue = getCurrentUserMapBytes(prefix); |
| Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap( |
| objectMapper, |
| oldUserMapValue |
| ); |
| BasicAuthorizerUser user = userMap.get(userName); |
| if (userMap.get(userName) == null) { |
| throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName); |
| } |
| |
| if (!user.getRoles().contains(roleName)) { |
| throw new BasicSecurityDBResourceException("User [%s] does not have role [%s].", userName, roleName); |
| } |
| |
| user.getRoles().remove(roleName); |
| byte[] newUserMapValue = BasicAuthUtils.serializeAuthorizerUserMap(objectMapper, userMap); |
| |
| // Role map is unchanged, but submit as an update to ensure that the table didn't change (e.g., role deleted) |
| return tryUpdateUserAndRoleMap( |
| prefix, |
| userMap, oldUserMapValue, newUserMapValue, |
| roleMap, oldRoleMapValue, oldRoleMapValue |
| ); |
| } |
| |
| private boolean assignGroupMappingRoleOnce(String prefix, String groupMappingName, String roleName) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } |
| |
| byte[] oldGroupMappingMapValue = getCurrentGroupMappingMapBytes(prefix); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap( |
| objectMapper, |
| oldGroupMappingMapValue |
| ); |
| BasicAuthorizerGroupMapping groupMapping = groupMappingMap.get(groupMappingName); |
| if (groupMappingMap.get(groupMappingName) == null) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] does not exist.", groupMappingName); |
| } |
| |
| if (groupMapping.getRoles().contains(roleName)) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] already has role [%s].", groupMappingName, roleName); |
| } |
| |
| groupMapping.getRoles().add(roleName); |
| byte[] newGroupMapValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap); |
| |
| // Role map is unchanged, but submit as an update to ensure that the table didn't change (e.g., role deleted) |
| return tryUpdateGroupMappingAndRoleMap( |
| prefix, |
| groupMappingMap, oldGroupMappingMapValue, newGroupMapValue, |
| roleMap, oldRoleMapValue, oldRoleMapValue |
| ); |
| } |
| |
| private boolean unassignGroupMappingRoleOnce(String prefix, String groupMappingName, String roleName) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } |
| |
| byte[] oldGroupMappingMapValue = getCurrentGroupMappingMapBytes(prefix); |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap( |
| objectMapper, |
| oldGroupMappingMapValue |
| ); |
| BasicAuthorizerGroupMapping groupMapping = groupMappingMap.get(groupMappingName); |
| if (groupMappingMap.get(groupMappingName) == null) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] does not exist.", groupMappingName); |
| } |
| |
| if (!groupMapping.getRoles().contains(roleName)) { |
| throw new BasicSecurityDBResourceException("Group mapping [%s] does not have role [%s].", groupMappingName, roleName); |
| } |
| |
| groupMapping.getRoles().remove(roleName); |
| byte[] newGroupMapValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap); |
| |
| // Role map is unchanged, but submit as an update to ensure that the table didn't change (e.g., role deleted) |
| return tryUpdateGroupMappingAndRoleMap( |
| prefix, |
| groupMappingMap, oldGroupMappingMapValue, newGroupMapValue, |
| roleMap, oldRoleMapValue, oldRoleMapValue |
| ); |
| } |
| |
| private boolean setPermissionsOnce(String prefix, String roleName, List<ResourceAction> permissions) |
| { |
| byte[] oldRoleMapValue = getCurrentRoleMapBytes(prefix); |
| Map<String, BasicAuthorizerRole> roleMap = BasicAuthUtils.deserializeAuthorizerRoleMap( |
| objectMapper, |
| oldRoleMapValue |
| ); |
| if (roleMap.get(roleName) == null) { |
| throw new BasicSecurityDBResourceException("Role [%s] does not exist.", roleName); |
| } |
| roleMap.put( |
| roleName, |
| new BasicAuthorizerRole(roleName, BasicAuthorizerPermission.makePermissionList(permissions)) |
| ); |
| byte[] newRoleMapValue = BasicAuthUtils.serializeAuthorizerRoleMap(objectMapper, roleMap); |
| |
| return tryUpdateRoleMap(prefix, roleMap, oldRoleMapValue, newRoleMapValue); |
| } |
| |
| private void initSuperUsersAndGroupMapping( |
| String authorizerName, |
| Map<String, BasicAuthorizerUser> userMap, |
| Map<String, BasicAuthorizerRole> roleMap, |
| Map<String, BasicAuthorizerGroupMapping> groupMappingMap, |
| String initialAdminUser, |
| String initialAdminRole, |
| String initialAdminGroupMapping |
| ) |
| { |
| if (!roleMap.containsKey(BasicAuthUtils.ADMIN_NAME)) { |
| createRoleInternal(authorizerName, BasicAuthUtils.ADMIN_NAME); |
| setPermissionsInternal(authorizerName, BasicAuthUtils.ADMIN_NAME, SUPERUSER_PERMISSIONS); |
| } |
| |
| if (!roleMap.containsKey(BasicAuthUtils.INTERNAL_USER_NAME)) { |
| createRoleInternal(authorizerName, BasicAuthUtils.INTERNAL_USER_NAME); |
| setPermissionsInternal(authorizerName, BasicAuthUtils.INTERNAL_USER_NAME, SUPERUSER_PERMISSIONS); |
| } |
| |
| if (!userMap.containsKey(BasicAuthUtils.ADMIN_NAME)) { |
| createUserInternal(authorizerName, BasicAuthUtils.ADMIN_NAME); |
| assignUserRoleInternal(authorizerName, BasicAuthUtils.ADMIN_NAME, BasicAuthUtils.ADMIN_NAME); |
| } |
| |
| if (!userMap.containsKey(BasicAuthUtils.INTERNAL_USER_NAME)) { |
| createUserInternal(authorizerName, BasicAuthUtils.INTERNAL_USER_NAME); |
| assignUserRoleInternal(authorizerName, BasicAuthUtils.INTERNAL_USER_NAME, BasicAuthUtils.INTERNAL_USER_NAME); |
| } |
| |
| if (initialAdminRole != null |
| && !(initialAdminRole.equals(BasicAuthUtils.ADMIN_NAME) || initialAdminRole.equals(BasicAuthUtils.INTERNAL_USER_NAME)) |
| && !roleMap.containsKey(initialAdminRole)) { |
| createRoleInternal(authorizerName, initialAdminRole); |
| setPermissionsInternal(authorizerName, initialAdminRole, SUPERUSER_PERMISSIONS); |
| } |
| |
| if (initialAdminUser != null |
| && !(initialAdminUser.equals(BasicAuthUtils.ADMIN_NAME) || initialAdminUser.equals(BasicAuthUtils.INTERNAL_USER_NAME)) |
| && !userMap.containsKey(initialAdminUser)) { |
| createUserInternal(authorizerName, initialAdminUser); |
| assignUserRoleInternal(authorizerName, initialAdminUser, initialAdminRole == null ? BasicAuthUtils.ADMIN_NAME : initialAdminRole); |
| } |
| |
| if (initialAdminGroupMapping != null && !groupMappingMap.containsKey(BasicAuthUtils.ADMIN_GROUP_MAPPING_NAME)) { |
| BasicAuthorizerGroupMapping groupMapping = |
| new BasicAuthorizerGroupMapping( |
| BasicAuthUtils.ADMIN_GROUP_MAPPING_NAME, |
| initialAdminGroupMapping, |
| new HashSet<>(Collections.singletonList(initialAdminRole == null ? BasicAuthUtils.ADMIN_NAME : initialAdminRole)) |
| ); |
| createGroupMappingInternal(authorizerName, groupMapping); |
| } |
| } |
| } |