Github user twdsilva commented on a diff in the pull request:

    https://github.com/apache/phoenix/pull/283#discussion_r153685552
  
    --- Diff: 
phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java ---
    @@ -4168,4 +4176,124 @@ public MutationState useSchema(UseSchemaStatement 
useSchemaStatement) throws SQL
             }
             return new MutationState(0, 0, connection);
         }
    +
    +    public MutationState changePermissions(ChangePermsStatement 
changePermsStatement) throws SQLException {
    +
    +        logger.info(changePermsStatement.toString());
    +
    +        try(HBaseAdmin admin = connection.getQueryServices().getAdmin()) {
    +            ClusterConnection clusterConnection = (ClusterConnection) 
admin.getConnection();
    +
    +            if (changePermsStatement.getSchemaName() != null) {
    +                // SYSTEM.CATALOG doesn't have any entry for "default" 
HBase namespace, hence we will bypass the check
    +                
if(!changePermsStatement.getSchemaName().equals(QueryConstants.HBASE_DEFAULT_SCHEMA_NAME))
 {
    +                    
FromCompiler.getResolverForSchema(changePermsStatement.getSchemaName(), 
connection);
    +                }
    +
    +                changePermsOnSchema(clusterConnection, 
changePermsStatement);
    +            } else if (changePermsStatement.getTableName() != null) {
    +                PTable inputTable = PhoenixRuntime.getTable(connection,
    +                        
SchemaUtil.normalizeFullTableName(changePermsStatement.getTableName().toString()));
    +                if (!(PTableType.TABLE.equals(inputTable.getType()) || 
PTableType.SYSTEM.equals(inputTable.getType()))) {
    +                    throw new AccessDeniedException("Cannot GRANT or 
REVOKE permissions on INDEX TABLES or VIEWS");
    +                }
    +
    +                changePermsOnTables(clusterConnection, admin, 
changePermsStatement, inputTable);
    +            } else {
    +
    +                changePermsOnUser(clusterConnection, changePermsStatement);
    +            }
    +
    +        } catch (SQLException e) {
    +            // Bubble up the SQL Exception
    +            throw e;
    +        } catch (Throwable throwable) {
    +            // Wrap around other exceptions to PhoenixIOException (Ex: 
org.apache.hadoop.hbase.security.AccessDeniedException)
    +            throw ServerUtil.parseServerException(throwable);
    +        }
    +
    +        return new MutationState(0, 0, connection);
    +    }
    +
    +    private void changePermsOnSchema(ClusterConnection clusterConnection, 
ChangePermsStatement changePermsStatement) throws Throwable {
    +        if(changePermsStatement.isGrantStatement()) {
    +            AccessControlClient.grant(clusterConnection, 
changePermsStatement.getSchemaName(), changePermsStatement.getName(), 
changePermsStatement.getPermsList());
    +        } else {
    +            AccessControlClient.revoke(clusterConnection, 
changePermsStatement.getSchemaName(), changePermsStatement.getName(), 
Permission.Action.values());
    +        }
    +    }
    +
    +    private void changePermsOnTables(ClusterConnection clusterConnection, 
HBaseAdmin admin, ChangePermsStatement changePermsStatement, PTable inputTable) 
throws Throwable {
    +
    +        org.apache.hadoop.hbase.TableName tableName = 
SchemaUtil.getPhysicalTableName
    +                (inputTable.getPhysicalName().getBytes(), 
inputTable.isNamespaceMapped());
    +
    +        changePermsOnTable(clusterConnection, changePermsStatement, 
tableName);
    +
    +        boolean schemaInconsistency = false;
    +        List<PTable> inconsistentTables = null;
    +
    +        for(PTable indexTable : inputTable.getIndexes()) {
    +            // Local Indexes don't correspond to new physical table, they 
are just stored in separate CF of base table.
    +            if(indexTable.getIndexType().equals(IndexType.LOCAL)) {
    +                continue;
    +            }
    +            if (inputTable.isNamespaceMapped() != 
indexTable.isNamespaceMapped()) {
    +                schemaInconsistency = true;
    +                if(inconsistentTables == null) {
    +                    inconsistentTables = new ArrayList<>();
    +                }
    +                inconsistentTables.add(indexTable);
    +                continue;
    +            }
    +            logger.info("Updating permissions for Index Table: " +
    +                    indexTable.getName() + " Base Table: " + 
inputTable.getName());
    +            tableName = 
SchemaUtil.getPhysicalTableName(indexTable.getPhysicalName().getBytes(), 
indexTable.isNamespaceMapped());
    +            changePermsOnTable(clusterConnection, changePermsStatement, 
tableName);
    +        }
    +
    +        if(schemaInconsistency) {
    +            for(PTable table : inconsistentTables) {
    +                logger.error("Fail to propagate permissions to Index 
Table: " + table.getName());
    +            }
    +            throw new 
TablesNotInSyncException(inputTable.getTableName().getString(),
    +                    inconsistentTables.get(0).getTableName().getString(), 
"Namespace properties");
    +        }
    +
    +        if(inputTable.isMultiTenant()) {
    --- End diff --
    
    non multi-tenant tables could also have views which have indexes, so you 
need to check if the view index table exists for them and then keep the perms 
in sync if it does.


---

Reply via email to