use of com.google.gerrit.entities.Account in project gerrit by GerritCodeReview.
the class AccountIT method validateAccountActivation.
@Test
public void validateAccountActivation() throws Exception {
Account.Id activatableAccountId = accountOperations.newAccount().inactive().preferredEmail("foo@activatable.com").create();
Account.Id deactivatableAccountId = accountOperations.newAccount().preferredEmail("foo@deactivatable.com").create();
AccountActivationValidationListener validationListener = new AccountActivationValidationListener() {
@Override
public void validateActivation(AccountState account) throws ValidationException {
String preferredEmail = account.account().preferredEmail();
if (preferredEmail == null || !preferredEmail.endsWith("@activatable.com")) {
throw new ValidationException("not allowed to active account");
}
}
@Override
public void validateDeactivation(AccountState account) throws ValidationException {
String preferredEmail = account.account().preferredEmail();
if (preferredEmail == null || !preferredEmail.endsWith("@deactivatable.com")) {
throw new ValidationException("not allowed to deactive account");
}
}
};
AccountActivationListener listener = mock(AccountActivationListener.class);
try (Registration registration = extensionRegistry.newRegistration().add(validationListener).add(listener)) {
/* Test account that can be activated, but not deactivated */
// Deactivate account that is already inactive
ResourceConflictException thrown = assertThrows(ResourceConflictException.class, () -> gApi.accounts().id(activatableAccountId.get()).setActive(false));
assertThat(thrown).hasMessageThat().isEqualTo("account not active");
assertThat(accountOperations.account(activatableAccountId).get().active()).isFalse();
verifyNoInteractions(listener);
// Activate account that can be activated
gApi.accounts().id(activatableAccountId.get()).setActive(true);
assertThat(accountOperations.account(activatableAccountId).get().active()).isTrue();
verify(listener).onAccountActivated(activatableAccountId.get());
verifyNoMoreInteractions(listener);
// Activate account that is already active
gApi.accounts().id(activatableAccountId.get()).setActive(true);
assertThat(accountOperations.account(activatableAccountId).get().active()).isTrue();
verifyNoMoreInteractions(listener);
// Try deactivating account that cannot be deactivated
thrown = assertThrows(ResourceConflictException.class, () -> gApi.accounts().id(activatableAccountId.get()).setActive(false));
assertThat(thrown).hasMessageThat().isEqualTo("not allowed to deactive account");
assertThat(accountOperations.account(activatableAccountId).get().active()).isTrue();
verifyNoMoreInteractions(listener);
/* Test account that can be deactivated, but not activated */
// Activate account that is already inactive
gApi.accounts().id(deactivatableAccountId.get()).setActive(true);
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isTrue();
verifyNoMoreInteractions(listener);
// Deactivate account that can be deactivated
gApi.accounts().id(deactivatableAccountId.get()).setActive(false);
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
verify(listener).onAccountDeactivated(deactivatableAccountId.get());
verifyNoMoreInteractions(listener);
// Deactivate account that is already inactive
thrown = assertThrows(ResourceConflictException.class, () -> gApi.accounts().id(deactivatableAccountId.get()).setActive(false));
assertThat(thrown).hasMessageThat().isEqualTo("account not active");
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
verifyNoMoreInteractions(listener);
// Try activating account that cannot be activated
thrown = assertThrows(ResourceConflictException.class, () -> gApi.accounts().id(deactivatableAccountId.get()).setActive(true));
assertThat(thrown).hasMessageThat().isEqualTo("not allowed to active account");
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
verifyNoMoreInteractions(listener);
}
}
use of com.google.gerrit.entities.Account in project gerrit by GerritCodeReview.
the class AbstractDaemonTest method verifyNoAccountDetailsInChangeNotes.
/**
* Verify that NoteDB commits do not persist user-sensitive information, by running checks for all
* commits in {@link RefNames#changeMetaRef} for all changes, created during the test.
*
* <p>These tests prevent regression, assuming appropriate test coverage for new features. The
* verification is disabled by default and can be enabled using {@link VerifyNoPiiInChangeNotes}
* annotation either on test class or method.
*/
protected void verifyNoAccountDetailsInChangeNotes() throws RestApiException, IOException {
List<ChangeInfo> allChanges = gApi.changes().query().get();
List<AccountState> allAccounts = accounts.all();
for (ChangeInfo change : allChanges) {
try (Repository repo = repoManager.openRepository(Project.nameKey(change.project))) {
String metaRefName = RefNames.changeMetaRef(Change.Id.tryParse(change._number.toString()).get());
ObjectId metaTip = repo.getRefDatabase().exactRef(metaRefName).getObjectId();
ChangeNotesRevWalk revWalk = ChangeNotesCommit.newRevWalk(repo);
revWalk.reset();
revWalk.markStart(revWalk.parseCommit(metaTip));
ChangeNotesCommit commit;
while ((commit = revWalk.next()) != null) {
String fullMessage = commit.getFullMessage();
for (AccountState accountState : allAccounts) {
Account account = accountState.account();
assertThat(fullMessage).doesNotContain(account.getName());
if (account.fullName() != null) {
assertThat(fullMessage).doesNotContain(account.fullName());
}
if (account.displayName() != null) {
assertThat(fullMessage).doesNotContain(account.displayName());
}
if (account.preferredEmail() != null) {
assertThat(fullMessage).doesNotContain(account.preferredEmail());
}
if (accountState.userName().isPresent()) {
assertThat(fullMessage).doesNotContain(accountState.userName().get());
}
List<String> allEmails = accountState.externalIds().stream().map(ExternalId::email).filter(Objects::nonNull).collect(toImmutableList());
for (String email : allEmails) {
assertThat(fullMessage).doesNotContain(email);
}
}
}
}
}
}
use of com.google.gerrit.entities.Account in project gerrit by GerritCodeReview.
the class InitAdminUser method postRun.
@Override
public void postRun() throws Exception {
if (!accounts.hasAnyAccount()) {
welcome();
}
AuthType authType = flags.cfg.getEnum(AuthType.values(), "auth", null, "type", null);
if (authType != AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT) {
return;
}
if (!accounts.hasAnyAccount()) {
ui.header("Gerrit Administrator");
if (ui.yesno(true, "Create administrator user")) {
Account.Id id = Account.id(sequencesOnInit.nextAccountId());
String username = ui.readString("admin", "username");
String name = ui.readString("Administrator", "name");
String httpPassword = ui.readString("secret", "HTTP password");
AccountSshKey sshKey = readSshKey(id);
String email = readEmail(sshKey);
List<ExternalId> extIds = new ArrayList<>(2);
extIds.add(externalIdFactory.createUsername(username, id, httpPassword));
if (email != null) {
extIds.add(externalIdFactory.createEmail(id, email));
}
externalIds.insert("Add external IDs for initial admin user", extIds);
Account persistedAccount = accounts.insert(Account.builder(id, TimeUtil.now()).setFullName(name).setPreferredEmail(email));
// Only two groups should exist at this point in time and hence iterating over all of them
// is cheap.
Optional<GroupReference> adminGroupReference = groupsOnInit.getAllGroupReferences().filter(group -> group.getName().equals("Administrators")).findAny();
if (!adminGroupReference.isPresent()) {
throw new NoSuchGroupException("Administrators");
}
GroupReference adminGroup = adminGroupReference.get();
groupsOnInit.addGroupMember(adminGroup.getUUID(), persistedAccount);
if (sshKey != null) {
VersionedAuthorizedKeysOnInit authorizedKeys = authorizedKeysFactory.create(id).load();
authorizedKeys.addKey(sshKey.sshPublicKey());
authorizedKeys.save("Add SSH key for initial admin user\n");
}
AccountState as = AccountState.forAccount(persistedAccount, extIds);
for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
accountIndex.replace(as);
}
InternalGroup adminInternalGroup = groupsOnInit.getExistingGroup(adminGroup);
for (GroupIndex groupIndex : groupIndexCollection.getWriteIndexes()) {
groupIndex.replace(adminInternalGroup);
}
}
}
}
use of com.google.gerrit.entities.Account in project gerrit by GerritCodeReview.
the class ChangeJson method removableReviewers.
private Collection<AccountInfo> removableReviewers(ChangeData cd, ChangeInfo out) throws PermissionBackendException {
// Although this is called removableReviewers, this method also determines
// which CCs are removable.
//
// For reviewers, we need to look at each approval, because the reviewer
// should only be considered removable if *all* of their approvals can be
// removed. First, add all reviewers with *any* removable approval to the
// "removable" set. Along the way, if we encounter a non-removable approval,
// add the reviewer to the "fixed" set. Before we return, remove all members
// of "fixed" from "removable", because not all of their approvals can be
// removed.
Collection<LabelInfo> labels = out.labels.values();
Set<Account.Id> fixed = Sets.newHashSetWithExpectedSize(labels.size());
Set<Account.Id> removable = new HashSet<>();
// Add all reviewers, which will later be removed if they are in the "fixed" set.
removable.addAll(out.reviewers.getOrDefault(ReviewerState.REVIEWER, Collections.emptySet()).stream().filter(a -> a._accountId != null).map(a -> Account.id(a._accountId)).collect(Collectors.toSet()));
// Check if the user has the permission to remove a reviewer. This means we can bypass the
// testRemoveReviewer check for a specific reviewer in the loop saving potentially many
// permission checks.
boolean canRemoveAnyReviewer = permissionBackend.user(userProvider.get()).change(cd).test(ChangePermission.REMOVE_REVIEWER);
for (LabelInfo label : labels) {
if (label.all == null) {
continue;
}
for (ApprovalInfo ai : label.all) {
Account.Id id = Account.id(ai._accountId);
if (!canRemoveAnyReviewer && !removeReviewerControl.testRemoveReviewer(cd, userProvider.get(), id, MoreObjects.firstNonNull(ai.value, 0))) {
fixed.add(id);
}
}
}
// CCs are simpler than reviewers. They are removable if the ChangeControl
// would permit a non-negative approval by that account to be removed, in
// which case add them to removable. We don't need to add unremovable CCs to
// "fixed" because we only visit each CC once here.
Collection<AccountInfo> ccs = out.reviewers.get(ReviewerState.CC);
if (ccs != null) {
for (AccountInfo ai : ccs) {
if (ai._accountId != null) {
Account.Id id = Account.id(ai._accountId);
if (canRemoveAnyReviewer || removeReviewerControl.testRemoveReviewer(cd, userProvider.get(), id, 0)) {
removable.add(id);
}
}
}
}
// Subtract any reviewers with non-removable approvals from the "removable"
// set. This also subtracts any CCs that for some reason also hold
// unremovable approvals.
removable.removeAll(fixed);
List<AccountInfo> result = Lists.newArrayListWithCapacity(removable.size());
for (Account.Id id : removable) {
result.add(accountLoader.get(id));
}
// Reviewers added by email are always removable
for (Collection<AccountInfo> infos : out.reviewers.values()) {
for (AccountInfo info : infos) {
if (info._accountId == null) {
result.add(info);
}
}
}
return result;
}
use of com.google.gerrit.entities.Account in project gerrit by GerritCodeReview.
the class ChangeQueryBuilder method destination.
@Operator
public Predicate<ChangeData> destination(String value) throws QueryParseException {
// [name=]<name>[,user=<user>] || [user=<user>,][name=]<name>
PredicateArgs inputArgs = new PredicateArgs(value);
String name = null;
Account.Id account = null;
try (Repository git = args.repoManager.openRepository(args.allUsersName)) {
// [name=]<name>
if (inputArgs.keyValue.containsKey(ARG_ID_NAME)) {
name = inputArgs.keyValue.get(ARG_ID_NAME).value();
} else if (inputArgs.positional.size() == 1) {
name = Iterables.getOnlyElement(inputArgs.positional);
} else if (inputArgs.positional.size() > 1) {
throw new QueryParseException("Error parsing named destination: " + value);
}
// [,user=<user>]
if (inputArgs.keyValue.containsKey(ARG_ID_USER)) {
Set<Account.Id> accounts = parseAccount(inputArgs.keyValue.get(ARG_ID_USER).value());
if (accounts != null && accounts.size() > 1) {
throw error(String.format("\"%s\" resolves to multiple accounts", inputArgs.keyValue.get(ARG_ID_USER)));
}
account = (accounts == null ? self() : Iterables.getOnlyElement(accounts));
} else {
account = self();
}
VersionedAccountDestinations d = VersionedAccountDestinations.forUser(account);
d.load(args.allUsersName, git);
Set<BranchNameKey> destinations = d.getDestinationList().getDestinations(name);
if (destinations != null && !destinations.isEmpty()) {
return new DestinationPredicate(destinations, value);
}
} catch (RepositoryNotFoundException e) {
throw new QueryParseException("Unknown named destination (no " + args.allUsersName + " repo): " + name, e);
} catch (IOException | ConfigInvalidException e) {
throw new QueryParseException("Error parsing named destination: " + value, e);
}
throw new QueryParseException("Unknown named destination: " + name);
}
Aggregations