Merge branch 'stable-2.15' into stable-2.16
* stable-2.15: Set version to 2.15.7 Trigger audit for GIT over Http commands Change-Id: If5451ef6b21df9219b06dd045f1138c5367fc3b2
This commit is contained in:
commit
98ecbb1cfe
|
@ -128,6 +128,7 @@ import com.google.gerrit.server.update.BatchUpdate;
|
|||
import com.google.gerrit.testing.ConfigSuite;
|
||||
import com.google.gerrit.testing.FakeEmailSender;
|
||||
import com.google.gerrit.testing.FakeEmailSender.Message;
|
||||
import com.google.gerrit.testing.FakeGroupAuditService;
|
||||
import com.google.gerrit.testing.NoteDbMode;
|
||||
import com.google.gerrit.testing.SshMode;
|
||||
import com.google.gerrit.testing.TempFileUtil;
|
||||
|
@ -244,6 +245,7 @@ public abstract class AbstractDaemonTest {
|
|||
@Inject protected ChangeNoteUtil changeNoteUtil;
|
||||
@Inject protected ChangeResource.Factory changeResourceFactory;
|
||||
@Inject protected FakeEmailSender sender;
|
||||
@Inject protected FakeGroupAuditService auditService;
|
||||
@Inject protected GerritApi gApi;
|
||||
@Inject protected GitRepositoryManager repoManager;
|
||||
@Inject protected GroupBackend groupBackend;
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.google.gerrit.server.util.OneOffRequestContext;
|
|||
import com.google.gerrit.server.util.SocketUtil;
|
||||
import com.google.gerrit.server.util.SystemLog;
|
||||
import com.google.gerrit.testing.FakeEmailSender;
|
||||
import com.google.gerrit.testing.FakeGroupAuditService;
|
||||
import com.google.gerrit.testing.InMemoryDatabase;
|
||||
import com.google.gerrit.testing.InMemoryRepositoryManager;
|
||||
import com.google.gerrit.testing.NoteDbChecker;
|
||||
|
@ -355,6 +356,7 @@ public class GerritServer implements AutoCloseable {
|
|||
},
|
||||
site);
|
||||
daemon.setEmailModuleForTesting(new FakeEmailSender.Module());
|
||||
daemon.setAuditEventModuleForTesting(new FakeGroupAuditService.Module());
|
||||
daemon.setAdditionalSysModuleForTesting(testSysModule);
|
||||
daemon.setEnableSshd(desc.useSsh());
|
||||
daemon.setSlave(isSlave(baseConfig));
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (C) 2018 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.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.Singleton;
|
||||
import java.util.Collection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class AuditServiceImpl implements AuditService {
|
||||
private static final Logger log = LoggerFactory.getLogger(AuditServiceImpl.class);
|
||||
|
||||
private final DynamicSet<AuditListener> auditListeners;
|
||||
private final DynamicSet<GroupMemberAuditListener> groupMemberAuditListeners;
|
||||
|
||||
@Inject
|
||||
public AuditServiceImpl(
|
||||
DynamicSet<AuditListener> auditListeners,
|
||||
DynamicSet<GroupMemberAuditListener> groupMemberAuditListeners) {
|
||||
this.auditListeners = auditListeners;
|
||||
this.groupMemberAuditListeners = groupMemberAuditListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(AuditEvent action) {
|
||||
for (AuditListener auditListener : auditListeners) {
|
||||
auditListener.onAuditableAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ import java.lang.annotation.Target;
|
|||
* Audit annotation for JSON/RPC interfaces.
|
||||
*
|
||||
* <p>Flag with @Audit all the JSON/RPC methods to be traced in audit-trail and submitted to the
|
||||
* AuditService.
|
||||
* GroupAuditService.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
package com.google.gerrit.httpd;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.common.data.Capable;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
|
@ -23,6 +25,7 @@ import com.google.gerrit.reviewdb.client.Project;
|
|||
import com.google.gerrit.server.AccessPath;
|
||||
import com.google.gerrit.server.AnonymousUser;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.audit.HttpAuditEvent;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gerrit.server.git.DefaultAdvertiseRefsHook;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
|
@ -30,12 +33,14 @@ import com.google.gerrit.server.git.TransferConfig;
|
|||
import com.google.gerrit.server.git.UploadPackInitializer;
|
||||
import com.google.gerrit.server.git.receive.AsyncReceiveCommits;
|
||||
import com.google.gerrit.server.git.validators.UploadValidators;
|
||||
import com.google.gerrit.server.group.GroupAuditService;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gerrit.server.project.ProjectState;
|
||||
import com.google.gerrit.server.util.time.TimeUtil;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
@ -141,6 +146,30 @@ public class GitOverHttpServlet extends GitServlet {
|
|||
addReceivePackFilter(receiveFilter);
|
||||
}
|
||||
|
||||
private static String extractWhat(HttpServletRequest request) {
|
||||
StringBuilder commandName = new StringBuilder(request.getRequestURL());
|
||||
if (request.getQueryString() != null) {
|
||||
commandName.append("?").append(request.getQueryString());
|
||||
}
|
||||
return commandName.toString();
|
||||
}
|
||||
|
||||
private static ListMultimap<String, String> extractParameters(HttpServletRequest request) {
|
||||
|
||||
ListMultimap<String, String> multiMap = ArrayListMultimap.create();
|
||||
if (request.getQueryString() != null) {
|
||||
request
|
||||
.getParameterMap()
|
||||
.forEach(
|
||||
(k, v) -> {
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
multiMap.put(k, v[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
return multiMap;
|
||||
}
|
||||
|
||||
static class Resolver implements RepositoryResolver<HttpServletRequest> {
|
||||
private final GitRepositoryManager manager;
|
||||
private final PermissionBackend permissionBackend;
|
||||
|
@ -240,12 +269,19 @@ public class GitOverHttpServlet extends GitServlet {
|
|||
static class UploadFilter implements Filter {
|
||||
private final UploadValidators.Factory uploadValidatorsFactory;
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final Provider<CurrentUser> userProvider;
|
||||
private final GroupAuditService groupAuditService;
|
||||
|
||||
@Inject
|
||||
UploadFilter(
|
||||
UploadValidators.Factory uploadValidatorsFactory, PermissionBackend permissionBackend) {
|
||||
UploadValidators.Factory uploadValidatorsFactory,
|
||||
PermissionBackend permissionBackend,
|
||||
Provider<CurrentUser> userProvider,
|
||||
GroupAuditService groupAuditService) {
|
||||
this.uploadValidatorsFactory = uploadValidatorsFactory;
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.userProvider = userProvider;
|
||||
this.groupAuditService = groupAuditService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -268,7 +304,22 @@ public class GitOverHttpServlet extends GitServlet {
|
|||
return;
|
||||
} catch (PermissionBackendException e) {
|
||||
throw new ServletException(e);
|
||||
} finally {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
groupAuditService.dispatch(
|
||||
new HttpAuditEvent(
|
||||
httpRequest.getSession().getId(),
|
||||
userProvider.get(),
|
||||
extractWhat(httpRequest),
|
||||
TimeUtil.nowMs(),
|
||||
extractParameters(httpRequest),
|
||||
httpRequest.getMethod(),
|
||||
httpRequest,
|
||||
httpResponse.getStatus(),
|
||||
httpResponse));
|
||||
}
|
||||
|
||||
// We use getRemoteHost() here instead of getRemoteAddr() because REMOTE_ADDR
|
||||
// may have been overridden by a proxy server -- we'll try to avoid this.
|
||||
UploadValidators uploadValidators =
|
||||
|
@ -326,15 +377,18 @@ public class GitOverHttpServlet extends GitServlet {
|
|||
private final Cache<AdvertisedObjectsCacheKey, Set<ObjectId>> cache;
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final Provider<CurrentUser> userProvider;
|
||||
private final GroupAuditService groupAuditService;
|
||||
|
||||
@Inject
|
||||
ReceiveFilter(
|
||||
@Named(ID_CACHE) Cache<AdvertisedObjectsCacheKey, Set<ObjectId>> cache,
|
||||
PermissionBackend permissionBackend,
|
||||
Provider<CurrentUser> userProvider) {
|
||||
Provider<CurrentUser> userProvider,
|
||||
GroupAuditService groupAuditService) {
|
||||
this.cache = cache;
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.userProvider = userProvider;
|
||||
this.groupAuditService = groupAuditService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -365,6 +419,20 @@ public class GitOverHttpServlet extends GitServlet {
|
|||
return;
|
||||
} catch (PermissionBackendException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
groupAuditService.dispatch(
|
||||
new HttpAuditEvent(
|
||||
httpRequest.getSession().getId(),
|
||||
userProvider.get(),
|
||||
extractWhat(httpRequest),
|
||||
TimeUtil.nowMs(),
|
||||
extractParameters(httpRequest),
|
||||
httpRequest.getMethod(),
|
||||
httpRequest,
|
||||
httpResponse.getStatus(),
|
||||
httpResponse));
|
||||
}
|
||||
|
||||
if (canUpload != Capable.OK) {
|
||||
|
|
|
@ -17,8 +17,8 @@ package com.google.gerrit.httpd;
|
|||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.common.Nullable;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.audit.AuditEvent;
|
||||
import com.google.gerrit.server.audit.AuditService;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||
|
|
|
@ -199,6 +199,7 @@ public class Daemon extends SiteProgram {
|
|||
private AbstractModule luceneModule;
|
||||
private Module emailModule;
|
||||
private Module testSysModule;
|
||||
private Module auditEventModule;
|
||||
|
||||
private Runnable serverStarted;
|
||||
private IndexType indexType;
|
||||
|
@ -319,6 +320,11 @@ public class Daemon extends SiteProgram {
|
|||
emailModule = module;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setAuditEventModuleForTesting(Module module) {
|
||||
auditEventModule = module;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setLuceneModule(LuceneIndexModule m) {
|
||||
luceneModule = m;
|
||||
|
@ -425,7 +431,6 @@ public class Daemon extends SiteProgram {
|
|||
modules.add(cfgInjector.getInstance(GerritGlobalModule.class));
|
||||
modules.add(new GerritApiModule());
|
||||
modules.add(new PluginApiModule());
|
||||
modules.add(new AuditModule());
|
||||
|
||||
modules.add(new SearchingChangeCacheImpl.Module(slave));
|
||||
modules.add(new InternalAccountDirectory.Module());
|
||||
|
@ -438,6 +443,11 @@ public class Daemon extends SiteProgram {
|
|||
} else {
|
||||
modules.add(new SmtpEmailSender.Module());
|
||||
}
|
||||
if (auditEventModule != null) {
|
||||
modules.add(auditEventModule);
|
||||
} else {
|
||||
modules.add(new AuditModule());
|
||||
}
|
||||
modules.add(new SignedTokenEmailTokenVerifier.Module());
|
||||
modules.add(new RestApiModule());
|
||||
modules.add(new GpgModule(config));
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.audit;
|
||||
package com.google.gerrit.server;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
|
@ -20,7 +20,6 @@ import com.google.auto.value.AutoValue;
|
|||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.util.time.TimeUtil;
|
||||
|
||||
public class AuditEvent {
|
|
@ -15,6 +15,7 @@
|
|||
package com.google.gerrit.server.audit;
|
||||
|
||||
import com.google.gerrit.extensions.annotations.ExtensionPoint;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
|
||||
@ExtensionPoint
|
||||
public interface AuditListener {
|
||||
|
|
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.audit;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import com.google.gerrit.server.audit.group.GroupAuditListener;
|
||||
import com.google.gerrit.server.audit.group.GroupMemberAuditEvent;
|
||||
import com.google.gerrit.server.audit.group.GroupSubgroupAuditEvent;
|
||||
|
@ -39,6 +40,7 @@ public class AuditService implements GroupAuditService {
|
|||
this.groupAuditListeners = groupAuditListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(AuditEvent action) {
|
||||
auditListeners.runEach(l -> l.onAuditableAction(action));
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package com.google.gerrit.server.audit;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
|
||||
public class HttpAuditEvent extends AuditEvent {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package com.google.gerrit.server.audit;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
|
||||
public class SshAuditEvent extends AuditEvent {
|
||||
|
|
|
@ -18,9 +18,11 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Account.Id;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public interface GroupAuditService {
|
||||
void dispatch(AuditEvent action);
|
||||
|
||||
void dispatchAddMembers(
|
||||
Account.Id actor,
|
||||
|
|
|
@ -275,8 +275,7 @@ class GroupRebuilder {
|
|||
* Distinct event types.
|
||||
*
|
||||
* <p>Events at the same time by the same user are batched together by type. The types should
|
||||
* correspond to the possible batch operations supported by {@link
|
||||
* com.google.gerrit.server.audit.AuditService}.
|
||||
* correspond to the possible batch operations supported by AuditService.
|
||||
*/
|
||||
enum Type {
|
||||
ADD_MEMBER,
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (C) 2018 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.testing;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import com.google.gerrit.server.audit.AuditListener;
|
||||
import com.google.gerrit.server.audit.group.GroupAuditListener;
|
||||
import com.google.gerrit.server.audit.group.GroupMemberAuditEvent;
|
||||
import com.google.gerrit.server.audit.group.GroupSubgroupAuditEvent;
|
||||
import com.google.gerrit.server.group.GroupAuditService;
|
||||
import com.google.gerrit.server.plugincontext.PluginSetContext;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class FakeGroupAuditService implements GroupAuditService {
|
||||
|
||||
private final PluginSetContext<GroupAuditListener> groupAuditListeners;
|
||||
private final PluginSetContext<AuditListener> auditListeners;
|
||||
|
||||
public static class Module extends AbstractModule {
|
||||
@Override
|
||||
public void configure() {
|
||||
DynamicSet.setOf(binder(), GroupAuditListener.class);
|
||||
DynamicSet.setOf(binder(), AuditListener.class);
|
||||
bind(GroupAuditService.class).to(FakeGroupAuditService.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
public FakeGroupAuditService(
|
||||
PluginSetContext<GroupAuditListener> groupAuditListeners,
|
||||
PluginSetContext<AuditListener> auditListeners) {
|
||||
this.groupAuditListeners = groupAuditListeners;
|
||||
this.auditListeners = auditListeners;
|
||||
}
|
||||
|
||||
public List<AuditEvent> auditEvents = new ArrayList<>();
|
||||
|
||||
public void clearEvents() {
|
||||
auditEvents.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(AuditEvent action) {
|
||||
auditEvents.add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchAddMembers(
|
||||
Account.Id actor,
|
||||
AccountGroup.UUID updatedGroup,
|
||||
ImmutableSet<Account.Id> addedMembers,
|
||||
Timestamp addedOn) {
|
||||
GroupMemberAuditEvent event =
|
||||
GroupMemberAuditEvent.create(actor, updatedGroup, addedMembers, addedOn);
|
||||
groupAuditListeners.runEach(l -> l.onAddMembers(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDeleteMembers(
|
||||
Account.Id actor,
|
||||
AccountGroup.UUID updatedGroup,
|
||||
ImmutableSet<Account.Id> deletedMembers,
|
||||
Timestamp deletedOn) {
|
||||
GroupMemberAuditEvent event =
|
||||
GroupMemberAuditEvent.create(actor, updatedGroup, deletedMembers, deletedOn);
|
||||
groupAuditListeners.runEach(l -> l.onDeleteMembers(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchAddSubgroups(
|
||||
Account.Id actor,
|
||||
AccountGroup.UUID updatedGroup,
|
||||
ImmutableSet<AccountGroup.UUID> addedSubgroups,
|
||||
Timestamp addedOn) {
|
||||
GroupSubgroupAuditEvent event =
|
||||
GroupSubgroupAuditEvent.create(actor, updatedGroup, addedSubgroups, addedOn);
|
||||
groupAuditListeners.runEach(l -> l.onAddSubgroups(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDeleteSubgroups(
|
||||
Account.Id actor,
|
||||
AccountGroup.UUID updatedGroup,
|
||||
ImmutableSet<AccountGroup.UUID> deletedSubgroups,
|
||||
Timestamp deletedOn) {
|
||||
GroupSubgroupAuditEvent event =
|
||||
GroupSubgroupAuditEvent.create(actor, updatedGroup, deletedSubgroups, deletedOn);
|
||||
groupAuditListeners.runEach(l -> l.onDeleteSubgroups(event));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (C) 2018 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.acceptance.git;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.gerrit.server.AuditEvent;
|
||||
import java.util.Collections;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GitOverHttpServletIT extends AbstractPushForReview {
|
||||
|
||||
@Before
|
||||
public void beforeEach() throws Exception {
|
||||
CredentialsProvider.setDefault(
|
||||
new UsernamePasswordCredentialsProvider(admin.username, admin.httpPassword));
|
||||
selectProtocol(AbstractPushForReview.Protocol.HTTP);
|
||||
auditService.clearEvents();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receivePackAuditEventLog() throws Exception {
|
||||
testRepo
|
||||
.git()
|
||||
.push()
|
||||
.setRemote("origin")
|
||||
.setRefSpecs(new RefSpec("HEAD:refs/for/master"))
|
||||
.call();
|
||||
|
||||
// Git smart protocol makes two requests:
|
||||
// https://github.com/git/git/blob/master/Documentation/technical/http-protocol.txt
|
||||
assertThat(auditService.auditEvents.size()).isEqualTo(2);
|
||||
|
||||
AuditEvent e = auditService.auditEvents.get(1);
|
||||
assertThat(e.who.getAccountId()).isEqualTo(admin.id);
|
||||
assertThat(e.what).endsWith("/git-receive-pack");
|
||||
assertThat(e.params).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadPackAuditEventLog() throws Exception {
|
||||
testRepo.git().fetch().call();
|
||||
|
||||
assertThat(auditService.auditEvents.size()).isEqualTo(1);
|
||||
|
||||
AuditEvent e = auditService.auditEvents.get(0);
|
||||
assertThat(e.who.toString()).isEqualTo("ANONYMOUS");
|
||||
assertThat(e.params.get("service"))
|
||||
.containsExactlyElementsIn(Collections.singletonList("git-upload-pack"));
|
||||
assertThat(e.what).endsWith("service=git-upload-pack");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue