예제 #1
0
  private List<List<ChangeInfo>> query() throws OrmException, QueryParseException {
    if (imp.isDisabled()) {
      throw new QueryParseException("query disabled");
    }
    if (queries == null || queries.isEmpty()) {
      queries = Collections.singletonList("status:open");
    } else if (queries.size() > 10) {
      // Hard-code a default maximum number of queries to prevent
      // users from submitting too much to the server in a single call.
      throw new QueryParseException("limit of 10 queries");
    }

    IdentifiedUser self = null;
    try {
      if (user.get().isIdentifiedUser()) {
        self = (IdentifiedUser) user.get();
        self.asyncStarredChanges();
      }
      return query0();
    } finally {
      if (self != null) {
        self.abortStarredChanges();
      }
    }
  }
  private void postAdd(Change change, PostResult result) throws OrmException, EmailException {
    if (result.reviewers.isEmpty()) {
      return;
    }

    // Execute hook for added reviewers
    //
    PatchSet patchSet = db.get().patchSets().get(change.currentPatchSetId());
    for (AccountInfo info : result.reviewers) {
      Account account = accountCache.get(info._id).getAccount();
      hooks.doReviewerAddedHook(change, account, patchSet, db.get());
    }

    // Email the reviewers
    //
    // The user knows they added themselves, don't bother emailing them.
    List<Account.Id> added = Lists.newArrayListWithCapacity(result.reviewers.size());
    for (AccountInfo info : result.reviewers) {
      if (!info._id.equals(currentUser.getAccountId())) {
        added.add(info._id);
      }
    }
    if (!added.isEmpty()) {
      AddReviewerSender cm;

      cm = addReviewerSenderFactory.create(change);
      cm.setFrom(currentUser.getAccountId());
      cm.addReviewers(added);
      cm.send();
    }
  }
  private void addReviewers(ChangeResource rsrc, PostResult result, Set<IdentifiedUser> reviewers)
      throws OrmException, EmailException {
    if (reviewers.isEmpty()) {
      result.reviewers = ImmutableList.of();
      return;
    }

    PatchSet.Id psid = rsrc.getChange().currentPatchSetId();
    Set<Account.Id> existing = Sets.newHashSet();
    for (PatchSetApproval psa : db.get().patchSetApprovals().byPatchSet(psid)) {
      existing.add(psa.getAccountId());
    }

    result.reviewers = Lists.newArrayListWithCapacity(reviewers.size());
    List<PatchSetApproval> toInsert = Lists.newArrayListWithCapacity(reviewers.size());
    for (IdentifiedUser user : reviewers) {
      Account.Id id = user.getAccountId();
      if (existing.contains(id)) {
        continue;
      }
      ChangeControl control = rsrc.getControl().forUser(user);
      PatchSetApproval psa = dummyApproval(control, psid, id);
      result.reviewers.add(json.format(new ReviewerInfo(id), control, ImmutableList.of(psa)));
      toInsert.add(psa);
    }
    db.get().patchSetApprovals().insert(toInsert);
    accountLoaderFactory.create(true).fill(result.reviewers);
    postAdd(rsrc.getChange(), result);
  }
예제 #4
0
  public void setFrom(final Account.Id id) {
    super.setFrom(id);

    /** Is the from user in an email squelching group? */
    final IdentifiedUser user = args.identifiedUserFactory.create(id);
    final Set<AccountGroup.UUID> gids = user.getEffectiveGroups();
    for (final AccountGroup.UUID gid : gids) {
      if (args.groupCache.get(gid).isEmailOnlyAuthors()) {
        emailOnlyAuthors = true;
        break;
      }
    }
  }
예제 #5
0
  public Response<String> apply(IdentifiedUser user, String newPassword)
      throws ResourceNotFoundException, ResourceConflictException, OrmException {
    if (user.getUserName() == null) {
      throw new ResourceConflictException("username must be set");
    }

    AccountExternalId id =
        dbProvider
            .get()
            .accountExternalIds()
            .get(new AccountExternalId.Key(SCHEME_USERNAME, user.getUserName()));
    if (id == null) {
      throw new ResourceNotFoundException();
    }
    id.setPassword(newPassword);
    dbProvider.get().accountExternalIds().update(Collections.singleton(id));
    accountCache.evict(user.getAccountId());

    return Strings.isNullOrEmpty(newPassword) ? Response.<String>none() : Response.ok(newPassword);
  }
예제 #6
0
    String getMessage() {
      StringBuilder msg = new StringBuilder();

      msg.append("\r\n");
      msg.append("  ****    Welcome to Gerrit Code Review    ****\r\n");
      msg.append("\r\n");

      Account account = user.getAccount();
      String name = account.getFullName();
      if (name == null || name.isEmpty()) {
        name = user.getUserName();
      }
      msg.append("  Hi ");
      msg.append(name);
      msg.append(", you have successfully connected over SSH.");
      msg.append("\r\n");
      msg.append("\r\n");

      msg.append("  Unfortunately, interactive shells are disabled.\r\n");
      msg.append("  To clone a hosted Git repository, use:\r\n");
      msg.append("\r\n");

      if (!sshInfo.getHostKeys().isEmpty()) {
        String host = sshInfo.getHostKeys().get(0).getHost();
        if (host.startsWith("*:")) {
          host = getGerritHost() + host.substring(1);
        }

        msg.append("  git clone ssh://");
        msg.append(user.getUserName());
        msg.append("@");
        msg.append(host);
        msg.append("/");
        msg.append("REPOSITORY_NAME.git");
        msg.append("\r\n");
      }

      msg.append("\r\n");
      return msg.toString();
    }
예제 #7
0
파일: SshKeys.java 프로젝트: web1992/gerrit
 public AccountResource.SshKey parse(IdentifiedUser user, IdString id)
     throws ResourceNotFoundException, OrmException {
   try {
     int seq = Integer.parseInt(id.get(), 10);
     AccountSshKey sshKey =
         dbProvider.get().accountSshKeys().get(new AccountSshKey.Id(user.getAccountId(), seq));
     if (sshKey == null) {
       throw new ResourceNotFoundException(id);
     }
     return new AccountResource.SshKey(user, sshKey);
   } catch (NumberFormatException e) {
     throw new ResourceNotFoundException(id);
   }
 }
예제 #8
0
 private void assertScoreIsAllowed(
     final PatchSet.Id patchSetId, final ChangeControl changeControl, ApproveOption ao, Short v)
     throws UnloggedFailure {
   final PatchSetApproval psa =
       new PatchSetApproval(
           new PatchSetApproval.Key(patchSetId, currentUser.getAccountId(), ao.getCategoryId()),
           v);
   final FunctionState fs =
       functionStateFactory.create(
           changeControl.getChange(), patchSetId, Collections.<PatchSetApproval>emptyList());
   psa.setValue(v);
   fs.normalize(approvalTypes.byId(psa.getCategoryId()), psa);
   if (v != psa.getValue()) {
     throw error(ao.name() + "=" + ao.value() + " not permitted");
   }
 }
예제 #9
0
파일: MergeOp.java 프로젝트: web1992/gerrit
  private BatchMetaDataUpdate approve(
      ChangeControl control,
      PatchSet.Id psId,
      IdentifiedUser user,
      ChangeUpdate update,
      Timestamp timestamp)
      throws OrmException {
    Map<PatchSetApproval.Key, PatchSetApproval> byKey = Maps.newHashMap();
    for (PatchSetApproval psa : approvalsUtil.byPatchSet(db, control, psId)) {
      if (!byKey.containsKey(psa.getKey())) {
        byKey.put(psa.getKey(), psa);
      }
    }

    PatchSetApproval submit =
        new PatchSetApproval(
            new PatchSetApproval.Key(psId, user.getAccountId(), LabelId.SUBMIT),
            (short) 1,
            TimeUtil.nowTs());
    byKey.put(submit.getKey(), submit);
    submit.setValue((short) 1);
    submit.setGranted(timestamp);

    // Flatten out existing approvals for this patch set based upon the current
    // permissions. Once the change is closed the approvals are not updated at
    // presentation view time, except for zero votes used to indicate a reviewer
    // was added. So we need to make sure votes are accurate now. This way if
    // permissions get modified in the future, historical records stay accurate.
    LabelNormalizer.Result normalized = labelNormalizer.normalize(control, byKey.values());

    // TODO(dborowitz): Don't use a label in notedb; just check when status
    // change happened.
    update.putApproval(submit.getLabel(), submit.getValue());
    logDebug("Adding submit label " + submit);

    db.patchSetApprovals().upsert(normalized.getNormalized());
    db.patchSetApprovals().delete(normalized.deleted());

    try {
      return saveToBatch(control, update, normalized, timestamp);
    } catch (IOException e) {
      throw new OrmException(e);
    }
  }
  @Override
  public List<AccountExternalId> call() throws OrmException {
    final AccountExternalId.Key last = session.getLastLoginExternalId();
    final List<AccountExternalId> ids =
        db.accountExternalIds().byAccount(user.getAccountId()).toList();

    for (final AccountExternalId e : ids) {
      e.setTrusted(authConfig.isIdentityTrustable(Collections.singleton(e)));

      // The identity can be deleted only if its not the one used to
      // establish this web session, and if only if an identity was
      // actually used to establish this web session.
      //
      if (e.isScheme(SCHEME_USERNAME)) {
        e.setCanDelete(false);
      } else {
        e.setCanDelete(last != null && !last.equals(e.getKey()));
      }
    }
    return ids;
  }
  @Override
  public GroupMembership membershipsOf(IdentifiedUser user) {
    String id = findId(user.state().getExternalIds());
    if (id == null) {
      return GroupMembership.EMPTY;
    }

    try {
      final Set<AccountGroup.UUID> groups = membershipCache.get(id);
      return new ListGroupMembership(groups) {
        @Override
        public Set<AccountGroup.UUID> getKnownGroups() {
          Set<AccountGroup.UUID> g = Sets.newHashSet(groups);
          g.retainAll(projectCache.guessRelevantGroupUUIDs());
          return g;
        }
      };
    } catch (ExecutionException e) {
      log.warn(String.format("Cannot lookup membershipsOf %s in LDAP", id), e);
      return GroupMembership.EMPTY;
    }
  }
예제 #12
0
파일: MergeOp.java 프로젝트: web1992/gerrit
  private void setApproval(ChangeData cd, IdentifiedUser user) throws OrmException, IOException {
    Timestamp timestamp = TimeUtil.nowTs();
    ChangeControl control = cd.changeControl();
    PatchSet.Id psId = cd.currentPatchSet().getId();
    PatchSet.Id psIdNewRev = commits.get(cd.change().getId()).change().currentPatchSetId();

    logDebug("Add approval for " + cd + " from user " + user);
    ChangeUpdate update = updateFactory.create(control, timestamp);
    update.putReviewer(user.getAccountId(), REVIEWER);
    List<SubmitRecord> record = records.get(cd.change().getId());
    if (record != null) {
      update.merge(record);
    }
    db.changes().beginTransaction(cd.change().getId());
    try {
      BatchMetaDataUpdate batch = approve(control, psId, user, update, timestamp);
      batch.write(update, new CommitBuilder());

      // If the submit strategy created a new revision (rebase, cherry-pick)
      // approve that as well
      if (!psIdNewRev.equals(psId)) {
        update.setPatchSetId(psId);
        update.commit();
        // Create a new ChangeUpdate instance because we need to store meta data
        // on another patch set (psIdNewRev).
        update = updateFactory.create(control, timestamp);
        batch = approve(control, psIdNewRev, user, update, timestamp);
        // Write update commit after all normalized label commits.
        batch.write(update, new CommitBuilder());
      }
      db.commit();
    } finally {
      db.rollback();
    }
    update.commit();
    indexer.index(db, cd.change());
  }
예제 #13
0
파일: MergeOp.java 프로젝트: web1992/gerrit
  private RefUpdate updateBranch(Branch.NameKey destBranch, IdentifiedUser caller)
      throws IntegrationException {
    RefUpdate branchUpdate = getPendingRefUpdate(destBranch);
    CodeReviewCommit branchTip = getBranchTip(destBranch);

    MergeTip mergeTip = mergeTips.get(destBranch);

    CodeReviewCommit currentTip = mergeTip != null ? mergeTip.getCurrentTip() : null;
    if (Objects.equals(branchTip, currentTip)) {
      if (currentTip != null) {
        logDebug("Branch already at merge tip {}, no update to perform", currentTip.name());
      } else {
        logDebug("Both branch and merge tip are nonexistent, no update");
      }
      return null;
    } else if (currentTip == null) {
      logDebug("No merge tip, no update to perform");
      return null;
    }

    if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
      logDebug("Loading new configuration from {}", RefNames.REFS_CONFIG);
      try {
        ProjectConfig cfg = new ProjectConfig(destProject.getProject().getNameKey());
        cfg.load(repo, currentTip);
      } catch (Exception e) {
        throw new IntegrationException(
            "Submit would store invalid"
                + " project configuration "
                + currentTip.name()
                + " for "
                + destProject.getProject().getName(),
            e);
      }
    }

    branchUpdate.setRefLogIdent(
        identifiedUserFactory.create(caller.getAccountId()).newRefLogIdent());
    branchUpdate.setForceUpdate(false);
    branchUpdate.setNewObjectId(currentTip);
    branchUpdate.setRefLogMessage("merged", true);
    try {
      RefUpdate.Result result = branchUpdate.update(rw);
      logDebug(
          "Update of {}: {}..{} returned status {}",
          branchUpdate.getName(),
          branchUpdate.getOldObjectId(),
          branchUpdate.getNewObjectId(),
          result);
      switch (result) {
        case NEW:
        case FAST_FORWARD:
          if (branchUpdate.getResult() == RefUpdate.Result.FAST_FORWARD) {
            tagCache.updateFastForward(
                destBranch.getParentKey(),
                branchUpdate.getName(),
                branchUpdate.getOldObjectId(),
                currentTip);
          }

          if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
            Project p = destProject.getProject();
            projectCache.evict(p);
            destProject = projectCache.get(p.getNameKey());
            repoManager.setProjectDescription(p.getNameKey(), p.getDescription());
          }

          return branchUpdate;

        case LOCK_FAILURE:
          throw new IntegrationException("Failed to lock " + branchUpdate.getName());
        default:
          throw new IOException(branchUpdate.getResult().name() + '\n' + branchUpdate);
      }
    } catch (IOException e) {
      throw new IntegrationException("Cannot update " + branchUpdate.getName(), e);
    }
  }
예제 #14
0
  private String[] makeEnv(final HttpServletRequest req, final ProjectControl project) {
    final EnvList env = new EnvList(_env);
    final int contentLength = Math.max(0, req.getContentLength());

    // These ones are from "The WWW Common Gateway Interface Version 1.1"
    //
    env.set("AUTH_TYPE", req.getAuthType());
    env.set("CONTENT_LENGTH", Integer.toString(contentLength));
    env.set("CONTENT_TYPE", req.getContentType());
    env.set("GATEWAY_INTERFACE", "CGI/1.1");
    env.set("PATH_INFO", req.getPathInfo());
    env.set("PATH_TRANSLATED", null);
    env.set("QUERY_STRING", req.getQueryString());
    env.set("REMOTE_ADDR", req.getRemoteAddr());
    env.set("REMOTE_HOST", req.getRemoteHost());
    env.set("HTTPS", req.isSecure() ? "ON" : "OFF");

    // The identity information reported about the connection by a
    // RFC 1413 [11] request to the remote agent, if
    // available. Servers MAY choose not to support this feature, or
    // not to request the data for efficiency reasons.
    // "REMOTE_IDENT" => "NYI"
    //
    env.set("REQUEST_METHOD", req.getMethod());
    env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath());
    env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString());
    env.set("SERVER_NAME", req.getServerName());
    env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
    env.set("SERVER_PROTOCOL", req.getProtocol());
    env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());

    final Enumeration<String> hdrs = enumerateHeaderNames(req);
    while (hdrs.hasMoreElements()) {
      final String name = hdrs.nextElement();
      final String value = req.getHeader(name);
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
    }

    env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
    env.set("GERRIT_PROJECT_NAME", project.getProject().getName());

    if (project.forUser(anonymousUserProvider.get()).isVisible()) {
      env.set("GERRIT_ANONYMOUS_READ", "1");
    }

    String remoteUser = null;
    if (project.getCurrentUser().isIdentifiedUser()) {
      final IdentifiedUser u = (IdentifiedUser) project.getCurrentUser();
      final String user = u.getUserName();
      env.set("GERRIT_USER_NAME", user);
      if (user != null && !user.isEmpty()) {
        remoteUser = user;
      } else {
        remoteUser = "******" + u.getAccountId();
      }
    }
    env.set("REMOTE_USER", remoteUser);

    // Override CGI settings using alternative URI provided by gitweb.url.
    // This is required to trick gitweb into thinking that it's served under
    // different URL. Setting just $my_uri on the perl's side isn't enough,
    // because few actions (atom, blobdiff_plain, commitdiff_plain) rely on
    // URL returned by $cgi->self_url().
    //
    if (gitwebUrl != null) {
      int schemePort = -1;

      if (gitwebUrl.getScheme() != null) {
        if (gitwebUrl.getScheme().equals("http")) {
          env.set("HTTPS", "OFF");
          schemePort = 80;
        } else {
          env.set("HTTPS", "ON");
          schemePort = 443;
        }
      }

      if (gitwebUrl.getHost() != null) {
        env.set("SERVER_NAME", gitwebUrl.getHost());
        env.set("HTTP_HOST", gitwebUrl.getHost());
      }

      if (gitwebUrl.getPort() != -1) {
        env.set("SERVER_PORT", Integer.toString(gitwebUrl.getPort()));
      } else if (schemePort != -1) {
        env.set("SERVER_PORT", Integer.toString(schemePort));
      }

      if (gitwebUrl.getPath() != null) {
        env.set("SCRIPT_NAME", gitwebUrl.getPath().isEmpty() ? "/" : gitwebUrl.getPath());
      }
    }

    return env.getEnvArray();
  }
예제 #15
0
    @Override
    public void onPreMerge(
        final Repository repo,
        final CodeReviewCommit commit,
        final ProjectState destProject,
        final Branch.NameKey destBranch,
        final PatchSet.Id patchSetId)
        throws MergeValidationException {
      if (RefNames.REFS_CONFIG.equals(destBranch.get())) {
        final Project.NameKey newParent;
        try {
          ProjectConfig cfg = new ProjectConfig(destProject.getProject().getNameKey());
          cfg.load(repo, commit);
          newParent = cfg.getProject().getParent(allProjectsName);
          final Project.NameKey oldParent = destProject.getProject().getParent(allProjectsName);
          if (oldParent == null) {
            // update of the 'All-Projects' project
            if (newParent != null) {
              throw new MergeValidationException(ROOT_NO_PARENT);
            }
          } else {
            if (!oldParent.equals(newParent)) {
              PatchSetApproval psa = approvalsUtil.getSubmitter(db, commit.notes(), patchSetId);
              if (psa == null) {
                throw new MergeValidationException(SET_BY_ADMIN);
              }
              final IdentifiedUser submitter = identifiedUserFactory.create(psa.getAccountId());
              if (!submitter.getCapabilities().canAdministrateServer()) {
                throw new MergeValidationException(SET_BY_ADMIN);
              }

              if (projectCache.get(newParent) == null) {
                throw new MergeValidationException(PARENT_NOT_FOUND);
              }
            }
          }

          for (Entry<ProjectConfigEntry> e : pluginConfigEntries) {
            PluginConfig pluginCfg = cfg.getPluginConfig(e.getPluginName());
            ProjectConfigEntry configEntry = e.getProvider().get();

            String value = pluginCfg.getString(e.getExportName());
            String oldValue =
                destProject
                    .getConfig()
                    .getPluginConfig(e.getPluginName())
                    .getString(e.getExportName());

            if ((value == null ? oldValue != null : !value.equals(oldValue))
                && !configEntry.isEditable(destProject)) {
              throw new MergeValidationException(PLUGIN_VALUE_NOT_EDITABLE);
            }

            if (ProjectConfigEntry.Type.LIST.equals(configEntry.getType())
                && value != null
                && !configEntry.getPermittedValues().contains(value)) {
              throw new MergeValidationException(PLUGIN_VALUE_NOT_PERMITTED);
            }
          }
        } catch (ConfigInvalidException | IOException e) {
          throw new MergeValidationException(INVALID_CONFIG);
        }
      }
    }