diff --git a/presto-main-base/src/main/java/com/facebook/presto/security/AccessControlManager.java b/presto-main-base/src/main/java/com/facebook/presto/security/AccessControlManager.java index 16b7ba6267406..0b87c68bf3c9f 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/security/AccessControlManager.java +++ b/presto-main-base/src/main/java/com/facebook/presto/security/AccessControlManager.java @@ -56,7 +56,6 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import static com.facebook.presto.metadata.MetadataUtil.toSchemaTableName; import static com.facebook.presto.spi.StandardErrorCode.INVALID_COLUMN_MASK; @@ -80,13 +79,14 @@ public class AccessControlManager private final Map systemAccessControlFactories = new ConcurrentHashMap<>(); private final Map connectorAccessControl = new ConcurrentHashMap<>(); - private final AtomicReference systemAccessControl = new AtomicReference<>(new InitializingSystemAccessControl()); + private final StatsRecordingSystemAccessControl systemAccessControl = new StatsRecordingSystemAccessControl(new InitializingSystemAccessControl()); private final AtomicBoolean systemAccessControlLoading = new AtomicBoolean(); private final CounterStat authenticationSuccess = new CounterStat(); private final CounterStat authenticationFail = new CounterStat(); private final CounterStat authorizationSuccess = new CounterStat(); private final CounterStat authorizationFail = new CounterStat(); + private StatsRecordingSystemAccessControl.Stats detailedStats = new StatsRecordingSystemAccessControl.Stats(); @Inject public AccessControlManager(TransactionManager transactionManager) @@ -159,8 +159,7 @@ protected void setSystemAccessControl(String name, Map propertie SystemAccessControlFactory systemAccessControlFactory = systemAccessControlFactories.get(name); checkState(systemAccessControlFactory != null, "Access control %s is not registered", name); - SystemAccessControl systemAccessControl = systemAccessControlFactory.create(ImmutableMap.copyOf(properties)); - this.systemAccessControl.set(systemAccessControl); + systemAccessControl.updateDelegate(systemAccessControlFactory.create(ImmutableMap.copyOf(properties))); log.info("-- Loaded system access control %s --", name); } @@ -171,7 +170,7 @@ public void checkCanSetUser(Identity identity, AccessControlContext context, Opt requireNonNull(principal, "principal is null"); requireNonNull(userName, "userName is null"); - authenticationCheck(() -> systemAccessControl.get().checkCanSetUser(identity, context, principal, userName)); + authenticationCheck(() -> systemAccessControl.checkCanSetUser(identity, context, principal, userName)); } @Override @@ -180,7 +179,7 @@ public AuthorizedIdentity selectAuthorizedIdentity(Identity identity, AccessCont requireNonNull(userName, "userName is null"); requireNonNull(certificates, "certificates is null"); - return systemAccessControl.get().selectAuthorizedIdentity(identity, context, userName, certificates); + return systemAccessControl.selectAuthorizedIdentity(identity, context, userName, certificates); } @Override @@ -189,7 +188,7 @@ public void checkQueryIntegrity(Identity identity, AccessControlContext context, requireNonNull(identity, "identity is null"); requireNonNull(query, "query is null"); - authenticationCheck(() -> systemAccessControl.get().checkQueryIntegrity(identity, context, query, viewDefinitions, materializedViewDefinitions)); + authenticationCheck(() -> systemAccessControl.checkQueryIntegrity(identity, context, query, viewDefinitions, materializedViewDefinitions)); } @Override @@ -198,7 +197,7 @@ public Set filterCatalogs(Identity identity, AccessControlContext contex requireNonNull(identity, "identity is null"); requireNonNull(catalogs, "catalogs is null"); - return systemAccessControl.get().filterCatalogs(identity, context, catalogs); + return systemAccessControl.filterCatalogs(identity, context, catalogs); } @Override @@ -207,7 +206,7 @@ public void checkCanAccessCatalog(Identity identity, AccessControlContext contex requireNonNull(identity, "identity is null"); requireNonNull(catalogName, "catalog is null"); - authenticationCheck(() -> systemAccessControl.get().checkCanAccessCatalog(identity, context, catalogName)); + authenticationCheck(() -> systemAccessControl.checkCanAccessCatalog(identity, context, catalogName)); } @Override @@ -218,7 +217,7 @@ public void checkCanCreateSchema(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, schemaName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanCreateSchema(identity, context, schemaName)); + authorizationCheck(() -> systemAccessControl.checkCanCreateSchema(identity, context, schemaName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, schemaName.getCatalogName()); if (entry != null) { @@ -234,7 +233,7 @@ public void checkCanDropSchema(TransactionId transactionId, Identity identity, A authenticationCheck(() -> checkCanAccessCatalog(identity, context, schemaName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDropSchema(identity, context, schemaName)); + authorizationCheck(() -> systemAccessControl.checkCanDropSchema(identity, context, schemaName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, schemaName.getCatalogName()); if (entry != null) { @@ -250,7 +249,7 @@ public void checkCanRenameSchema(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, schemaName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanRenameSchema(identity, context, schemaName, newSchemaName)); + authorizationCheck(() -> systemAccessControl.checkCanRenameSchema(identity, context, schemaName, newSchemaName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, schemaName.getCatalogName()); if (entry != null) { @@ -266,7 +265,7 @@ public void checkCanShowSchemas(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, catalogName)); - authorizationCheck(() -> systemAccessControl.get().checkCanShowSchemas(identity, context, catalogName)); + authorizationCheck(() -> systemAccessControl.checkCanShowSchemas(identity, context, catalogName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, catalogName); if (entry != null) { @@ -285,7 +284,7 @@ public Set filterSchemas(TransactionId transactionId, Identity identity, return ImmutableSet.of(); } - schemaNames = systemAccessControl.get().filterSchemas(identity, context, catalogName, schemaNames); + schemaNames = systemAccessControl.filterSchemas(identity, context, catalogName, schemaNames); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, catalogName); if (entry != null) { @@ -302,7 +301,7 @@ public void checkCanShowCreateTable(TransactionId transactionId, Identity identi authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanShowCreateTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanShowCreateTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -318,7 +317,7 @@ public void checkCanCreateTable(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanCreateTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanCreateTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -334,7 +333,7 @@ public void checkCanDropTable(TransactionId transactionId, Identity identity, Ac authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDropTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanDropTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -351,7 +350,7 @@ public void checkCanRenameTable(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanRenameTable(identity, context, toCatalogSchemaTableName(tableName), toCatalogSchemaTableName(newTableName))); + authorizationCheck(() -> systemAccessControl.checkCanRenameTable(identity, context, toCatalogSchemaTableName(tableName), toCatalogSchemaTableName(newTableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -365,7 +364,7 @@ public void checkCanSetTableProperties(TransactionId transactionId, Identity ide requireNonNull(identity, "identity is null"); requireNonNull(tableName, "tableName is null"); authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanSetTableProperties(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanSetTableProperties(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { authorizationCheck(() -> entry.getAccessControl().checkCanSetTableProperties(entry.getTransactionHandle(transactionId), identity.toConnectorIdentity(tableName.getCatalogName()), context, toSchemaTableName(tableName), properties)); @@ -380,7 +379,7 @@ public void checkCanShowTablesMetadata(TransactionId transactionId, Identity ide authenticationCheck(() -> checkCanAccessCatalog(identity, context, schema.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanShowTablesMetadata(identity, context, schema)); + authorizationCheck(() -> systemAccessControl.checkCanShowTablesMetadata(identity, context, schema)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, schema.getCatalogName()); if (entry != null) { @@ -399,7 +398,7 @@ public Set filterTables(TransactionId transactionId, Identity i return ImmutableSet.of(); } - tableNames = systemAccessControl.get().filterTables(identity, context, catalogName, tableNames); + tableNames = systemAccessControl.filterTables(identity, context, catalogName, tableNames); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, catalogName); if (entry != null) { @@ -418,7 +417,7 @@ public void checkCanShowColumnsMetadata(TransactionId transactionId, Identity id authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanShowColumnsMetadata(identity, context, catalogSchemaTableName)); + authorizationCheck(() -> systemAccessControl.checkCanShowColumnsMetadata(identity, context, catalogSchemaTableName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -439,7 +438,7 @@ public List filterColumns(TransactionId transactionId, Identity return ImmutableList.of(); } - columns = systemAccessControl.get().filterColumns(identity, context, toCatalogSchemaTableName(tableName), columns); + columns = systemAccessControl.filterColumns(identity, context, toCatalogSchemaTableName(tableName), columns); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -456,7 +455,7 @@ public void checkCanAddColumns(TransactionId transactionId, Identity identity, A authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanAddColumn(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanAddColumn(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -472,7 +471,7 @@ public void checkCanDropColumn(TransactionId transactionId, Identity identity, A authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDropColumn(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanDropColumn(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -488,7 +487,7 @@ public void checkCanRenameColumn(TransactionId transactionId, Identity identity, authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanRenameColumn(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanRenameColumn(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -504,7 +503,7 @@ public void checkCanInsertIntoTable(TransactionId transactionId, Identity identi authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanInsertIntoTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanInsertIntoTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -520,7 +519,7 @@ public void checkCanDeleteFromTable(TransactionId transactionId, Identity identi authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDeleteFromTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanDeleteFromTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -536,7 +535,7 @@ public void checkCanTruncateTable(TransactionId transactionId, Identity identity authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanTruncateTable(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanTruncateTable(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -552,7 +551,7 @@ public void checkCanUpdateTableColumns(TransactionId transactionId, Identity ide authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanUpdateTableColumns(identity, context, toCatalogSchemaTableName(tableName), updatedColumnNames)); + authorizationCheck(() -> systemAccessControl.checkCanUpdateTableColumns(identity, context, toCatalogSchemaTableName(tableName), updatedColumnNames)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -568,7 +567,7 @@ public void checkCanCreateView(TransactionId transactionId, Identity identity, A authenticationCheck(() -> checkCanAccessCatalog(identity, context, viewName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanCreateView(identity, context, toCatalogSchemaTableName(viewName))); + authorizationCheck(() -> systemAccessControl.checkCanCreateView(identity, context, toCatalogSchemaTableName(viewName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, viewName.getCatalogName()); if (entry != null) { @@ -585,7 +584,7 @@ public void checkCanRenameView(TransactionId transactionId, Identity identity, A authenticationCheck(() -> checkCanAccessCatalog(identity, context, viewName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanRenameView(identity, context, toCatalogSchemaTableName(viewName), toCatalogSchemaTableName(newViewName))); + authorizationCheck(() -> systemAccessControl.checkCanRenameView(identity, context, toCatalogSchemaTableName(viewName), toCatalogSchemaTableName(newViewName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, viewName.getCatalogName()); if (entry != null) { @@ -601,7 +600,7 @@ public void checkCanDropView(TransactionId transactionId, Identity identity, Acc authenticationCheck(() -> checkCanAccessCatalog(identity, context, viewName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDropView(identity, context, toCatalogSchemaTableName(viewName))); + authorizationCheck(() -> systemAccessControl.checkCanDropView(identity, context, toCatalogSchemaTableName(viewName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, viewName.getCatalogName()); if (entry != null) { @@ -617,7 +616,7 @@ public void checkCanCreateViewWithSelectFromColumns(TransactionId transactionId, authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanCreateViewWithSelectFromColumns(identity, context, toCatalogSchemaTableName(tableName), columnNames)); + authorizationCheck(() -> systemAccessControl.checkCanCreateViewWithSelectFromColumns(identity, context, toCatalogSchemaTableName(tableName), columnNames)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -634,7 +633,7 @@ public void checkCanGrantTablePrivilege(TransactionId transactionId, Identity id authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanGrantTablePrivilege(identity, context, privilege, toCatalogSchemaTableName(tableName), grantee, withGrantOption)); + authorizationCheck(() -> systemAccessControl.checkCanGrantTablePrivilege(identity, context, privilege, toCatalogSchemaTableName(tableName), grantee, withGrantOption)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -651,7 +650,7 @@ public void checkCanRevokeTablePrivilege(TransactionId transactionId, Identity i authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanRevokeTablePrivilege(identity, context, privilege, toCatalogSchemaTableName(tableName), revokee, grantOptionFor)); + authorizationCheck(() -> systemAccessControl.checkCanRevokeTablePrivilege(identity, context, privilege, toCatalogSchemaTableName(tableName), revokee, grantOptionFor)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -665,7 +664,7 @@ public void checkCanSetSystemSessionProperty(Identity identity, AccessControlCon requireNonNull(identity, "identity is null"); requireNonNull(propertyName, "propertyName is null"); - authorizationCheck(() -> systemAccessControl.get().checkCanSetSystemSessionProperty(identity, context, propertyName)); + authorizationCheck(() -> systemAccessControl.checkCanSetSystemSessionProperty(identity, context, propertyName)); } @Override @@ -677,7 +676,7 @@ public void checkCanSetCatalogSessionProperty(TransactionId transactionId, Ident authenticationCheck(() -> checkCanAccessCatalog(identity, context, catalogName)); - authorizationCheck(() -> systemAccessControl.get().checkCanSetCatalogSessionProperty(identity, context, catalogName, propertyName)); + authorizationCheck(() -> systemAccessControl.checkCanSetCatalogSessionProperty(identity, context, catalogName, propertyName)); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, catalogName); if (entry != null) { @@ -694,7 +693,7 @@ public void checkCanSelectFromColumns(TransactionId transactionId, Identity iden authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanSelectFromColumns( + authorizationCheck(() -> systemAccessControl.checkCanSelectFromColumns( identity, context, toCatalogSchemaTableName(tableName), @@ -836,7 +835,7 @@ public void checkCanDropConstraint(TransactionId transactionId, Identity identit authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanDropConstraint(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanDropConstraint(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -852,7 +851,7 @@ public void checkCanAddConstraints(TransactionId transactionId, Identity identit authenticationCheck(() -> checkCanAccessCatalog(identity, context, tableName.getCatalogName())); - authorizationCheck(() -> systemAccessControl.get().checkCanAddConstraint(identity, context, toCatalogSchemaTableName(tableName))); + authorizationCheck(() -> systemAccessControl.checkCanAddConstraint(identity, context, toCatalogSchemaTableName(tableName))); CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, tableName.getCatalogName()); if (entry != null) { @@ -874,7 +873,7 @@ public List getRowFilters(TransactionId transactionId, Identity .forEach(filters::add); } - systemAccessControl.get().getRowFilters(identity, context, toCatalogSchemaTableName(tableName)) + systemAccessControl.getRowFilters(identity, context, toCatalogSchemaTableName(tableName)) .forEach(filters::add); return filters.build(); @@ -897,7 +896,7 @@ public Map getColumnMasks(TransactionId transact columnMasksBuilder.putAll(connectorMasks); } - Map systemMasks = systemAccessControl.get().getColumnMasks(identity, context, toCatalogSchemaTableName(tableName), columns); + Map systemMasks = systemAccessControl.getColumnMasks(identity, context, toCatalogSchemaTableName(tableName), columns); columnMasksBuilder.putAll(systemMasks); try { @@ -943,6 +942,13 @@ public CounterStat getAuthorizationFail() return authorizationFail; } + @Managed + @Nested + public StatsRecordingSystemAccessControl.Stats getDetailedStats() + { + return systemAccessControl.getStats(); + } + private void authenticationCheck(Runnable runnable) { try { diff --git a/presto-main-base/src/main/java/com/facebook/presto/security/StatsRecordingSystemAccessControl.java b/presto-main-base/src/main/java/com/facebook/presto/security/StatsRecordingSystemAccessControl.java new file mode 100644 index 0000000000000..6d408afc4bec8 --- /dev/null +++ b/presto-main-base/src/main/java/com/facebook/presto/security/StatsRecordingSystemAccessControl.java @@ -0,0 +1,1082 @@ +/* + * Licensed 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 com.facebook.presto.security; + +import com.facebook.presto.common.CatalogSchemaName; +import com.facebook.presto.common.QualifiedObjectName; +import com.facebook.presto.common.RuntimeUnit; +import com.facebook.presto.spi.CatalogSchemaTableName; +import com.facebook.presto.spi.ColumnMetadata; +import com.facebook.presto.spi.MaterializedViewDefinition; +import com.facebook.presto.spi.SchemaTableName; +import com.facebook.presto.spi.analyzer.ViewDefinition; +import com.facebook.presto.spi.security.AccessControlContext; +import com.facebook.presto.spi.security.AuthorizedIdentity; +import com.facebook.presto.spi.security.Identity; +import com.facebook.presto.spi.security.PrestoPrincipal; +import com.facebook.presto.spi.security.Privilege; +import com.facebook.presto.spi.security.SystemAccessControl; +import com.facebook.presto.spi.security.ViewExpression; +import org.weakref.jmx.Managed; +import org.weakref.jmx.Nested; + +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import static java.util.Objects.requireNonNull; + +public final class StatsRecordingSystemAccessControl + implements SystemAccessControl +{ + private final Stats stats = new Stats(); + private final AtomicReference delegate = new AtomicReference<>(); + + public StatsRecordingSystemAccessControl(SystemAccessControl delegate) + { + updateDelegate(delegate); + } + + public void updateDelegate(SystemAccessControl delegate) + { + this.delegate.set(requireNonNull(delegate, "delegate is null")); + } + + public Stats getStats() + { + return stats; + } + + @Override + public void checkCanSetUser(Identity identity, AccessControlContext context, Optional principal, String userName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanSetUser(identity, context, principal, userName); + } + catch (RuntimeException e) { + stats.checkCanSetUser.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanSetUser", RuntimeUnit.NANO, duration); + stats.checkCanSetUser.record(duration); + } + } + + @Override + public AuthorizedIdentity selectAuthorizedIdentity(Identity identity, AccessControlContext context, String userName, List certificates) + { + long start = System.nanoTime(); + try { + return delegate.get().selectAuthorizedIdentity(identity, context, userName, certificates); + } + catch (RuntimeException e) { + stats.selectAuthorizedIdentity.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.selectAuthorizedIdentity", RuntimeUnit.NANO, duration); + stats.selectAuthorizedIdentity.record(duration); + } + } + + @Override + public void checkQueryIntegrity(Identity identity, AccessControlContext context, String query, Map viewDefinitions, Map materializedViewDefinitions) + { + long start = System.nanoTime(); + try { + delegate.get().checkQueryIntegrity(identity, context, query, viewDefinitions, materializedViewDefinitions); + } + catch (RuntimeException e) { + stats.checkQueryIntegrity.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkQueryIntegrity", RuntimeUnit.NANO, duration); + stats.checkQueryIntegrity.record(duration); + } + } + + @Override + public void checkCanSetSystemSessionProperty(Identity identity, AccessControlContext context, String propertyName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanSetSystemSessionProperty(identity, context, propertyName); + } + catch (RuntimeException e) { + stats.checkCanSetSystemSessionProperty.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanSetSystemSessionProperty", RuntimeUnit.NANO, duration); + stats.checkCanSetSystemSessionProperty.record(duration); + } + } + + @Override + public void checkCanAccessCatalog(Identity identity, AccessControlContext context, String catalogName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanAccessCatalog(identity, context, catalogName); + } + catch (RuntimeException e) { + stats.checkCanAccessCatalog.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanAccessCatalog", RuntimeUnit.NANO, duration); + stats.checkCanAccessCatalog.record(duration); + } + } + + @Override + public Set filterCatalogs(Identity identity, AccessControlContext context, Set catalogs) + { + long start = System.nanoTime(); + try { + return delegate.get().filterCatalogs(identity, context, catalogs); + } + catch (RuntimeException e) { + stats.filterCatalogs.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.filterCatalogs", RuntimeUnit.NANO, duration); + stats.filterCatalogs.record(duration); + } + } + + @Override + public void checkCanCreateSchema(Identity identity, AccessControlContext context, CatalogSchemaName schema) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanCreateSchema(identity, context, schema); + } + catch (RuntimeException e) { + stats.checkCanCreateSchema.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanCreateSchema", RuntimeUnit.NANO, duration); + stats.checkCanCreateSchema.record(duration); + } + } + + @Override + public void checkCanDropSchema(Identity identity, AccessControlContext context, CatalogSchemaName schema) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDropSchema(identity, context, schema); + } + catch (RuntimeException e) { + stats.checkCanDropSchema.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDropSchema", RuntimeUnit.NANO, duration); + stats.checkCanDropSchema.record(duration); + } + } + + @Override + public void checkCanRenameSchema(Identity identity, AccessControlContext context, CatalogSchemaName schema, String newSchemaName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanRenameSchema(identity, context, schema, newSchemaName); + } + catch (RuntimeException e) { + stats.checkCanRenameSchema.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanRenameSchema", RuntimeUnit.NANO, duration); + stats.checkCanRenameSchema.record(duration); + } + } + + @Override + public void checkCanShowSchemas(Identity identity, AccessControlContext context, String catalogName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanShowSchemas(identity, context, catalogName); + } + catch (RuntimeException e) { + stats.checkCanShowSchemas.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanShowSchemas", RuntimeUnit.NANO, duration); + stats.checkCanShowSchemas.record(duration); + } + } + + @Override + public Set filterSchemas(Identity identity, AccessControlContext context, String catalogName, Set schemaNames) + { + long start = System.nanoTime(); + try { + return delegate.get().filterSchemas(identity, context, catalogName, schemaNames); + } + catch (RuntimeException e) { + stats.filterSchemas.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.filterSchemas", RuntimeUnit.NANO, duration); + stats.filterSchemas.record(duration); + } + } + + @Override + public void checkCanShowCreateTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanShowCreateTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanShowCreateTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanShowCreateTable", RuntimeUnit.NANO, duration); + stats.checkCanShowCreateTable.record(duration); + } + } + + @Override + public void checkCanCreateTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanCreateTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanCreateTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanCreateTable", RuntimeUnit.NANO, duration); + stats.checkCanCreateTable.record(duration); + } + } + + @Override + public void checkCanSetTableProperties(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanSetTableProperties(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanSetTableProperties.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanSetTableProperties", RuntimeUnit.NANO, duration); + stats.checkCanSetTableProperties.record(duration); + } + } + + @Override + public void checkCanDropTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDropTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanDropTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDropTable", RuntimeUnit.NANO, duration); + stats.checkCanDropTable.record(duration); + } + } + + @Override + public void checkCanRenameTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table, CatalogSchemaTableName newTable) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanRenameTable(identity, context, table, newTable); + } + catch (RuntimeException e) { + stats.checkCanRenameTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanRenameTable", RuntimeUnit.NANO, duration); + stats.checkCanRenameTable.record(duration); + } + } + + @Override + public void checkCanShowTablesMetadata(Identity identity, AccessControlContext context, CatalogSchemaName schema) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanShowTablesMetadata(identity, context, schema); + } + catch (RuntimeException e) { + stats.checkCanShowTablesMetadata.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanShowTablesMetadata", RuntimeUnit.NANO, duration); + stats.checkCanShowTablesMetadata.record(duration); + } + } + + @Override + public Set filterTables(Identity identity, AccessControlContext context, String catalogName, Set tableNames) + { + long start = System.nanoTime(); + try { + return delegate.get().filterTables(identity, context, catalogName, tableNames); + } + catch (RuntimeException e) { + stats.filterTables.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.filterTables", RuntimeUnit.NANO, duration); + stats.filterTables.record(duration); + } + } + + @Override + public void checkCanShowColumnsMetadata(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanShowColumnsMetadata(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanShowColumnsMetadata.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanShowColumnsMetadata", RuntimeUnit.NANO, duration); + stats.checkCanShowColumnsMetadata.record(duration); + } + } + + @Override + public List filterColumns(Identity identity, AccessControlContext context, CatalogSchemaTableName table, List columns) + { + long start = System.nanoTime(); + try { + return delegate.get().filterColumns(identity, context, table, columns); + } + catch (RuntimeException e) { + stats.filterColumns.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.filterColumns", RuntimeUnit.NANO, duration); + stats.filterColumns.record(duration); + } + } + + @Override + public void checkCanAddColumn(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanAddColumn(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanAddColumn.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanAddColumn", RuntimeUnit.NANO, duration); + stats.checkCanAddColumn.record(duration); + } + } + + @Override + public void checkCanDropColumn(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDropColumn(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanDropColumn.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDropColumn", RuntimeUnit.NANO, duration); + stats.checkCanDropColumn.record(duration); + } + } + + @Override + public void checkCanRenameColumn(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanRenameColumn(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanRenameColumn.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanRenameColumn", RuntimeUnit.NANO, duration); + stats.checkCanRenameColumn.record(duration); + } + } + + @Override + public void checkCanSelectFromColumns(Identity identity, AccessControlContext context, CatalogSchemaTableName table, Set columns) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanSelectFromColumns(identity, context, table, columns); + } + catch (RuntimeException e) { + stats.checkCanSelectFromColumns.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanSelectFromColumns", RuntimeUnit.NANO, duration); + stats.checkCanSelectFromColumns.record(duration); + } + } + + @Override + public void checkCanInsertIntoTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanInsertIntoTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanInsertIntoTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanInsertIntoTable", RuntimeUnit.NANO, duration); + stats.checkCanInsertIntoTable.record(duration); + } + } + + @Override + public void checkCanDeleteFromTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDeleteFromTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanDeleteFromTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDeleteFromTable", RuntimeUnit.NANO, duration); + stats.checkCanDeleteFromTable.record(duration); + } + } + + @Override + public void checkCanTruncateTable(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanTruncateTable(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanTruncateTable.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanTruncateTable", RuntimeUnit.NANO, duration); + stats.checkCanTruncateTable.record(duration); + } + } + + @Override + public void checkCanUpdateTableColumns(Identity identity, AccessControlContext context, CatalogSchemaTableName table, Set updatedColumnNames) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanUpdateTableColumns(identity, context, table, updatedColumnNames); + } + catch (RuntimeException e) { + stats.checkCanUpdateTableColumns.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanUpdateTableColumns", RuntimeUnit.NANO, duration); + stats.checkCanUpdateTableColumns.record(duration); + } + } + + @Override + public void checkCanCreateView(Identity identity, AccessControlContext context, CatalogSchemaTableName view) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanCreateView(identity, context, view); + } + catch (RuntimeException e) { + stats.checkCanCreateView.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanCreateView", RuntimeUnit.NANO, duration); + stats.checkCanCreateView.record(duration); + } + } + + @Override + public void checkCanRenameView(Identity identity, AccessControlContext context, CatalogSchemaTableName view, CatalogSchemaTableName newView) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanRenameView(identity, context, view, newView); + } + catch (RuntimeException e) { + stats.checkCanRenameView.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanRenameView", RuntimeUnit.NANO, duration); + stats.checkCanRenameView.record(duration); + } + } + + @Override + public void checkCanDropView(Identity identity, AccessControlContext context, CatalogSchemaTableName view) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDropView(identity, context, view); + } + catch (RuntimeException e) { + stats.checkCanDropView.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDropView", RuntimeUnit.NANO, duration); + stats.checkCanDropView.record(duration); + } + } + + @Override + public void checkCanCreateViewWithSelectFromColumns(Identity identity, AccessControlContext context, CatalogSchemaTableName table, Set columns) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanCreateViewWithSelectFromColumns(identity, context, table, columns); + } + catch (RuntimeException e) { + stats.checkCanCreateViewWithSelectFromColumns.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanCreateViewWithSelectFromColumns", RuntimeUnit.NANO, duration); + stats.checkCanCreateViewWithSelectFromColumns.record(duration); + } + } + + @Override + public void checkCanSetCatalogSessionProperty(Identity identity, AccessControlContext context, String catalogName, String propertyName) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanSetCatalogSessionProperty(identity, context, catalogName, propertyName); + } + catch (RuntimeException e) { + stats.checkCanSetCatalogSessionProperty.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanSetCatalogSessionProperty", RuntimeUnit.NANO, duration); + stats.checkCanSetCatalogSessionProperty.record(duration); + } + } + + @Override + public void checkCanGrantTablePrivilege(Identity identity, AccessControlContext context, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal grantee, boolean withGrantOption) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanGrantTablePrivilege(identity, context, privilege, table, grantee, withGrantOption); + } + catch (RuntimeException e) { + stats.checkCanGrantTablePrivilege.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanGrantTablePrivilege", RuntimeUnit.NANO, duration); + stats.checkCanGrantTablePrivilege.record(duration); + } + } + + @Override + public void checkCanRevokeTablePrivilege(Identity identity, AccessControlContext context, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal revokee, boolean grantOptionFor) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanRevokeTablePrivilege(identity, context, privilege, table, revokee, grantOptionFor); + } + catch (RuntimeException e) { + stats.checkCanRevokeTablePrivilege.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanRevokeTablePrivilege", RuntimeUnit.NANO, duration); + stats.checkCanRevokeTablePrivilege.record(duration); + } + } + + @Override + public void checkCanDropConstraint(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanDropConstraint(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanDropConstraint.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanDropConstraint", RuntimeUnit.NANO, duration); + stats.checkCanDropConstraint.record(duration); + } + } + + @Override + public void checkCanAddConstraint(Identity identity, AccessControlContext context, CatalogSchemaTableName table) + { + long start = System.nanoTime(); + try { + delegate.get().checkCanAddConstraint(identity, context, table); + } + catch (RuntimeException e) { + stats.checkCanAddConstraint.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.checkCanAddConstraint", RuntimeUnit.NANO, duration); + stats.checkCanAddConstraint.record(duration); + } + } + + @Override + public List getRowFilters(Identity identity, AccessControlContext context, CatalogSchemaTableName tableName) + { + long start = System.nanoTime(); + try { + return delegate.get().getRowFilters(identity, context, tableName); + } + catch (RuntimeException e) { + stats.getRowFilters.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.getRowFilters", RuntimeUnit.NANO, duration); + stats.getRowFilters.record(duration); + } + } + + @Override + public Map getColumnMasks(Identity identity, AccessControlContext context, CatalogSchemaTableName tableName, List columns) + { + long start = System.nanoTime(); + try { + return delegate.get().getColumnMasks(identity, context, tableName, columns); + } + catch (RuntimeException e) { + stats.getColumnMasks.recordFailure(); + throw e; + } + finally { + long duration = System.nanoTime() - start; + context.getRuntimeStats().addMetricValue("systemAccessControl.getColumnMasks", RuntimeUnit.NANO, duration); + stats.getColumnMasks.record(duration); + } + } + + public static class Stats + { + final SystemAccessControlStats checkCanSetUser = new SystemAccessControlStats(); + final SystemAccessControlStats selectAuthorizedIdentity = new SystemAccessControlStats(); + final SystemAccessControlStats checkQueryIntegrity = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanSetSystemSessionProperty = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanAccessCatalog = new SystemAccessControlStats(); + final SystemAccessControlStats filterCatalogs = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanCreateSchema = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDropSchema = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanRenameSchema = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanShowSchemas = new SystemAccessControlStats(); + final SystemAccessControlStats filterSchemas = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanShowCreateTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanCreateTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanSetTableProperties = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDropTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanRenameTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanShowTablesMetadata = new SystemAccessControlStats(); + final SystemAccessControlStats filterTables = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanShowColumnsMetadata = new SystemAccessControlStats(); + final SystemAccessControlStats filterColumns = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanAddColumn = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDropColumn = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanRenameColumn = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanSelectFromColumns = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanInsertIntoTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDeleteFromTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanTruncateTable = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanUpdateTableColumns = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanCreateView = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanRenameView = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDropView = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanCreateViewWithSelectFromColumns = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanSetCatalogSessionProperty = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanGrantTablePrivilege = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanRevokeTablePrivilege = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanDropConstraint = new SystemAccessControlStats(); + final SystemAccessControlStats checkCanAddConstraint = new SystemAccessControlStats(); + final SystemAccessControlStats getRowFilters = new SystemAccessControlStats(); + final SystemAccessControlStats getColumnMasks = new SystemAccessControlStats(); + + @Managed + @Nested + public SystemAccessControlStats getCheckCanSetUser() + { + return checkCanSetUser; + } + + @Managed + @Nested + public SystemAccessControlStats getSelectAuthorizedIdentity() + { + return selectAuthorizedIdentity; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckQueryIntegrity() + { + return checkQueryIntegrity; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanSetSystemSessionProperty() + { + return checkCanSetSystemSessionProperty; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanAccessCatalog() + { + return checkCanAccessCatalog; + } + + @Managed + @Nested + public SystemAccessControlStats getFilterCatalogs() + { + return filterCatalogs; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanCreateSchema() + { + return checkCanCreateSchema; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDropSchema() + { + return checkCanDropSchema; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanRenameSchema() + { + return checkCanRenameSchema; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanShowSchemas() + { + return checkCanShowSchemas; + } + + @Managed + @Nested + public SystemAccessControlStats getFilterSchemas() + { + return filterSchemas; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanShowCreateTable() + { + return checkCanShowCreateTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanCreateTable() + { + return checkCanCreateTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanSetTableProperties() + { + return checkCanSetTableProperties; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDropTable() + { + return checkCanDropTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanRenameTable() + { + return checkCanRenameTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanShowTablesMetadata() + { + return checkCanShowTablesMetadata; + } + + @Managed + @Nested + public SystemAccessControlStats getFilterTables() + { + return filterTables; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanShowColumnsMetadata() + { + return checkCanShowColumnsMetadata; + } + + @Managed + @Nested + public SystemAccessControlStats getFilterColumns() + { + return filterColumns; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanAddColumn() + { + return checkCanAddColumn; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDropColumn() + { + return checkCanDropColumn; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanRenameColumn() + { + return checkCanRenameColumn; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanSelectFromColumns() + { + return checkCanSelectFromColumns; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanInsertIntoTable() + { + return checkCanInsertIntoTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDeleteFromTable() + { + return checkCanDeleteFromTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanTruncateTable() + { + return checkCanTruncateTable; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanUpdateTableColumns() + { + return checkCanUpdateTableColumns; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanCreateView() + { + return checkCanCreateView; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanRenameView() + { + return checkCanRenameView; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDropView() + { + return checkCanDropView; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanCreateViewWithSelectFromColumns() + { + return checkCanCreateViewWithSelectFromColumns; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanSetCatalogSessionProperty() + { + return checkCanSetCatalogSessionProperty; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanGrantTablePrivilege() + { + return checkCanGrantTablePrivilege; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanRevokeTablePrivilege() + { + return checkCanRevokeTablePrivilege; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanDropConstraint() + { + return checkCanDropConstraint; + } + + @Managed + @Nested + public SystemAccessControlStats getCheckCanAddConstraint() + { + return checkCanAddConstraint; + } + + @Managed + @Nested + public SystemAccessControlStats getGetRowFilters() + { + return getRowFilters; + } + + @Managed + @Nested + public SystemAccessControlStats getGetColumnMasks() + { + return getColumnMasks; + } + } +} diff --git a/presto-main-base/src/main/java/com/facebook/presto/security/SystemAccessControlStats.java b/presto-main-base/src/main/java/com/facebook/presto/security/SystemAccessControlStats.java new file mode 100644 index 0000000000000..95babfbb9e80d --- /dev/null +++ b/presto-main-base/src/main/java/com/facebook/presto/security/SystemAccessControlStats.java @@ -0,0 +1,52 @@ +/* + * Licensed 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 com.facebook.presto.security; + +import com.facebook.airlift.stats.CounterStat; +import com.facebook.airlift.stats.TimeStat; +import org.weakref.jmx.Managed; +import org.weakref.jmx.Nested; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +public class SystemAccessControlStats +{ + private final CounterStat failures = new CounterStat(); + private final TimeStat time = new TimeStat(MICROSECONDS); + + public void record(long nanos) + { + time.add(nanos, NANOSECONDS); + } + + public void recordFailure() + { + failures.update(1); + } + + @Managed + @Nested + public TimeStat getTime() + { + return time; + } + + @Managed + @Nested + public CounterStat getFailures() + { + return failures; + } +} diff --git a/presto-main-base/src/test/java/com/facebook/presto/security/TestStatsRecordingSystemAccessControl.java b/presto-main-base/src/test/java/com/facebook/presto/security/TestStatsRecordingSystemAccessControl.java new file mode 100644 index 0000000000000..70b1109c71b3c --- /dev/null +++ b/presto-main-base/src/test/java/com/facebook/presto/security/TestStatsRecordingSystemAccessControl.java @@ -0,0 +1,51 @@ +/* + * Licensed 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 com.facebook.presto.security; + +import com.facebook.presto.common.RuntimeStats; +import com.facebook.presto.spi.QueryId; +import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.security.AccessControlContext; +import com.facebook.presto.spi.security.SystemAccessControl; +import org.testng.annotations.Test; + +import java.util.Collections; +import java.util.Optional; + +import static com.facebook.presto.spi.testing.InterfaceTestUtils.assertAllMethodsOverridden; +import static org.testng.Assert.assertEquals; + +public class TestStatsRecordingSystemAccessControl +{ + public static final AccessControlContext CONTEXT = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); + + @Test + public void testEverythingDelegated() + { + assertAllMethodsOverridden(SystemAccessControl.class, StatsRecordingSystemAccessControl.class); + } + + @Test + public void testStatsRecording() + { + SystemAccessControl delegate = new AllowAllSystemAccessControl(); + StatsRecordingSystemAccessControl statsRecordingAccessControl = new StatsRecordingSystemAccessControl(delegate); + + assertEquals(statsRecordingAccessControl.getStats().getCheckCanAccessCatalog().getTime().getAllTime().getCount(), 0.0); + + statsRecordingAccessControl.checkCanAccessCatalog(null, CONTEXT, "test-catalog"); + + assertEquals(statsRecordingAccessControl.getStats().getCheckCanAccessCatalog().getTime().getAllTime().getCount(), 1.0); + } +}