Remove current_user predicates
The result of a submittability check should not depend on the user who is asking for it. If administrators want to make a distinction on who should be allowed to submit a change, they can use permissions to do so. This is especially true for the submit rule that would enforce that only change owners can submit a change. This can be achieved by using the change owners group in a permission rule. More discussions can be found at: https://groups.google.com/forum/#!msg/repo-discuss/vW6XhUOkqik/Ea4pco6vlCQJ Change-Id: I73b370bdd4e9729365e8daac3f1a8a7b155ffc4d
This commit is contained in:
		
				
					committed by
					
						
						Edwin Kempin
					
				
			
			
				
	
			
			
			
						parent
						
							a3d0ed721a
						
					
				
				
					commit
					d7990904e4
				
			@@ -51,13 +51,6 @@ of them we must use a qualified name like `gerrit:change_branch(X)`.
 | 
			
		||||
|`commit_stats/3`   |`commit_stats(5,20,50).`
 | 
			
		||||
    |Number of files modified, number of insertions and the number of deletions.
 | 
			
		||||
 | 
			
		||||
.4+|`current_user/1`  |`current_user(user(1000000)).`
 | 
			
		||||
    .4+|Current user as one of the four given possibilities
 | 
			
		||||
 | 
			
		||||
                      |`current_user(user(anonymous)).`
 | 
			
		||||
                      |`current_user(user(peer_daemon)).`
 | 
			
		||||
                      |`current_user(user(replication)).`
 | 
			
		||||
 | 
			
		||||
|`pure_revert/1`     |`pure_revert(1).`
 | 
			
		||||
    |link:rest-api-changes.html#get-pure-revert[Pure revert] as integer atom (1 if
 | 
			
		||||
        the change is a pure revert, 0 otherwise)
 | 
			
		||||
 
 | 
			
		||||
@@ -977,30 +977,7 @@ add_apprentice_master(S1, S2) :-
 | 
			
		||||
add_apprentice_master(S, S).
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
=== Example 15: Only allow Author to submit change
 | 
			
		||||
This example adds a new needed category `Only-Author-Can-Submit` for any user
 | 
			
		||||
that is not the author of the patch. This effectively blocks all users except
 | 
			
		||||
the author from submitting the change. This could result in an impossible
 | 
			
		||||
situation if the author does not have permissions for submitting the change.
 | 
			
		||||
 | 
			
		||||
`rules.pl`
 | 
			
		||||
[source,prolog]
 | 
			
		||||
----
 | 
			
		||||
submit_rule(S) :-
 | 
			
		||||
    gerrit:default_submit(In),
 | 
			
		||||
    In =.. [submit | Ls],
 | 
			
		||||
    only_allow_author_to_submit(Ls, R),
 | 
			
		||||
    S =.. [submit | R].
 | 
			
		||||
 | 
			
		||||
only_allow_author_to_submit(S, S) :-
 | 
			
		||||
    gerrit:commit_author(Id),
 | 
			
		||||
    gerrit:current_user(Id),
 | 
			
		||||
    !.
 | 
			
		||||
 | 
			
		||||
only_allow_author_to_submit(S1, [label('Only-Author-Can-Submit', need(_)) | S1]).
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
=== Example 16: Make change submittable if all comments have been resolved
 | 
			
		||||
=== Example 15: Make change submittable if all comments have been resolved
 | 
			
		||||
In this example we will use the `unresolved_comments_count` fact about a
 | 
			
		||||
change. Our goal is to block the submission of any change with some
 | 
			
		||||
unresolved comments. Basically, it can be achieved by the following rules:
 | 
			
		||||
@@ -1050,7 +1027,7 @@ It's only used to show `'Needs All-Comments-Resolved'` in the UI to clearly
 | 
			
		||||
indicate to the user that all the comments have to be resolved for the
 | 
			
		||||
change to become submittable.
 | 
			
		||||
 | 
			
		||||
=== Example 17: Make change submittable if it is a pure revert
 | 
			
		||||
=== Example 16: Make change submittable if it is a pure revert
 | 
			
		||||
In this example we will use the `pure_revert` fact about a
 | 
			
		||||
change. Our goal is to block the submission of any change that is not a
 | 
			
		||||
pure revert. Basically, it can be achieved by the following rules:
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ import com.google.gerrit.extensions.client.SubmitType;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.account.AccountCache;
 | 
			
		||||
import com.google.gerrit.server.account.Accounts;
 | 
			
		||||
import com.google.gerrit.server.account.Emails;
 | 
			
		||||
@@ -87,7 +86,7 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public interface Factory {
 | 
			
		||||
    SubmitRuleEvaluator create(CurrentUser user, ChangeData cd);
 | 
			
		||||
    SubmitRuleEvaluator create(ChangeData cd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private final AccountCache accountCache;
 | 
			
		||||
@@ -99,7 +98,6 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
  private SubmitRuleOptions.Builder optsBuilder = SubmitRuleOptions.builder();
 | 
			
		||||
  private SubmitRuleOptions opts;
 | 
			
		||||
  private Change change;
 | 
			
		||||
  private CurrentUser user;
 | 
			
		||||
  private PatchSet patchSet;
 | 
			
		||||
  private boolean logErrors = true;
 | 
			
		||||
  private long reductionsConsumed;
 | 
			
		||||
@@ -113,13 +111,11 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
      Accounts accounts,
 | 
			
		||||
      Emails emails,
 | 
			
		||||
      ProjectCache projectCache,
 | 
			
		||||
      @Assisted CurrentUser user,
 | 
			
		||||
      @Assisted ChangeData cd) {
 | 
			
		||||
    this.accountCache = accountCache;
 | 
			
		||||
    this.accounts = accounts;
 | 
			
		||||
    this.emails = emails;
 | 
			
		||||
    this.projectCache = projectCache;
 | 
			
		||||
    this.user = user;
 | 
			
		||||
    this.cd = cd;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -229,11 +225,7 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
    try {
 | 
			
		||||
      results =
 | 
			
		||||
          evaluateImpl(
 | 
			
		||||
              "locate_submit_rule",
 | 
			
		||||
              "can_submit",
 | 
			
		||||
              "locate_submit_filter",
 | 
			
		||||
              "filter_submit_results",
 | 
			
		||||
              user);
 | 
			
		||||
              "locate_submit_rule", "can_submit", "locate_submit_filter", "filter_submit_results");
 | 
			
		||||
    } catch (RuleEvalException e) {
 | 
			
		||||
      return ruleError(e.getMessage(), e);
 | 
			
		||||
    }
 | 
			
		||||
@@ -391,11 +383,7 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
              "locate_submit_type",
 | 
			
		||||
              "get_submit_type",
 | 
			
		||||
              "locate_submit_type_filter",
 | 
			
		||||
              "filter_submit_type_results",
 | 
			
		||||
              // Do not include current user in submit type evaluation. This is used
 | 
			
		||||
              // for mergeability checks, which are stored persistently and so must
 | 
			
		||||
              // have a consistent view of the submit type.
 | 
			
		||||
              null);
 | 
			
		||||
              "filter_submit_type_results");
 | 
			
		||||
    } catch (RuleEvalException e) {
 | 
			
		||||
      return typeError(e.getMessage(), e);
 | 
			
		||||
    }
 | 
			
		||||
@@ -460,10 +448,9 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
      String userRuleLocatorName,
 | 
			
		||||
      String userRuleWrapperName,
 | 
			
		||||
      String filterRuleLocatorName,
 | 
			
		||||
      String filterRuleWrapperName,
 | 
			
		||||
      CurrentUser user)
 | 
			
		||||
      String filterRuleWrapperName)
 | 
			
		||||
      throws RuleEvalException {
 | 
			
		||||
    PrologEnvironment env = getPrologEnvironment(user);
 | 
			
		||||
    PrologEnvironment env = getPrologEnvironment();
 | 
			
		||||
    try {
 | 
			
		||||
      Term sr = env.once("gerrit", userRuleLocatorName, new VariableTerm());
 | 
			
		||||
      List<Term> results = new ArrayList<>();
 | 
			
		||||
@@ -507,7 +494,7 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private PrologEnvironment getPrologEnvironment(CurrentUser user) throws RuleEvalException {
 | 
			
		||||
  private PrologEnvironment getPrologEnvironment() throws RuleEvalException {
 | 
			
		||||
    PrologEnvironment env;
 | 
			
		||||
    try {
 | 
			
		||||
      if (opts.rule() == null) {
 | 
			
		||||
@@ -529,9 +516,6 @@ public class SubmitRuleEvaluator {
 | 
			
		||||
    env.set(StoredValues.EMAILS, emails);
 | 
			
		||||
    env.set(StoredValues.REVIEW_DB, cd.db());
 | 
			
		||||
    env.set(StoredValues.CHANGE_DATA, cd);
 | 
			
		||||
    if (user != null) {
 | 
			
		||||
      env.set(StoredValues.CURRENT_USER, user);
 | 
			
		||||
    }
 | 
			
		||||
    env.set(StoredValues.PROJECT_STATE, projectState);
 | 
			
		||||
    return env;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -911,11 +911,7 @@ public class ChangeData {
 | 
			
		||||
      if (!lazyLoad) {
 | 
			
		||||
        return Collections.emptyList();
 | 
			
		||||
      }
 | 
			
		||||
      records =
 | 
			
		||||
          submitRuleEvaluatorFactory
 | 
			
		||||
              .create(userFactory.create(change().getOwner()), this)
 | 
			
		||||
              .setOptions(options)
 | 
			
		||||
              .evaluate();
 | 
			
		||||
      records = submitRuleEvaluatorFactory.create(this).setOptions(options).evaluate();
 | 
			
		||||
      submitRecords.put(options, records);
 | 
			
		||||
    }
 | 
			
		||||
    return records;
 | 
			
		||||
@@ -932,10 +928,7 @@ public class ChangeData {
 | 
			
		||||
 | 
			
		||||
  public SubmitTypeRecord submitTypeRecord() throws OrmException {
 | 
			
		||||
    if (submitTypeRecord == null) {
 | 
			
		||||
      submitTypeRecord =
 | 
			
		||||
          submitRuleEvaluatorFactory
 | 
			
		||||
              .create(userFactory.create(change().getOwner()), this)
 | 
			
		||||
              .getSubmitType();
 | 
			
		||||
      submitTypeRecord = submitRuleEvaluatorFactory.create(this).getSubmitType();
 | 
			
		||||
    }
 | 
			
		||||
    return submitTypeRecord;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ import com.google.gerrit.index.query.QueryResult;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.config.TrackingFooters;
 | 
			
		||||
import com.google.gerrit.server.data.ChangeAttribute;
 | 
			
		||||
import com.google.gerrit.server.data.PatchSetAttribute;
 | 
			
		||||
@@ -82,7 +81,6 @@ public class OutputStreamQuery {
 | 
			
		||||
  private final ChangeQueryProcessor queryProcessor;
 | 
			
		||||
  private final EventFactory eventFactory;
 | 
			
		||||
  private final TrackingFooters trackingFooters;
 | 
			
		||||
  private final CurrentUser user;
 | 
			
		||||
  private final SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory;
 | 
			
		||||
 | 
			
		||||
  private OutputFormat outputFormat = OutputFormat.TEXT;
 | 
			
		||||
@@ -107,7 +105,6 @@ public class OutputStreamQuery {
 | 
			
		||||
      ChangeQueryProcessor queryProcessor,
 | 
			
		||||
      EventFactory eventFactory,
 | 
			
		||||
      TrackingFooters trackingFooters,
 | 
			
		||||
      CurrentUser user,
 | 
			
		||||
      SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory) {
 | 
			
		||||
    this.db = db;
 | 
			
		||||
    this.repoManager = repoManager;
 | 
			
		||||
@@ -115,7 +112,6 @@ public class OutputStreamQuery {
 | 
			
		||||
    this.queryProcessor = queryProcessor;
 | 
			
		||||
    this.eventFactory = eventFactory;
 | 
			
		||||
    this.trackingFooters = trackingFooters;
 | 
			
		||||
    this.user = user;
 | 
			
		||||
    this.submitRuleEvaluatorFactory = submitRuleEvaluatorFactory;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -254,7 +250,7 @@ public class OutputStreamQuery {
 | 
			
		||||
 | 
			
		||||
    if (includeSubmitRecords) {
 | 
			
		||||
      eventFactory.addSubmitRecords(
 | 
			
		||||
          c, submitRuleEvaluatorFactory.create(user, d).setAllowClosed(true).evaluate());
 | 
			
		||||
          c, submitRuleEvaluatorFactory.create(d).setAllowClosed(true).evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (includeCommitMessage) {
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,6 @@ import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
 | 
			
		||||
import com.google.gerrit.server.ChangeUtil;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.change.MergeabilityCache;
 | 
			
		||||
import com.google.gerrit.server.change.RevisionResource;
 | 
			
		||||
import com.google.gerrit.server.git.BranchOrderSection;
 | 
			
		||||
@@ -113,7 +112,7 @@ public class Mergeable implements RestReadView<RevisionResource> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ChangeData cd = changeDataFactory.create(db.get(), resource.getNotes());
 | 
			
		||||
    result.submitType = getSubmitType(resource.getUser(), cd, ps);
 | 
			
		||||
    result.submitType = getSubmitType(cd, ps);
 | 
			
		||||
 | 
			
		||||
    try (Repository git = gitManager.openRepository(change.getProject())) {
 | 
			
		||||
      ObjectId commit = toId(ps);
 | 
			
		||||
@@ -145,10 +144,9 @@ public class Mergeable implements RestReadView<RevisionResource> {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private SubmitType getSubmitType(CurrentUser user, ChangeData cd, PatchSet patchSet)
 | 
			
		||||
      throws OrmException {
 | 
			
		||||
  private SubmitType getSubmitType(ChangeData cd, PatchSet patchSet) throws OrmException {
 | 
			
		||||
    SubmitTypeRecord rec =
 | 
			
		||||
        submitRuleEvaluatorFactory.create(user, cd).setPatchSet(patchSet).getSubmitType();
 | 
			
		||||
        submitRuleEvaluatorFactory.create(cd).setPatchSet(patchSet).getSubmitType();
 | 
			
		||||
    if (rec.status != SubmitTypeRecord.Status.OK) {
 | 
			
		||||
      throw new OrmException("Submit type rule failed: " + rec);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -451,7 +451,7 @@ public class PostReviewers
 | 
			
		||||
        result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size());
 | 
			
		||||
        for (Account.Id accountId : opResult.addedCCs()) {
 | 
			
		||||
          IdentifiedUser u = identifiedUserFactory.create(accountId);
 | 
			
		||||
          result.ccs.add(json.format(caller, new ReviewerInfo(accountId.get()), perm.user(u), cd));
 | 
			
		||||
          result.ccs.add(json.format(new ReviewerInfo(accountId.get()), perm.user(u), cd));
 | 
			
		||||
        }
 | 
			
		||||
        accountLoaderFactory.create(true).fill(result.ccs);
 | 
			
		||||
        for (Address a : reviewersByEmail) {
 | 
			
		||||
@@ -464,7 +464,6 @@ public class PostReviewers
 | 
			
		||||
          IdentifiedUser u = identifiedUserFactory.create(psa.getAccountId());
 | 
			
		||||
          result.reviewers.add(
 | 
			
		||||
              json.format(
 | 
			
		||||
                  caller,
 | 
			
		||||
                  new ReviewerInfo(psa.getAccountId().get()),
 | 
			
		||||
                  perm.user(u),
 | 
			
		||||
                  cd,
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@ import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.ApprovalsUtil;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.account.AccountLoader;
 | 
			
		||||
import com.google.gerrit.server.change.ReviewerResource;
 | 
			
		||||
import com.google.gerrit.server.permissions.LabelPermission;
 | 
			
		||||
@@ -79,7 +78,6 @@ public class ReviewerJson {
 | 
			
		||||
      }
 | 
			
		||||
      ReviewerInfo info =
 | 
			
		||||
          format(
 | 
			
		||||
              rsrc.getChangeResource().getUser(),
 | 
			
		||||
              new ReviewerInfo(rsrc.getReviewerUser().getAccountId().get()),
 | 
			
		||||
              permissionBackend.user(rsrc.getReviewerUser()).database(db).change(cd),
 | 
			
		||||
              cd);
 | 
			
		||||
@@ -95,12 +93,10 @@ public class ReviewerJson {
 | 
			
		||||
    return format(ImmutableList.<ReviewerResource>of(rsrc));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public ReviewerInfo format(
 | 
			
		||||
      CurrentUser user, ReviewerInfo out, PermissionBackend.ForChange perm, ChangeData cd)
 | 
			
		||||
  public ReviewerInfo format(ReviewerInfo out, PermissionBackend.ForChange perm, ChangeData cd)
 | 
			
		||||
      throws OrmException, PermissionBackendException {
 | 
			
		||||
    PatchSet.Id psId = cd.change().currentPatchSetId();
 | 
			
		||||
    return format(
 | 
			
		||||
        user,
 | 
			
		||||
        out,
 | 
			
		||||
        perm,
 | 
			
		||||
        cd,
 | 
			
		||||
@@ -109,7 +105,6 @@ public class ReviewerJson {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public ReviewerInfo format(
 | 
			
		||||
      CurrentUser user,
 | 
			
		||||
      ReviewerInfo out,
 | 
			
		||||
      PermissionBackend.ForChange perm,
 | 
			
		||||
      ChangeData cd,
 | 
			
		||||
@@ -129,7 +124,7 @@ public class ReviewerJson {
 | 
			
		||||
    // do not exist in the DB.
 | 
			
		||||
    PatchSet ps = cd.currentPatchSet();
 | 
			
		||||
    if (ps != null) {
 | 
			
		||||
      for (SubmitRecord rec : submitRuleEvaluatorFactory.create(user, cd).evaluate()) {
 | 
			
		||||
      for (SubmitRecord rec : submitRuleEvaluatorFactory.create(cd).evaluate()) {
 | 
			
		||||
        if (rec.labels == null) {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -71,8 +71,7 @@ public class TestSubmitRule implements RestModifyView<RevisionResource, TestSubm
 | 
			
		||||
    }
 | 
			
		||||
    input.filters = MoreObjects.firstNonNull(input.filters, filters);
 | 
			
		||||
    SubmitRuleEvaluator evaluator =
 | 
			
		||||
        submitRuleEvaluatorFactory.create(
 | 
			
		||||
            rsrc.getUser(), changeDataFactory.create(db.get(), rsrc.getNotes()));
 | 
			
		||||
        submitRuleEvaluatorFactory.create(changeDataFactory.create(db.get(), rsrc.getNotes()));
 | 
			
		||||
 | 
			
		||||
    List<SubmitRecord> records =
 | 
			
		||||
        evaluator
 | 
			
		||||
 
 | 
			
		||||
@@ -65,8 +65,7 @@ public class TestSubmitType implements RestModifyView<RevisionResource, TestSubm
 | 
			
		||||
    }
 | 
			
		||||
    input.filters = MoreObjects.firstNonNull(input.filters, filters);
 | 
			
		||||
    SubmitRuleEvaluator evaluator =
 | 
			
		||||
        submitRuleEvaluatorFactory.create(
 | 
			
		||||
            rsrc.getUser(), changeDataFactory.create(db.get(), rsrc.getNotes()));
 | 
			
		||||
        submitRuleEvaluatorFactory.create(changeDataFactory.create(db.get(), rsrc.getNotes()));
 | 
			
		||||
 | 
			
		||||
    SubmitTypeRecord rec =
 | 
			
		||||
        evaluator
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.AnonymousUser;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
import com.google.gerrit.server.account.AccountCache;
 | 
			
		||||
import com.google.gerrit.server.account.Accounts;
 | 
			
		||||
@@ -54,7 +53,6 @@ public final class StoredValues {
 | 
			
		||||
  public static final StoredValue<Emails> EMAILS = create(Emails.class);
 | 
			
		||||
  public static final StoredValue<ReviewDb> REVIEW_DB = create(ReviewDb.class);
 | 
			
		||||
  public static final StoredValue<ChangeData> CHANGE_DATA = create(ChangeData.class);
 | 
			
		||||
  public static final StoredValue<CurrentUser> CURRENT_USER = create(CurrentUser.class);
 | 
			
		||||
  public static final StoredValue<ProjectState> PROJECT_STATE = create(ProjectState.class);
 | 
			
		||||
 | 
			
		||||
  public static Change getChange(Prolog engine) throws SystemException {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,69 +0,0 @@
 | 
			
		||||
// Copyright (C) 2011 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package gerrit;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.server.AnonymousUser;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.PeerDaemonUser;
 | 
			
		||||
import com.google.gerrit.server.rules.StoredValues;
 | 
			
		||||
import com.googlecode.prolog_cafe.exceptions.EvaluationException;
 | 
			
		||||
import com.googlecode.prolog_cafe.exceptions.PrologException;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.IntegerTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Operation;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Predicate;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Prolog;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.StructureTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.SymbolTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Term;
 | 
			
		||||
 | 
			
		||||
public class PRED_current_user_1 extends Predicate.P1 {
 | 
			
		||||
  private static final SymbolTerm user = SymbolTerm.intern("user", 1);
 | 
			
		||||
  private static final SymbolTerm anonymous = SymbolTerm.intern("anonymous");
 | 
			
		||||
  private static final SymbolTerm peerDaemon = SymbolTerm.intern("peer_daemon");
 | 
			
		||||
 | 
			
		||||
  public PRED_current_user_1(Term a1, Operation n) {
 | 
			
		||||
    arg1 = a1;
 | 
			
		||||
    cont = n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Operation exec(Prolog engine) throws PrologException {
 | 
			
		||||
    engine.setB0();
 | 
			
		||||
    Term a1 = arg1.dereference();
 | 
			
		||||
 | 
			
		||||
    CurrentUser curUser = StoredValues.CURRENT_USER.getOrNull(engine);
 | 
			
		||||
    if (curUser == null) {
 | 
			
		||||
      throw new EvaluationException("Current user not available in this rule type");
 | 
			
		||||
    }
 | 
			
		||||
    Term resultTerm;
 | 
			
		||||
 | 
			
		||||
    if (curUser.isIdentifiedUser()) {
 | 
			
		||||
      Account.Id id = curUser.getAccountId();
 | 
			
		||||
      resultTerm = new IntegerTerm(id.get());
 | 
			
		||||
    } else if (curUser instanceof AnonymousUser) {
 | 
			
		||||
      resultTerm = anonymous;
 | 
			
		||||
    } else if (curUser instanceof PeerDaemonUser) {
 | 
			
		||||
      resultTerm = peerDaemon;
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new EvaluationException("Unknown user type");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!a1.unify(new StructureTerm(user, resultTerm), engine.trail)) {
 | 
			
		||||
      return engine.fail();
 | 
			
		||||
    }
 | 
			
		||||
    return cont;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,108 +0,0 @@
 | 
			
		||||
// Copyright (C) 2011 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package gerrit;
 | 
			
		||||
 | 
			
		||||
import static com.googlecode.prolog_cafe.lang.SymbolTerm.intern;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
import com.google.gerrit.server.rules.PrologEnvironment;
 | 
			
		||||
import com.google.gerrit.server.rules.StoredValues;
 | 
			
		||||
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
 | 
			
		||||
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
 | 
			
		||||
import com.googlecode.prolog_cafe.exceptions.PrologException;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.IntegerTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Operation;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Predicate;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Prolog;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.StructureTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.SymbolTerm;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.Term;
 | 
			
		||||
import com.googlecode.prolog_cafe.lang.VariableTerm;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Loads a CurrentUser object for a user identity.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Values are cached in the hash {@code current_user}, avoiding recreation during a single
 | 
			
		||||
 * evaluation.
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 *   current_user(user(+AccountId), -CurrentUser).
 | 
			
		||||
 * </pre>
 | 
			
		||||
 */
 | 
			
		||||
class PRED_current_user_2 extends Predicate.P2 {
 | 
			
		||||
  private static final SymbolTerm user = intern("user", 1);
 | 
			
		||||
  private static final SymbolTerm anonymous = intern("anonymous");
 | 
			
		||||
 | 
			
		||||
  PRED_current_user_2(Term a1, Term a2, Operation n) {
 | 
			
		||||
    arg1 = a1;
 | 
			
		||||
    arg2 = a2;
 | 
			
		||||
    cont = n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Operation exec(Prolog engine) throws PrologException {
 | 
			
		||||
    engine.setB0();
 | 
			
		||||
    Term a1 = arg1.dereference();
 | 
			
		||||
    Term a2 = arg2.dereference();
 | 
			
		||||
 | 
			
		||||
    if (a1 instanceof VariableTerm) {
 | 
			
		||||
      throw new PInstantiationException(this, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!a2.unify(createUser(engine, a1), engine.trail)) {
 | 
			
		||||
      return engine.fail();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cont;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Term createUser(Prolog engine, Term key) {
 | 
			
		||||
    if (!(key instanceof StructureTerm)
 | 
			
		||||
        || key.arity() != 1
 | 
			
		||||
        || !((StructureTerm) key).functor().equals(user)) {
 | 
			
		||||
      throw new IllegalTypeException(this, 1, "user(int)", key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Term idTerm = key.arg(0);
 | 
			
		||||
    CurrentUser user;
 | 
			
		||||
    if (idTerm instanceof IntegerTerm) {
 | 
			
		||||
      Map<Account.Id, IdentifiedUser> cache = StoredValues.USERS.get(engine);
 | 
			
		||||
      Account.Id accountId = new Account.Id(((IntegerTerm) idTerm).intValue());
 | 
			
		||||
      user = cache.get(accountId);
 | 
			
		||||
      if (user == null) {
 | 
			
		||||
        IdentifiedUser.GenericFactory userFactory = userFactory(engine);
 | 
			
		||||
        IdentifiedUser who = userFactory.create(accountId);
 | 
			
		||||
        cache.put(accountId, who);
 | 
			
		||||
        user = who;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else if (idTerm.equals(anonymous)) {
 | 
			
		||||
      user = StoredValues.ANONYMOUS_USER.get(engine);
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new IllegalTypeException(this, 1, "user(int)", key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return new JavaObjectTerm(user);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static IdentifiedUser.GenericFactory userFactory(Prolog engine) {
 | 
			
		||||
    return ((PrologEnvironment) engine.control).getArgs().getUserFactory();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user