Block off commands on a server for certain user groups.
This feature adds two new options to gerrit.config file: upload and receive with the allowGroup attribute, that restrict to some specific groups the ability to run upload/receive commands on the server. [sp: All bugs are mine, I refactored the code a bit from the original] Change-Id: Ibd31bd11234e429f8b0201bbb03099f737281f21 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -1341,6 +1341,27 @@ auto-detected and one thread per CPU is used, per client request.
|
||||
By default, 1.
|
||||
|
||||
|
||||
[[receive]]Section receive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets the group of users allowed to execute 'receive-pack' on the
|
||||
server, 'receive-pack' is what runs on the server during a user's
|
||||
push or repo upload command.
|
||||
|
||||
----
|
||||
[receive]
|
||||
allowGroup = GROUP_ALLOWED_TO_EXECUTE
|
||||
allowGroup = YET_ANOTHER_GROUP_ALLOWED_TO_EXECUTE
|
||||
----
|
||||
|
||||
[[receive.allowGroup]]receive.allowGroup::
|
||||
+
|
||||
Name of the groups of users that are allowed to execute
|
||||
'receive-pack' on the server. One or more groups can be set.
|
||||
+
|
||||
If no groups are added, any user will be allowed to execute
|
||||
'receive-pack' on the server.
|
||||
|
||||
|
||||
[[repository]]Section repository
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Repositories in this sense are the same as projects.
|
||||
@@ -1676,6 +1697,28 @@ reasonable timeout value.
|
||||
+
|
||||
Defaults to 0 seconds, wait indefinitely.
|
||||
|
||||
|
||||
[[upload]]Section upload
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets the group of users allowed to execute 'upload-pack' on the
|
||||
server, 'upload-pack' is what runs on the server during a user's
|
||||
fetch, clone or repo sync command.
|
||||
|
||||
----
|
||||
[upload]
|
||||
allowGroup = GROUP_ALLOWED_TO_EXECUTE
|
||||
allowGroup = YET_ANOTHER_GROUP_ALLOWED_TO_EXECUTE
|
||||
----
|
||||
|
||||
[[upload.allowGroup]]upload.allowGroup::
|
||||
+
|
||||
Name of the groups of users that are allowed to execute 'upload-pack'
|
||||
on the server. One or more groups can be set.
|
||||
+
|
||||
If no groups are added, any user will be allowed to execute
|
||||
'upload-pack' on the server.
|
||||
|
||||
|
||||
[[user]] Section user
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -187,10 +187,14 @@ public class ProjectServlet extends GitServlet {
|
||||
|
||||
@Override
|
||||
public UploadPack create(HttpServletRequest req, Repository repo)
|
||||
throws ServiceNotEnabledException {
|
||||
throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
||||
ProjectControl pc = getProjectControl(req);
|
||||
if (!pc.canRunUploadPack()) {
|
||||
throw new ServiceNotAuthorizedException();
|
||||
}
|
||||
|
||||
// The Resolver above already checked READ access for us.
|
||||
//
|
||||
ProjectControl pc = getProjectControl(req);
|
||||
UploadPack up = new UploadPack(repo);
|
||||
up.setPackConfig(packConfig);
|
||||
if (!pc.allRefsAreVisible()) {
|
||||
@@ -212,6 +216,10 @@ public class ProjectServlet extends GitServlet {
|
||||
public ReceivePack create(HttpServletRequest req, Repository db)
|
||||
throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
||||
final ProjectControl pc = getProjectControl(req);
|
||||
if (!pc.canRunReceivePack()) {
|
||||
throw new ServiceNotAuthorizedException();
|
||||
}
|
||||
|
||||
if (pc.getCurrentUser() instanceof IdentifiedUser) {
|
||||
final IdentifiedUser user = (IdentifiedUser) pc.getCurrentUser();
|
||||
final ReceiveCommits rc = factory.create(pc, db);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2010 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.common;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/** Utilities for manipulating Collections . */
|
||||
public class CollectionsUtil {
|
||||
/**
|
||||
* Checks if any of the elements in the first collection can be found in the
|
||||
* second collection.
|
||||
*
|
||||
* @param findAnyOfThese which elements to look for.
|
||||
* @param inThisCollection where to look for them.
|
||||
* @param <E> type of the elements in question.
|
||||
* @return {@code true} if any of the elements in {@code findAnyOfThese} can
|
||||
* be found in {@code inThisCollection}, {@code false} otherwise.
|
||||
*/
|
||||
public static <E> boolean isAnyIncludedIn(Collection<E> findAnyOfThese,
|
||||
Collection<E> inThisCollection) {
|
||||
for (E findThisItem : findAnyOfThese) {
|
||||
if (inThisCollection.contains(findThisItem)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private CollectionsUtil() {
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,7 @@ import com.google.gerrit.server.mail.FromAddressGeneratorProvider;
|
||||
import com.google.gerrit.server.mail.SmtpEmailSender;
|
||||
import com.google.gerrit.server.patch.PatchListCacheImpl;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.project.AccessControlModule;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.ProjectCacheImpl;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
@@ -136,10 +137,6 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
|
||||
bind(Project.NameKey.class).annotatedWith(WildProjectName.class)
|
||||
.toProvider(WildProjectNameProvider.class).in(SINGLETON);
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>(){}).annotatedWith(ProjectCreatorGroups.class)
|
||||
.toProvider(ProjectCreatorGroupsProvider.class).in(SINGLETON);
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>(){}).annotatedWith(ProjectOwnerGroups.class)
|
||||
.toProvider(ProjectOwnerGroupsProvider.class).in(SINGLETON);
|
||||
bind(ApprovalTypes.class).toProvider(ApprovalTypesProvider.class).in(
|
||||
SINGLETON);
|
||||
bind(EmailExpander.class).toProvider(EmailExpanderProvider.class).in(
|
||||
@@ -156,6 +153,7 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
install(GroupCacheImpl.module());
|
||||
install(PatchListCacheImpl.module());
|
||||
install(ProjectCacheImpl.module());
|
||||
install(new AccessControlModule());
|
||||
|
||||
factory(AccountInfoCacheFactory.Factory.class);
|
||||
factory(ProjectState.Factory.class);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2010 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.config;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
/**
|
||||
* Used to populate the groups of users that are allowed to run
|
||||
* receive-pack on the server.
|
||||
*
|
||||
* Gerrit.config example:
|
||||
*
|
||||
* <pre>
|
||||
* [receive]
|
||||
* allowGroup = RECEIVE_GROUP_ALLOWED
|
||||
* </pre>
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@BindingAnnotation
|
||||
public @interface GitReceivePackGroups {
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2010 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.config;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class GitReceivePackGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public GitReceivePackGroupsProvider(@GerritServerConfig Config config,
|
||||
AuthConfig authConfig, SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "receive", null, "allowGroup");
|
||||
|
||||
// If no group was set, default to "registered users"
|
||||
//
|
||||
if (groupIds.isEmpty()) {
|
||||
HashSet<AccountGroup.Id> all = new HashSet<AccountGroup.Id>();
|
||||
all.addAll(authConfig.getRegisteredGroups());
|
||||
all.removeAll(authConfig.getAnonymousGroups());
|
||||
groupIds = Collections.unmodifiableSet(all);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2010 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.config;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
/**
|
||||
* Used to populate the groups of users that are allowed to run
|
||||
* upload-pack on the server.
|
||||
*
|
||||
* Gerrit.config example:
|
||||
*
|
||||
* <pre>
|
||||
* [upload]
|
||||
* allowGroup = UPLOAD_GROUP_ALLOWED
|
||||
* </pre>
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@BindingAnnotation
|
||||
public @interface GitUploadPackGroups {
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2010 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.config;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class GitUploadPackGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
public GitUploadPackGroupsProvider(@GerritServerConfig Config config,
|
||||
AuthConfig authConfig, SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "upload", null, "allowGroup");
|
||||
|
||||
// If no group was set, default to "registered users" and "anonymous"
|
||||
//
|
||||
if (groupIds.isEmpty()) {
|
||||
HashSet<AccountGroup.Id> all = new HashSet<AccountGroup.Id>();
|
||||
all.addAll(authConfig.getRegisteredGroups());
|
||||
all.addAll(authConfig.getAnonymousGroups());
|
||||
groupIds = Collections.unmodifiableSet(all);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2010 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.config;
|
||||
|
||||
import static com.google.gerrit.server.config.ConfigUtil.groupsFor;
|
||||
import static java.util.Collections.unmodifiableSet;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class GroupSetProvider implements
|
||||
Provider<Set<AccountGroup.Id>> {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(GroupSetProvider.class);
|
||||
|
||||
protected Set<AccountGroup.Id> groupIds;
|
||||
|
||||
@Inject
|
||||
protected GroupSetProvider(@GerritServerConfig Config config,
|
||||
SchemaFactory<ReviewDb> db, String section, String subsection, String name) {
|
||||
String[] groupNames = config.getStringList(section, subsection, name);
|
||||
groupIds = unmodifiableSet(groupsFor(db, groupNames, log));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AccountGroup.Id> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
||||
@@ -14,19 +14,14 @@
|
||||
|
||||
package com.google.gerrit.server.config;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.SystemConfig;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provider of the group(s) which are allowed to create new projects. Currently
|
||||
@@ -39,27 +34,14 @@ import java.util.Set;
|
||||
* createGroup = Administrators
|
||||
* </pre>
|
||||
*/
|
||||
public class ProjectCreatorGroupsProvider implements
|
||||
Provider<Set<AccountGroup.Id>> {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(ProjectCreatorGroupsProvider.class);
|
||||
|
||||
private final Set<AccountGroup.Id> groupIds;
|
||||
|
||||
public class ProjectCreatorGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
ProjectCreatorGroupsProvider(@GerritServerConfig final Config config,
|
||||
SchemaFactory<ReviewDb> db, final SystemConfig systemConfig) {
|
||||
String[] names = config.getStringList("repository", "*", "createGroup");
|
||||
Set<AccountGroup.Id> createGroups = ConfigUtil.groupsFor(db, names, log);
|
||||
public ProjectCreatorGroupsProvider(@GerritServerConfig final Config config,
|
||||
final SystemConfig systemConfig, final SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "repository", "*", "createGroup");
|
||||
|
||||
if (createGroups.isEmpty()) {
|
||||
if (groupIds.isEmpty()) {
|
||||
groupIds = Collections.singleton(systemConfig.adminGroupId);
|
||||
} else {
|
||||
groupIds = createGroups;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<AccountGroup.Id> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,8 @@ import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -37,28 +34,15 @@ import java.util.Set;
|
||||
* ownerGroup = Administrators
|
||||
* </pre>
|
||||
*/
|
||||
public class ProjectOwnerGroupsProvider implements
|
||||
Provider<Set<AccountGroup.Id>> {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(ProjectOwnerGroupsProvider.class);
|
||||
|
||||
private final Set<AccountGroup.Id> groupIds;
|
||||
|
||||
public class ProjectOwnerGroupsProvider extends GroupSetProvider {
|
||||
@Inject
|
||||
ProjectOwnerGroupsProvider(@GerritServerConfig final Config config,
|
||||
SchemaFactory<ReviewDb> db,
|
||||
@ProjectCreatorGroups Set<AccountGroup.Id> creatorGroups) {
|
||||
String[] names = config.getStringList("repository", "*", "ownerGroup");
|
||||
Set<AccountGroup.Id> ownerGroups = ConfigUtil.groupsFor(db, names, log);
|
||||
public ProjectOwnerGroupsProvider(
|
||||
@ProjectCreatorGroups final Set<AccountGroup.Id> creatorGroups,
|
||||
@GerritServerConfig final Config config, final SchemaFactory<ReviewDb> db) {
|
||||
super(config, db, "repository", "*", "ownerGroup");
|
||||
|
||||
if (ownerGroups.isEmpty()) {
|
||||
if (groupIds.isEmpty()) {
|
||||
groupIds = creatorGroups;
|
||||
} else {
|
||||
groupIds = ownerGroups;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<AccountGroup.Id> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2010 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.project;
|
||||
|
||||
import static com.google.inject.Scopes.SINGLETON;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.server.config.FactoryModule;
|
||||
import com.google.gerrit.server.config.GitReceivePackGroups;
|
||||
import com.google.gerrit.server.config.GitReceivePackGroupsProvider;
|
||||
import com.google.gerrit.server.config.GitUploadPackGroups;
|
||||
import com.google.gerrit.server.config.GitUploadPackGroupsProvider;
|
||||
import com.google.gerrit.server.config.ProjectCreatorGroups;
|
||||
import com.google.gerrit.server.config.ProjectCreatorGroupsProvider;
|
||||
import com.google.gerrit.server.config.ProjectOwnerGroups;
|
||||
import com.google.gerrit.server.config.ProjectOwnerGroupsProvider;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class AccessControlModule extends FactoryModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
.annotatedWith(ProjectCreatorGroups.class) //
|
||||
.toProvider(ProjectCreatorGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
.annotatedWith(ProjectOwnerGroups.class) //
|
||||
.toProvider(ProjectOwnerGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
.annotatedWith(GitUploadPackGroups.class) //
|
||||
.toProvider(GitUploadPackGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
bind(new TypeLiteral<Set<AccountGroup.Id>>() {}) //
|
||||
.annotatedWith(GitReceivePackGroups.class) //
|
||||
.toProvider(GitReceivePackGroupsProvider.class).in(SINGLETON);
|
||||
|
||||
factory(ProjectControl.AssistedFactory.class);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import static com.google.gerrit.common.CollectionsUtil.*;
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ApprovalCategory;
|
||||
import com.google.gerrit.reviewdb.Branch;
|
||||
@@ -22,8 +23,11 @@ import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.RefRight;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.ReplicationUser;
|
||||
import com.google.gerrit.server.config.GitReceivePackGroups;
|
||||
import com.google.gerrit.server.config.GitUploadPackGroups;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -93,10 +97,22 @@ public class ProjectControl {
|
||||
}
|
||||
}
|
||||
|
||||
interface AssistedFactory {
|
||||
ProjectControl create(CurrentUser who, ProjectState ps);
|
||||
}
|
||||
|
||||
private final Set<AccountGroup.Id> uploadGroups;
|
||||
private final Set<AccountGroup.Id> receiveGroups;
|
||||
|
||||
private final CurrentUser user;
|
||||
private final ProjectState state;
|
||||
|
||||
ProjectControl(final CurrentUser who, final ProjectState ps) {
|
||||
@Inject
|
||||
ProjectControl(@GitUploadPackGroups Set<AccountGroup.Id> uploadGroups,
|
||||
@GitReceivePackGroups Set<AccountGroup.Id> receiveGroups,
|
||||
@Assisted CurrentUser who, @Assisted ProjectState ps) {
|
||||
this.uploadGroups = uploadGroups;
|
||||
this.receiveGroups = receiveGroups;
|
||||
user = who;
|
||||
state = ps;
|
||||
}
|
||||
@@ -230,4 +246,12 @@ public class ProjectControl {
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
public boolean canRunUploadPack() {
|
||||
return isAnyIncludedIn(uploadGroups, user.getEffectiveGroups());
|
||||
}
|
||||
|
||||
public boolean canRunReceivePack() {
|
||||
return isAnyIncludedIn(receiveGroups, user.getEffectiveGroups());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public class ProjectState {
|
||||
private final AnonymousUser anonymousUser;
|
||||
private final Project.NameKey wildProject;
|
||||
private final ProjectCache projectCache;
|
||||
private final ProjectControl.AssistedFactory projectControlFactory;
|
||||
|
||||
private final Project project;
|
||||
private final Collection<RefRight> localRights;
|
||||
@@ -51,11 +52,13 @@ public class ProjectState {
|
||||
protected ProjectState(final AnonymousUser anonymousUser,
|
||||
final ProjectCache projectCache,
|
||||
@WildProjectName final Project.NameKey wildProject,
|
||||
final ProjectControl.AssistedFactory projectControlFactory,
|
||||
@Assisted final Project project,
|
||||
@Assisted final Collection<RefRight> rights) {
|
||||
this.anonymousUser = anonymousUser;
|
||||
this.projectCache = projectCache;
|
||||
this.wildProject = wildProject;
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
|
||||
this.project = project;
|
||||
this.localRights = rights;
|
||||
@@ -160,7 +163,7 @@ public class ProjectState {
|
||||
}
|
||||
|
||||
public ProjectControl controlFor(final CurrentUser user) {
|
||||
return new ProjectControl(user, this);
|
||||
return projectControlFactory.create(user, this);
|
||||
}
|
||||
|
||||
private static Collection<RefRight> filter(Collection<RefRight> all,
|
||||
|
||||
@@ -217,15 +217,18 @@ public class RefControlTest extends TestCase {
|
||||
}
|
||||
|
||||
private ProjectControl user(AccountGroup.Id... memberOf) {
|
||||
return new ProjectControl(new MockUser(memberOf), newProjectState());
|
||||
return new ProjectControl(Collections.<AccountGroup.Id> emptySet(),
|
||||
Collections.<AccountGroup.Id> emptySet(), new MockUser(memberOf),
|
||||
newProjectState());
|
||||
}
|
||||
|
||||
private ProjectState newProjectState() {
|
||||
ProjectCache projectCache = null;
|
||||
Project.NameKey wildProject = null;
|
||||
ProjectControl.AssistedFactory projectControlFactory = null;
|
||||
ProjectState ps =
|
||||
new ProjectState(anonymousUser, projectCache, wildProject, new Project(
|
||||
projectNameKey), local);
|
||||
new ProjectState(anonymousUser, projectCache, wildProject,
|
||||
projectControlFactory, new Project(projectNameKey), local);
|
||||
ps.setInheritedRights(inherited);
|
||||
return ps;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.sshd.commands;
|
||||
|
||||
import com.google.gerrit.common.CollectionsUtil;
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.ApprovalCategory;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
@@ -38,7 +39,6 @@ import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -126,26 +126,6 @@ final class CreateProject extends BaseCommand {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of the elements in the first collection can be found in the
|
||||
* second collection.
|
||||
*
|
||||
* @param findAnyOfThese which elements to look for.
|
||||
* @param inThisCollection where to look for them.
|
||||
* @param <E> type of the elements in question.
|
||||
* @return {@code true} if any of the elements in {@code findAnyOfThese} can
|
||||
* be found in {@code inThisCollection}, {@code false} otherwise.
|
||||
*/
|
||||
private static <E> boolean isAnyIncludedIn(Collection<E> findAnyOfThese,
|
||||
Collection<E> inThisCollection) {
|
||||
for (E findThisItem : findAnyOfThese) {
|
||||
if (inThisCollection.contains(findThisItem)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createProject() throws OrmException {
|
||||
final Project.NameKey newProjectNameKey = new Project.NameKey(projectName);
|
||||
|
||||
@@ -179,7 +159,7 @@ final class CreateProject extends BaseCommand {
|
||||
projectName.substring(0, projectName.length() - ".git".length());
|
||||
}
|
||||
|
||||
if (!isAnyIncludedIn(currentUser.getEffectiveGroups(), projectCreatorGroups)) {
|
||||
if (!CollectionsUtil.isAnyIncludedIn(currentUser.getEffectiveGroups(), projectCreatorGroups)) {
|
||||
throw new Failure(1, "fatal: Not permitted to create " + projectName);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ final class Receive extends AbstractGitCommand {
|
||||
|
||||
@Override
|
||||
protected void runImpl() throws IOException, Failure {
|
||||
if (!projectControl.canRunReceivePack()) {
|
||||
throw new Failure(1, "fatal: receive-pack not permitted on this server");
|
||||
}
|
||||
|
||||
final ReceiveCommits receive = factory.create(projectControl, repo);
|
||||
|
||||
ReceiveCommits.Capable r = receive.canUpload();
|
||||
|
||||
@@ -36,6 +36,10 @@ final class Upload extends AbstractGitCommand {
|
||||
|
||||
@Override
|
||||
protected void runImpl() throws IOException, Failure {
|
||||
if (!projectControl.canRunUploadPack()) {
|
||||
throw new Failure(1, "fatal: upload-pack not permitted on this server");
|
||||
}
|
||||
|
||||
final UploadPack up = new UploadPack(repo);
|
||||
if (!projectControl.allRefsAreVisible()) {
|
||||
up.setRefFilter(new VisibleRefFilter(repo, projectControl, db.get()));
|
||||
|
||||
Reference in New Issue
Block a user