Dynamic catalog support file access control.

This commit is contained in:
zhangjingfang 2020-09-10 10:45:40 +08:00
parent 8365c8bb6c
commit f5ee87cb87
9 changed files with 84 additions and 10 deletions

View File

@ -42,7 +42,7 @@ public interface AccessControl
*/
Set<String> filterCatalogs(Identity identity, Set<String> catalogs);
/*
/**
* Check whether identity is allowed to access catalogs
*/
default void checkCanAccessCatalogs(Identity identity) {}

View File

@ -163,6 +163,14 @@ public class AccessControlManager
return systemAccessControl.get().filterCatalogs(identity, catalogs);
}
@Override
public void checkCanAccessCatalogs(Identity identity)
{
requireNonNull(identity, "identity is null");
authenticationCheck(() -> systemAccessControl.get().checkCanShowCatalogs(identity));
}
@Override
public void checkCanAccessCatalog(Identity identity, String catalogName)
{

View File

@ -193,6 +193,11 @@ public class AllowAllSystemAccessControl
{
}
@Override
public void checkCanShowCatalogs(Identity identity)
{
}
@Override
public void checkCanCreateCatalog(Identity identity, String catalogName)
{

View File

@ -38,10 +38,10 @@ public class CatalogAccessControlRule
this.catalogRegex = requireNonNull(catalogRegex, "catalogRegex is null");
}
public Optional<Boolean> match(String user, String catalog)
public Optional<Boolean> match(String user, Optional<String> catalog)
{
if (userRegex.map(regex -> regex.matcher(user).matches()).orElse(true) &&
catalogRegex.map(regex -> regex.matcher(catalog).matches()).orElse(true)) {
catalogRegex.map(regex -> regex.matcher(catalog.orElse("")).matches()).orElse(true)) {
return Optional.of(allow);
}
return Optional.empty();

View File

@ -63,19 +63,36 @@ public class FileBasedSystemAccessControl
this.principalUserMatchRules = principalUserMatchRules;
}
@Override
public void checkCanShowCatalogs(Identity identity)
{
if (!canAccessCatalog(identity)) {
denyCatalogAccess();
}
}
@Override
public void checkCanCreateCatalog(Identity identity, String catalogName)
{
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
denyCatalogAccess(catalogName);
}
}
@Override
public void checkCanDropCatalog(Identity identity, String catalogName)
{
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
denyCatalogAccess(catalogName);
}
}
@Override
public void checkCanUpdateCatalog(Identity identity, String catalogName)
{
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
denyCatalogAccess(catalogName);
}
}
@Override
@ -120,7 +137,7 @@ public class FileBasedSystemAccessControl
@Override
public void checkCanAccessCatalog(Identity identity, String catalogName)
{
if (!canAccessCatalog(identity, catalogName)) {
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
denyCatalogAccess(catalogName);
}
}
@ -130,14 +147,19 @@ public class FileBasedSystemAccessControl
{
ImmutableSet.Builder<String> filteredCatalogs = ImmutableSet.builder();
for (String catalog : catalogs) {
if (canAccessCatalog(identity, catalog)) {
if (canAccessCatalog(identity, Optional.of(catalog))) {
filteredCatalogs.add(catalog);
}
}
return filteredCatalogs.build();
}
private boolean canAccessCatalog(Identity identity, String catalogName)
private boolean canAccessCatalog(Identity identity)
{
return canAccessCatalog(identity, Optional.empty());
}
private boolean canAccessCatalog(Identity identity, Optional<String> catalogName)
{
for (CatalogAccessControlRule rule : catalogRules) {
Optional<Boolean> allowed = rule.match(identity.getUser(), catalogName);
@ -171,7 +193,7 @@ public class FileBasedSystemAccessControl
@Override
public Set<String> filterSchemas(Identity identity, String catalogName, Set<String> schemaNames)
{
if (!canAccessCatalog(identity, catalogName)) {
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
return ImmutableSet.of();
}
@ -206,7 +228,7 @@ public class FileBasedSystemAccessControl
@Override
public Set<SchemaTableName> filterTables(Identity identity, String catalogName, Set<SchemaTableName> tableNames)
{
if (!canAccessCatalog(identity, catalogName)) {
if (!canAccessCatalog(identity, Optional.of(catalogName))) {
return ImmutableSet.of();
}
@ -221,7 +243,7 @@ public class FileBasedSystemAccessControl
@Override
public List<ColumnMetadata> filterColumns(Identity identity, CatalogSchemaTableName tableName, List<ColumnMetadata> columns)
{
if (!canAccessCatalog(identity, tableName.getCatalogName())) {
if (!canAccessCatalog(identity, Optional.of(tableName.getCatalogName()))) {
return ImmutableList.of();
}

View File

@ -123,7 +123,28 @@ public class TestFileBasedSystemAccessControl
assertEquals(accessControlManager.filterCatalogs(bob, allCatalogs), bobCatalogs);
Set<String> nonAsciiUserCatalogs = ImmutableSet.of("open-to-all", "all-allowed", "\u0200\u0200\u0200");
assertEquals(accessControlManager.filterCatalogs(nonAsciiUser, allCatalogs), nonAsciiUserCatalogs);
accessControlManager.checkCanCreateCatalog(alice, "alice-catalog");
accessControlManager.checkCanDropCatalog(alice, "alice-catalog");
accessControlManager.checkCanUpdateCatalog(alice, "alice-catalog");
accessControlManager.checkCanAccessCatalog(alice, "alice-catalog");
accessControlManager.checkCanAccessCatalogs(admin);
});
assertThrows(AccessDeniedException.class, () -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanCreateCatalog(bob, "alice-catalog");
}));
assertThrows(AccessDeniedException.class, () -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanDropCatalog(bob, "alice-catalog");
}));
assertThrows(AccessDeniedException.class, () -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanUpdateCatalog(bob, "alice-catalog");
}));
assertThrows(AccessDeniedException.class, () -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanAccessCatalog(bob, "alice-catalog");
}));
assertThrows(AccessDeniedException.class, () -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanAccessCatalogs(bob);
}));
}
@Test

View File

@ -72,6 +72,12 @@ public abstract class ForwardingSystemAccessControl
return delegate().filterCatalogs(identity, catalogs);
}
@Override
public void checkCanShowCatalogs(Identity identity)
{
delegate().checkCanShowCatalogs(identity);
}
@Override
public void checkCanCreateCatalog(Identity identity, String catalogName)
{

View File

@ -41,6 +41,11 @@ public class AccessDeniedException
throw new AccessDeniedException(format("Principal %s cannot become user %s%s", principal.orElse(null), userName, formatExtraInfo(extraInfo)));
}
public static void denyCatalogAccess()
{
denyCatalogAccess(null);
}
public static void denyCatalogAccess(String catalogName)
{
denyCatalogAccess(catalogName, null);
@ -48,7 +53,7 @@ public class AccessDeniedException
public static void denyCatalogAccess(String catalogName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot access catalog %s%s", catalogName, formatExtraInfo(extraInfo)));
throw new AccessDeniedException(format("Cannot access catalog %s%s", catalogName == null ? "" : catalogName, formatExtraInfo(extraInfo)));
}
public static void denyCreateSchema(String schemaName)

View File

@ -83,6 +83,13 @@ public interface SystemAccessControl
return Collections.emptySet();
}
/**
* Check whether identity is can show catalogs
*
* @throws AccessDeniedException if not allowed
*/
default void checkCanShowCatalogs(Identity identity) {}
/**
* Check whether identity is can create a catalog
*