diff options
author | Antonio Barone <syntonyze@gmail.com> | 2018-11-13 15:58:16 -0800 |
---|---|---|
committer | David Pursehouse <dpursehouse@collab.net> | 2018-11-14 00:43:58 +0000 |
commit | 98ecbb1cfe8e3b9074c375223110c6c4573d0add (patch) | |
tree | 69158054e5ce95fd3e5d1ab99a5df7b1f1ad526e | |
parent | b22b8a7b12688e942e1c2c966a3c55ee45bbafed (diff) | |
parent | d93736f81ba65edd33a5751ce3c7e8dafe2a9c23 (diff) |
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
16 files changed, 370 insertions, 9 deletions
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java index 496ee5b481..a4b5a945e7 100644 --- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java +++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java @@ -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; diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java index 9f9cbf937b..be8932e3a6 100644 --- a/java/com/google/gerrit/acceptance/GerritServer.java +++ b/java/com/google/gerrit/acceptance/GerritServer.java @@ -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)); diff --git a/java/com/google/gerrit/audit/AuditServiceImpl.java b/java/com/google/gerrit/audit/AuditServiceImpl.java new file mode 100644 index 0000000000..940742fc9d --- /dev/null +++ b/java/com/google/gerrit/audit/AuditServiceImpl.java @@ -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); + } + } + } +} diff --git a/java/com/google/gerrit/common/audit/Audit.java b/java/com/google/gerrit/common/audit/Audit.java index 25e4caf67f..a791e97429 100644 --- a/java/com/google/gerrit/common/audit/Audit.java +++ b/java/com/google/gerrit/common/audit/Audit.java @@ -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}) diff --git a/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/java/com/google/gerrit/httpd/GitOverHttpServlet.java index 77ce983240..08ff8a74f7 100644 --- a/java/com/google/gerrit/httpd/GitOverHttpServlet.java +++ b/java/com/google/gerrit/httpd/GitOverHttpServlet.java @@ -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) { diff --git a/java/com/google/gerrit/httpd/HttpLogoutServlet.java b/java/com/google/gerrit/httpd/HttpLogoutServlet.java index abfcc22df4..ab7bfdfee5 100644 --- a/java/com/google/gerrit/httpd/HttpLogoutServlet.java +++ b/java/com/google/gerrit/httpd/HttpLogoutServlet.java @@ -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; diff --git a/java/com/google/gerrit/pgm/Daemon.java b/java/com/google/gerrit/pgm/Daemon.java index 2249c762ad..a777a1cb29 100644 --- a/java/com/google/gerrit/pgm/Daemon.java +++ b/java/com/google/gerrit/pgm/Daemon.java @@ -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; @@ -320,6 +321,11 @@ public class Daemon extends SiteProgram { } @VisibleForTesting + public void setAuditEventModuleForTesting(Module module) { + auditEventModule = module; + } + + @VisibleForTesting public void setLuceneModule(LuceneIndexModule m) { luceneModule = m; inMemoryTest = true; @@ -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)); diff --git a/java/com/google/gerrit/server/audit/AuditEvent.java b/java/com/google/gerrit/server/AuditEvent.java index 46b28449b9..773a307aa6 100644 --- a/java/com/google/gerrit/server/audit/AuditEvent.java +++ b/java/com/google/gerrit/server/AuditEvent.java @@ -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 { diff --git a/java/com/google/gerrit/server/audit/AuditListener.java b/java/com/google/gerrit/server/audit/AuditListener.java index 3f8c298d03..f555bbd1ff 100644 --- a/java/com/google/gerrit/server/audit/AuditListener.java +++ b/java/com/google/gerrit/server/audit/AuditListener.java @@ -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 { diff --git a/java/com/google/gerrit/server/audit/AuditService.java b/java/com/google/gerrit/server/audit/AuditService.java index cbca65b9ff..425e22a7ec 100644 --- a/java/com/google/gerrit/server/audit/AuditService.java +++ b/java/com/google/gerrit/server/audit/AuditService.java @@ -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)); } diff --git a/java/com/google/gerrit/server/audit/HttpAuditEvent.java b/java/com/google/gerrit/server/audit/HttpAuditEvent.java index 11a6b63088..5ea248531b 100644 --- a/java/com/google/gerrit/server/audit/HttpAuditEvent.java +++ b/java/com/google/gerrit/server/audit/HttpAuditEvent.java @@ -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 { diff --git a/java/com/google/gerrit/server/audit/SshAuditEvent.java b/java/com/google/gerrit/server/audit/SshAuditEvent.java index 89f01acf51..fee959eda2 100644 --- a/java/com/google/gerrit/server/audit/SshAuditEvent.java +++ b/java/com/google/gerrit/server/audit/SshAuditEvent.java @@ -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 { diff --git a/java/com/google/gerrit/server/group/GroupAuditService.java b/java/com/google/gerrit/server/group/GroupAuditService.java index c543a6e409..4b851ea0b8 100644 --- a/java/com/google/gerrit/server/group/GroupAuditService.java +++ b/java/com/google/gerrit/server/group/GroupAuditService.java @@ -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, diff --git a/java/com/google/gerrit/server/schema/GroupRebuilder.java b/java/com/google/gerrit/server/schema/GroupRebuilder.java index 54cbb86ac4..0157025a87 100644 --- a/java/com/google/gerrit/server/schema/GroupRebuilder.java +++ b/java/com/google/gerrit/server/schema/GroupRebuilder.java @@ -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, diff --git a/java/com/google/gerrit/testing/FakeGroupAuditService.java b/java/com/google/gerrit/testing/FakeGroupAuditService.java new file mode 100644 index 0000000000..7c6674b4c6 --- /dev/null +++ b/java/com/google/gerrit/testing/FakeGroupAuditService.java @@ -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)); + } +} diff --git a/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java b/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java new file mode 100644 index 0000000000..42e046ad02 --- /dev/null +++ b/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java @@ -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"); + } +} |