| // 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.impala.catalog; |
| |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import org.apache.impala.thrift.TCatalogObject; |
| import org.apache.impala.thrift.TCatalogObjectType; |
| import org.apache.impala.thrift.TPrincipal; |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Sets; |
| import org.apache.impala.thrift.TPrincipalType; |
| |
| /** |
| * A base class that represents a principal in an authorization policy. |
| * This class is thread safe. |
| */ |
| public abstract class Principal extends CatalogObjectImpl { |
| private final TPrincipal principal_; |
| // The last principal ID assigned, starts at 0. |
| private static AtomicInteger principalId_ = new AtomicInteger(0); |
| // URIs are case sensitive, so we need to store privilege names in a case sensitive way. |
| private final CatalogObjectCache<PrincipalPrivilege> principalPrivileges_ = |
| new CatalogObjectCache<>(false); |
| |
| protected Principal(String principalName, TPrincipalType type, |
| Set<String> grantGroups) { |
| principal_ = new TPrincipal(); |
| principal_.setPrincipal_name(principalName); |
| principal_.setPrincipal_type(type); |
| principal_.setPrincipal_id(principalId_.incrementAndGet()); |
| principal_.setGrant_groups(Lists.newArrayList(grantGroups)); |
| } |
| |
| protected Principal(TPrincipal principal) { |
| principal_ = principal; |
| } |
| |
| /** |
| * Adds a privilege to the principal. Returns true if the privilege was added |
| * successfully or false if there was a newer version of the privilege already added |
| * to the principal. |
| */ |
| public boolean addPrivilege(PrincipalPrivilege privilege) { |
| return principalPrivileges_.add(privilege); |
| } |
| |
| /** |
| * Returns all privileges for this principal. If no privileges have been added to the |
| * principal, an empty list is returned. |
| */ |
| public List<PrincipalPrivilege> getPrivileges() { |
| return new ArrayList<>(principalPrivileges_.getValues()); |
| } |
| |
| /** |
| * Returns all privilege names for this principal, or an empty set of no privileges are |
| * granted to the principal. |
| */ |
| public Set<String> getPrivilegeNames() { |
| return new HashSet<>(principalPrivileges_.keySet()); |
| } |
| |
| /** |
| * Gets a privilege with the given name from this principal. If no privilege exists |
| * with this name null is returned. |
| */ |
| public PrincipalPrivilege getPrivilege(String privilegeName) { |
| return principalPrivileges_.get(privilegeName); |
| } |
| |
| /** |
| * Removes a privilege with the given name from the principal. Returns the removed |
| * privilege or null if no privilege exists with this name. |
| */ |
| public PrincipalPrivilege removePrivilege(String privilegeName) { |
| return principalPrivileges_.remove(privilegeName); |
| } |
| |
| /** |
| * Adds a new grant group to this principal. |
| */ |
| public synchronized void addGrantGroup(String groupName) { |
| if (principal_.getGrant_groups().contains(groupName)) return; |
| principal_.addToGrant_groups(groupName); |
| } |
| |
| /** |
| * Removes a grant group from this principal. |
| */ |
| public synchronized void removeGrantGroup(String groupName) { |
| principal_.getGrant_groups().remove(groupName); |
| // Should never have duplicates in the list of groups. |
| Preconditions.checkState(!principal_.getGrant_groups().contains(groupName)); |
| } |
| |
| /** |
| * Returns the Thrift representation of the principal. |
| */ |
| public TPrincipal toThrift() { |
| return principal_; |
| } |
| |
| /** |
| * Creates a Principal from a TPrincipal thrift struct. |
| */ |
| public static Principal fromThrift(TPrincipal thriftPrincipal) { |
| return thriftPrincipal.getPrincipal_type() == TPrincipalType.ROLE ? |
| new Role(thriftPrincipal) : new User(thriftPrincipal); |
| } |
| |
| /** |
| * Creates a new instance of Principal. |
| */ |
| public static Principal newInstance(String principalName, TPrincipalType type, |
| Set<String> grantGroups) { |
| return type == TPrincipalType.ROLE ? |
| new Role(principalName, grantGroups) : new User(principalName, grantGroups); |
| } |
| |
| /** |
| * Gets the set of group names that have been granted to this principal or an empty |
| * set if no groups have been granted. |
| */ |
| public Set<String> getGrantGroups() { |
| return Sets.newHashSet(principal_.getGrant_groups()); |
| } |
| |
| @Override |
| public TCatalogObjectType getCatalogObjectType() { |
| return TCatalogObjectType.PRINCIPAL; |
| } |
| |
| @Override |
| public String getName() { return principal_.getPrincipal_name(); } |
| |
| /** |
| * Returns the principal ID. |
| */ |
| public int getId() { return principal_.getPrincipal_id(); } |
| |
| @Override |
| protected void setTCatalogObject(TCatalogObject catalogObject) { |
| catalogObject.setPrincipal(toThrift()); |
| } |
| |
| /** |
| * Returns the principal type. |
| */ |
| public TPrincipalType getPrincipalType() { return principal_.getPrincipal_type(); } |
| |
| public static String toString(TPrincipalType type) { |
| String principal; |
| switch (type) { |
| case ROLE: |
| principal = "Role"; |
| break; |
| case USER: |
| principal = "User"; |
| break; |
| case GROUP: |
| principal = "Group"; |
| break; |
| default: |
| throw new IllegalStateException(String.format("Unsupported principal type " + |
| "%s.", type)); |
| } |
| return principal; |
| } |
| } |