Verify the user as a valid, accepted contributor agreement before upload

We cannot accept changes into most open source projects unless the
contributor has acknowledged they are permitted and willing to make
the code available under the necessary licenses.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2008-12-30 13:22:01 -08:00
parent 25dd683941
commit b0b3fc63e9
3 changed files with 95 additions and 3 deletions

View File

@@ -16,8 +16,11 @@ package com.google.gerrit.server.ssh;
import com.google.gerrit.client.Link;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.reviewdb.AccountAgreement;
import com.google.gerrit.client.reviewdb.Branch;
import com.google.gerrit.client.reviewdb.Change;
import com.google.gerrit.client.reviewdb.ContactInformation;
import com.google.gerrit.client.reviewdb.ContributorAgreement;
import com.google.gerrit.client.reviewdb.PatchSet;
import com.google.gerrit.git.PatchSetImporter;
import com.google.gerrit.server.GerritServer;
@@ -78,11 +81,10 @@ class Receive extends AbstractGitCommand {
@Override
protected void runImpl() throws IOException, Failure {
server = getGerritServer();
verifyActiveContributorAgreement();
lookup(reviewerId, "reviewer", reviewerEmail);
lookup(ccId, "cc", ccEmail);
// TODO verify user has signed a CLA for this project
rp = new ReceivePack(repo);
rp.setAllowCreates(true);
rp.setAllowDeletes(true);
@@ -116,6 +118,92 @@ class Receive extends AbstractGitCommand {
}
}
private void verifyActiveContributorAgreement() throws Failure {
AccountAgreement bestAgreement = null;
ContributorAgreement bestCla = null;
try {
for (final AccountAgreement a : db.accountAgreements().byAccount(
userAccount.getId()).toList()) {
final ContributorAgreement cla =
db.contributorAgreements().get(a.getAgreementId());
if (cla == null || !cla.isActive()) {
continue;
}
if (bestAgreement == null
|| bestAgreement.getStatus() != AccountAgreement.Status.VERIFIED) {
bestAgreement = a;
bestCla = cla;
}
if (bestAgreement.getStatus() == AccountAgreement.Status.VERIFIED) {
break;
}
}
} catch (OrmException e) {
throw new Failure(1, "database error");
}
if (bestCla != null && bestCla.isRequireContactInformation()) {
final ContactInformation info = userAccount.getContactInformation();
boolean fail = false;
fail |= missing(userAccount.getFullName());
fail |= missing(userAccount.getPreferredEmail());
fail |= info == null || missing(info.getAddress());
if (fail) {
final StringBuilder msg = new StringBuilder();
msg.append("\nfatal: ");
msg.append(bestCla.getShortName());
msg.append(" contributor agreement requires");
msg.append(" current contact information.\n");
if (server.getCanonicalURL() != null) {
msg.append("\nPlease review your contact information");
msg.append(":\n\n ");
msg.append(server.getCanonicalURL());
msg.append("Gerrit#");
msg.append(Link.SETTINGS_CONTACT);
msg.append("\n");
}
msg.append("\n");
throw new Failure(1, msg.toString());
}
}
if (bestAgreement != null) {
switch (bestAgreement.getStatus()) {
case VERIFIED:
return;
case REJECTED:
throw new Failure(1, "\nfatal: " + bestCla.getShortName()
+ " contributor agreement was rejected."
+ "\n (rejected on " + bestAgreement.getReviewedOn()
+ ")\n");
case NEW:
throw new Failure(1, "\nfatal: " + bestCla.getShortName()
+ " contributor agreement is still pending review.\n");
}
}
final StringBuilder msg = new StringBuilder();
msg.append("\nfatal: A Contributor Agreement"
+ " must be completed before uploading");
if (server.getCanonicalURL() != null) {
msg.append(":\n\n ");
msg.append(server.getCanonicalURL());
msg.append("Gerrit#");
msg.append(Link.SETTINGS_AGREEMENTS);
msg.append("\n");
} else {
msg.append(".");
}
msg.append("\n");
throw new Failure(1, msg.toString());
}
private static boolean missing(final String value) {
return value == null || value.trim().equals("");
}
private void lookup(final Set<Account.Id> accountIds,
final String addressType, final Set<String> emails) throws Failure {
final StringBuilder errors = new StringBuilder();