Use AccountGroup.UUID instead of Account.Id
By switching to the UUID we can have a globally unique identifier for group membership throughout the server, even if group information comes in from a different data source. Change-Id: Icb49d6a6aff8e62864ac0f78ceedbe03f01de894 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -20,7 +20,6 @@ import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||
import com.google.gerrit.reviewdb.Account;
|
||||
import com.google.gerrit.reviewdb.AccountExternalId;
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.AccountGroup.Id;
|
||||
import com.google.gerrit.reviewdb.AccountGroupName;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
@@ -158,10 +157,11 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
|
||||
map.put(account.getId(), info);
|
||||
break;
|
||||
case SAME_GROUP: {
|
||||
Set<AccountGroup.Id> usersGroups = groupsOf(account);
|
||||
usersGroups.removeAll(authConfig.getRegisteredGroups());
|
||||
Set<AccountGroup.UUID> usersGroups = groupsOf(account);
|
||||
usersGroups.remove(AccountGroup.ANONYMOUS_USERS);
|
||||
usersGroups.remove(AccountGroup.REGISTERED_USERS);
|
||||
usersGroups.remove(authConfig.getBatchUsersGroup());
|
||||
for (AccountGroup.Id myGroup : currentUser.get().getEffectiveGroups()) {
|
||||
for (AccountGroup.UUID myGroup : currentUser.get().getEffectiveGroups()) {
|
||||
if (usersGroups.contains(myGroup)) {
|
||||
map.put(account.getId(), info);
|
||||
break;
|
||||
@@ -176,9 +176,9 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Id> groupsOf(Account account) {
|
||||
private Set<AccountGroup.UUID> groupsOf(Account account) {
|
||||
IdentifiedUser user = userFactory.create(account.getId());
|
||||
return new HashSet<AccountGroup.Id>(user.getEffectiveGroups());
|
||||
return new HashSet<AccountGroup.UUID>(user.getEffectiveGroups());
|
||||
}
|
||||
|
||||
public void suggestAccountGroup(final String query, final int limit,
|
||||
@@ -189,7 +189,7 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
|
||||
final String b = a + MAX_SUFFIX;
|
||||
final int max = 10;
|
||||
final int n = limit <= 0 ? max : Math.min(limit, max);
|
||||
Set<AccountGroup.Id> memberOf = currentUser.get().getEffectiveGroups();
|
||||
Set<AccountGroup.UUID> memberOf = currentUser.get().getEffectiveGroups();
|
||||
List<AccountGroupName> names = new ArrayList<AccountGroupName>(n);
|
||||
for (AccountGroupName group : db.accountGroupNames()
|
||||
.suggestByName(a, b, n)) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.gerrit.reviewdb.AccountGroupAgreement;
|
||||
import com.google.gerrit.reviewdb.ContributorAgreement;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -36,13 +37,16 @@ class AgreementInfoFactory extends Handler<AgreementInfo> {
|
||||
}
|
||||
|
||||
private final ReviewDb db;
|
||||
private final GroupCache groupCache;
|
||||
private final IdentifiedUser user;
|
||||
|
||||
private AgreementInfo info;
|
||||
|
||||
@Inject
|
||||
AgreementInfoFactory(final ReviewDb db, final IdentifiedUser user) {
|
||||
AgreementInfoFactory(final ReviewDb db, final GroupCache groupCache,
|
||||
final IdentifiedUser user) {
|
||||
this.db = db;
|
||||
this.groupCache = groupCache;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@@ -55,9 +59,14 @@ class AgreementInfoFactory extends Handler<AgreementInfo> {
|
||||
|
||||
final List<AccountGroupAgreement> groupAccepted =
|
||||
new ArrayList<AccountGroupAgreement>();
|
||||
for (final AccountGroup.Id groupId : user.getEffectiveGroups()) {
|
||||
for (final AccountGroup.UUID groupUUID : user.getEffectiveGroups()) {
|
||||
AccountGroup group = groupCache.get(groupUUID);
|
||||
if (group == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<AccountGroupAgreement> temp =
|
||||
db.accountGroupAgreements().byGroup(groupId).toList();
|
||||
db.accountGroupAgreements().byGroup(group.getId()).toList();
|
||||
|
||||
Collections.reverse(temp);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -281,7 +282,7 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
|
||||
Collections.singleton(new AccountGroupIncludeAudit(m,
|
||||
getAccountId())));
|
||||
db.accountGroupIncludes().insert(Collections.singleton(m));
|
||||
groupIncludeCache.evictInclude(a.getId());
|
||||
groupIncludeCache.evictInclude(a.getGroupUUID());
|
||||
}
|
||||
|
||||
return groupDetailFactory.create(groupId).call();
|
||||
@@ -361,6 +362,7 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
|
||||
}
|
||||
|
||||
final Account.Id me = getAccountId();
|
||||
final Set<AccountGroup.Id> groupsToEvict = new HashSet<AccountGroup.Id>();
|
||||
for (final AccountGroupInclude.Key k : keys) {
|
||||
final AccountGroupInclude m =
|
||||
db.accountGroupIncludes().get(k);
|
||||
@@ -385,9 +387,12 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
|
||||
Collections.singleton(audit));
|
||||
}
|
||||
db.accountGroupIncludes().delete(Collections.singleton(m));
|
||||
groupIncludeCache.evictInclude(m.getIncludeId());
|
||||
groupsToEvict.add(k.getIncludeId());
|
||||
}
|
||||
}
|
||||
for (AccountGroup group : db.accountGroups().get(groupsToEvict)) {
|
||||
groupIncludeCache.evictInclude(group.getGroupUUID());
|
||||
}
|
||||
return VoidResult.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -42,10 +42,10 @@ class MyGroupsFactory extends Handler<List<AccountGroup>> {
|
||||
|
||||
@Override
|
||||
public List<AccountGroup> call() throws Exception {
|
||||
final Set<AccountGroup.Id> effective = user.getEffectiveGroups();
|
||||
final Set<AccountGroup.UUID> effective = user.getEffectiveGroups();
|
||||
final int cnt = effective.size();
|
||||
final List<AccountGroup> groupList = new ArrayList<AccountGroup>(cnt);
|
||||
for (final AccountGroup.Id groupId : effective) {
|
||||
for (final AccountGroup.UUID groupId : effective) {
|
||||
groupList.add(groupCache.get(groupId));
|
||||
}
|
||||
Collections.sort(groupList, new Comparator<AccountGroup>() {
|
||||
|
||||
@@ -127,7 +127,7 @@ final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail>
|
||||
}
|
||||
|
||||
private void computeAllowed() {
|
||||
final Set<AccountGroup.Id> am = user.getEffectiveGroups();
|
||||
final Set<AccountGroup.UUID> am = user.getEffectiveGroups();
|
||||
final ProjectState pe = projectCache.get(change.getProject());
|
||||
for (ApprovalCategory.Id category : approvalTypes.getApprovalCategories()) {
|
||||
RefControl rc = pe.controlFor(user).controlForRef(change.getDest());
|
||||
@@ -136,7 +136,7 @@ final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail>
|
||||
}
|
||||
}
|
||||
|
||||
private void computeAllowed(final Set<AccountGroup.Id> am,
|
||||
private void computeAllowed(final Set<AccountGroup.UUID> am,
|
||||
final List<RefRight> list, ApprovalCategory.Id category) {
|
||||
|
||||
Set<ApprovalCategoryValue.Id> s = allowed.get(category);
|
||||
@@ -146,7 +146,7 @@ final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail>
|
||||
}
|
||||
|
||||
for (final RefRight r : list) {
|
||||
if (!am.contains(r.getAccountGroupId())) {
|
||||
if (!am.contains(r.getAccountGroupUUID())) {
|
||||
continue;
|
||||
}
|
||||
final ApprovalType at =
|
||||
|
||||
@@ -116,6 +116,8 @@ public final class RefRight {
|
||||
@Column(id = 3)
|
||||
protected short maxValue;
|
||||
|
||||
protected transient AccountGroup.UUID groupUUID;
|
||||
|
||||
protected RefRight() {
|
||||
}
|
||||
|
||||
@@ -123,11 +125,12 @@ public final class RefRight {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public RefRight(final RefRight refRight, final AccountGroup.Id groupId) {
|
||||
public RefRight(final RefRight refRight, final AccountGroup.UUID groupId) {
|
||||
this(new RefRight.Key(refRight.getKey().projectName,
|
||||
refRight.getKey().refPattern, refRight.getKey().categoryId, groupId));
|
||||
refRight.getKey().refPattern, refRight.getKey().categoryId, null));
|
||||
setMinValue(refRight.getMinValue());
|
||||
setMaxValue(refRight.getMaxValue());
|
||||
setAccountGroupUUID(groupId);
|
||||
}
|
||||
|
||||
public RefRight.Key getKey() {
|
||||
@@ -161,6 +164,14 @@ public final class RefRight {
|
||||
return key.groupId;
|
||||
}
|
||||
|
||||
public AccountGroup.UUID getAccountGroupUUID() {
|
||||
return groupUUID;
|
||||
}
|
||||
|
||||
public void setAccountGroupUUID(AccountGroup.UUID uuid) {
|
||||
groupUUID = uuid;
|
||||
}
|
||||
|
||||
public short getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ public class AnonymousUser extends CurrentUser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
return authConfig.getAnonymousGroups();
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
return Collections.singleton(AccountGroup.ANONYMOUS_USERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class CurrentUser {
|
||||
*
|
||||
* @return active groups for this user.
|
||||
*/
|
||||
public abstract Set<AccountGroup.Id> getEffectiveGroups();
|
||||
public abstract Set<AccountGroup.UUID> getEffectiveGroups();
|
||||
|
||||
/** Set of changes starred by this user. */
|
||||
public abstract Set<Change.Id> getStarredChanges();
|
||||
|
||||
@@ -43,11 +43,14 @@ import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URL;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
@@ -139,6 +142,28 @@ public class IdentifiedUser extends CurrentUser {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(IdentifiedUser.class);
|
||||
|
||||
private static final Set<AccountGroup.UUID> registeredGroups =
|
||||
new AbstractSet<AccountGroup.UUID>() {
|
||||
private final List<AccountGroup.UUID> groups =
|
||||
Collections.unmodifiableList(Arrays.asList(new AccountGroup.UUID[] {
|
||||
AccountGroup.ANONYMOUS_USERS, AccountGroup.REGISTERED_USERS}));
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return groups.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<AccountGroup.UUID> iterator() {
|
||||
return groups.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return groups.size();
|
||||
}
|
||||
};
|
||||
|
||||
private final Provider<String> canonicalUrl;
|
||||
private final Realm realm;
|
||||
private final AccountCache accountCache;
|
||||
@@ -154,7 +179,7 @@ public class IdentifiedUser extends CurrentUser {
|
||||
|
||||
private AccountState state;
|
||||
private Set<String> emailAddresses;
|
||||
private Set<AccountGroup.Id> effectiveGroups;
|
||||
private Set<AccountGroup.UUID> effectiveGroups;
|
||||
private Set<Change.Id> starredChanges;
|
||||
private Collection<AccountProjectWatch> notificationFilters;
|
||||
|
||||
@@ -217,14 +242,14 @@ public class IdentifiedUser extends CurrentUser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
if (effectiveGroups == null) {
|
||||
Set<AccountGroup.Id> seedGroups;
|
||||
Set<AccountGroup.UUID> seedGroups;
|
||||
|
||||
if (authConfig.isIdentityTrustable(state().getExternalIds())) {
|
||||
seedGroups = realm.groups(state());
|
||||
} else {
|
||||
seedGroups = authConfig.getRegisteredGroups();
|
||||
seedGroups = registeredGroups;
|
||||
}
|
||||
|
||||
effectiveGroups = getIncludedGroups(seedGroups);
|
||||
@@ -233,14 +258,14 @@ public class IdentifiedUser extends CurrentUser {
|
||||
return effectiveGroups;
|
||||
}
|
||||
|
||||
private Set<AccountGroup.Id> getIncludedGroups(Set<AccountGroup.Id> seedGroups) {
|
||||
Set<AccountGroup.Id> includes = new HashSet<AccountGroup.Id> (seedGroups);
|
||||
Queue<AccountGroup.Id> groupQueue = new LinkedList<AccountGroup.Id> (seedGroups);
|
||||
private Set<AccountGroup.UUID> getIncludedGroups(Set<AccountGroup.UUID> seedGroups) {
|
||||
Set<AccountGroup.UUID> includes = new HashSet<AccountGroup.UUID> (seedGroups);
|
||||
Queue<AccountGroup.UUID> groupQueue = new LinkedList<AccountGroup.UUID> (seedGroups);
|
||||
|
||||
while (groupQueue.size() > 0) {
|
||||
AccountGroup.Id id = groupQueue.remove();
|
||||
AccountGroup.UUID id = groupQueue.remove();
|
||||
|
||||
for (final AccountGroup.Id groupId : groupIncludeCache.getByInclude(id)) {
|
||||
for (final AccountGroup.UUID groupId : groupIncludeCache.getByInclude(id)) {
|
||||
if (includes.add(groupId)) {
|
||||
groupQueue.add(groupId);
|
||||
}
|
||||
|
||||
@@ -36,21 +36,21 @@ public class PeerDaemonUser extends CurrentUser {
|
||||
PeerDaemonUser create(@Assisted SocketAddress peer);
|
||||
}
|
||||
|
||||
private final Set<AccountGroup.Id> effectiveGroups;
|
||||
private final Set<AccountGroup.UUID> effectiveGroups;
|
||||
private final SocketAddress peer;
|
||||
|
||||
@Inject
|
||||
protected PeerDaemonUser(AuthConfig authConfig, @Assisted SocketAddress peer) {
|
||||
super(AccessPath.SSH_COMMAND, authConfig);
|
||||
|
||||
final HashSet<AccountGroup.Id> g = new HashSet<AccountGroup.Id>();
|
||||
final HashSet<AccountGroup.UUID> g = new HashSet<AccountGroup.UUID>();
|
||||
g.add(authConfig.getAdministratorsGroup());
|
||||
this.effectiveGroups = Collections.unmodifiableSet(g);
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
return effectiveGroups;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,18 @@ import java.util.Set;
|
||||
|
||||
public class ReplicationUser extends CurrentUser {
|
||||
/** Magic set of groups enabling read of any project and reference. */
|
||||
public static final Set<AccountGroup.Id> EVERYTHING_VISIBLE =
|
||||
Collections.unmodifiableSet(new HashSet<AccountGroup.Id>(0));
|
||||
public static final Set<AccountGroup.UUID> EVERYTHING_VISIBLE =
|
||||
Collections.unmodifiableSet(new HashSet<AccountGroup.UUID>(0));
|
||||
|
||||
public interface Factory {
|
||||
ReplicationUser create(@Assisted Set<AccountGroup.Id> authGroups);
|
||||
ReplicationUser create(@Assisted Set<AccountGroup.UUID> authGroups);
|
||||
}
|
||||
|
||||
private final Set<AccountGroup.Id> effectiveGroups;
|
||||
private final Set<AccountGroup.UUID> effectiveGroups;
|
||||
|
||||
@Inject
|
||||
protected ReplicationUser(AuthConfig authConfig,
|
||||
@Assisted Set<AccountGroup.Id> authGroups) {
|
||||
@Assisted Set<AccountGroup.UUID> authGroups) {
|
||||
super(AccessPath.REPLICATION, authConfig);
|
||||
|
||||
if (authGroups == EVERYTHING_VISIBLE) {
|
||||
@@ -53,12 +53,12 @@ public class ReplicationUser extends CurrentUser {
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<AccountGroup.Id> copy(Set<AccountGroup.Id> groups) {
|
||||
return Collections.unmodifiableSet(new HashSet<AccountGroup.Id>(groups));
|
||||
private static Set<AccountGroup.UUID> copy(Set<AccountGroup.UUID> groups) {
|
||||
return Collections.unmodifiableSet(new HashSet<AccountGroup.UUID>(groups));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
return effectiveGroups;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.server.cache.Cache;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gerrit.server.cache.EntryCreator;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
@@ -90,18 +89,13 @@ public class AccountCacheImpl implements AccountCache {
|
||||
|
||||
static class ByIdLoader extends EntryCreator<Account.Id, AccountState> {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
private final Set<AccountGroup.Id> registered;
|
||||
private final Set<AccountGroup.Id> anonymous;
|
||||
private final GroupCache groupCache;
|
||||
private final Cache<String, Account.Id> byName;
|
||||
|
||||
@Inject
|
||||
ByIdLoader(SchemaFactory<ReviewDb> sf, AuthConfig auth,
|
||||
GroupCache groupCache,
|
||||
ByIdLoader(SchemaFactory<ReviewDb> sf, GroupCache groupCache,
|
||||
@Named(BYUSER_NAME) Cache<String, Account.Id> byUsername) {
|
||||
this.schema = sf;
|
||||
this.registered = auth.getRegisteredGroups();
|
||||
this.anonymous = auth.getAnonymousGroups();
|
||||
this.groupCache = groupCache;
|
||||
this.byName = byUsername;
|
||||
}
|
||||
@@ -133,21 +127,18 @@ public class AccountCacheImpl implements AccountCache {
|
||||
Collections.unmodifiableCollection(db.accountExternalIds().byAccount(
|
||||
who).toList());
|
||||
|
||||
Set<AccountGroup.Id> internalGroups = new HashSet<AccountGroup.Id>();
|
||||
Set<AccountGroup.UUID> internalGroups = new HashSet<AccountGroup.UUID>();
|
||||
for (AccountGroupMember g : db.accountGroupMembers().byAccount(who)) {
|
||||
final AccountGroup.Id groupId = g.getAccountGroupId();
|
||||
final AccountGroup group = groupCache.get(groupId);
|
||||
if (group != null && group.getType() == AccountGroup.Type.INTERNAL) {
|
||||
internalGroups.add(groupId);
|
||||
internalGroups.add(group.getGroupUUID());
|
||||
}
|
||||
}
|
||||
|
||||
if (internalGroups.isEmpty()) {
|
||||
internalGroups = registered;
|
||||
} else {
|
||||
internalGroups.addAll(registered);
|
||||
internalGroups = Collections.unmodifiableSet(internalGroups);
|
||||
}
|
||||
internalGroups.add(AccountGroup.REGISTERED_USERS);
|
||||
internalGroups.add(AccountGroup.ANONYMOUS_USERS);
|
||||
internalGroups = Collections.unmodifiableSet(internalGroups);
|
||||
|
||||
return new AccountState(account, internalGroups, externalIds);
|
||||
}
|
||||
@@ -156,6 +147,8 @@ public class AccountCacheImpl implements AccountCache {
|
||||
public AccountState missing(final Account.Id accountId) {
|
||||
final Account account = new Account(accountId);
|
||||
final Collection<AccountExternalId> ids = Collections.emptySet();
|
||||
final Set<AccountGroup.UUID> anonymous =
|
||||
Collections.singleton(AccountGroup.ANONYMOUS_USERS);
|
||||
return new AccountState(account, anonymous, ids);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,9 @@ public class AccountManager {
|
||||
// is going to be the site's administrator and just make them that
|
||||
// to bootstrap the authentication database.
|
||||
//
|
||||
final AccountGroup.Id admin = authConfig.getAdministratorsGroup();
|
||||
final AccountGroup.UUID uuid = authConfig.getAdministratorsGroup();
|
||||
final AccountGroup g = db.accountGroups().byUUID(uuid).iterator().next();
|
||||
final AccountGroup.Id admin = g.getId();
|
||||
final AccountGroupMember m =
|
||||
new AccountGroupMember(new AccountGroupMember.Key(newId, admin));
|
||||
db.accountGroupMembersAudit().insert(
|
||||
|
||||
@@ -26,11 +26,11 @@ import java.util.Set;
|
||||
|
||||
public class AccountState {
|
||||
private final Account account;
|
||||
private final Set<AccountGroup.Id> internalGroups;
|
||||
private final Set<AccountGroup.UUID> internalGroups;
|
||||
private final Collection<AccountExternalId> externalIds;
|
||||
|
||||
public AccountState(final Account account,
|
||||
final Set<AccountGroup.Id> actualGroups,
|
||||
final Set<AccountGroup.UUID> actualGroups,
|
||||
final Collection<AccountExternalId> externalIds) {
|
||||
this.account = account;
|
||||
this.internalGroups = actualGroups;
|
||||
@@ -89,7 +89,7 @@ public class AccountState {
|
||||
}
|
||||
|
||||
/** The set of groups maintained directly within the Gerrit database. */
|
||||
public Set<AccountGroup.Id> getInternalGroups() {
|
||||
public Set<AccountGroup.UUID> getInternalGroups() {
|
||||
return internalGroups;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public final class DefaultRealm implements Realm {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> groups(final AccountState who) {
|
||||
public Set<AccountGroup.UUID> groups(final AccountState who) {
|
||||
return who.getInternalGroups();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.server.cache.Cache;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gerrit.server.cache.EntryCreator;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
@@ -113,12 +112,10 @@ public class GroupCacheImpl implements GroupCache {
|
||||
|
||||
static class ByIdLoader extends EntryCreator<AccountGroup.Id, AccountGroup> {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
private final AccountGroup.Id administrators;
|
||||
|
||||
@Inject
|
||||
ByIdLoader(final SchemaFactory<ReviewDb> sf, final AuthConfig authConfig) {
|
||||
ByIdLoader(final SchemaFactory<ReviewDb> sf) {
|
||||
schema = sf;
|
||||
administrators = authConfig.getAdministratorsGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,7 +139,6 @@ public class GroupCacheImpl implements GroupCache {
|
||||
new AccountGroup.NameKey("Deleted Group" + key.toString());
|
||||
final AccountGroup g = new AccountGroup(name, key, null);
|
||||
g.setType(AccountGroup.Type.SYSTEM);
|
||||
g.setOwnerGroupId(administrators);
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.util.Collection;
|
||||
|
||||
/** Tracks group inclusions in memory for efficient access. */
|
||||
public interface GroupIncludeCache {
|
||||
public Collection<AccountGroup.Id> getByInclude(AccountGroup.Id groupId);
|
||||
public Collection<AccountGroup.UUID> getByInclude(AccountGroup.UUID groupId);
|
||||
|
||||
public void evictInclude(AccountGroup.Id groupId);
|
||||
public void evictInclude(AccountGroup.UUID groupId);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,16 +21,17 @@ import com.google.gerrit.server.cache.Cache;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gerrit.server.cache.EntryCreator;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Named;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Tracks group inclusions in memory for efficient access. */
|
||||
@Singleton
|
||||
@@ -41,8 +42,8 @@ public class GroupIncludeCacheImpl implements GroupIncludeCache {
|
||||
return new CacheModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
final TypeLiteral<Cache<AccountGroup.Id, Collection<AccountGroup.Id>>> byInclude =
|
||||
new TypeLiteral<Cache<AccountGroup.Id, Collection<AccountGroup.Id>>>() {};
|
||||
final TypeLiteral<Cache<AccountGroup.UUID, Collection<AccountGroup.UUID>>> byInclude =
|
||||
new TypeLiteral<Cache<AccountGroup.UUID, Collection<AccountGroup.UUID>>>() {};
|
||||
core(byInclude, BYINCLUDE_NAME).populateWith(ByIncludeLoader.class);
|
||||
|
||||
bind(GroupIncludeCacheImpl.class);
|
||||
@@ -51,23 +52,24 @@ public class GroupIncludeCacheImpl implements GroupIncludeCache {
|
||||
};
|
||||
}
|
||||
|
||||
private final Cache<AccountGroup.Id, Collection<AccountGroup.Id>> byInclude;
|
||||
private final Cache<AccountGroup.UUID, Collection<AccountGroup.UUID>> byInclude;
|
||||
|
||||
@Inject
|
||||
GroupIncludeCacheImpl(
|
||||
@Named(BYINCLUDE_NAME) Cache<AccountGroup.Id, Collection<AccountGroup.Id>> byInclude) {
|
||||
@Named(BYINCLUDE_NAME) Cache<AccountGroup.UUID, Collection<AccountGroup.UUID>> byInclude) {
|
||||
this.byInclude = byInclude;
|
||||
}
|
||||
|
||||
public Collection<AccountGroup.Id> getByInclude(final AccountGroup.Id groupId) {
|
||||
public Collection<AccountGroup.UUID> getByInclude(AccountGroup.UUID groupId) {
|
||||
return byInclude.get(groupId);
|
||||
}
|
||||
|
||||
public void evictInclude(AccountGroup.Id groupId) {
|
||||
public void evictInclude(AccountGroup.UUID groupId) {
|
||||
byInclude.remove(groupId);
|
||||
}
|
||||
|
||||
static class ByIncludeLoader extends EntryCreator<AccountGroup.Id, Collection<AccountGroup.Id>> {
|
||||
static class ByIncludeLoader extends
|
||||
EntryCreator<AccountGroup.UUID, Collection<AccountGroup.UUID>> {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
|
||||
@Inject
|
||||
@@ -76,14 +78,23 @@ public class GroupIncludeCacheImpl implements GroupIncludeCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AccountGroup.Id> createEntry(final AccountGroup.Id key) throws Exception {
|
||||
public Collection<AccountGroup.UUID> createEntry(final AccountGroup.UUID key) throws Exception {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
ArrayList<AccountGroup.Id> groupArray = new ArrayList<AccountGroup.Id> ();
|
||||
for (AccountGroupInclude agi : db.accountGroupIncludes().byInclude(key)) {
|
||||
groupArray.add(agi.getGroupId());
|
||||
List<AccountGroup> group = db.accountGroups().byUUID(key).toList();
|
||||
if (group.size() != 1) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<AccountGroup.Id> ids = new HashSet<AccountGroup.Id>();
|
||||
for (AccountGroupInclude agi : db.accountGroupIncludes().byInclude(group.get(0).getId())) {
|
||||
ids.add(agi.getGroupId());
|
||||
}
|
||||
|
||||
Set<AccountGroup.UUID> groupArray = new HashSet<AccountGroup.UUID> ();
|
||||
for (AccountGroup g : db.accountGroups().get(ids)) {
|
||||
groupArray.add(g.getGroupUUID());
|
||||
}
|
||||
return Collections.unmodifiableCollection(groupArray);
|
||||
} finally {
|
||||
db.close();
|
||||
@@ -91,7 +102,7 @@ public class GroupIncludeCacheImpl implements GroupIncludeCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AccountGroup.Id> missing(final AccountGroup.Id key) {
|
||||
public Collection<AccountGroup.UUID> missing(final AccountGroup.UUID key) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.eclipse.jgit.lib.PersonIdent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class PerformCreateGroup {
|
||||
@@ -160,8 +161,9 @@ public class PerformCreateGroup {
|
||||
db.accountGroupIncludes().insert(includeList);
|
||||
db.accountGroupIncludesAudit().insert(includesAudit);
|
||||
|
||||
for (AccountGroup.Id includeId : groups) {
|
||||
groupIncludeCache.evictInclude(includeId);
|
||||
for (AccountGroup group : db.accountGroups().get(
|
||||
new HashSet<AccountGroup.Id>(groups))) {
|
||||
groupIncludeCache.evictInclude(group.getGroupUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface Realm {
|
||||
|
||||
public void onCreateAccount(AuthRequest who, Account account);
|
||||
|
||||
public Set<AccountGroup.Id> groups(AccountState who);
|
||||
public Set<AccountGroup.UUID> groups(AccountState who);
|
||||
|
||||
/**
|
||||
* Locate an account whose local username is the given account name.
|
||||
|
||||
@@ -133,7 +133,7 @@ import javax.net.ssl.SSLSocketFactory;
|
||||
}
|
||||
}
|
||||
|
||||
Set<AccountGroup.Id> queryForGroups(final DirContext ctx,
|
||||
Set<AccountGroup.UUID> queryForGroups(final DirContext ctx,
|
||||
final String username, LdapQuery.Result account)
|
||||
throws NamingException, AccountException {
|
||||
final LdapSchema schema = getSchema(ctx);
|
||||
@@ -175,12 +175,12 @@ import javax.net.ssl.SSLSocketFactory;
|
||||
}
|
||||
}
|
||||
|
||||
final Set<AccountGroup.Id> actual = new HashSet<AccountGroup.Id>();
|
||||
final Set<AccountGroup.UUID> actual = new HashSet<AccountGroup.UUID>();
|
||||
for (String dn : groupDNs) {
|
||||
for (AccountGroup group : groupCache
|
||||
.get(new AccountGroup.ExternalNameKey(dn))) {
|
||||
if (group.getType() == AccountGroup.Type.LDAP) {
|
||||
actual.add(group.getId());
|
||||
actual.add(group.getGroupUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ public class LdapModule extends CacheModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
final TypeLiteral<Cache<String, Set<AccountGroup.Id>>> groups =
|
||||
new TypeLiteral<Cache<String, Set<AccountGroup.Id>>>() {};
|
||||
final TypeLiteral<Cache<String, Set<AccountGroup.UUID>>> groups =
|
||||
new TypeLiteral<Cache<String, Set<AccountGroup.UUID>>>() {};
|
||||
core(groups, GROUP_CACHE).maxAge(1, HOURS) //
|
||||
.populateWith(LdapRealm.MemberLoader.class);
|
||||
|
||||
|
||||
@@ -68,14 +68,14 @@ class LdapRealm implements Realm {
|
||||
private final Cache<String, Account.Id> usernameCache;
|
||||
private final Set<Account.FieldName> readOnlyAccountFields;
|
||||
|
||||
private final Cache<String, Set<AccountGroup.Id>> membershipCache;
|
||||
private final Cache<String, Set<AccountGroup.UUID>> membershipCache;
|
||||
|
||||
@Inject
|
||||
LdapRealm(
|
||||
final Helper helper,
|
||||
final AuthConfig authConfig,
|
||||
final EmailExpander emailExpander,
|
||||
@Named(LdapModule.GROUP_CACHE) final Cache<String, Set<AccountGroup.Id>> membershipCache,
|
||||
@Named(LdapModule.GROUP_CACHE) final Cache<String, Set<AccountGroup.UUID>> membershipCache,
|
||||
@Named(LdapModule.USERNAME_CACHE) final Cache<String, Account.Id> usernameCache,
|
||||
@GerritServerConfig final Config config) {
|
||||
this.helper = helper;
|
||||
@@ -241,8 +241,8 @@ class LdapRealm implements Realm {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> groups(final AccountState who) {
|
||||
final HashSet<AccountGroup.Id> r = new HashSet<AccountGroup.Id>();
|
||||
public Set<AccountGroup.UUID> groups(final AccountState who) {
|
||||
final HashSet<AccountGroup.UUID> r = new HashSet<AccountGroup.UUID>();
|
||||
r.addAll(membershipCache.get(findId(who.getExternalIds())));
|
||||
r.addAll(who.getInternalGroups());
|
||||
return r;
|
||||
@@ -324,7 +324,7 @@ class LdapRealm implements Realm {
|
||||
}
|
||||
}
|
||||
|
||||
static class MemberLoader extends EntryCreator<String, Set<AccountGroup.Id>> {
|
||||
static class MemberLoader extends EntryCreator<String, Set<AccountGroup.UUID>> {
|
||||
private final Helper helper;
|
||||
|
||||
@Inject
|
||||
@@ -333,7 +333,7 @@ class LdapRealm implements Realm {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> createEntry(final String username)
|
||||
public Set<AccountGroup.UUID> createEntry(final String username)
|
||||
throws Exception {
|
||||
final DirContext ctx = helper.open();
|
||||
try {
|
||||
@@ -348,7 +348,7 @@ class LdapRealm implements Realm {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> missing(final String key) {
|
||||
public Set<AccountGroup.UUID> missing(final String key) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ import org.eclipse.jgit.lib.Config;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Authentication related settings from {@code gerrit.config}. */
|
||||
@Singleton
|
||||
@@ -45,10 +43,8 @@ public class AuthConfig {
|
||||
private final boolean cookieSecure;
|
||||
private final SignedToken emailReg;
|
||||
|
||||
private final AccountGroup.Id administratorGroup;
|
||||
private final Set<AccountGroup.Id> anonymousGroups;
|
||||
private final Set<AccountGroup.Id> registeredGroups;
|
||||
private final AccountGroup.Id batchUsersGroup;
|
||||
private final AccountGroup.UUID administratorGroup;
|
||||
private final AccountGroup.UUID batchUsersGroup;
|
||||
|
||||
private final boolean allowGoogleAccountUpgrade;
|
||||
|
||||
@@ -64,13 +60,8 @@ public class AuthConfig {
|
||||
cookieSecure = cfg.getBoolean("auth", "cookiesecure", false);
|
||||
emailReg = new SignedToken(5 * 24 * 60 * 60, s.registerEmailPrivateKey);
|
||||
|
||||
final HashSet<AccountGroup.Id> r = new HashSet<AccountGroup.Id>(2);
|
||||
r.add(s.anonymousGroupId);
|
||||
r.add(s.registeredGroupId);
|
||||
registeredGroups = Collections.unmodifiableSet(r);
|
||||
anonymousGroups = Collections.singleton(s.anonymousGroupId);
|
||||
administratorGroup = s.adminGroupId;
|
||||
batchUsersGroup = s.batchUsersGroupId;
|
||||
administratorGroup = s.adminGroupUUID;
|
||||
batchUsersGroup = s.batchUsersGroupUUID;
|
||||
|
||||
if (authType == AuthType.OPENID) {
|
||||
allowGoogleAccountUpgrade =
|
||||
@@ -127,25 +118,15 @@ public class AuthConfig {
|
||||
}
|
||||
|
||||
/** Identity of the magic group with full powers. */
|
||||
public AccountGroup.Id getAdministratorsGroup() {
|
||||
public AccountGroup.UUID getAdministratorsGroup() {
|
||||
return administratorGroup;
|
||||
}
|
||||
|
||||
/** Identity of the group whose service is degraded to lower priority. */
|
||||
public AccountGroup.Id getBatchUsersGroup() {
|
||||
public AccountGroup.UUID getBatchUsersGroup() {
|
||||
return batchUsersGroup;
|
||||
}
|
||||
|
||||
/** Groups that all users, including anonymous users, belong to. */
|
||||
public Set<AccountGroup.Id> getAnonymousGroups() {
|
||||
return anonymousGroups;
|
||||
}
|
||||
|
||||
/** Groups that all users who have created an account belong to. */
|
||||
public Set<AccountGroup.Id> getRegisteredGroups() {
|
||||
return registeredGroups;
|
||||
}
|
||||
|
||||
/** OpenID identities which the server permits for authentication. */
|
||||
public List<OpenIdProviderPattern> getAllowedOpenIDs() {
|
||||
return allowedOpenIDs;
|
||||
|
||||
@@ -310,10 +310,10 @@ public class ConfigUtil {
|
||||
* @return the actual groups resolved from the database. If no groups are
|
||||
* found, returns an empty {@code Set}, never {@code null}.
|
||||
*/
|
||||
public static Set<AccountGroup.Id> groupsFor(
|
||||
public static Set<AccountGroup.UUID> groupsFor(
|
||||
SchemaFactory<ReviewDb> dbfactory, String[] groupNames, Logger log,
|
||||
String groupNotFoundWarning) {
|
||||
final Set<AccountGroup.Id> result = new HashSet<AccountGroup.Id>();
|
||||
final Set<AccountGroup.UUID> result = new HashSet<AccountGroup.UUID>();
|
||||
try {
|
||||
final ReviewDb db = dbfactory.open();
|
||||
try {
|
||||
@@ -322,9 +322,16 @@ public class ConfigUtil {
|
||||
db.accountGroupNames().get(new AccountGroup.NameKey(name));
|
||||
if (group == null) {
|
||||
log.warn(MessageFormat.format(groupNotFoundWarning, name));
|
||||
} else {
|
||||
result.add(group.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
AccountGroup ag = db.accountGroups().get(group.getId());
|
||||
if (ag == null) {
|
||||
log.warn(MessageFormat.format(groupNotFoundWarning, name));
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(ag.getGroupUUID());
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
@@ -345,7 +352,7 @@ public class ConfigUtil {
|
||||
* @return the actual groups resolved from the database. If no groups are
|
||||
* found, returns an empty {@code Set}, never {@code null}.
|
||||
*/
|
||||
public static Set<AccountGroup.Id> groupsFor(
|
||||
public static Set<AccountGroup.UUID> groupsFor(
|
||||
SchemaFactory<ReviewDb> dbfactory, String[] groupNames, Logger log) {
|
||||
return groupsFor(dbfactory, groupNames, log,
|
||||
"Group \"{0}\" not in database, skipping.");
|
||||
|
||||
@@ -22,21 +22,17 @@ import com.google.inject.Inject;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class GitReceivePackGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public GitReceivePackGroupsProvider(@GerritServerConfig Config config,
|
||||
AuthConfig authConfig, SchemaFactory<ReviewDb> db) {
|
||||
SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "receive", null, "allowGroup");
|
||||
|
||||
// If no group was set, default to "registered users"
|
||||
//
|
||||
if (groupIds.isEmpty()) {
|
||||
HashSet<AccountGroup.Id> all = new HashSet<AccountGroup.Id>();
|
||||
all.addAll(authConfig.getRegisteredGroups());
|
||||
all.removeAll(authConfig.getAnonymousGroups());
|
||||
groupIds = Collections.unmodifiableSet(all);
|
||||
groupIds = Collections.singleton(AccountGroup.REGISTERED_USERS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,15 @@ import java.util.HashSet;
|
||||
public class GitUploadPackGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public GitUploadPackGroupsProvider(@GerritServerConfig Config config,
|
||||
AuthConfig authConfig, SchemaFactory<ReviewDb> db) {
|
||||
SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "upload", null, "allowGroup");
|
||||
|
||||
// If no group was set, default to "registered users" and "anonymous"
|
||||
//
|
||||
if (groupIds.isEmpty()) {
|
||||
HashSet<AccountGroup.Id> all = new HashSet<AccountGroup.Id>();
|
||||
all.addAll(authConfig.getRegisteredGroups());
|
||||
all.addAll(authConfig.getAnonymousGroups());
|
||||
HashSet<AccountGroup.UUID> all = new HashSet<AccountGroup.UUID>();
|
||||
all.add(AccountGroup.REGISTERED_USERS);
|
||||
all.add(AccountGroup.ANONYMOUS_USERS);
|
||||
groupIds = Collections.unmodifiableSet(all);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ import org.slf4j.LoggerFactory;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class GroupSetProvider implements
|
||||
Provider<Set<AccountGroup.Id>> {
|
||||
Provider<Set<AccountGroup.UUID>> {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(GroupSetProvider.class);
|
||||
|
||||
protected Set<AccountGroup.Id> groupIds;
|
||||
protected Set<AccountGroup.UUID> groupIds;
|
||||
|
||||
@Inject
|
||||
protected GroupSetProvider(@GerritServerConfig Config config,
|
||||
@@ -44,7 +44,7 @@ public abstract class GroupSetProvider implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> get() {
|
||||
public Set<AccountGroup.UUID> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package com.google.gerrit.server.config;
|
||||
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.SystemConfig;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@@ -37,11 +36,11 @@ import java.util.Collections;
|
||||
public class ProjectCreatorGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public ProjectCreatorGroupsProvider(@GerritServerConfig final Config config,
|
||||
final SystemConfig systemConfig, final SchemaFactory<ReviewDb> db) {
|
||||
final AuthConfig authConfig, final SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "repository", "*", "createGroup");
|
||||
|
||||
if (groupIds.isEmpty()) {
|
||||
groupIds = Collections.singleton(systemConfig.adminGroupId);
|
||||
groupIds = Collections.singleton(authConfig.getAdministratorsGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.Set;
|
||||
public class ProjectOwnerGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public ProjectOwnerGroupsProvider(
|
||||
@ProjectCreatorGroups final Set<AccountGroup.Id> creatorGroups,
|
||||
@ProjectCreatorGroups final Set<AccountGroup.UUID> creatorGroups,
|
||||
@GerritServerConfig final Config config, final SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "repository", "*", "ownerGroup");
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ public class PushReplication implements ReplicationQueue {
|
||||
|
||||
String[] authGroupNames =
|
||||
cfg.getStringList("remote", rc.getName(), "authGroup");
|
||||
final Set<AccountGroup.Id> authGroups;
|
||||
final Set<AccountGroup.UUID> authGroups;
|
||||
if (authGroupNames.length > 0) {
|
||||
authGroups = ConfigUtil.groupsFor(db, authGroupNames, //
|
||||
log, "Group \"{0}\" not in database, removing from authGroup");
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||
import com.google.gerrit.server.config.TrackingFooters;
|
||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||
@@ -145,6 +146,7 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
private final ChangeHookRunner hooks;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final ProjectCache projectCache;
|
||||
private final GroupCache groupCache;
|
||||
private final String canonicalWebUrl;
|
||||
private final PersonIdent gerritIdent;
|
||||
private final TrackingFooters trackingFooters;
|
||||
@@ -181,6 +183,7 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
final ChangeHookRunner hooks,
|
||||
final ProjectCache projectCache,
|
||||
final GitRepositoryManager repoManager,
|
||||
final GroupCache groupCache,
|
||||
@CanonicalWebUrl @Nullable final String canonicalWebUrl,
|
||||
@GerritPersonIdent final PersonIdent gerritIdent,
|
||||
final TrackingFooters trackingFooters,
|
||||
@@ -199,6 +202,7 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
this.hooks = hooks;
|
||||
this.projectCache = projectCache;
|
||||
this.repoManager = repoManager;
|
||||
this.groupCache = groupCache;
|
||||
this.canonicalWebUrl = canonicalWebUrl;
|
||||
this.gerritIdent = gerritIdent;
|
||||
this.trackingFooters = trackingFooters;
|
||||
@@ -417,9 +421,14 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
AbstractAgreement bestAgreement = null;
|
||||
ContributorAgreement bestCla = null;
|
||||
|
||||
OUTER: for (AccountGroup.Id groupId : currentUser.getEffectiveGroups()) {
|
||||
OUTER: for (AccountGroup.UUID groupUUID : currentUser.getEffectiveGroups()) {
|
||||
AccountGroup group = groupCache.get(groupUUID);
|
||||
if (group == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<AccountGroupAgreement> temp =
|
||||
db.accountGroupAgreements().byGroup(groupId).toList();
|
||||
db.accountGroupAgreements().byGroup(group.getId()).toList();
|
||||
|
||||
Collections.reverse(temp);
|
||||
|
||||
|
||||
@@ -69,8 +69,8 @@ public abstract class ChangeEmail extends OutgoingEmail {
|
||||
|
||||
/** Is the from user in an email squelching group? */
|
||||
final IdentifiedUser user = args.identifiedUserFactory.create(id);
|
||||
final Set<AccountGroup.Id> gids = user.getEffectiveGroups();
|
||||
for (final AccountGroup.Id gid : gids) {
|
||||
final Set<AccountGroup.UUID> gids = user.getEffectiveGroups();
|
||||
for (final AccountGroup.UUID gid : gids) {
|
||||
if (args.groupCache.get(gid).isEmailOnlyAuthors()) {
|
||||
emailOnlyAuthors = true;
|
||||
break;
|
||||
@@ -273,11 +273,11 @@ public abstract class ChangeEmail extends OutgoingEmail {
|
||||
}
|
||||
|
||||
/** Get the groups which own the project. */
|
||||
protected Set<AccountGroup.Id> getProjectOwners() {
|
||||
protected Set<AccountGroup.UUID> getProjectOwners() {
|
||||
final ProjectState r;
|
||||
|
||||
r = args.projectCache.get(change.getProject());
|
||||
return r != null ? r.getOwners() : Collections.<AccountGroup.Id> emptySet();
|
||||
return r != null ? r.getOwners() : Collections.<AccountGroup.UUID> emptySet();
|
||||
}
|
||||
|
||||
/** TO or CC all vested parties (change owner, patch set uploader, author). */
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.gerrit.reviewdb.AccountGroupMember;
|
||||
import com.google.gerrit.reviewdb.AccountProjectWatch;
|
||||
import com.google.gerrit.reviewdb.Change;
|
||||
import com.google.gerrit.reviewdb.AccountProjectWatch.NotifyType;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.ssh.SshInfo;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
@@ -34,10 +35,13 @@ public class CreateChangeSender extends NewChangeSender {
|
||||
public CreateChangeSender create(Change change);
|
||||
}
|
||||
|
||||
private final GroupCache groupCache;
|
||||
|
||||
@Inject
|
||||
public CreateChangeSender(EmailArguments ea, SshInfo sshInfo,
|
||||
@Assisted Change c) {
|
||||
GroupCache groupCache, @Assisted Change c) {
|
||||
super(ea, sshInfo, c);
|
||||
this.groupCache = groupCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,10 +56,13 @@ public class CreateChangeSender extends NewChangeSender {
|
||||
// Try to mark interested owners with a TO and not a BCC line.
|
||||
//
|
||||
final Set<Account.Id> owners = new HashSet<Account.Id>();
|
||||
for (AccountGroup.Id g : getProjectOwners()) {
|
||||
for (AccountGroupMember m : args.db.get().accountGroupMembers()
|
||||
.byGroup(g)) {
|
||||
owners.add(m.getAccountId());
|
||||
for (AccountGroup.UUID uuid : getProjectOwners()) {
|
||||
AccountGroup group = groupCache.get(uuid);
|
||||
if (group != null) {
|
||||
for (AccountGroupMember m : args.db.get().accountGroupMembers()
|
||||
.byGroup(group.getId())) {
|
||||
owners.add(m.getAccountId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,19 +33,19 @@ import java.util.Set;
|
||||
public class AccessControlModule extends FactoryModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
bind(new TypeLiteral<Set<AccountGroup.UUID>>() {}) //
|
||||
.annotatedWith(ProjectCreatorGroups.class) //
|
||||
.toProvider(ProjectCreatorGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
bind(new TypeLiteral<Set<AccountGroup.UUID>>() {}) //
|
||||
.annotatedWith(ProjectOwnerGroups.class) //
|
||||
.toProvider(ProjectOwnerGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
bind(new TypeLiteral<Set<AccountGroup.UUID>>() {}) //
|
||||
.annotatedWith(GitUploadPackGroups.class) //
|
||||
.toProvider(GitUploadPackGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
bind(new TypeLiteral<Set<AccountGroup.UUID>>() {}) //
|
||||
.annotatedWith(GitReceivePackGroups.class) //
|
||||
.toProvider(GitReceivePackGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.RefRight;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
@@ -34,8 +35,11 @@ import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@@ -191,9 +195,27 @@ public class ProjectCacheImpl implements ProjectCache {
|
||||
cfg.load(git);
|
||||
|
||||
final Project p = cfg.getProject();
|
||||
final Collection<RefRight> rights =
|
||||
Collections.unmodifiableCollection(db.refRights().byProject(key)
|
||||
.toList());
|
||||
|
||||
Collection<RefRight> rights = db.refRights().byProject(key).toList();
|
||||
|
||||
Set<AccountGroup.Id> groupIds = new HashSet<AccountGroup.Id>();
|
||||
for (RefRight r : rights) {
|
||||
groupIds.add(r.getAccountGroupId());
|
||||
}
|
||||
Map<AccountGroup.Id, AccountGroup> groupsById =
|
||||
db.accountGroups().toMap(db.accountGroups().get(groupIds));
|
||||
|
||||
for (RefRight r : rights) {
|
||||
AccountGroup group = groupsById.get(r.getAccountGroupId());
|
||||
if (group != null) {
|
||||
r.setAccountGroupUUID(group.getGroupUUID());
|
||||
} else {
|
||||
r.setAccountGroupUUID(new AccountGroup.UUID("DELETED_GROUP_"
|
||||
+ r.getAccountGroupId().get()));
|
||||
}
|
||||
}
|
||||
rights = Collections.unmodifiableCollection(rights);
|
||||
|
||||
return projectStateFactory.create(p, rights);
|
||||
} finally {
|
||||
git.close();
|
||||
|
||||
@@ -101,16 +101,16 @@ public class ProjectControl {
|
||||
ProjectControl create(CurrentUser who, ProjectState ps);
|
||||
}
|
||||
|
||||
private final Set<AccountGroup.Id> uploadGroups;
|
||||
private final Set<AccountGroup.Id> receiveGroups;
|
||||
private final Set<AccountGroup.UUID> uploadGroups;
|
||||
private final Set<AccountGroup.UUID> receiveGroups;
|
||||
|
||||
private final RefControl.Factory refControlFactory;
|
||||
private final CurrentUser user;
|
||||
private final ProjectState state;
|
||||
|
||||
@Inject
|
||||
ProjectControl(@GitUploadPackGroups Set<AccountGroup.Id> uploadGroups,
|
||||
@GitReceivePackGroups Set<AccountGroup.Id> receiveGroups,
|
||||
ProjectControl(@GitUploadPackGroups Set<AccountGroup.UUID> uploadGroups,
|
||||
@GitReceivePackGroups Set<AccountGroup.UUID> receiveGroups,
|
||||
final RefControl.Factory refControlFactory,
|
||||
@Assisted CurrentUser who, @Assisted ProjectState ps) {
|
||||
this.uploadGroups = uploadGroups;
|
||||
@@ -197,10 +197,10 @@ public class ProjectControl {
|
||||
// TODO (anatol.pomazau): Try to merge this method with similar RefRightsForPattern#canPerform
|
||||
private boolean canPerformOnAnyRef(ApprovalCategory.Id actionId,
|
||||
short requireValue) {
|
||||
final Set<AccountGroup.Id> groups = user.getEffectiveGroups();
|
||||
final Set<AccountGroup.UUID> groups = user.getEffectiveGroups();
|
||||
|
||||
for (final RefRight pr : state.getAllRights(actionId, true)) {
|
||||
if (groups.contains(pr.getAccountGroupId())
|
||||
if (groups.contains(pr.getAccountGroupUUID())
|
||||
&& pr.getMaxValue() >= requireValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ProjectState {
|
||||
|
||||
private final Project project;
|
||||
private final Collection<RefRight> localRights;
|
||||
private final Set<AccountGroup.Id> localOwners;
|
||||
private final Set<AccountGroup.UUID> localOwners;
|
||||
|
||||
private volatile Collection<RefRight> inheritedRights;
|
||||
|
||||
@@ -75,12 +75,12 @@ public class ProjectState {
|
||||
this.project = project;
|
||||
this.localRights = rights;
|
||||
|
||||
final HashSet<AccountGroup.Id> groups = new HashSet<AccountGroup.Id>();
|
||||
final HashSet<AccountGroup.UUID> groups = new HashSet<AccountGroup.UUID>();
|
||||
for (final RefRight right : rights) {
|
||||
if (ApprovalCategory.OWN.equals(right.getApprovalCategoryId())
|
||||
&& right.getMaxValue() > 0
|
||||
&& right.getRefPattern().equals(RefRight.ALL)) {
|
||||
groups.add(right.getAccountGroupId());
|
||||
groups.add(right.getAccountGroupUUID());
|
||||
}
|
||||
}
|
||||
localOwners = Collections.unmodifiableSet(groups);
|
||||
@@ -216,7 +216,7 @@ public class ProjectState {
|
||||
* are no local owners the local owners of the nearest parent project
|
||||
* that has local owners are returned
|
||||
*/
|
||||
public Set<AccountGroup.Id> getOwners() {
|
||||
public Set<AccountGroup.UUID> getOwners() {
|
||||
if (!localOwners.isEmpty() || isSpecialWildProject()
|
||||
|| project.getParent() == null) {
|
||||
return localOwners;
|
||||
@@ -237,11 +237,11 @@ public class ProjectState {
|
||||
* owners) and all groups to which the owner privilege for 'refs/*' is
|
||||
* assigned for one of the parent projects (the inherited owners).
|
||||
*/
|
||||
public Set<AccountGroup.Id> getAllOwners() {
|
||||
final HashSet<AccountGroup.Id> owners = new HashSet<AccountGroup.Id>();
|
||||
public Set<AccountGroup.UUID> getAllOwners() {
|
||||
final HashSet<AccountGroup.UUID> owners = new HashSet<AccountGroup.UUID>();
|
||||
for (final RefRight right : getAllRights(ApprovalCategory.OWN, true)) {
|
||||
if (right.getMaxValue() > 0 && right.getRefPattern().equals(RefRight.ALL)) {
|
||||
owners.add(right.getAccountGroupId());
|
||||
owners.add(right.getAccountGroupUUID());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(owners);
|
||||
|
||||
@@ -68,7 +68,6 @@ public class RefControl {
|
||||
RefControl create(ProjectControl projectControl, String ref);
|
||||
}
|
||||
|
||||
private final SystemConfig systemConfig;
|
||||
private final ProjectControl projectControl;
|
||||
private final String refName;
|
||||
|
||||
@@ -76,10 +75,8 @@ public class RefControl {
|
||||
private Boolean canForgeCommitter;
|
||||
|
||||
@Inject
|
||||
protected RefControl(final SystemConfig systemConfig,
|
||||
@Assisted final ProjectControl projectControl,
|
||||
protected RefControl(@Assisted final ProjectControl projectControl,
|
||||
@Assisted String ref) {
|
||||
this.systemConfig = systemConfig;
|
||||
if (isRE(ref)) {
|
||||
ref = shortestExample(ref);
|
||||
|
||||
@@ -270,7 +267,7 @@ public class RefControl {
|
||||
public short normalize(ApprovalCategory.Id category, short score) {
|
||||
short minAllowed = 0, maxAllowed = 0;
|
||||
for (RefRight r : getApplicableRights(category)) {
|
||||
if (getCurrentUser().getEffectiveGroups().contains(r.getAccountGroupId())) {
|
||||
if (getCurrentUser().getEffectiveGroups().contains(r.getAccountGroupUUID())) {
|
||||
minAllowed = (short) Math.min(minAllowed, r.getMinValue());
|
||||
maxAllowed = (short) Math.max(maxAllowed, r.getMaxValue());
|
||||
}
|
||||
@@ -320,9 +317,9 @@ public class RefControl {
|
||||
* @param groups The groups of the user
|
||||
* @return The allowed value for this ref for all the specified groups
|
||||
*/
|
||||
private boolean allowedValueForRef(Set<AccountGroup.Id> groups, short level) {
|
||||
private boolean allowedValueForRef(Set<AccountGroup.UUID> groups, short level) {
|
||||
for (RefRight right : rights) {
|
||||
if (groups.contains(right.getAccountGroupId())
|
||||
if (groups.contains(right.getAccountGroupUUID())
|
||||
&& right.getMaxValue() >= level) {
|
||||
return true;
|
||||
}
|
||||
@@ -332,7 +329,7 @@ public class RefControl {
|
||||
}
|
||||
|
||||
boolean canPerform(ApprovalCategory.Id actionId, short level) {
|
||||
final Set<AccountGroup.Id> groups = getCurrentUser().getEffectiveGroups();
|
||||
final Set<AccountGroup.UUID> groups = getCurrentUser().getEffectiveGroups();
|
||||
|
||||
List<RefRight> allRights = new ArrayList<RefRight>();
|
||||
allRights.addAll(getAllRights(actionId));
|
||||
@@ -538,9 +535,9 @@ public class RefControl {
|
||||
*/
|
||||
private Set<RefRight> resolveOwnerGroups(final RefRight refRight) {
|
||||
final Set<RefRight> resolvedRefRights = new HashSet<RefRight>();
|
||||
if (refRight.getAccountGroupId().equals(systemConfig.ownerGroupId)) {
|
||||
for (final AccountGroup.Id ownerGroup : getProjectState().getAllOwners()) {
|
||||
if (!ownerGroup.equals(systemConfig.ownerGroupId)) {
|
||||
if (AccountGroup.PROJECT_OWNERS.equals(refRight.getAccountGroupUUID())) {
|
||||
for (final AccountGroup.UUID ownerGroup : getProjectState().getAllOwners()) {
|
||||
if (!AccountGroup.PROJECT_OWNERS.equals(ownerGroup)) {
|
||||
resolvedRefRights.add(new RefRight(refRight, ownerGroup));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,15 +344,15 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
//
|
||||
AccountGroup g = args.groupCache.get(new AccountGroup.NameKey(who));
|
||||
if (g != null) {
|
||||
return visibleto(new SingleGroupUser(args.authConfig, g.getId()));
|
||||
return visibleto(new SingleGroupUser(args.authConfig, g.getGroupUUID()));
|
||||
}
|
||||
|
||||
Collection<AccountGroup> matches =
|
||||
args.groupCache.get(new AccountGroup.ExternalNameKey(who));
|
||||
if (matches != null && !matches.isEmpty()) {
|
||||
HashSet<AccountGroup.Id> ids = new HashSet<AccountGroup.Id>();
|
||||
HashSet<AccountGroup.UUID> ids = new HashSet<AccountGroup.UUID>();
|
||||
for (AccountGroup group : matches) {
|
||||
ids.add(group.getId());
|
||||
ids.add(group.getGroupUUID());
|
||||
}
|
||||
return visibleto(new SingleGroupUser(args.authConfig, ids));
|
||||
}
|
||||
|
||||
@@ -26,19 +26,19 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
final class SingleGroupUser extends CurrentUser {
|
||||
private final Set<AccountGroup.Id> groups;
|
||||
private final Set<AccountGroup.UUID> groups;
|
||||
|
||||
SingleGroupUser(AuthConfig authConfig, AccountGroup.Id groupId) {
|
||||
SingleGroupUser(AuthConfig authConfig, AccountGroup.UUID groupId) {
|
||||
this(authConfig, Collections.singleton(groupId));
|
||||
}
|
||||
|
||||
SingleGroupUser(AuthConfig authConfig, Set<AccountGroup.Id> groups) {
|
||||
SingleGroupUser(AuthConfig authConfig, Set<AccountGroup.UUID> groups) {
|
||||
super(AccessPath.UNKNOWN, authConfig);
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ public abstract class CategoryFunction {
|
||||
final FunctionState state) {
|
||||
RefControl rc = state.controlFor(user);
|
||||
for (final RefRight pr : rc.getApplicableRights(at.getCategory().getId())) {
|
||||
if (user.getEffectiveGroups().contains(pr.getAccountGroupId())
|
||||
if (user.getEffectiveGroups().contains(pr.getAccountGroupUUID())
|
||||
&& (pr.getMinValue() < 0 || pr.getMaxValue() > 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class FunctionState {
|
||||
//
|
||||
short minAllowed = 0, maxAllowed = 0;
|
||||
for (final RefRight r : rc.getApplicableRights(a.getCategoryId())) {
|
||||
final AccountGroup.Id grp = r.getAccountGroupId();
|
||||
final AccountGroup.UUID grp = r.getAccountGroupUUID();
|
||||
if (user.getEffectiveGroups().contains(grp)) {
|
||||
minAllowed = (short) Math.min(minAllowed, r.getMinValue());
|
||||
maxAllowed = (short) Math.max(maxAllowed, r.getMaxValue());
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SubmitFunction extends CategoryFunction {
|
||||
if (valid(at, state)) {
|
||||
RefControl rc = state.controlFor(user);
|
||||
for (final RefRight pr : rc.getApplicableRights(at.getCategory().getId())) {
|
||||
if (user.getEffectiveGroups().contains(pr.getAccountGroupId())
|
||||
if (user.getEffectiveGroups().contains(pr.getAccountGroupUUID())
|
||||
&& pr.getMaxValue() > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ public class FromAddressGeneratorProviderTest extends TestCase {
|
||||
account.setFullName(name);
|
||||
account.setPreferredEmail(email);
|
||||
final AccountState s =
|
||||
new AccountState(account, Collections.<AccountGroup.Id> emptySet(),
|
||||
new AccountState(account, Collections.<AccountGroup.UUID> emptySet(),
|
||||
Collections.<AccountExternalId> emptySet());
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RefControlTest extends TestCase {
|
||||
@@ -188,25 +190,24 @@ public class RefControlTest extends TestCase {
|
||||
|
||||
private final Project.NameKey local = new Project.NameKey("test");
|
||||
private final Project.NameKey parent = new Project.NameKey("parent");
|
||||
private final AccountGroup.Id admin = new AccountGroup.Id(1);
|
||||
private final AccountGroup.Id anonymous = new AccountGroup.Id(2);
|
||||
private final AccountGroup.Id registered = new AccountGroup.Id(3);
|
||||
private final AccountGroup.Id owners = new AccountGroup.Id(4);
|
||||
private final AccountGroup.UUID admin = new AccountGroup.UUID("test.admin");
|
||||
private final AccountGroup.UUID anonymous = AccountGroup.ANONYMOUS_USERS;
|
||||
private final AccountGroup.UUID registered = AccountGroup.REGISTERED_USERS;
|
||||
|
||||
private final AccountGroup.Id devs = new AccountGroup.Id(5);
|
||||
private final AccountGroup.Id fixers = new AccountGroup.Id(6);
|
||||
private final AccountGroup.UUID devs = new AccountGroup.UUID("test.devs");
|
||||
private final AccountGroup.UUID fixers = new AccountGroup.UUID("test.fixers");
|
||||
|
||||
private final SystemConfig systemConfig;
|
||||
private final AuthConfig authConfig;
|
||||
private final AnonymousUser anonymousUser;
|
||||
|
||||
private final Map<AccountGroup.UUID, AccountGroup.Id> groupIds =
|
||||
new HashMap<AccountGroup.UUID, AccountGroup.Id>();
|
||||
|
||||
public RefControlTest() {
|
||||
systemConfig = SystemConfig.create();
|
||||
systemConfig.adminGroupId = admin;
|
||||
systemConfig.anonymousGroupId = anonymous;
|
||||
systemConfig.registeredGroupId = registered;
|
||||
systemConfig.ownerGroupId = owners;
|
||||
systemConfig.batchUsersGroupId = anonymous;
|
||||
systemConfig.adminGroupUUID = admin;
|
||||
systemConfig.batchUsersGroupUUID = anonymous;
|
||||
try {
|
||||
byte[] bin = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8");
|
||||
systemConfig.registerEmailPrivateKey = Base64.encodeBase64String(bin);
|
||||
@@ -249,15 +250,22 @@ public class RefControlTest extends TestCase {
|
||||
}
|
||||
|
||||
private void grant(Project.NameKey project, ApprovalCategory.Id categoryId,
|
||||
AccountGroup.Id group, String ref, int maxValue) {
|
||||
AccountGroup.UUID group, String ref, int maxValue) {
|
||||
grant(project, categoryId, group, ref, maxValue, maxValue);
|
||||
}
|
||||
|
||||
private void grant(Project.NameKey project, ApprovalCategory.Id categoryId, AccountGroup.Id group,
|
||||
String ref, int minValue, int maxValue) {
|
||||
private void grant(Project.NameKey project, ApprovalCategory.Id categoryId,
|
||||
AccountGroup.UUID groupUUID, String ref, int minValue, int maxValue) {
|
||||
AccountGroup.Id groupId = groupIds.get(groupUUID);
|
||||
if (groupId == null) {
|
||||
groupId = new AccountGroup.Id(groupIds.size() + 1);
|
||||
groupIds.put(groupUUID, groupId);
|
||||
}
|
||||
|
||||
RefRight right =
|
||||
new RefRight(new RefRight.Key(project, new RefPattern(ref),
|
||||
categoryId, group));
|
||||
categoryId, groupId));
|
||||
right.setAccountGroupUUID(groupUUID);
|
||||
right.setMinValue((short) minValue);
|
||||
right.setMaxValue((short) maxValue);
|
||||
|
||||
@@ -270,15 +278,15 @@ public class RefControlTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private ProjectControl user(AccountGroup.Id... memberOf) {
|
||||
private ProjectControl user(AccountGroup.UUID... memberOf) {
|
||||
RefControl.Factory refControlFactory = new RefControl.Factory() {
|
||||
@Override
|
||||
public RefControl create(final ProjectControl projectControl, final String ref) {
|
||||
return new RefControl(systemConfig, projectControl, ref);
|
||||
return new RefControl(projectControl, ref);
|
||||
}
|
||||
};
|
||||
return new ProjectControl(Collections.<AccountGroup.Id> emptySet(),
|
||||
Collections.<AccountGroup.Id> emptySet(), refControlFactory,
|
||||
return new ProjectControl(Collections.<AccountGroup.UUID> emptySet(),
|
||||
Collections.<AccountGroup.UUID> emptySet(), refControlFactory,
|
||||
new MockUser(memberOf), newProjectState());
|
||||
}
|
||||
|
||||
@@ -295,17 +303,17 @@ public class RefControlTest extends TestCase {
|
||||
}
|
||||
|
||||
private class MockUser extends CurrentUser {
|
||||
private final Set<AccountGroup.Id> groups;
|
||||
private final Set<AccountGroup.UUID> groups;
|
||||
|
||||
MockUser(AccountGroup.Id[] groupId) {
|
||||
MockUser(AccountGroup.UUID[] groupId) {
|
||||
super(AccessPath.UNKNOWN, RefControlTest.this.authConfig);
|
||||
groups = new HashSet<AccountGroup.Id>(Arrays.asList(groupId));
|
||||
groups = new HashSet<AccountGroup.UUID>(Arrays.asList(groupId));
|
||||
groups.add(registered);
|
||||
groups.add(anonymous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> getEffectiveGroups() {
|
||||
public Set<AccountGroup.UUID> getEffectiveGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.google.gerrit.server.git.WorkQueue;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.ssh.SshInfo;
|
||||
import com.google.gerrit.sshd.args4j.AccountGroupIdHandler;
|
||||
import com.google.gerrit.sshd.args4j.AccountGroupUUIDHandler;
|
||||
import com.google.gerrit.sshd.args4j.AccountIdHandler;
|
||||
import com.google.gerrit.sshd.args4j.PatchSetIdHandler;
|
||||
import com.google.gerrit.sshd.args4j.ProjectControlHandler;
|
||||
@@ -117,6 +118,7 @@ public class SshModule extends FactoryModule {
|
||||
|
||||
registerOptionHandler(Account.Id.class, AccountIdHandler.class);
|
||||
registerOptionHandler(AccountGroup.Id.class, AccountGroupIdHandler.class);
|
||||
registerOptionHandler(AccountGroup.UUID.class, AccountGroupUUIDHandler.class);
|
||||
registerOptionHandler(PatchSet.Id.class, PatchSetIdHandler.class);
|
||||
registerOptionHandler(ProjectControl.class, ProjectControlHandler.class);
|
||||
registerOptionHandler(SocketAddress.class, SocketAddressHandler.class);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2009 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 com.google.gerrit.sshd.args4j;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.kohsuke.args4j.CmdLineException;
|
||||
import org.kohsuke.args4j.CmdLineParser;
|
||||
import org.kohsuke.args4j.OptionDef;
|
||||
import org.kohsuke.args4j.spi.OptionHandler;
|
||||
import org.kohsuke.args4j.spi.Parameters;
|
||||
import org.kohsuke.args4j.spi.Setter;
|
||||
|
||||
public class AccountGroupUUIDHandler extends OptionHandler<AccountGroup.UUID> {
|
||||
private final GroupCache groupCache;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject
|
||||
public AccountGroupUUIDHandler(final GroupCache groupCache,
|
||||
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
|
||||
@Assisted final Setter setter) {
|
||||
super(parser, option, setter);
|
||||
this.groupCache = groupCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int parseArguments(final Parameters params)
|
||||
throws CmdLineException {
|
||||
final String n = params.getParameter(0);
|
||||
final AccountGroup group = groupCache.get(new AccountGroup.NameKey(n));
|
||||
if (group == null) {
|
||||
throw new CmdLineException(owner, "Group \"" + n + "\" does not exist");
|
||||
}
|
||||
setter.addValue(group.getGroupUUID());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getDefaultMetaVariable() {
|
||||
return "GROUP";
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.Project.SubmitType;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.config.ProjectCreatorGroups;
|
||||
import com.google.gerrit.server.config.ProjectOwnerGroups;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
@@ -64,7 +65,7 @@ final class CreateProject extends BaseCommand {
|
||||
private String projectName;
|
||||
|
||||
@Option(name = "--owner", aliases = {"-o"}, usage = "owner(s) of project")
|
||||
private List<AccountGroup.Id> ownerIds;
|
||||
private List<AccountGroup.UUID> ownerIds;
|
||||
|
||||
@Option(name = "--parent", aliases = {"-p"}, metaVar = "NAME", usage = "parent project")
|
||||
private ProjectControl newParent;
|
||||
@@ -104,13 +105,16 @@ final class CreateProject extends BaseCommand {
|
||||
@Inject
|
||||
private ProjectCache projectCache;
|
||||
|
||||
@Inject
|
||||
private GroupCache groupCache;
|
||||
|
||||
@Inject
|
||||
@ProjectCreatorGroups
|
||||
private Set<AccountGroup.Id> projectCreatorGroups;
|
||||
private Set<AccountGroup.UUID> projectCreatorGroups;
|
||||
|
||||
@Inject
|
||||
@ProjectOwnerGroups
|
||||
private Set<AccountGroup.Id> projectOwnerGroups;
|
||||
private Set<AccountGroup.UUID> projectOwnerGroups;
|
||||
|
||||
@Inject
|
||||
private IdentifiedUser currentUser;
|
||||
@@ -202,10 +206,12 @@ final class CreateProject extends BaseCommand {
|
||||
ConfigInvalidException {
|
||||
|
||||
List<RefRight> access = new ArrayList<RefRight>();
|
||||
for (AccountGroup.Id ownerId : ownerIds) {
|
||||
for (AccountGroup.UUID ownerId : ownerIds) {
|
||||
AccountGroup group = groupCache.get(ownerId);
|
||||
|
||||
final RefRight.Key prk =
|
||||
new RefRight.Key(nameKey, new RefRight.RefPattern(
|
||||
RefRight.ALL), ApprovalCategory.OWN, ownerId);
|
||||
RefRight.ALL), ApprovalCategory.OWN, group.getId());
|
||||
final RefRight pr = new RefRight(prk);
|
||||
pr.setMaxValue((short) 1);
|
||||
pr.setMinValue((short) 1);
|
||||
@@ -251,9 +257,9 @@ final class CreateProject extends BaseCommand {
|
||||
|
||||
if (ownerIds != null && !ownerIds.isEmpty()) {
|
||||
ownerIds =
|
||||
new ArrayList<AccountGroup.Id>(new HashSet<AccountGroup.Id>(ownerIds));
|
||||
new ArrayList<AccountGroup.UUID>(new HashSet<AccountGroup.UUID>(ownerIds));
|
||||
} else {
|
||||
ownerIds = new ArrayList<AccountGroup.Id>(projectOwnerGroups);
|
||||
ownerIds = new ArrayList<AccountGroup.UUID>(projectOwnerGroups);
|
||||
}
|
||||
|
||||
while (branch.startsWith("/")) {
|
||||
|
||||
Reference in New Issue
Block a user