Exemple #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;
    }
  }
Exemple #2
0
  private static Comment makeNewComment(Resource target, User sender, String body)
      throws IssueNotFound, PostingNotFound {
    Comment comment;
    Long id = Long.valueOf(target.getId());

    switch (target.getType()) {
      case ISSUE_POST:
        Issue issue = Issue.finder.byId(id);
        if (issue == null) {
          throw new IssueNotFound(id);
        }
        comment = new IssueComment(issue, sender, body);
        break;
      case BOARD_POST:
        Posting posting = Posting.finder.byId(id);
        if (posting == null) {
          throw new PostingNotFound(id);
        }
        comment = new PostingComment(posting, sender, body);
        break;
      default:
        throw new IllegalArgumentException("Unsupported resource type: " + target.getType());
    }

    return comment;
  }
Exemple #3
0
  /**
   * 업로드된 {@code file}을 주어진 {@code name}으로 {@code container}에 첨부한다.
   *
   * <p>when: 업로드된 파일이 사용자에게 첨부될 때. 혹은 사용자를 거치지 않고 바로 다른 리소스로 첨부될 때.
   *
   * <p>업로드된 파일을 업로드 디렉토리로 옮긴다. 이 때 파일이름을 그 파일의 해시값으로 변경한다. 그 후 이 파일에 대한 메타정보 및 첨부될 대상에 대한 정보를 이
   * 엔터티에 담는다. 만약 이 엔터티와 같은 내용을 갖고 있는 엔터티가 이미 존재한다면, 이미 {@code container}에 같은 첨부가 존재하고 있으므로 첨부하지 않고
   * {@code false}를 반환한다. 그렇지 않다면 첨부 후 {@code true}를 반환한다.
   *
   * @param file 첨부할 파일
   * @param name 파일 이름
   * @param container 파일이 첨부될 리소스
   * @return 파일이 새로 첨부되었다면 {@code true}, 이미 같은 첨부가 존재하여 첨부되지 않았다면 {@code false}
   * @throws IOException
   * @throws NoSuchAlgorithmException
   */
  @Transient
  public boolean store(File file, String name, Resource container)
      throws IOException, NoSuchAlgorithmException {
    // Store the file as its SHA1 hash in filesystem, and record its
    // metadata - containerType, containerId, size and hash - in Database.
    this.containerType = container.getType();
    this.containerId = container.getId();
    this.createdDate = JodaDateUtil.now();

    if (name == null) {
      this.name = file.getName();
    } else {
      this.name = name;
    }

    if (this.mimeType == null) {
      this.mimeType = FileUtil.detectMediaType(file, name);
    }

    // the size must be set before it is moved.
    this.size = file.length();
    this.hash = Attachment.moveFileIntoUploadDirectory(file);

    // Add the attachment into the Database only if there is no same record.
    Attachment sameAttach = Attachment.findBy(this);
    if (sameAttach == null) {
      super.save();
      return true;
    } else {
      this.id = sameAttach.id;
      return false;
    }
  }
Exemple #4
0
  @Transactional
  protected static ReviewComment saveReviewComment(
      Resource target, User sender, Content content, String messageID, Address[] allRecipients)
      throws MessagingException, IOException, NoSuchAlgorithmException {
    ReviewComment comment;
    CommentThread thread = CommentThread.find.byId(Long.valueOf(target.getId()));

    if (thread == null) {
      throw new IllegalArgumentException();
    }

    comment = new ReviewComment();
    comment.setContents(content.body);
    comment.author = new UserIdent(sender);
    comment.thread = thread;
    comment.save();

    Map<String, Attachment> relatedAttachments =
        saveAttachments(content.attachments, comment.asResource());

    if (new ContentType(content.type).match(MimeType.HTML)) {
      // replace cid with attachments
      comment.setContents(replaceCidWithAttachments(comment.getContents(), relatedAttachments));
      comment.update();
    }

    new OriginalEmail(messageID, comment.asResource()).save();

    // Add the event
    if (thread.isOnPullRequest()) {
      addEvent(
          NotificationEvent.forNewComment(sender, thread.pullRequest, comment),
          allRecipients,
          sender);
    } else {
      try {
        String commitId;

        if (thread instanceof CodeCommentThread) {
          commitId = ((CodeCommentThread) thread).commitId;
        } else if (thread instanceof NonRangedCodeCommentThread) {
          commitId = ((NonRangedCodeCommentThread) thread).commitId;
        } else {
          throw new IllegalArgumentException();
        }

        addEvent(
            NotificationEvent.forNewCommitComment(target.getProject(), comment, commitId, sender),
            allRecipients,
            sender);
      } catch (Exception e) {
        Logger.warn("Failed to send a notification", e);
      }
    }

    return comment;
  }
Exemple #5
0
 /**
  * {@code from}에 첨부된 파일중 파일 아이디가{@code selectedFileIds}에 해당하는 첨부 파일을 {@code to}로 옮긴다.
  *
  * <p>when: 업로드 직후 일시적으로 사용자에게 첨부되었던 첨부 파일들을, 특정 리소스(이슈, 게시물 등)으로 옮기려 할 때
  *
  * @param from 첨부 파일이 원래 있었던 리소스
  * @param to 첨부 파일이 새로 옮겨질 리소스
  * @return
  */
 public static int moveOnlySelected(Resource from, Resource to, String[] selectedFileIds) {
   if (selectedFileIds.length == 0) {
     return NOTHING_TO_ATTACH;
   }
   List<Attachment> attachments =
       Attachment.find.where().idIn(Arrays.asList(selectedFileIds)).findList();
   for (Attachment attachment : attachments) {
     if (attachment.containerId.equals(from.getId())
         && attachment.containerType == from.getType()) {
       attachment.moveTo(to);
     }
   }
   return attachments.size();
 }
Exemple #6
0
 /**
  * 이 첨부 파일을 {@code to}로 옮긴다.
  *
  * @param to 첨부 파일이 새로 옮겨질 리소스
  * @return
  */
 public void moveTo(Resource to) {
   containerType = to.getType();
   containerId = to.getId();
   update();
 }
Exemple #7
0
 /**
  * 주어진 {@code container}에 첨부된 첨부 파일의 갯수를 반환한다.
  *
  * <p>when:
  *
  * @param container 첨부 파일이 첨부된 리소스
  * @return 첨부 파일의 목록
  */
 public static int countByContainer(Resource container) {
   return find.where()
       .eq("containerType", container.getType())
       .eq("containerId", container.getId())
       .findRowCount();
 }
Exemple #8
0
 /**
  * 주어진 {@code container}의 첨부된 첨부 파일의 목록을 반환한다.
  *
  * @param container 첨부 파일이 첨부된 리소스
  * @return 첨부 파일의 목록
  */
 public static List<Attachment> findByContainer(Resource container) {
   return findByContainer(container.getType(), container.getId());
 }