class WorkspacePermissionsFilter extends CheMethodInvokerFilter {

  @Override
  public void filter(GenericResourceMethod genericResourceMethod, Object[] arguments)
      throws ForbiddenException, ServerException, NotFoundException {
    final String methodName = genericResourceMethod.getMethod().getName();

    final Subject currentSubject = EnvironmentContext.getCurrent().getSubject();
    String action;
    String key;

    switch (methodName) {
      case "getSettings":
      case "getWorkspaces":
        // methods accessible to every user
        return;

      case "getByNamespace":
        {
          if (superPrivilegesChecker.hasSuperPrivileges()) {
            return;
          }
          checkAccountPermissions((String) arguments[1], AccountOperation.MANAGE_WORKSPACES);
          return;
        }

      case "create":
        {
          checkAccountPermissions((String) arguments[4], AccountOperation.CREATE_WORKSPACE);
          return;
        }

      case "delete":
        key = ((String) arguments[0]);
        action = DELETE;
        break;

      case "stop":
        if (superPrivilegesChecker.hasSuperPrivileges()) {
          return;
        }
        // fall through
      case "startById":
        key = ((String) arguments[0]);
        action = RUN;
        break;

      case "getByKey":
        if (superPrivilegesChecker.hasSuperPrivileges()) {
          return;
        }
        key = ((String) arguments[0]);
        action = READ;
        break;

      case "update":
        key = ((String) arguments[0]);
        action = CONFIGURE;
        break;

      default:
        throw new ForbiddenException("The user does not have permission to perform this operation");
    }

    final WorkspaceImpl workspace = workspaceManager.getWorkspace(key);
    try {
      checkAccountPermissions(workspace.getNamespace(), AccountOperation.MANAGE_WORKSPACES);
      // user is authorized to perform any operation if workspace belongs to account where he has
      // the corresponding permissions
    } catch (ForbiddenException e) {
      // check permissions on workspace level
      if (!currentSubject.hasPermission(DOMAIN_ID, workspace.getId(), action)) {
        throw new ForbiddenException(
            "The user does not have permission to "
                + action
                + " workspace with id '"
                + workspace.getId()
                + "'");
      }
    }
  }

  @Inject public  WorkspacePermissionsFilter(
      WorkspaceManager workspaceManager,
      AccountManager accountManager,
      Set<AccountPermissionsChecker> accountPermissionsCheckers,
      SuperPrivilegesChecker superPrivilegesChecker);

}