Esempio n. 1
0
  /**
   * Global 리소스에 대해 주어진 리소스의 operation을 허용하는지 여부
   *
   * <p>임시 업로드 파일은 해당 파일을 업로드한 사용자만 접근할 수 있다. 비공개 프로젝트는 해당 프로젝트의 멤버만 접근할 수 있다. 공개 프로젝트는 모든 사용자가 접근할
   * 수 있다. 사용자 및 사용자의 아바타는 그 사용자 본인만 갱신 혹은 삭제할 수 있다. 프로젝트는 그 프로젝트의 관리자만이 갱신 혹은 삭제할 수 있다.
   *
   * @param user
   * @param resource
   * @param operation
   * @return
   */
  private static boolean isGlobalResourceAllowed(
      User user, Resource resource, Operation operation) {
    // Temporary attachments are allowed only for the user who uploads them.
    if (resource.getType() == ResourceType.ATTACHMENT
        && resource.getContainer().getType() == ResourceType.USER) {
      return user.id.equals(resource.getContainer().getId());
    }

    if (operation == Operation.READ) {
      if (resource.getType() == ResourceType.PROJECT) {
        Project project = Project.find.byId(resource.getId());
        return project != null && (project.isPublic || ProjectUser.isMember(user.id, project.id));
      }

      // anyone can read any resource which is not a project.
      return true;
    }

    // UPDATE, DELETE
    switch (resource.getType()) {
      case USER:
      case USER_AVATAR:
        return user.id.equals(resource.getId());
      case PROJECT:
        return ProjectUser.isManager(user.id, resource.getId());
      default:
        // undefined
        return false;
    }
  }
Esempio n. 2
0
  /**
   * {@code user}가 프로젝트 리소스인 {@code resource}에 {@code operation}을 하는 것이 허용되는지의 여부를 반환한다.
   *
   * <p>See docs/technical/access-control.md for more information.
   *
   * @param user
   * @param project
   * @param resource
   * @param operation
   * @return
   */
  private static boolean isProjectResourceAllowed(
      User user, Project project, Resource resource, Operation operation) {
    if (ProjectUser.isManager(user.id, project.id)) {
      return true;
    }

    // If the resource is an attachment, the permission depends on its container.
    if (resource.getType() == ResourceType.ATTACHMENT) {
      switch (operation) {
        case READ:
          return isAllowed(user, resource.getContainer(), Operation.READ);
        case UPDATE:
        case DELETE:
          return isAllowed(user, resource.getContainer(), Operation.UPDATE);
      }
    }

    // Access Control for members, nonmembers and anonymous.
    // - Anyone can read public project's resource.
    // - Members can update anything and delete anything except code repository.
    // - Nonmember can update or delete a resource if only
    //     * the user is the author of the resource,
    //     * the resource is not a code repository,
    //     * and the project to which the resource belongs is public.
    // See docs/technical/access-control.md for more information.
    switch (operation) {
      case READ:
        return project.isPublic || ProjectUser.isMember(user.id, project.id);
      case UPDATE:
        if (ProjectUser.isMember(user.id, project.id)) {
          return true;
        }

        if (resource.getType() == ResourceType.CODE) {
          // Nonmember cannot update the repository.
          return false;
        } else {
          return project.isPublic && isEditableAsAuthor(user, project, resource);
        }
      case DELETE:
        if (resource.getType() == ResourceType.CODE) {
          return false;
        } else {
          return ProjectUser.isMember(user.id, project.id)
              || (project.isPublic && isEditableAsAuthor(user, project, resource));
        }
      default:
        // undefined
        return false;
    }
  }