private List<HivePrivilegeObject> filterShowTables(
      List<HivePrivilegeObject> listObjs, String userName, HiveAuthzBinding hiveAuthzBinding) {
    List<HivePrivilegeObject> filteredResult = new ArrayList<HivePrivilegeObject>();
    Subject subject = new Subject(userName);
    HiveAuthzPrivileges tableMetaDataPrivilege =
        new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
            .addInputObjectPriviledge(
                AuthorizableType.Column, EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT))
            .setOperationScope(HiveOperationScope.TABLE)
            .setOperationType(
                org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationType.INFO)
            .build();

    for (HivePrivilegeObject obj : listObjs) {
      // if user has privileges on table, add to filtered list, else discard
      Table table = new Table(obj.getObjectName());
      Database database;
      database = new Database(obj.getDbname());

      List<List<DBModelAuthorizable>> inputHierarchy = new ArrayList<List<DBModelAuthorizable>>();
      List<List<DBModelAuthorizable>> outputHierarchy = new ArrayList<List<DBModelAuthorizable>>();
      List<DBModelAuthorizable> externalAuthorizableHierarchy =
          new ArrayList<DBModelAuthorizable>();
      externalAuthorizableHierarchy.add(hiveAuthzBinding.getAuthServer());
      externalAuthorizableHierarchy.add(database);
      externalAuthorizableHierarchy.add(table);
      externalAuthorizableHierarchy.add(Column.ALL);
      inputHierarchy.add(externalAuthorizableHierarchy);

      try {
        hiveAuthzBinding.authorize(
            HiveOperation.SHOWTABLES,
            tableMetaDataPrivilege,
            subject,
            inputHierarchy,
            outputHierarchy);
        filteredResult.add(obj);
      } catch (AuthorizationException e) {
        // squash the exception, user doesn't have privileges, so the table is
        // not added to
        // filtered list.
      }
    }
    return filteredResult;
  }
  private List<HivePrivilegeObject> filterShowDatabases(
      List<HivePrivilegeObject> listObjs, String userName, HiveAuthzBinding hiveAuthzBinding) {
    List<HivePrivilegeObject> filteredResult = new ArrayList<HivePrivilegeObject>();
    Subject subject = new Subject(userName);
    HiveAuthzPrivileges anyPrivilege =
        new HiveAuthzPrivileges.AuthzPrivilegeBuilder()
            .addInputObjectPriviledge(
                AuthorizableType.Column,
                EnumSet.of(
                    DBModelAction.SELECT,
                    DBModelAction.INSERT,
                    DBModelAction.ALTER,
                    DBModelAction.CREATE,
                    DBModelAction.DROP,
                    DBModelAction.INDEX,
                    DBModelAction.LOCK))
            .setOperationScope(HiveOperationScope.CONNECT)
            .setOperationType(
                org.apache.sentry.binding.hive.authz.HiveAuthzPrivileges.HiveOperationType.QUERY)
            .build();

    for (HivePrivilegeObject obj : listObjs) {
      // if user has privileges on database, add to filtered list, else discard
      Database database = null;

      // if default is not restricted, continue
      if (DEFAULT_DATABASE_NAME.equalsIgnoreCase(obj.getObjectName())
          && "false"
              .equalsIgnoreCase(
                  hiveAuthzBinding
                      .getAuthzConf()
                      .get(
                          HiveAuthzConf.AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(),
                          "false"))) {
        filteredResult.add(obj);
        continue;
      }

      database = new Database(obj.getObjectName());

      List<List<DBModelAuthorizable>> inputHierarchy = new ArrayList<List<DBModelAuthorizable>>();
      List<List<DBModelAuthorizable>> outputHierarchy = new ArrayList<List<DBModelAuthorizable>>();
      List<DBModelAuthorizable> externalAuthorizableHierarchy =
          new ArrayList<DBModelAuthorizable>();
      externalAuthorizableHierarchy.add(hiveAuthzBinding.getAuthServer());
      externalAuthorizableHierarchy.add(database);
      externalAuthorizableHierarchy.add(Table.ALL);
      externalAuthorizableHierarchy.add(Column.ALL);
      inputHierarchy.add(externalAuthorizableHierarchy);

      try {
        hiveAuthzBinding.authorize(
            HiveOperation.SHOWDATABASES, anyPrivilege, subject, inputHierarchy, outputHierarchy);
        filteredResult.add(obj);
      } catch (AuthorizationException e) {
        // squash the exception, user doesn't have privileges, so the table is
        // not added to
        // filtered list.
      }
    }
    return filteredResult;
  }
  /**
   * Check if current user has privileges to perform given operation type hiveOpType on the given
   * input and output objects
   *
   * @param hiveOpType
   * @param inputHObjs
   * @param outputHObjs
   * @param context
   * @throws SentryAccessControlException
   */
  @Override
  public void checkPrivileges(
      HiveOperationType hiveOpType,
      List<HivePrivilegeObject> inputHObjs,
      List<HivePrivilegeObject> outputHObjs,
      HiveAuthzContext context)
      throws HiveAuthzPluginException, HiveAccessControlException {
    if (LOG.isDebugEnabled()) {
      String msg =
          "Checking privileges for operation "
              + hiveOpType
              + " by user "
              + authenticator.getUserName()
              + " on "
              + " input objects "
              + inputHObjs
              + " and output objects "
              + outputHObjs
              + ". Context Info: "
              + context;
      LOG.debug(msg);
    }

    HiveOperation hiveOp = SentryAuthorizerUtil.convert2HiveOperation(hiveOpType.name());
    HiveAuthzPrivileges stmtAuthPrivileges = null;
    if (HiveOperation.DESCTABLE.equals(hiveOp)
        && !(context.getCommandString().contains("EXTENDED")
            || context.getCommandString().contains("FORMATTED"))) {
      stmtAuthPrivileges = HiveAuthzPrivilegesMap.getHiveAuthzPrivileges(HiveOperation.SHOWCOLUMNS);
    } else {
      stmtAuthPrivileges = HiveAuthzPrivilegesMap.getHiveAuthzPrivileges(hiveOp);
    }

    HiveAuthzBinding hiveAuthzBinding = null;
    try {
      hiveAuthzBinding = getAuthzBinding();
      if (stmtAuthPrivileges == null) {
        // We don't handle authorizing this statement
        return;
      }

      List<List<DBModelAuthorizable>> inputHierarchyList =
          SentryAuthorizerUtil.convert2SentryPrivilegeList(
              hiveAuthzBinding.getAuthServer(), inputHObjs);
      List<List<DBModelAuthorizable>> outputHierarchyList =
          SentryAuthorizerUtil.convert2SentryPrivilegeList(
              hiveAuthzBinding.getAuthServer(), outputHObjs);

      // Workaround for metadata queries
      addExtendHierarchy(
          hiveOp,
          stmtAuthPrivileges,
          inputHierarchyList,
          outputHierarchyList,
          context.getCommandString(),
          hiveAuthzBinding);

      hiveAuthzBinding.authorize(
          hiveOp,
          stmtAuthPrivileges,
          new Subject(authenticator.getUserName()),
          inputHierarchyList,
          outputHierarchyList);
    } catch (AuthorizationException e) {
      Database db = null;
      Table tab = null;
      AccessURI udfURI = null;
      AccessURI partitionURI = null;
      if (outputHObjs != null) {
        for (HivePrivilegeObject obj : outputHObjs) {
          switch (obj.getType()) {
            case DATABASE:
              db = new Database(obj.getObjectName());
              break;
            case TABLE_OR_VIEW:
              db = new Database(obj.getDbname());
              tab = new Table(obj.getObjectName());
              break;
            case PARTITION:
              db = new Database(obj.getDbname());
              tab = new Table(obj.getObjectName());
            case LOCAL_URI:
            case DFS_URI:
          }
        }
      }
      String permsRequired = "";
      SentryOnFailureHookContext hookCtx =
          new SentryOnFailureHookContextImpl(
              context.getCommandString(),
              null,
              null,
              hiveOp,
              db,
              tab,
              udfURI,
              partitionURI,
              authenticator.getUserName(),
              context.getIpAddress(),
              e,
              authzConf);
      SentryAuthorizerUtil.executeOnFailureHooks(hookCtx, authzConf);
      for (String perm : hiveAuthzBinding.getLastQueryPrivilegeErrors()) {
        permsRequired += perm + ";";
      }
      SessionState.get().getConf().set(HiveAuthzConf.HIVE_SENTRY_AUTH_ERRORS, permsRequired);
      String msg =
          HiveAuthzConf.HIVE_SENTRY_PRIVILEGE_ERROR_MESSAGE
              + "\n Required privileges for this query: "
              + permsRequired;
      throw new HiveAccessControlException(msg, e);
    } catch (Exception e) {
      throw new HiveAuthzPluginException(e.getClass() + ": " + e.getMessage(), e);
    } finally {
      if (hiveAuthzBinding != null) {
        hiveAuthzBinding.close();
      }
    }

    if ("true"
        .equalsIgnoreCase(
            SessionState.get().getConf().get(HiveAuthzConf.HIVE_SENTRY_MOCK_COMPILATION))) {
      throw new HiveAccessControlException(
          HiveAuthzConf.HIVE_SENTRY_MOCK_ERROR
              + " Mock query compilation aborted. Set "
              + HiveAuthzConf.HIVE_SENTRY_MOCK_COMPILATION
              + " to 'false' for normal query processing");
    }
  }