Merge "Make audit of account group membership changes pluggable"
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.httpd.rpc.account;
|
package com.google.gerrit.httpd.rpc.account;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.common.ChangeHooks;
|
import com.google.gerrit.common.ChangeHooks;
|
||||||
import com.google.gerrit.common.data.AccountSecurity;
|
import com.google.gerrit.common.data.AccountSecurity;
|
||||||
import com.google.gerrit.common.data.ContributorAgreement;
|
import com.google.gerrit.common.data.ContributorAgreement;
|
||||||
@@ -27,7 +28,6 @@ import com.google.gerrit.reviewdb.client.Account;
|
|||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.client.ContactInformation;
|
import com.google.gerrit.reviewdb.client.ContactInformation;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
@@ -71,6 +71,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
|
|
||||||
private final ChangeHooks hooks;
|
private final ChangeHooks hooks;
|
||||||
private final GroupCache groupCache;
|
private final GroupCache groupCache;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AccountSecurityImpl(final Provider<ReviewDb> schema,
|
AccountSecurityImpl(final Provider<ReviewDb> schema,
|
||||||
@@ -82,7 +83,8 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
final ChangeUserName.CurrentUser changeUserNameFactory,
|
final ChangeUserName.CurrentUser changeUserNameFactory,
|
||||||
final DeleteExternalIds.Factory deleteExternalIdsFactory,
|
final DeleteExternalIds.Factory deleteExternalIdsFactory,
|
||||||
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
|
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
|
||||||
final ChangeHooks hooks, final GroupCache groupCache) {
|
final ChangeHooks hooks, final GroupCache groupCache,
|
||||||
|
final AuditService auditService) {
|
||||||
super(schema, currentUser);
|
super(schema, currentUser);
|
||||||
contactStore = cs;
|
contactStore = cs;
|
||||||
realm = r;
|
realm = r;
|
||||||
@@ -92,6 +94,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
byEmailCache = abec;
|
byEmailCache = abec;
|
||||||
accountCache = uac;
|
accountCache = uac;
|
||||||
accountManager = am;
|
accountManager = am;
|
||||||
|
this.auditService = auditService;
|
||||||
|
|
||||||
useContactInfo = contactStore != null && contactStore.isEnabled();
|
useContactInfo = contactStore != null && contactStore.isEnabled();
|
||||||
|
|
||||||
@@ -198,9 +201,8 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
AccountGroupMember m = db.accountGroupMembers().get(key);
|
AccountGroupMember m = db.accountGroupMembers().get(key);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new AccountGroupMember(key);
|
m = new AccountGroupMember(key);
|
||||||
db.accountGroupMembersAudit().insert(
|
auditService.dispatchAddAccountsToGroup(account.getId(), Collections
|
||||||
Collections.singleton(new AccountGroupMemberAudit(
|
.singleton(m));
|
||||||
m, account.getId(), TimeUtil.nowTs())));
|
|
||||||
db.accountGroupMembers().insert(Collections.singleton(m));
|
db.accountGroupMembers().insert(Collections.singleton(m));
|
||||||
accountCache.evict(m.getAccountId());
|
accountCache.evict(m.getAccountId());
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ public class AuditModule extends AbstractModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
DynamicSet.setOf(binder(), AuditListener.class);
|
DynamicSet.setOf(binder(), AuditListener.class);
|
||||||
|
DynamicSet.setOf(binder(), GroupMemberAuditListener.class);
|
||||||
bind(AuditService.class);
|
bind(AuditService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,16 +15,30 @@
|
|||||||
package com.google.gerrit.audit;
|
package com.google.gerrit.audit;
|
||||||
|
|
||||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AuditService {
|
public class AuditService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AuditService.class);
|
||||||
|
|
||||||
private final DynamicSet<AuditListener> auditListeners;
|
private final DynamicSet<AuditListener> auditListeners;
|
||||||
|
private final DynamicSet<GroupMemberAuditListener> groupMemberAuditListeners;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AuditService(DynamicSet<AuditListener> auditListeners) {
|
public AuditService(DynamicSet<AuditListener> auditListeners,
|
||||||
|
DynamicSet<GroupMemberAuditListener> groupMemberAuditListeners) {
|
||||||
this.auditListeners = auditListeners;
|
this.auditListeners = auditListeners;
|
||||||
|
this.groupMemberAuditListeners = groupMemberAuditListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispatch(AuditEvent action) {
|
public void dispatch(AuditEvent action) {
|
||||||
@@ -32,4 +46,48 @@ public class AuditService {
|
|||||||
auditListener.onAuditableAction(action);
|
auditListener.onAuditableAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatchAddAccountsToGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupMember> added) {
|
||||||
|
for (GroupMemberAuditListener auditListener : groupMemberAuditListeners) {
|
||||||
|
try {
|
||||||
|
auditListener.onAddAccountsToGroup(actor, added);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("failed to log add accounts to group event", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispatchDeleteAccountsFromGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupMember> removed) {
|
||||||
|
for (GroupMemberAuditListener auditListener : groupMemberAuditListeners) {
|
||||||
|
try {
|
||||||
|
auditListener.onDeleteAccountsFromGroup(actor, removed);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("failed to log delete accounts from group event", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispatchAddGroupsToGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupById> added) {
|
||||||
|
for (GroupMemberAuditListener auditListener : groupMemberAuditListeners) {
|
||||||
|
try {
|
||||||
|
auditListener.onAddGroupsToGroup(actor, added);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("failed to log add groups to group event", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispatchDeleteGroupsFromGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupById> removed) {
|
||||||
|
for (GroupMemberAuditListener auditListener : groupMemberAuditListeners) {
|
||||||
|
try {
|
||||||
|
auditListener.onDeleteGroupsFromGroup(actor, removed);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("failed to log delete groups from group event", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (C) 2014 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.audit;
|
||||||
|
|
||||||
|
import com.google.gerrit.extensions.annotations.ExtensionPoint;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account.Id;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ExtensionPoint
|
||||||
|
public interface GroupMemberAuditListener {
|
||||||
|
|
||||||
|
void onAddAccountsToGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupMember> added);
|
||||||
|
|
||||||
|
void onDeleteAccountsFromGroup(Account.Id actor,
|
||||||
|
Collection<AccountGroupMember> removed);
|
||||||
|
|
||||||
|
void onAddGroupsToGroup(Id actor, Collection<AccountGroupById> added);
|
||||||
|
|
||||||
|
void onDeleteGroupsFromGroup(Id actor, Collection<AccountGroupById> deleted);
|
||||||
|
}
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.account;
|
package com.google.gerrit.server.account;
|
||||||
|
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
|
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
||||||
import com.google.gerrit.common.data.AccessSection;
|
import com.google.gerrit.common.data.AccessSection;
|
||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
@@ -23,7 +25,6 @@ import com.google.gerrit.reviewdb.client.Account;
|
|||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.project.ProjectCache;
|
import com.google.gerrit.server.project.ProjectCache;
|
||||||
@@ -53,6 +54,7 @@ public class AccountManager {
|
|||||||
private final ChangeUserName.Factory changeUserNameFactory;
|
private final ChangeUserName.Factory changeUserNameFactory;
|
||||||
private final ProjectCache projectCache;
|
private final ProjectCache projectCache;
|
||||||
private final AtomicBoolean awaitsFirstAccountCheck;
|
private final AtomicBoolean awaitsFirstAccountCheck;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AccountManager(final SchemaFactory<ReviewDb> schema,
|
AccountManager(final SchemaFactory<ReviewDb> schema,
|
||||||
@@ -60,7 +62,8 @@ public class AccountManager {
|
|||||||
final Realm accountMapper,
|
final Realm accountMapper,
|
||||||
final IdentifiedUser.GenericFactory userFactory,
|
final IdentifiedUser.GenericFactory userFactory,
|
||||||
final ChangeUserName.Factory changeUserNameFactory,
|
final ChangeUserName.Factory changeUserNameFactory,
|
||||||
final ProjectCache projectCache) throws OrmException {
|
final ProjectCache projectCache,
|
||||||
|
final AuditService auditService) throws OrmException {
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
this.byIdCache = byIdCache;
|
this.byIdCache = byIdCache;
|
||||||
this.byEmailCache = byEmailCache;
|
this.byEmailCache = byEmailCache;
|
||||||
@@ -69,6 +72,7 @@ public class AccountManager {
|
|||||||
this.changeUserNameFactory = changeUserNameFactory;
|
this.changeUserNameFactory = changeUserNameFactory;
|
||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
this.awaitsFirstAccountCheck = new AtomicBoolean(true);
|
this.awaitsFirstAccountCheck = new AtomicBoolean(true);
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,8 +231,7 @@ public class AccountManager {
|
|||||||
final AccountGroup.Id adminId = g.getId();
|
final AccountGroup.Id adminId = g.getId();
|
||||||
final AccountGroupMember m =
|
final AccountGroupMember m =
|
||||||
new AccountGroupMember(new AccountGroupMember.Key(newId, adminId));
|
new AccountGroupMember(new AccountGroupMember.Key(newId, adminId));
|
||||||
db.accountGroupMembersAudit().insert(Collections.singleton(
|
auditService.dispatchAddAccountsToGroup(newId, Collections.singleton(m));
|
||||||
new AccountGroupMemberAudit(m, newId, TimeUtil.nowTs())));
|
|
||||||
db.accountGroupMembers().insert(Collections.singleton(m));
|
db.accountGroupMembers().insert(Collections.singleton(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.account;
|
package com.google.gerrit.server.account;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.common.data.GroupDescriptions;
|
import com.google.gerrit.common.data.GroupDescriptions;
|
||||||
import com.google.gerrit.common.errors.InvalidSshKeyException;
|
import com.google.gerrit.common.errors.InvalidSshKeyException;
|
||||||
@@ -30,7 +31,6 @@ import com.google.gerrit.reviewdb.client.Account;
|
|||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.client.AccountSshKey;
|
import com.google.gerrit.reviewdb.client.AccountSshKey;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -74,13 +74,14 @@ public class CreateAccount implements RestModifyView<TopLevelResource, Input> {
|
|||||||
private final AccountByEmailCache byEmailCache;
|
private final AccountByEmailCache byEmailCache;
|
||||||
private final AccountInfo.Loader.Factory infoLoader;
|
private final AccountInfo.Loader.Factory infoLoader;
|
||||||
private final String username;
|
private final String username;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateAccount(ReviewDb db, Provider<IdentifiedUser> currentUser,
|
CreateAccount(ReviewDb db, Provider<IdentifiedUser> currentUser,
|
||||||
GroupsCollection groupsCollection, SshKeyCache sshKeyCache,
|
GroupsCollection groupsCollection, SshKeyCache sshKeyCache,
|
||||||
AccountCache accountCache, AccountByEmailCache byEmailCache,
|
AccountCache accountCache, AccountByEmailCache byEmailCache,
|
||||||
AccountInfo.Loader.Factory infoLoader,
|
AccountInfo.Loader.Factory infoLoader,
|
||||||
@Assisted String username) {
|
@Assisted String username, AuditService auditService) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.groupsCollection = groupsCollection;
|
this.groupsCollection = groupsCollection;
|
||||||
@@ -89,6 +90,7 @@ public class CreateAccount implements RestModifyView<TopLevelResource, Input> {
|
|||||||
this.byEmailCache = byEmailCache;
|
this.byEmailCache = byEmailCache;
|
||||||
this.infoLoader = infoLoader;
|
this.infoLoader = infoLoader;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -169,9 +171,8 @@ public class CreateAccount implements RestModifyView<TopLevelResource, Input> {
|
|||||||
for (AccountGroup.Id groupId : groups) {
|
for (AccountGroup.Id groupId : groups) {
|
||||||
AccountGroupMember m =
|
AccountGroupMember m =
|
||||||
new AccountGroupMember(new AccountGroupMember.Key(id, groupId));
|
new AccountGroupMember(new AccountGroupMember.Key(id, groupId));
|
||||||
db.accountGroupMembersAudit().insert(Collections.singleton(
|
auditService.dispatchAddAccountsToGroup(currentUser.get().getAccountId(),
|
||||||
new AccountGroupMemberAudit(
|
Collections.singleton(m));
|
||||||
m, currentUser.get().getAccountId(), TimeUtil.nowTs())));
|
|
||||||
db.accountGroupMembers().insert(Collections.singleton(m));
|
db.accountGroupMembers().insert(Collections.singleton(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,19 +14,17 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.account;
|
package com.google.gerrit.server.account;
|
||||||
|
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.common.errors.NameAlreadyUsedException;
|
import com.google.gerrit.common.errors.NameAlreadyUsedException;
|
||||||
import com.google.gerrit.common.errors.PermissionDeniedException;
|
import com.google.gerrit.common.errors.PermissionDeniedException;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.GerritPersonIdent;
|
import com.google.gerrit.server.GerritPersonIdent;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.util.TimeUtil;
|
|
||||||
import com.google.gwtorm.server.OrmDuplicateKeyException;
|
import com.google.gwtorm.server.OrmDuplicateKeyException;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@@ -52,12 +50,13 @@ public class PerformCreateGroup {
|
|||||||
private final PersonIdent serverIdent;
|
private final PersonIdent serverIdent;
|
||||||
private final GroupCache groupCache;
|
private final GroupCache groupCache;
|
||||||
private final CreateGroupArgs createGroupArgs;
|
private final CreateGroupArgs createGroupArgs;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PerformCreateGroup(ReviewDb db, AccountCache accountCache,
|
PerformCreateGroup(ReviewDb db, AccountCache accountCache,
|
||||||
GroupIncludeCache groupIncludeCache, IdentifiedUser currentUser,
|
GroupIncludeCache groupIncludeCache, IdentifiedUser currentUser,
|
||||||
@GerritPersonIdent PersonIdent serverIdent, GroupCache groupCache,
|
@GerritPersonIdent PersonIdent serverIdent, GroupCache groupCache,
|
||||||
@Assisted CreateGroupArgs createGroupArgs) {
|
@Assisted CreateGroupArgs createGroupArgs, AuditService auditService) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.groupIncludeCache = groupIncludeCache;
|
this.groupIncludeCache = groupIncludeCache;
|
||||||
@@ -65,6 +64,7 @@ public class PerformCreateGroup {
|
|||||||
this.serverIdent = serverIdent;
|
this.serverIdent = serverIdent;
|
||||||
this.groupCache = groupCache;
|
this.groupCache = groupCache;
|
||||||
this.createGroupArgs = createGroupArgs;
|
this.createGroupArgs = createGroupArgs;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,18 +127,13 @@ public class PerformCreateGroup {
|
|||||||
private void addMembers(final AccountGroup.Id groupId,
|
private void addMembers(final AccountGroup.Id groupId,
|
||||||
final Collection<? extends Account.Id> members) throws OrmException {
|
final Collection<? extends Account.Id> members) throws OrmException {
|
||||||
List<AccountGroupMember> memberships = new ArrayList<>();
|
List<AccountGroupMember> memberships = new ArrayList<>();
|
||||||
List<AccountGroupMemberAudit> membershipsAudit = new ArrayList<>();
|
|
||||||
for (Account.Id accountId : members) {
|
for (Account.Id accountId : members) {
|
||||||
final AccountGroupMember membership =
|
final AccountGroupMember membership =
|
||||||
new AccountGroupMember(new AccountGroupMember.Key(accountId, groupId));
|
new AccountGroupMember(new AccountGroupMember.Key(accountId, groupId));
|
||||||
memberships.add(membership);
|
memberships.add(membership);
|
||||||
|
|
||||||
final AccountGroupMemberAudit audit = new AccountGroupMemberAudit(
|
|
||||||
membership, currentUser.getAccountId(), TimeUtil.nowTs());
|
|
||||||
membershipsAudit.add(audit);
|
|
||||||
}
|
}
|
||||||
db.accountGroupMembers().insert(memberships);
|
db.accountGroupMembers().insert(memberships);
|
||||||
db.accountGroupMembersAudit().insert(membershipsAudit);
|
auditService.dispatchAddAccountsToGroup(currentUser.getAccountId(), memberships);
|
||||||
|
|
||||||
for (Account.Id accountId : members) {
|
for (Account.Id accountId : members) {
|
||||||
accountCache.evict(accountId);
|
accountCache.evict(accountId);
|
||||||
@@ -148,18 +143,13 @@ public class PerformCreateGroup {
|
|||||||
private void addGroups(final AccountGroup.Id groupId,
|
private void addGroups(final AccountGroup.Id groupId,
|
||||||
final Collection<? extends AccountGroup.UUID> groups) throws OrmException {
|
final Collection<? extends AccountGroup.UUID> groups) throws OrmException {
|
||||||
List<AccountGroupById> includeList = new ArrayList<>();
|
List<AccountGroupById> includeList = new ArrayList<>();
|
||||||
List<AccountGroupByIdAud> includesAudit = new ArrayList<>();
|
|
||||||
for (AccountGroup.UUID includeUUID : groups) {
|
for (AccountGroup.UUID includeUUID : groups) {
|
||||||
final AccountGroupById groupInclude =
|
final AccountGroupById groupInclude =
|
||||||
new AccountGroupById(new AccountGroupById.Key(groupId, includeUUID));
|
new AccountGroupById(new AccountGroupById.Key(groupId, includeUUID));
|
||||||
includeList.add(groupInclude);
|
includeList.add(groupInclude);
|
||||||
|
|
||||||
final AccountGroupByIdAud audit = new AccountGroupByIdAud(
|
|
||||||
groupInclude, currentUser.getAccountId(), TimeUtil.nowTs());
|
|
||||||
includesAudit.add(audit);
|
|
||||||
}
|
}
|
||||||
db.accountGroupById().insert(includeList);
|
db.accountGroupById().insert(includeList);
|
||||||
db.accountGroupByIdAud().insert(includesAudit);
|
auditService.dispatchAddGroupsToGroup(currentUser.getAccountId(), includeList);
|
||||||
|
|
||||||
for (AccountGroup.UUID uuid : groups) {
|
for (AccountGroup.UUID uuid : groups) {
|
||||||
groupIncludeCache.evictMemberIn(uuid);
|
groupIncludeCache.evictMemberIn(uuid);
|
||||||
|
@@ -18,6 +18,7 @@ import com.google.common.base.Strings;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.common.data.GroupDescription;
|
import com.google.gerrit.common.data.GroupDescription;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
@@ -27,14 +28,12 @@ import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.account.GroupControl;
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
import com.google.gerrit.server.account.GroupIncludeCache;
|
import com.google.gerrit.server.account.GroupIncludeCache;
|
||||||
import com.google.gerrit.server.group.AddIncludedGroups.Input;
|
import com.google.gerrit.server.group.AddIncludedGroups.Input;
|
||||||
import com.google.gerrit.server.group.GroupJson.GroupInfo;
|
import com.google.gerrit.server.group.GroupJson.GroupInfo;
|
||||||
import com.google.gerrit.server.util.TimeUtil;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -75,15 +74,17 @@ public class AddIncludedGroups implements RestModifyView<GroupResource, Input> {
|
|||||||
private final GroupIncludeCache groupIncludeCache;
|
private final GroupIncludeCache groupIncludeCache;
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
private final GroupJson json;
|
private final GroupJson json;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AddIncludedGroups(GroupsCollection groupsCollection,
|
public AddIncludedGroups(GroupsCollection groupsCollection,
|
||||||
GroupIncludeCache groupIncludeCache,
|
GroupIncludeCache groupIncludeCache, Provider<ReviewDb> db,
|
||||||
Provider<ReviewDb> db, GroupJson json) {
|
GroupJson json, AuditService auditService) {
|
||||||
this.groupsCollection = groupsCollection;
|
this.groupsCollection = groupsCollection;
|
||||||
this.groupIncludeCache = groupIncludeCache;
|
this.groupIncludeCache = groupIncludeCache;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,7 +99,6 @@ public class AddIncludedGroups implements RestModifyView<GroupResource, Input> {
|
|||||||
|
|
||||||
GroupControl control = resource.getControl();
|
GroupControl control = resource.getControl();
|
||||||
Map<AccountGroup.UUID, AccountGroupById> newIncludedGroups = Maps.newHashMap();
|
Map<AccountGroup.UUID, AccountGroupById> newIncludedGroups = Maps.newHashMap();
|
||||||
List<AccountGroupByIdAud> newIncludedGroupsAudits = Lists.newLinkedList();
|
|
||||||
List<GroupInfo> result = Lists.newLinkedList();
|
List<GroupInfo> result = Lists.newLinkedList();
|
||||||
Account.Id me = ((IdentifiedUser) control.getCurrentUser()).getAccountId();
|
Account.Id me = ((IdentifiedUser) control.getCurrentUser()).getAccountId();
|
||||||
|
|
||||||
@@ -117,15 +117,13 @@ public class AddIncludedGroups implements RestModifyView<GroupResource, Input> {
|
|||||||
if (agi == null) {
|
if (agi == null) {
|
||||||
agi = new AccountGroupById(agiKey);
|
agi = new AccountGroupById(agiKey);
|
||||||
newIncludedGroups.put(d.getGroupUUID(), agi);
|
newIncludedGroups.put(d.getGroupUUID(), agi);
|
||||||
newIncludedGroupsAudits.add(
|
|
||||||
new AccountGroupByIdAud(agi, me, TimeUtil.nowTs()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.add(json.format(d));
|
result.add(json.format(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newIncludedGroups.isEmpty()) {
|
if (!newIncludedGroups.isEmpty()) {
|
||||||
db.get().accountGroupByIdAud().insert(newIncludedGroupsAudits);
|
auditService.dispatchAddGroupsToGroup(me, newIncludedGroups.values());
|
||||||
db.get().accountGroupById().insert(newIncludedGroups.values());
|
db.get().accountGroupById().insert(newIncludedGroups.values());
|
||||||
for (AccountGroupById agi : newIncludedGroups.values()) {
|
for (AccountGroupById agi : newIncludedGroups.values()) {
|
||||||
groupIncludeCache.evictMemberIn(agi.getIncludeUUID());
|
groupIncludeCache.evictMemberIn(agi.getIncludeUUID());
|
||||||
|
@@ -17,6 +17,7 @@ package com.google.gerrit.server.group;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
@@ -25,7 +26,6 @@ import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -39,7 +39,6 @@ import com.google.gerrit.server.account.AuthRequest;
|
|||||||
import com.google.gerrit.server.account.GroupControl;
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
import com.google.gerrit.server.config.AuthConfig;
|
import com.google.gerrit.server.config.AuthConfig;
|
||||||
import com.google.gerrit.server.group.AddMembers.Input;
|
import com.google.gerrit.server.group.AddMembers.Input;
|
||||||
import com.google.gerrit.server.util.TimeUtil;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -82,6 +81,7 @@ public class AddMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
private final AccountCache accountCache;
|
private final AccountCache accountCache;
|
||||||
private final AccountInfo.Loader.Factory infoFactory;
|
private final AccountInfo.Loader.Factory infoFactory;
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AddMembers(AccountManager accountManager,
|
AddMembers(AccountManager accountManager,
|
||||||
@@ -90,8 +90,10 @@ public class AddMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
AccountResolver accountResolver,
|
AccountResolver accountResolver,
|
||||||
AccountCache accountCache,
|
AccountCache accountCache,
|
||||||
AccountInfo.Loader.Factory infoFactory,
|
AccountInfo.Loader.Factory infoFactory,
|
||||||
Provider<ReviewDb> db) {
|
Provider<ReviewDb> db,
|
||||||
|
AuditService auditService) {
|
||||||
this.accountManager = accountManager;
|
this.accountManager = accountManager;
|
||||||
|
this.auditService = auditService;
|
||||||
this.authType = authConfig.getAuthType();
|
this.authType = authConfig.getAuthType();
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
this.accountResolver = accountResolver;
|
this.accountResolver = accountResolver;
|
||||||
@@ -112,7 +114,6 @@ public class AddMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
|
|
||||||
GroupControl control = resource.getControl();
|
GroupControl control = resource.getControl();
|
||||||
Map<Account.Id, AccountGroupMember> newAccountGroupMembers = Maps.newHashMap();
|
Map<Account.Id, AccountGroupMember> newAccountGroupMembers = Maps.newHashMap();
|
||||||
List<AccountGroupMemberAudit> newAccountGroupMemberAudits = Lists.newLinkedList();
|
|
||||||
List<AccountInfo> result = Lists.newLinkedList();
|
List<AccountInfo> result = Lists.newLinkedList();
|
||||||
Account.Id me = ((IdentifiedUser) control.getCurrentUser()).getAccountId();
|
Account.Id me = ((IdentifiedUser) control.getCurrentUser()).getAccountId();
|
||||||
AccountInfo.Loader loader = infoFactory.create(true);
|
AccountInfo.Loader loader = infoFactory.create(true);
|
||||||
@@ -135,14 +136,12 @@ public class AddMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new AccountGroupMember(key);
|
m = new AccountGroupMember(key);
|
||||||
newAccountGroupMembers.put(m.getAccountId(), m);
|
newAccountGroupMembers.put(m.getAccountId(), m);
|
||||||
newAccountGroupMemberAudits.add(
|
|
||||||
new AccountGroupMemberAudit(m, me, TimeUtil.nowTs()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.add(loader.get(a.getId()));
|
result.add(loader.get(a.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
db.get().accountGroupMembersAudit().insert(newAccountGroupMemberAudits);
|
auditService.dispatchAddAccountsToGroup(me, newAccountGroupMembers.values());
|
||||||
db.get().accountGroupMembers().insert(newAccountGroupMembers.values());
|
db.get().accountGroupMembers().insert(newAccountGroupMembers.values());
|
||||||
for (AccountGroupMember m : newAccountGroupMembers.values()) {
|
for (AccountGroupMember m : newAccountGroupMembers.values()) {
|
||||||
accountCache.evict(m.getAccountId());
|
accountCache.evict(m.getAccountId());
|
||||||
|
@@ -0,0 +1,201 @@
|
|||||||
|
// Copyright (C) 2014 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.server.group;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.gerrit.audit.GroupMemberAuditListener;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.account.AccountCache;
|
||||||
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
|
import com.google.gerrit.server.account.UniversalGroupBackend;
|
||||||
|
import com.google.gerrit.server.util.TimeUtil;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class DbGroupMemberAuditListener implements GroupMemberAuditListener {
|
||||||
|
private static final Logger log = org.slf4j.LoggerFactory
|
||||||
|
.getLogger(DbGroupMemberAuditListener.class);
|
||||||
|
|
||||||
|
private final Provider<ReviewDb> db;
|
||||||
|
private final AccountCache accountCache;
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
private final UniversalGroupBackend groupBackend;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public DbGroupMemberAuditListener(Provider<ReviewDb> db,
|
||||||
|
AccountCache accountCache, GroupCache groupCache,
|
||||||
|
UniversalGroupBackend groupBackend) {
|
||||||
|
this.db = db;
|
||||||
|
this.accountCache = accountCache;
|
||||||
|
this.groupCache = groupCache;
|
||||||
|
this.groupBackend = groupBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddAccountsToGroup(Account.Id me,
|
||||||
|
Collection<AccountGroupMember> added) {
|
||||||
|
List<AccountGroupMemberAudit> auditInserts = Lists.newLinkedList();
|
||||||
|
for (AccountGroupMember m : added) {
|
||||||
|
AccountGroupMemberAudit audit =
|
||||||
|
new AccountGroupMemberAudit(m, me, TimeUtil.nowTs());
|
||||||
|
auditInserts.add(audit);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
db.get().accountGroupMembersAudit().insert(auditInserts);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
logOrmExceptionForAccounts(
|
||||||
|
"Cannot log add accounts to group event performed by user", me,
|
||||||
|
added, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeleteAccountsFromGroup(Account.Id me,
|
||||||
|
Collection<AccountGroupMember> removed) {
|
||||||
|
List<AccountGroupMemberAudit> auditInserts = Lists.newLinkedList();
|
||||||
|
List<AccountGroupMemberAudit> auditUpdates = Lists.newLinkedList();
|
||||||
|
ReviewDb reviewDB = db.get();
|
||||||
|
try {
|
||||||
|
for (AccountGroupMember m : removed) {
|
||||||
|
AccountGroupMemberAudit audit = null;
|
||||||
|
for (AccountGroupMemberAudit a : reviewDB.accountGroupMembersAudit()
|
||||||
|
.byGroupAccount(m.getAccountGroupId(), m.getAccountId())) {
|
||||||
|
if (a.isActive()) {
|
||||||
|
audit = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audit != null) {
|
||||||
|
audit.removed(me, TimeUtil.nowTs());
|
||||||
|
auditUpdates.add(audit);
|
||||||
|
} else {
|
||||||
|
audit = new AccountGroupMemberAudit(m, me, TimeUtil.nowTs());
|
||||||
|
audit.removedLegacy();
|
||||||
|
auditInserts.add(audit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reviewDB.accountGroupMembersAudit().update(auditUpdates);
|
||||||
|
reviewDB.accountGroupMembersAudit().insert(auditInserts);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
logOrmExceptionForAccounts(
|
||||||
|
"Cannot log delete accounts from group event performed by user", me,
|
||||||
|
removed, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddGroupsToGroup(Account.Id me,
|
||||||
|
Collection<AccountGroupById> added) {
|
||||||
|
List<AccountGroupByIdAud> includesAudit = new ArrayList<>();
|
||||||
|
for (AccountGroupById groupInclude : added) {
|
||||||
|
AccountGroupByIdAud audit =
|
||||||
|
new AccountGroupByIdAud(groupInclude, me, TimeUtil.nowTs());
|
||||||
|
includesAudit.add(audit);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
db.get().accountGroupByIdAud().insert(includesAudit);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
logOrmExceptionForGroups(
|
||||||
|
"Cannot log add groups to group event performed by user", me, added,
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeleteGroupsFromGroup(Account.Id me,
|
||||||
|
Collection<AccountGroupById> removed) {
|
||||||
|
final List<AccountGroupByIdAud> auditUpdates = Lists.newLinkedList();
|
||||||
|
try {
|
||||||
|
for (final AccountGroupById g : removed) {
|
||||||
|
AccountGroupByIdAud audit = null;
|
||||||
|
for (AccountGroupByIdAud a : db.get().accountGroupByIdAud()
|
||||||
|
.byGroupInclude(g.getGroupId(), g.getIncludeUUID())) {
|
||||||
|
if (a.isActive()) {
|
||||||
|
audit = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audit != null) {
|
||||||
|
audit.removed(me, TimeUtil.nowTs());
|
||||||
|
auditUpdates.add(audit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.get().accountGroupByIdAud().update(auditUpdates);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
logOrmExceptionForGroups(
|
||||||
|
"Cannot log delete groups from group event performed by user", me,
|
||||||
|
removed, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOrmExceptionForAccounts(String header, Account.Id me,
|
||||||
|
Collection<AccountGroupMember> values, OrmException e) {
|
||||||
|
List<String> descriptions = new ArrayList<>();
|
||||||
|
for (AccountGroupMember m : values) {
|
||||||
|
Account.Id accountId = m.getAccountId();
|
||||||
|
String userName = accountCache.get(accountId).getUserName();
|
||||||
|
AccountGroup.Id groupId = m.getAccountGroupId();
|
||||||
|
String groupName = groupCache.get(groupId).getName();
|
||||||
|
|
||||||
|
descriptions.add(MessageFormat.format("account {0}/{1}, group {2}/{3}",
|
||||||
|
accountId, userName, groupId, groupName));
|
||||||
|
}
|
||||||
|
logOrmException(header, me, descriptions, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOrmExceptionForGroups(String header, Account.Id me,
|
||||||
|
Collection<AccountGroupById> values, OrmException e) {
|
||||||
|
List<String> descriptions = new ArrayList<>();
|
||||||
|
for (AccountGroupById m : values) {
|
||||||
|
AccountGroup.UUID groupUuid = m.getIncludeUUID();
|
||||||
|
String groupName = groupBackend.get(groupUuid).getName();
|
||||||
|
AccountGroup.Id targetGroupId = m.getGroupId();
|
||||||
|
String targetGroupName = groupCache.get(targetGroupId).getName();
|
||||||
|
|
||||||
|
descriptions.add(MessageFormat.format("group {0}/{1}, group {2}/{3}",
|
||||||
|
groupUuid, groupName, targetGroupId, targetGroupName));
|
||||||
|
}
|
||||||
|
logOrmException(header, me, descriptions, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOrmException(String header, Account.Id me,
|
||||||
|
Iterable<?> values, OrmException e) {
|
||||||
|
StringBuilder message = new StringBuilder(header);
|
||||||
|
message.append(" ");
|
||||||
|
message.append(me);
|
||||||
|
message.append("/");
|
||||||
|
message.append(accountCache.get(me).getUserName());
|
||||||
|
message.append(": ");
|
||||||
|
message.append(Joiner.on("; ").join(values));
|
||||||
|
log.error(message.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,7 @@ package com.google.gerrit.server.group;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.common.data.GroupDescription;
|
import com.google.gerrit.common.data.GroupDescription;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
@@ -26,14 +27,12 @@ import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.account.GroupControl;
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
import com.google.gerrit.server.account.GroupIncludeCache;
|
import com.google.gerrit.server.account.GroupIncludeCache;
|
||||||
import com.google.gerrit.server.group.AddIncludedGroups.Input;
|
import com.google.gerrit.server.group.AddIncludedGroups.Input;
|
||||||
import com.google.gerrit.server.util.TimeUtil;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -48,16 +47,17 @@ public class DeleteIncludedGroups implements RestModifyView<GroupResource, Input
|
|||||||
private final GroupIncludeCache groupIncludeCache;
|
private final GroupIncludeCache groupIncludeCache;
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
private final Provider<CurrentUser> self;
|
private final Provider<CurrentUser> self;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DeleteIncludedGroups(GroupsCollection groupsCollection,
|
DeleteIncludedGroups(GroupsCollection groupsCollection,
|
||||||
GroupIncludeCache groupIncludeCache,
|
GroupIncludeCache groupIncludeCache, Provider<ReviewDb> db,
|
||||||
Provider<ReviewDb> db,
|
Provider<CurrentUser> self, AuditService auditService) {
|
||||||
Provider<CurrentUser> self) {
|
|
||||||
this.groupsCollection = groupsCollection;
|
this.groupsCollection = groupsCollection;
|
||||||
this.groupIncludeCache = groupIncludeCache;
|
this.groupIncludeCache = groupIncludeCache;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.self = self;
|
this.self = self;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -109,27 +109,10 @@ public class DeleteIncludedGroups implements RestModifyView<GroupResource, Input
|
|||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAudits(final List<AccountGroupById> toBeRemoved)
|
private void writeAudits(final List<AccountGroupById> toRemoved)
|
||||||
throws OrmException {
|
throws OrmException {
|
||||||
final Account.Id me = ((IdentifiedUser) self.get()).getAccountId();
|
final Account.Id me = ((IdentifiedUser) self.get()).getAccountId();
|
||||||
final List<AccountGroupByIdAud> auditUpdates = Lists.newLinkedList();
|
auditService.dispatchDeleteGroupsFromGroup(me, toRemoved);
|
||||||
for (final AccountGroupById g : toBeRemoved) {
|
|
||||||
AccountGroupByIdAud audit = null;
|
|
||||||
for (AccountGroupByIdAud a : db.get()
|
|
||||||
.accountGroupByIdAud().byGroupInclude(g.getGroupId(),
|
|
||||||
g.getIncludeUUID())) {
|
|
||||||
if (a.isActive()) {
|
|
||||||
audit = a;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audit != null) {
|
|
||||||
audit.removed(me, TimeUtil.nowTs());
|
|
||||||
auditUpdates.add(audit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db.get().accountGroupByIdAud().update(auditUpdates);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.server.group;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.audit.AuditService;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
import com.google.gerrit.extensions.restapi.Response;
|
import com.google.gerrit.extensions.restapi.Response;
|
||||||
@@ -24,7 +25,6 @@ import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -32,7 +32,6 @@ import com.google.gerrit.server.account.AccountCache;
|
|||||||
import com.google.gerrit.server.account.AccountsCollection;
|
import com.google.gerrit.server.account.AccountsCollection;
|
||||||
import com.google.gerrit.server.account.GroupControl;
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
import com.google.gerrit.server.group.AddMembers.Input;
|
import com.google.gerrit.server.group.AddMembers.Input;
|
||||||
import com.google.gerrit.server.util.TimeUtil;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -47,15 +46,18 @@ public class DeleteMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
private final AccountCache accountCache;
|
private final AccountCache accountCache;
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
private final Provider<CurrentUser> self;
|
private final Provider<CurrentUser> self;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DeleteMembers(AccountsCollection accounts,
|
DeleteMembers(AccountsCollection accounts,
|
||||||
AccountCache accountCache, Provider<ReviewDb> db,
|
AccountCache accountCache, Provider<ReviewDb> db,
|
||||||
Provider<CurrentUser> self) {
|
Provider<CurrentUser> self,
|
||||||
|
AuditService auditService) {
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.self = self;
|
this.self = self;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,32 +96,9 @@ public class DeleteMembers implements RestModifyView<GroupResource, Input> {
|
|||||||
return Response.none();
|
return Response.none();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAudits(final List<AccountGroupMember> toBeRemoved)
|
private void writeAudits(final List<AccountGroupMember> toRemove) {
|
||||||
throws OrmException {
|
|
||||||
final Account.Id me = ((IdentifiedUser) self.get()).getAccountId();
|
final Account.Id me = ((IdentifiedUser) self.get()).getAccountId();
|
||||||
final List<AccountGroupMemberAudit> auditUpdates = Lists.newLinkedList();
|
auditService.dispatchDeleteAccountsFromGroup(me, toRemove);
|
||||||
final List<AccountGroupMemberAudit> auditInserts = Lists.newLinkedList();
|
|
||||||
for (final AccountGroupMember m : toBeRemoved) {
|
|
||||||
AccountGroupMemberAudit audit = null;
|
|
||||||
for (AccountGroupMemberAudit a : db.get().accountGroupMembersAudit()
|
|
||||||
.byGroupAccount(m.getAccountGroupId(), m.getAccountId())) {
|
|
||||||
if (a.isActive()) {
|
|
||||||
audit = a;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audit != null) {
|
|
||||||
audit.removed(me, TimeUtil.nowTs());
|
|
||||||
auditUpdates.add(audit);
|
|
||||||
} else {
|
|
||||||
audit = new AccountGroupMemberAudit(m, me, TimeUtil.nowTs());
|
|
||||||
audit.removedLegacy();
|
|
||||||
auditInserts.add(audit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db.get().accountGroupMembersAudit().update(auditUpdates);
|
|
||||||
db.get().accountGroupMembersAudit().insert(auditInserts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Account.Id, AccountGroupMember> getMembers(
|
private Map<Account.Id, AccountGroupMember> getMembers(
|
||||||
|
@@ -18,7 +18,9 @@ import static com.google.gerrit.server.group.GroupResource.GROUP_KIND;
|
|||||||
import static com.google.gerrit.server.group.IncludedGroupResource.INCLUDED_GROUP_KIND;
|
import static com.google.gerrit.server.group.IncludedGroupResource.INCLUDED_GROUP_KIND;
|
||||||
import static com.google.gerrit.server.group.MemberResource.MEMBER_KIND;
|
import static com.google.gerrit.server.group.MemberResource.MEMBER_KIND;
|
||||||
|
|
||||||
|
import com.google.gerrit.audit.GroupMemberAuditListener;
|
||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
|
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||||
import com.google.gerrit.extensions.restapi.RestApiModule;
|
import com.google.gerrit.extensions.restapi.RestApiModule;
|
||||||
import com.google.gerrit.server.group.AddIncludedGroups.UpdateIncludedGroup;
|
import com.google.gerrit.server.group.AddIncludedGroups.UpdateIncludedGroup;
|
||||||
import com.google.gerrit.server.group.AddMembers.UpdateMember;
|
import com.google.gerrit.server.group.AddMembers.UpdateMember;
|
||||||
@@ -65,5 +67,9 @@ public class Module extends RestApiModule {
|
|||||||
delete(INCLUDED_GROUP_KIND).to(DeleteIncludedGroup.class);
|
delete(INCLUDED_GROUP_KIND).to(DeleteIncludedGroup.class);
|
||||||
|
|
||||||
install(new FactoryModuleBuilder().build(CreateGroup.Factory.class));
|
install(new FactoryModuleBuilder().build(CreateGroup.Factory.class));
|
||||||
|
|
||||||
|
DynamicSet.bind(binder(), GroupMemberAuditListener.class).to(
|
||||||
|
DbGroupMemberAuditListener.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user