blob: 4e605ae78ffebe54349c4e27c6bc73ee25dd85b6 [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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.sentry.api.service.thrift;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.sentry.api.common.ThriftConstants;
import org.apache.sentry.core.common.ActiveRoleSet;
import org.apache.sentry.core.common.Authorizable;
import org.apache.sentry.core.common.exception.SentryUserException;
import org.apache.sentry.core.common.transport.SentryConnection;
import org.apache.sentry.core.common.transport.SentryTransportPool;
import org.apache.sentry.core.common.transport.TTransportWrapper;
import org.apache.sentry.core.common.utils.PolicyFileConstants;
import org.apache.sentry.core.model.db.AccessConstants;
import org.apache.sentry.core.model.db.DBModelAuthorizable;
import org.apache.sentry.api.common.ApiConstants.ClientConfig;
import org.apache.sentry.api.common.ApiConstants.SentryPolicyServiceConstants;
import org.apache.sentry.api.common.ApiConstants.PrivilegeScope;
import org.apache.sentry.api.service.thrift.SentryPolicyService.Client;
import org.apache.sentry.api.common.SentryServiceUtil;
import org.apache.sentry.api.common.Status;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TMultiplexedProtocol;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Client implementation for Policy (HMS) clients.
* <p>
* The class is not thread-safe - it is up to the callers to ensure thread safety
*/
public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyServiceClient, SentryConnection {
private Client client;
private final SentryTransportPool transportPool;
private TTransportWrapper transport;
private final long maxMessageSize;
private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occurred ";
/**
* Initialize the sentry configurations.
*/
public SentryPolicyServiceClientDefaultImpl(Configuration conf,
SentryTransportPool transportPool)
throws IOException {
maxMessageSize = conf.getLong(ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE,
ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
this.transportPool = transportPool;
}
/**
* Sets the Client object which is usually a mock object of the Client class used for testing.
* @param client
*/
@VisibleForTesting
void setClient(Client client) {
this.client = client;
}
/**
* Connect to the sentry server
*
* @throws IOException
*/
@Override
public void connect() throws Exception {
if ((transport != null) && transport.isOpen()) {
return;
}
transport = transportPool.getTransport();
TMultiplexedProtocol protocol = new TMultiplexedProtocol(
new TBinaryProtocol(transport.getTTransport(), maxMessageSize, maxMessageSize,
true, true),
SentryPolicyServiceConstants.SENTRY_POLICY_SERVICE_NAME);
client = new Client(protocol);
}
@Override
public void createRole(String requestorUserName, String roleName)
throws SentryUserException {
TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setRoleName(roleName);
try {
TCreateSentryRoleResponse response = client.create_sentry_role(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void dropRole(String requestorUserName,
String roleName)
throws SentryUserException {
dropRole(requestorUserName, roleName, false);
}
@Override
public void dropRoleIfExists(String requestorUserName,
String roleName)
throws SentryUserException {
dropRole(requestorUserName, roleName, true);
}
private void dropRole(String requestorUserName,
String roleName, boolean ifExists)
throws SentryUserException {
TDropSentryRoleRequest request = new TDropSentryRoleRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setRoleName(roleName);
try {
TDropSentryRoleResponse response = client.drop_sentry_role(request);
Status status = Status.fromCode(response.getStatus().getValue());
if (ifExists && status == Status.NO_SUCH_OBJECT) {
return;
}
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
/**
* Gets sentry role objects for a given groupName using the Sentry service
*
* @param requestorUserName : user on whose behalf the request is issued
* @param groupName : groupName to look up ( if null returns all roles for all groups)
* @return Set of thrift sentry role objects
* @throws SentryUserException
*/
@Override
public Set<TSentryRole> listRolesByGroupName(
String requestorUserName,
String groupName)
throws SentryUserException {
TListSentryRolesRequest request = new TListSentryRolesRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setGroupName(groupName);
TListSentryRolesResponse response;
try {
response = client.list_sentry_roles_by_group(request);
Status status = Status.fromCode(response.getStatus().getValue());
if (status == Status.NO_SUCH_OBJECT) {
return Collections.emptySet();
}
Status.throwIfNotOk(response.getStatus());
return response.getRoles();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
/**
* Gets sentry role objects for a given userName using the Sentry service
*
* @param requestorUserName : user on whose behalf the request is issued
* @param userName : userName to look up (can't be empty)
* @return Set of thrift sentry role objects
* @throws SentryUserException
*/
@Override
public Set<TSentryRole> listRolesByUserName(String requestorUserName, String userName)
throws SentryUserException {
TListSentryRolesForUserRequest request = new TListSentryRolesForUserRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setUserName(userName);
TListSentryRolesResponse response;
try {
response = client.list_sentry_roles_by_user(request);
Status.throwIfNotOk(response.getStatus());
return response.getRoles();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public Set<TSentryPrivilege> listAllPrivilegesByRoleName(String requestorUserName,
String roleName)
throws SentryUserException {
return listPrivilegesByRoleName(requestorUserName, roleName, null);
}
/**
* Gets sentry privilege objects for a given roleName using the Sentry service
*
* @param requestorUserName : user on whose behalf the request is issued
* @param roleName : roleName to look up
* @param authorizable : authorizable Hierarchy (server->db->table etc)
* @return Set of thrift sentry privilege objects
* @throws SentryUserException
*/
@Override
public Set<TSentryPrivilege> listPrivilegesByRoleName(String requestorUserName,
String roleName, List<? extends Authorizable> authorizable)
throws SentryUserException {
TListSentryPrivilegesRequest request = new TListSentryPrivilegesRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setRoleName(""); // 'roleName' is required but it is deprecated by 'entityName'
request.setEntityName(roleName);
if (authorizable != null && !authorizable.isEmpty()) {
TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(authorizable);
request.setAuthorizableHierarchy(tSentryAuthorizable);
}
TListSentryPrivilegesResponse response;
try {
response = client.list_sentry_privileges_by_role(request);
Status.throwIfNotOk(response.getStatus());
return response.getPrivileges();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public Set<TSentryPrivilege> listAllPrivilegesByUserName(String requestorUserName,
String userName)
throws SentryUserException {
return listPrivilegesByUserName(requestorUserName, userName, null);
}
@Override
public Set<TSentryPrivilege> listPrivilegesByUserName(String requestorUserName, String userName,
List<? extends Authorizable> authorizable)
throws SentryUserException {
TListSentryPrivilegesRequest request = new TListSentryPrivilegesRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setEntityName(userName);
if (authorizable != null && !authorizable.isEmpty()) {
TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(authorizable);
request.setAuthorizableHierarchy(tSentryAuthorizable);
}
TListSentryPrivilegesResponse response;
try {
response = client.list_sentry_privileges_by_user(request);
if (response == null) {
throw new SentryUserException("The Sentry server has returned a NULL response. "
+ "See the Sentry server logs for more information about the error.");
}
Status.throwIfNotOk(response.getStatus());
return response.getPrivileges();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public Set<TSentryRole> listAllRoles(String requestorUserName)
throws SentryUserException {
return listRolesByGroupName(requestorUserName, null);
}
@Override
public Set<TSentryRole> listUserRoles(String requestorUserName)
throws SentryUserException {
Set<TSentryRole> tSentryRoles = Sets.newHashSet();
tSentryRoles.addAll(listRolesByGroupName(requestorUserName, AccessConstants.ALL));
tSentryRoles.addAll(listRolesByUserName(requestorUserName, requestorUserName));
return tSentryRoles;
}
@Override
public TSentryPrivilege grantURIPrivilege(String requestorUserName,
String roleName, String server, String uri)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName,
PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
}
@Override
public TSentryPrivilege grantURIPrivilege(String requestorUserName,
String roleName, String server, String uri, Boolean grantOption)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName,
PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
}
@Override
public void grantServerPrivilege(String requestorUserName,
String roleName, String server, String action)
throws SentryUserException {
// "ALL" and "*" should be synonyms for action and need to be unified with grantServerPrivilege without
// action explicitly specified.
if (AccessConstants.ACTION_ALL.equalsIgnoreCase(action) || AccessConstants.ALL.equals(action)) {
action = AccessConstants.ALL;
}
grantPrivilege(requestorUserName, roleName,
PrivilegeScope.SERVER, server, null, null, null, null, action);
}
@Deprecated
/***
* Should use grantServerPrivilege(String requestorUserName,
* String roleName, String server, String action, Boolean grantOption)
*/
public TSentryPrivilege grantServerPrivilege(String requestorUserName,
String roleName, String server, Boolean grantOption) throws SentryUserException {
return grantServerPrivilege(requestorUserName, roleName, server,
AccessConstants.ALL, grantOption);
}
@Override
public TSentryPrivilege grantServerPrivilege(String requestorUserName,
String roleName, String server, String action, Boolean grantOption)
throws SentryUserException {
// "ALL" and "*" should be synonyms for action and need to be unified with grantServerPrivilege without
// action explicitly specified.
if (AccessConstants.ACTION_ALL.equalsIgnoreCase(action) || AccessConstants.ALL.equals(action)) {
action = AccessConstants.ALL;
}
return grantPrivilege(requestorUserName, roleName,
PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
}
@Override
public TSentryPrivilege grantDatabasePrivilege(String requestorUserName,
String roleName, String server, String db, String action)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName,
PrivilegeScope.DATABASE, server, null, db, null, null, action);
}
@Override
public TSentryPrivilege grantDatabasePrivilege(String requestorUserName,
String roleName, String server, String db, String action, Boolean grantOption)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName,
PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
}
@Override
public TSentryPrivilege grantTablePrivilege(String requestorUserName,
String roleName, String server, String db, String table, String action)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName, PrivilegeScope.TABLE, server,
null,
db, table, null, action);
}
@Override
public TSentryPrivilege grantTablePrivilege(String requestorUserName,
String roleName, String server, String db, String table, String action, Boolean grantOption)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName, PrivilegeScope.TABLE, server,
null, db, table, null, action, grantOption);
}
@Override
public TSentryPrivilege grantColumnPrivilege(String requestorUserName,
String roleName, String server, String db, String table, String columnName, String action)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
null,
db, table, columnName, action);
}
@Override
public TSentryPrivilege grantColumnPrivilege(String requestorUserName,
String roleName, String server, String db, String table, String columnName, String action, Boolean grantOption)
throws SentryUserException {
return grantPrivilege(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
null, db, table, columnName, action, grantOption);
}
@Override
public Set<TSentryPrivilege> grantColumnsPrivileges(String requestorUserName,
String roleName, String server, String db, String table, List<String> columnNames, String action)
throws SentryUserException {
return grantPrivileges(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
null,
db, table, columnNames, action);
}
@Override
public Set<TSentryPrivilege> grantColumnsPrivileges(String requestorUserName,
String roleName, String server, String db, String table, List<String> columnNames, String action, Boolean grantOption)
throws SentryUserException {
return grantPrivileges(requestorUserName, roleName, PrivilegeScope.COLUMN,
server,
null, db, table, columnNames, action, grantOption);
}
@Override
public Set<TSentryPrivilege> grantPrivileges(
String requestorUserName, String roleName,
Set<TSentryPrivilege> privileges) throws SentryUserException {
return grantPrivilegesCore(requestorUserName, roleName, privileges);
}
@Override
public TSentryPrivilege grantPrivilege(String requestorUserName, String roleName,
TSentryPrivilege privilege) throws SentryUserException {
return grantPrivilegeCore(requestorUserName, roleName, privilege);
}
private TSentryPrivilege grantPrivilegeCore(String requestorUserName, String roleName,
TSentryPrivilege privilege) throws SentryUserException {
Set<TSentryPrivilege> results =
grantPrivilegesCore(requestorUserName, roleName, ImmutableSet.of(privilege));
if (results != null && results.size() > 0) {
return results.iterator().next();
} else {
return new TSentryPrivilege();
}
}
private Set<TSentryPrivilege> grantPrivilegesCore(String requestorUserName, String roleName,
Set<TSentryPrivilege> privileges) throws SentryUserException {
TAlterSentryRoleGrantPrivilegeRequest request = new TAlterSentryRoleGrantPrivilegeRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setRoleName(roleName);
request.setPrivileges(privileges);
try {
TAlterSentryRoleGrantPrivilegeResponse response =
client.alter_sentry_role_grant_privilege(request);
Status.throwIfNotOk(response.getStatus());
return response.getPrivileges();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@VisibleForTesting
public static TSentryAuthorizable setupSentryAuthorizable(
List<? extends Authorizable> authorizable) {
TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
for (Authorizable authzble : authorizable) {
if (authzble.getTypeName().equalsIgnoreCase(
DBModelAuthorizable.AuthorizableType.Server.toString())) {
tSentryAuthorizable.setServer(authzble.getName());
} else if (authzble.getTypeName().equalsIgnoreCase(
DBModelAuthorizable.AuthorizableType.URI.toString())) {
tSentryAuthorizable.setUri(authzble.getName());
} else if (authzble.getTypeName().equalsIgnoreCase(
DBModelAuthorizable.AuthorizableType.Db.toString())) {
tSentryAuthorizable.setDb(authzble.getName());
} else if (authzble.getTypeName().equalsIgnoreCase(
DBModelAuthorizable.AuthorizableType.Table.toString())) {
tSentryAuthorizable.setTable(authzble.getName());
} else if (authzble.getTypeName().equalsIgnoreCase(
DBModelAuthorizable.AuthorizableType.Column.toString())) {
tSentryAuthorizable.setColumn(authzble.getName());
}
}
return tSentryAuthorizable;
}
private TSentryPrivilege grantPrivilege(String requestorUserName,
String roleName,
PrivilegeScope scope, String serverName, String uri, String db,
String table, String column, String action) throws SentryUserException {
return grantPrivilege(requestorUserName, roleName, scope, serverName, uri,
db, table, column, action, false);
}
private TSentryPrivilege grantPrivilege(String requestorUserName,
String roleName, PrivilegeScope scope, String serverName, String uri, String db, String table,
String column, String action, Boolean grantOption)
throws SentryUserException {
TSentryPrivilege privilege =
convertToTSentryPrivilege(scope, serverName, uri, db, table, column, action, grantOption);
return grantPrivilegeCore(requestorUserName, roleName, privilege);
}
private Set<TSentryPrivilege> grantPrivileges(String requestorUserName,
String roleName,
PrivilegeScope scope, String serverName, String uri, String db,
String table, List<String> columns, String action) throws SentryUserException {
return grantPrivileges(requestorUserName, roleName, scope, serverName, uri,
db, table, columns, action, false);
}
private Set<TSentryPrivilege> grantPrivileges(String requestorUserName,
String roleName, PrivilegeScope scope, String serverName, String uri, String db, String
table,
List<String> columns, String action, Boolean grantOption)
throws SentryUserException {
Set<TSentryPrivilege> privileges = convertColumnPrivileges(scope,
serverName, uri, db, table, columns, action, grantOption);
return grantPrivilegesCore(requestorUserName, roleName, privileges);
}
@Override
public void revokePrivileges(String requestorUserName, String roleName, Set<TSentryPrivilege> privileges) throws SentryUserException {
this.revokePrivilegesCore(requestorUserName, roleName, privileges);
}
@Override
public void revokePrivilege(String requestorUserName, String roleName, TSentryPrivilege privilege) throws SentryUserException {
this.revokePrivilegeCore(requestorUserName, roleName, privilege);
}
private void revokePrivilegeCore(String requestorUserName, String roleName, TSentryPrivilege privilege) throws SentryUserException {
this.revokePrivilegesCore(requestorUserName, roleName, ImmutableSet.of(privilege));
}
private void revokePrivilegesCore(String requestorUserName, String roleName, Set<TSentryPrivilege> privileges) throws SentryUserException {
TAlterSentryRoleRevokePrivilegeRequest request = new TAlterSentryRoleRevokePrivilegeRequest();
request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
request.setRequestorUserName(requestorUserName);
request.setRoleName(roleName);
request.setPrivileges(privileges);
try {
TAlterSentryRoleRevokePrivilegeResponse response = client.alter_sentry_role_revoke_privilege(
request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void revokeURIPrivilege(String requestorUserName,
String roleName, String server, String uri)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
}
@Override
public void revokeURIPrivilege(String requestorUserName,
String roleName, String server, String uri, Boolean grantOption)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
}
@Override
public void revokeServerPrivilege(String requestorUserName,
String roleName, String server, String action)
throws SentryUserException {
// "ALL" and "*" should be synonyms for action and need to be unified with revokeServerPrivilege without
// action explicitly specified.
if (AccessConstants.ACTION_ALL.equalsIgnoreCase(action) || AccessConstants.ALL.equals(action)) {
action = AccessConstants.ALL;
}
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.SERVER, server, null, null, null, null, action);
}
public void revokeServerPrivilege(String requestorUserName,
String roleName, String server, String action, Boolean grantOption)
throws SentryUserException {
// "ALL" and "*" should be synonyms for action and need to be unified with revokeServerPrivilege without
// action explicitly specified.
if (AccessConstants.ACTION_ALL.equalsIgnoreCase(action) || AccessConstants.ALL.equals(action)) {
action = AccessConstants.ALL;
}
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
}
@Deprecated
/***
* Should use revokeServerPrivilege(String requestorUserName,
* String roleName, String server, String action, Boolean grantOption)
*/
@Override
public void revokeServerPrivilege(String requestorUserName,
String roleName, String server, boolean grantOption)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.SERVER, server, null, null, null, null, AccessConstants.ALL, grantOption);
}
@Override
public void revokeDatabasePrivilege(String requestorUserName,
String roleName, String server, String db, String action)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.DATABASE, server, null, db, null, null, action);
}
@Override
public void revokeDatabasePrivilege(String requestorUserName,
String roleName, String server, String db, String action, Boolean grantOption)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
}
@Override
public void revokeTablePrivilege(String requestorUserName,
String roleName, String server, String db, String table, String action)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.TABLE, server, null,
db, table, null, action);
}
@Override
public void revokeTablePrivilege(String requestorUserName,
String roleName, String server, String db, String table, String action, Boolean grantOption)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.TABLE, server, null,
db, table, null, action, grantOption);
}
@Override
public void revokeColumnPrivilege(String requestorUserName, String roleName,
String server, String db, String table, String columnName, String action)
throws SentryUserException {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
listBuilder.add(columnName);
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.COLUMN, server, null,
db, table, listBuilder.build(), action);
}
@Override
public void revokeColumnPrivilege(String requestorUserName, String roleName,
String server, String db, String table, String columnName, String action, Boolean grantOption)
throws SentryUserException {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
listBuilder.add(columnName);
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.COLUMN, server, null,
db, table, listBuilder.build(), action, grantOption);
}
@Override
public void revokeColumnsPrivilege(String requestorUserName, String roleName,
String server, String db, String table, List<String> columns, String action)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.COLUMN, server, null,
db, table, columns, action);
}
@Override
public void revokeColumnsPrivilege(String requestorUserName, String roleName,
String server, String db, String table, List<String> columns, String action, Boolean grantOption)
throws SentryUserException {
revokePrivilege(requestorUserName, roleName,
PrivilegeScope.COLUMN, server, null,
db, table, columns, action, grantOption);
}
private void revokePrivilege(String requestorUserName,
String roleName, PrivilegeScope scope, String serverName, String uri,
String db, String table, List<String> columns, String action)
throws SentryUserException {
this.revokePrivilege(requestorUserName, roleName, scope, serverName, uri, db, table, columns, action, false);
}
private void revokePrivilege(String requestorUserName, String roleName,
PrivilegeScope scope, String serverName, String uri, String db, String table, List<String> columns,
String action, Boolean grantOption)
throws SentryUserException {
Set<TSentryPrivilege> privileges = convertColumnPrivileges(scope,
serverName, uri, db, table, columns, action, grantOption);
this.revokePrivilegesCore(requestorUserName, roleName, privileges);
}
private Set<TSentryPrivilege> convertColumnPrivileges(
PrivilegeScope scope, String serverName, String uri, String db, String
table, List<String> columns,
String action, Boolean grantOption) {
ImmutableSet.Builder<TSentryPrivilege> setBuilder = ImmutableSet.builder();
if (columns == null || columns.isEmpty()) {
TSentryPrivilege privilege = new TSentryPrivilege();
privilege.setPrivilegeScope(scope.toString());
privilege.setServerName(serverName);
privilege.setURI(uri);
privilege.setDbName(db);
privilege.setTableName(table);
privilege.setColumnName(null);
privilege.setAction(action);
privilege.setCreateTime(System.currentTimeMillis());
privilege.setGrantOption(convertTSentryGrantOption(grantOption));
setBuilder.add(privilege);
} else {
for (String column : columns) {
TSentryPrivilege privilege = new TSentryPrivilege();
privilege.setPrivilegeScope(scope.toString());
privilege.setServerName(serverName);
privilege.setURI(uri);
privilege.setDbName(db);
privilege.setTableName(table);
privilege.setColumnName(column);
privilege.setAction(action);
privilege.setCreateTime(System.currentTimeMillis());
privilege.setGrantOption(convertTSentryGrantOption(grantOption));
setBuilder.add(privilege);
}
}
return setBuilder.build();
}
private TSentryPrivilege convertToTSentryPrivilege(
PrivilegeScope scope, String serverName, String uri, String db, String table, String
column,
String action, Boolean grantOption) {
TSentryPrivilege privilege = new TSentryPrivilege();
privilege.setPrivilegeScope(scope.toString());
privilege.setServerName(serverName);
privilege.setURI(uri);
privilege.setDbName(db);
privilege.setTableName(table);
privilege.setColumnName(column);
privilege.setAction(action);
privilege.setCreateTime(System.currentTimeMillis());
privilege.setGrantOption(convertTSentryGrantOption(grantOption));
return privilege;
}
private TSentryGrantOption convertTSentryGrantOption(Boolean grantOption) {
if (grantOption == null) {
return TSentryGrantOption.UNSET;
} else if (grantOption.equals(true)) {
return TSentryGrantOption.TRUE;
} else if (grantOption.equals(false)) {
return TSentryGrantOption.FALSE;
}
return TSentryGrantOption.FALSE;
}
@Override
public Set<String> listPrivilegesForProvider
(Set<String> groups, Set<String> users,
ActiveRoleSet roleSet, Authorizable... authorizable) throws SentryUserException {
TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(roleSet.isAll(), roleSet.getRoles());
TListSentryPrivilegesForProviderRequest request =
new TListSentryPrivilegesForProviderRequest(ThriftConstants.
TSENTRY_SERVICE_VERSION_CURRENT, groups, thriftRoleSet);
if (authorizable != null && authorizable.length > 0) {
TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(Lists
.newArrayList(authorizable));
request.setAuthorizableHierarchy(tSentryAuthorizable);
}
if (users != null) {
request.setUsers(users);
}
try {
TListSentryPrivilegesForProviderResponse response = client.list_sentry_privileges_for_provider(request);
Status.throwIfNotOk(response.getStatus());
return response.getPrivileges();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void grantRoleToGroup(String requestorUserName,
String groupName, String roleName)
throws SentryUserException {
grantRoleToGroups(requestorUserName, roleName, Sets.newHashSet(groupName));
}
@Override
public void revokeRoleFromGroup(String requestorUserName,
String groupName, String roleName)
throws SentryUserException {
revokeRoleFromGroups(requestorUserName, roleName, Sets.newHashSet(groupName));
}
@Override
public void grantRoleToGroups(String requestorUserName,
String roleName, Set<String> groups)
throws SentryUserException {
TAlterSentryRoleAddGroupsRequest request = new TAlterSentryRoleAddGroupsRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
roleName, convert2TGroups(groups));
try {
TAlterSentryRoleAddGroupsResponse response = client.alter_sentry_role_add_groups(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void revokeRoleFromGroups(String requestorUserName,
String roleName, Set<String> groups)
throws SentryUserException {
TAlterSentryRoleDeleteGroupsRequest request = new TAlterSentryRoleDeleteGroupsRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
roleName, convert2TGroups(groups));
try {
TAlterSentryRoleDeleteGroupsResponse response = client.alter_sentry_role_delete_groups(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void grantRoleToUser(String requestorUserName, String userName,
String roleName) throws SentryUserException {
grantRoleToUsers(requestorUserName, roleName, Sets.newHashSet(userName));
}
@Override
public void revokeRoleFromUser(String requestorUserName, String userName,
String roleName) throws SentryUserException {
revokeRoleFromUsers(requestorUserName, roleName, Sets.newHashSet(userName));
}
@Override
public void grantRoleToUsers(String requestorUserName, String roleName,
Set<String> users) throws SentryUserException {
TAlterSentryRoleAddUsersRequest request = new TAlterSentryRoleAddUsersRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
try {
TAlterSentryRoleAddUsersResponse response = client.alter_sentry_role_add_users(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void revokeRoleFromUsers(String requestorUserName, String roleName,
Set<String> users) throws SentryUserException {
TAlterSentryRoleDeleteUsersRequest request = new TAlterSentryRoleDeleteUsersRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
try {
TAlterSentryRoleDeleteUsersResponse response = client.alter_sentry_role_delete_users(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
private Set<TSentryGroup> convert2TGroups(Set<String> groups) {
Set<TSentryGroup> tGroups = Sets.newHashSet();
if (groups != null) {
for (String groupName : groups) {
tGroups.add(new TSentryGroup(groupName));
}
}
return tGroups;
}
@Override
public void dropPrivileges(String requestorUserName,
List<? extends Authorizable> authorizableObjects)
throws SentryUserException {
TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(authorizableObjects);
TDropPrivilegesRequest request = new TDropPrivilegesRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
tSentryAuthorizable);
try {
TDropPrivilegesResponse response = client.drop_sentry_privilege(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public void renamePrivileges(String requestorUserName,
List<? extends Authorizable> oldAuthorizables,
List<? extends Authorizable> newAuthorizables) throws SentryUserException {
TSentryAuthorizable tOldSentryAuthorizable = setupSentryAuthorizable(oldAuthorizables);
TSentryAuthorizable tNewSentryAuthorizable = setupSentryAuthorizable(newAuthorizables);
TRenamePrivilegesRequest request = new TRenamePrivilegesRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
tOldSentryAuthorizable, tNewSentryAuthorizable);
try {
TRenamePrivilegesResponse response = client
.rename_sentry_privilege(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
@Override
public Map<TSentryAuthorizable, TSentryPrivilegeMap> listPrivilegsbyAuthorizable(
String requestorUserName, Set<List<? extends Authorizable>> authorizables, Set<String> groups,
ActiveRoleSet roleSet) throws SentryUserException {
return listPrivilegsbyAuthorizable(requestorUserName, authorizables, groups, null, roleSet);
}
@Override
public Map<TSentryAuthorizable, TSentryPrivilegeMap> listPrivilegsbyAuthorizable
(
String requestorUserName,
Set<List<? extends Authorizable>> authorizables, Set<String> groups,
Set<String> users, ActiveRoleSet roleSet) throws SentryUserException {
Set<TSentryAuthorizable> authSet = Sets.newTreeSet();
for (List<? extends Authorizable> authorizableHierarchy : authorizables) {
authSet.add(setupSentryAuthorizable(authorizableHierarchy));
}
TListSentryPrivilegesByAuthRequest request = new TListSentryPrivilegesByAuthRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
authSet);
if (groups != null) {
request.setGroups(groups);
}
if (roleSet != null) {
request.setRoleSet(new TSentryActiveRoleSet(roleSet.isAll(), roleSet.getRoles()));
}
if (users != null) {
request.setUsers(users);
}
try {
TListSentryPrivilegesByAuthResponse response = client
.list_sentry_privileges_by_authorizable(request);
Status.throwIfNotOk(response.getStatus());
return response.getPrivilegesMapByAuth();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
/**
* Returns the configuration value in the sentry server associated with
* propertyName, or if propertyName does not exist, the defaultValue.
* There is no "requestorUserName" because this is regarded as an
* internal interface.
*
* @param propertyName Config attribute to search for
* @param defaultValue String to return if not found
* @return The value of the propertyName
* @throws SentryUserException
*/
@Override
public String getConfigValue(String propertyName, String defaultValue)
throws SentryUserException {
TSentryConfigValueRequest request = new TSentryConfigValueRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, propertyName);
if (defaultValue != null) {
request.setDefaultValue(defaultValue);
}
try {
TSentryConfigValueResponse response = client.get_sentry_config_value(request);
Status.throwIfNotOk(response.getStatus());
return response.getValue();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
/**
* Import the sentry mapping data, convert the mapping data from map structure to
* TSentryMappingData, and call the import API.
*
* @param policyFileMappingData Include 2 maps to save the mapping data, the following is the example of the data
* structure:
* for the following mapping data:
* group1=role1,role2
* group2=role2,role3
* role1=server=server1->db=db1
* role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
* role3=server=server1->url=hdfs://localhost/path
* <p>
* The policyFileMappingData will be inputed as:
* {
* groups={[group1={role1, role2}], group2=[role2, role3]},
* roles={role1=[server=server1->db=db1],
* role2=[server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2],
* role3=[server=server1->url=hdfs://localhost/path]
* }
* }
* @param requestorUserName The name of the request user
*/
@Override
public void importPolicy
(Map<String, Map<String, Set<String>>> policyFileMappingData,
String requestorUserName, boolean isOverwriteRole)
throws SentryUserException {
try {
TSentryMappingData tSentryMappingData = new TSentryMappingData();
// convert the mapping data for [group,role] from map structure to
// TSentryMappingData.GroupRolesMap
tSentryMappingData.setGroupRolesMap(policyFileMappingData.get(PolicyFileConstants.GROUPS));
tSentryMappingData.setUserRolesMap(policyFileMappingData.get(PolicyFileConstants.USER_ROLES));
// convert the mapping data for [role,privilege] from map structure to
// TSentryMappingData.RolePrivilegesMap
tSentryMappingData
.setRolePrivilegesMap(convertRolePrivilegesMapForSentryDB(policyFileMappingData
.get(PolicyFileConstants.ROLES)));
TSentryImportMappingDataRequest request = new TSentryImportMappingDataRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, isOverwriteRole,
tSentryMappingData);
TSentryImportMappingDataResponse response = client.import_sentry_mapping_data(request);
Status.throwIfNotOk(response.getStatus());
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
// convert the mapping data for [role,privilege] from map structure to
// TSentryMappingData.RolePrivilegesMap
private Map<String, Set<TSentryPrivilege>> convertRolePrivilegesMapForSentryDB(
Map<String, Set<String>> rolePrivilegesMap) {
Map<String, Set<TSentryPrivilege>> rolePrivilegesMapResult = Maps.newHashMap();
if (rolePrivilegesMap != null) {
for (Map.Entry<String, Set<String>> entry : rolePrivilegesMap.entrySet()) {
Set<TSentryPrivilege> tempTSentryPrivileges = Sets.newHashSet();
Set<String> tempPrivileges = entry.getValue();
for (String tempPrivilege : tempPrivileges) {
tempTSentryPrivileges.add(SentryServiceUtil.convertToTSentryPrivilege(tempPrivilege));
}
rolePrivilegesMapResult.put(entry.getKey(), tempTSentryPrivileges);
}
}
return rolePrivilegesMapResult;
}
// export the sentry mapping data with map structure
@Override
public Map<String, Map<String, Set<String>>> exportPolicy(String
requestorUserName,
String objectPath) throws SentryUserException {
TSentryExportMappingDataRequest request = new TSentryExportMappingDataRequest(
ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName);
request.setObjectPath(objectPath);
try {
TSentryExportMappingDataResponse response = client.export_sentry_mapping_data(request);
Status.throwIfNotOk(response.getStatus());
TSentryMappingData tSentryMappingData = response.getMappingData();
Map<String, Map<String, Set<String>>> resultMap = Maps.newHashMap();
resultMap.put(PolicyFileConstants.USER_ROLES, tSentryMappingData.getUserRolesMap());
resultMap.put(PolicyFileConstants.GROUPS, tSentryMappingData.getGroupRolesMap());
resultMap.put(PolicyFileConstants.ROLES, convertRolePrivilegesMapForPolicyFile(tSentryMappingData.getRolePrivilegesMap()));
return resultMap;
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
// convert the mapping data for [roleName,privilege] from TSentryMappingData.RolePrivilegesMap to
// map structure
private Map<String, Set<String>> convertRolePrivilegesMapForPolicyFile(
Map<String, Set<TSentryPrivilege>> rolePrivilegesMap) {
Map<String, Set<String>> rolePrivilegesMapForFile = Maps.newHashMap();
if (rolePrivilegesMap != null) {
for (Map.Entry<String, Set<TSentryPrivilege>> entry : rolePrivilegesMap.entrySet()) {
Set<TSentryPrivilege> tempSentryPrivileges = entry.getValue();
Set<String> tempStrPrivileges = Sets.newHashSet();
for (TSentryPrivilege tSentryPrivilege : tempSentryPrivileges) {
// convert TSentryPrivilege to privilege in string
String privilegeStr = SentryServiceUtil.convertTSentryPrivilegeToStr(tSentryPrivilege);
if (!StringUtils.isEmpty(privilegeStr)) {
tempStrPrivileges.add(privilegeStr);
}
}
rolePrivilegesMapForFile.put(entry.getKey(), tempStrPrivileges);
}
}
return rolePrivilegesMapForFile;
}
@Override
public void close() {
done();
}
@Override
public void done() {
if (transport != null) {
transportPool.returnTransport(transport);
transport = null;
}
}
@Override
public void invalidate() {
if (transport != null) {
transportPool.invalidateTransport(transport);
transport = null;
}
}
public long syncNotifications(long id) throws SentryUserException {
TSentrySyncIDRequest request =
new TSentrySyncIDRequest(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, id);
try {
TSentrySyncIDResponse response = client.sentry_sync_notifications(request);
Status.throwIfNotOk(response.getStatus());
return response.getId();
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
}
}