Enable create-project for non-Administrators
Allow other than 'Administrators' to use the create-project command. Added configuration parameters in gerrit.config to denote which group(s) are allowed to create projects, and which group(s) should be new projects' owner(s) by default. repository.*.createGroup specifies which group(s) are allowed to create projects. Default is 'Administrators'. repository.*.ownerGroup specifies which group(s) become the owner(s) of new projects. Default is whatever is specified by repository.*.createGroup, or 'Administrators' if no such configuration exists. Can be overridden by create-project's parameter --owner. Bug: issue 269 Change-Id: Ieeb694508dd4c12578877335a63944bc90d6b553
This commit is contained in:
parent
c025627422
commit
072b470570
@ -11,7 +11,7 @@ SYNOPSIS
|
||||
'ssh' -p <port> <host> 'gerrit create-project' \
|
||||
\--name <NAME> \
|
||||
[--branch <REF>] \
|
||||
[\--owner <GROUP>] \
|
||||
[\--owner <GROUP> ...] \
|
||||
[\--description <DESC>] \
|
||||
[\--submit-type <TYPE>] \
|
||||
[\--use-contributor-agreements] \
|
||||
@ -32,7 +32,11 @@ on the remote system to create the empty repository.
|
||||
|
||||
ACCESS
|
||||
------
|
||||
Caller must be a member of the privileged 'Administrators' group.
|
||||
Caller must be a member of any of the groups defined by
|
||||
repository.*.createGroup in gerrit.config.
|
||||
|
||||
If there is no such declaration, caller is required to be a member
|
||||
of the privileged 'Administrators' group.
|
||||
|
||||
SCRIPTING
|
||||
---------
|
||||
@ -49,13 +53,14 @@ OPTIONS
|
||||
Defaults to 'master'.
|
||||
|
||||
\--owner::
|
||||
Name of the group which will initially own this repository.
|
||||
The specified group must already be defined within Gerrit.
|
||||
Only one group can be specified on the command line.
|
||||
To specify additional owners, add the additional owners
|
||||
through the web interface after project creation.
|
||||
Name of the group(s) which will initially own this repository.
|
||||
The specified group(s) must already be defined within Gerrit.
|
||||
Several groups can be specified on the command line.
|
||||
+
|
||||
Defaults to `Administrators` if not specified.
|
||||
Defaults to what is specified by repository.*.ownerGroup
|
||||
in gerrit.config. If no such declaration(s) exist,
|
||||
repository.*.createGroup will be used. If they don't exist,
|
||||
`Administrators` will be used.
|
||||
|
||||
\--description::
|
||||
Initial description of the project. If not specified,
|
||||
|
@ -1235,6 +1235,45 @@ instance are generally worked on with the repo multi-repository tool.
|
||||
+
|
||||
By default, false, as not all instances will deploy repo.
|
||||
|
||||
[[repository]]Section repository
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Repositories in this sense are the same as projects.
|
||||
|
||||
In the following example configuration the `Administrators` and the
|
||||
`Registered Users` groups are set to be the ones to be allowed to
|
||||
create projects matching `*` (any project). `Registered Users` is
|
||||
set to be the default owner of new projects.
|
||||
|
||||
----
|
||||
[repository "*"]
|
||||
createGroup = Administrators
|
||||
createGroup = Registered Users
|
||||
ownerGroup = Registered Users
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Currently only the repository name `*` is supported.
|
||||
This is a wildcard designating all repositories.
|
||||
|
||||
[[repository.name.createGroup]]repository.<name>.createGroup::
|
||||
+
|
||||
A name of a group which exists in the database. Zero, one or many
|
||||
groups are allowed. Each on its own line. Groups which don't exist
|
||||
in the database are ignored.
|
||||
+
|
||||
If no groups are declared (or only non-existing ones), the default
|
||||
value `Administrators` is used.
|
||||
|
||||
[[repository.name.ownerGroup]]repository.<name>.ownerGroup::
|
||||
+
|
||||
A name of a group which exists in the database. Zero, one or many
|
||||
groups are allowed. Each on its own line. Groups which don't exist
|
||||
in the database are ignored.
|
||||
+
|
||||
If no groups are declared (or only non-existing ones), it defaults
|
||||
to whatever is declared by `repository.<name>.createGroup` (including
|
||||
any fallback to `Administrators`.)
|
||||
|
||||
[[sendemail]]Section sendemail
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -16,9 +16,18 @@ package com.google.gerrit.server.config;
|
||||
|
||||
import static org.eclipse.jgit.util.StringUtils.equalsIgnoreCase;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.AccountGroupName;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ConfigUtil {
|
||||
@ -199,6 +208,60 @@ public class ConfigUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve groups from group names, via the database. Group names not found in
|
||||
* the database will be skipped.
|
||||
*
|
||||
* @param dbfactory database to resolve from.
|
||||
* @param groupNames group names to resolve.
|
||||
* @param log log for any warnings and errors.
|
||||
* @param groupNotFoundWarning formatted message to output to the log for each
|
||||
* group name which is not found in the database. <code>{0}</code> will
|
||||
* be replaced with the group name.
|
||||
* @return the actual groups resolved from the database. If no groups are
|
||||
* found, returns an empty {@code Set}, never {@code null}.
|
||||
*/
|
||||
public static Set<AccountGroup.Id> groupsFor(
|
||||
SchemaFactory<ReviewDb> dbfactory, String[] groupNames, Logger log,
|
||||
String groupNotFoundWarning) {
|
||||
final Set<AccountGroup.Id> result = new HashSet<AccountGroup.Id>();
|
||||
try {
|
||||
final ReviewDb db = dbfactory.open();
|
||||
try {
|
||||
for (String name : groupNames) {
|
||||
AccountGroupName group =
|
||||
db.accountGroupNames().get(new AccountGroup.NameKey(name));
|
||||
if (group == null) {
|
||||
log.warn(MessageFormat.format(groupNotFoundWarning, name));
|
||||
} else {
|
||||
result.add(group.getId());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
log.error("Database error, cannot load groups", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve groups from group names, via the database. Group names not found in
|
||||
* the database will be skipped.
|
||||
*
|
||||
* @param dbfactory database to resolve from.
|
||||
* @param groupNames group names to resolve.
|
||||
* @param log log for any warnings and errors.
|
||||
* @return the actual groups resolved from the database. If no groups are
|
||||
* found, returns an empty {@code Set}, never {@code null}.
|
||||
*/
|
||||
public static Set<AccountGroup.Id> groupsFor(
|
||||
SchemaFactory<ReviewDb> dbfactory, String[] groupNames, Logger log) {
|
||||
return groupsFor(dbfactory, groupNames, log,
|
||||
"Group \"{0}\" not in database, skipping.");
|
||||
}
|
||||
|
||||
private static boolean match(final String a, final String... cases) {
|
||||
for (final String b : cases) {
|
||||
if (equalsIgnoreCase(a, b)) {
|
||||
|
@ -18,6 +18,7 @@ import static com.google.inject.Scopes.SINGLETON;
|
||||
|
||||
import com.google.gerrit.common.data.ApprovalTypes;
|
||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.AuthType;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.server.AnonymousUser;
|
||||
@ -64,9 +65,12 @@ import com.google.gerrit.server.util.IdGenerator;
|
||||
import com.google.gerrit.server.workflow.FunctionState;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/** Starts global state with standard dependencies. */
|
||||
public class GerritGlobalModule extends FactoryModule {
|
||||
private final AuthType loginType;
|
||||
@ -93,6 +97,10 @@ 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(
|
||||
|
@ -0,0 +1,30 @@
|
||||
// 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.inject.BindingAnnotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Marker on a {@code Set<AccountGroup.Id>} for the configured groups with
|
||||
* permission to create projects.
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@BindingAnnotation
|
||||
public @interface ProjectCreatorGroups {
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
// 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.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
|
||||
* only supports {@code createGroup} declarations in the {@code "*"} repository,
|
||||
* like so:
|
||||
*
|
||||
* <pre>
|
||||
* [repository "*"]
|
||||
* createGroup = Registered Users
|
||||
* 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;
|
||||
|
||||
@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);
|
||||
|
||||
if (createGroups.isEmpty()) {
|
||||
groupIds = Collections.singleton(systemConfig.adminGroupId);
|
||||
} else {
|
||||
groupIds = createGroups;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<AccountGroup.Id> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
// 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.inject.BindingAnnotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Marker on a {@code Set<AccountGroup.Id>} for the configured groups which
|
||||
* should become owners of a created project.
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@BindingAnnotation
|
||||
public @interface ProjectOwnerGroups {
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
// 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 com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provider of the group(s) which should become owners of a newly created
|
||||
* project. Currently only supports {@code ownerGroup} declarations in the
|
||||
* {@code "*"} repository, like so:
|
||||
*
|
||||
* <pre>
|
||||
* [repository "*"]
|
||||
* ownerGroup = Registered Users
|
||||
* 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;
|
||||
|
||||
@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);
|
||||
|
||||
if (ownerGroups.isEmpty()) {
|
||||
groupIds = creatorGroups;
|
||||
} else {
|
||||
groupIds = ownerGroups;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<AccountGroup.Id> get() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
@ -15,15 +15,14 @@
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.AccountGroupName;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.ReplicationUser;
|
||||
import com.google.gerrit.server.config.ConfigUtil;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Inject;
|
||||
@ -55,7 +54,6 @@ import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -322,7 +320,8 @@ public class PushReplication implements ReplicationQueue {
|
||||
String[] authGroupNames =
|
||||
cfg.getStringList("remote", rc.getName(), "authGroup");
|
||||
authEnabled = authGroupNames.length > 0;
|
||||
Set<AccountGroup.Id> authGroups = groupsFor(db, authGroupNames);
|
||||
Set<AccountGroup.Id> authGroups = ConfigUtil.groupsFor(db, authGroupNames, log,
|
||||
"Group \"{0}\" not in database, removing from authGroup");
|
||||
|
||||
final ReplicationUser remoteUser =
|
||||
replicationUserFactory.create(authGroups);
|
||||
@ -347,31 +346,6 @@ public class PushReplication implements ReplicationQueue {
|
||||
}).getInstance(PushOp.Factory.class);
|
||||
}
|
||||
|
||||
private static Set<AccountGroup.Id> groupsFor(
|
||||
SchemaFactory<ReviewDb> dbfactory, String[] groupNames) {
|
||||
final Set<AccountGroup.Id> result = new HashSet<AccountGroup.Id>();
|
||||
try {
|
||||
final ReviewDb db = dbfactory.open();
|
||||
try {
|
||||
for (String name : groupNames) {
|
||||
AccountGroupName group =
|
||||
db.accountGroupNames().get(new AccountGroup.NameKey(name));
|
||||
if (group == null) {
|
||||
log.warn("Group \"" + name + "\" not in database,"
|
||||
+ " removing from authGroup");
|
||||
} else {
|
||||
result.add(group.getId());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
log.error("Database error: " + e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int getInt(final RemoteConfig rc, final Config cfg,
|
||||
final String name, final int defValue) {
|
||||
return cfg.getInt("remote", rc.getName(), name, defValue);
|
||||
|
@ -20,10 +20,11 @@ import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.RefRight;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.Project.SubmitType;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.config.ProjectCreatorGroups;
|
||||
import com.google.gerrit.server.config.ProjectOwnerGroups;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.ReplicationQueue;
|
||||
import com.google.gerrit.sshd.AdminCommand;
|
||||
import com.google.gerrit.sshd.BaseCommand;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
@ -35,17 +36,20 @@ import org.eclipse.jgit.lib.Repository;
|
||||
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;
|
||||
import java.util.Set;
|
||||
|
||||
/** Create a new project. **/
|
||||
@AdminCommand
|
||||
final class AdminCreateProject extends BaseCommand {
|
||||
final class CreateProject extends BaseCommand {
|
||||
@Option(name = "--name", required = true, aliases = {"-n"}, metaVar = "NAME", usage = "name of project to be created")
|
||||
private String projectName;
|
||||
|
||||
@Option(name = "--owner", aliases = {"-o"}, usage = "owner of project\n"
|
||||
+ "(default: Administrators)")
|
||||
private AccountGroup.Id ownerId;
|
||||
@Option(name = "--owner", aliases = {"-o"}, usage = "owner(s) of project")
|
||||
private List<AccountGroup.Id> ownerIds;
|
||||
|
||||
@Option(name = "--description", aliases = {"-d"}, metaVar = "DESC", usage = "description of project")
|
||||
private String projectDescription = "";
|
||||
@ -71,7 +75,15 @@ final class AdminCreateProject extends BaseCommand {
|
||||
private GitRepositoryManager repoManager;
|
||||
|
||||
@Inject
|
||||
private AuthConfig authConfig;
|
||||
@ProjectCreatorGroups
|
||||
private Set<AccountGroup.Id> projectCreatorGroups;
|
||||
|
||||
@Inject
|
||||
@ProjectOwnerGroups
|
||||
private Set<AccountGroup.Id> projectOwnerGroups;
|
||||
|
||||
@Inject
|
||||
private IdentifiedUser currentUser;
|
||||
|
||||
@Inject
|
||||
private ReplicationQueue rq;
|
||||
@ -83,7 +95,6 @@ final class AdminCreateProject extends BaseCommand {
|
||||
public void run() throws Exception {
|
||||
PrintWriter p = toPrintWriter(out);
|
||||
|
||||
ownerId = authConfig.getAdministratorsGroup();
|
||||
parseCommandLine();
|
||||
|
||||
try {
|
||||
@ -111,16 +122,40 @@ final class AdminCreateProject 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);
|
||||
|
||||
final RefRight.Key prk =
|
||||
new RefRight.Key(newProjectNameKey, new RefRight.RefPattern(
|
||||
RefRight.ALL), ApprovalCategory.OWN, ownerId);
|
||||
final RefRight pr = new RefRight(prk);
|
||||
pr.setMaxValue((short) 1);
|
||||
pr.setMinValue((short) 1);
|
||||
db.refRights().insert(Collections.singleton(pr));
|
||||
List<RefRight> access = new ArrayList<RefRight>();
|
||||
for (AccountGroup.Id ownerId : ownerIds) {
|
||||
final RefRight.Key prk =
|
||||
new RefRight.Key(newProjectNameKey, new RefRight.RefPattern(
|
||||
RefRight.ALL), ApprovalCategory.OWN, ownerId);
|
||||
final RefRight pr = new RefRight(prk);
|
||||
pr.setMaxValue((short) 1);
|
||||
pr.setMinValue((short) 1);
|
||||
access.add(pr);
|
||||
}
|
||||
db.refRights().insert(access);
|
||||
|
||||
final Project newProject = new Project(newProjectNameKey);
|
||||
newProject.setDescription(projectDescription);
|
||||
@ -137,6 +172,17 @@ final class AdminCreateProject extends BaseCommand {
|
||||
projectName.substring(0, projectName.length() - ".git".length());
|
||||
}
|
||||
|
||||
if (!isAnyIncludedIn(currentUser.getEffectiveGroups(), projectCreatorGroups)) {
|
||||
throw new Failure(1, "fatal: Not permitted to create " + projectName);
|
||||
}
|
||||
|
||||
if (ownerIds != null && !ownerIds.isEmpty()) {
|
||||
ownerIds =
|
||||
new ArrayList<AccountGroup.Id>(new HashSet<AccountGroup.Id>(ownerIds));
|
||||
} else {
|
||||
ownerIds = new ArrayList<AccountGroup.Id>(projectOwnerGroups);
|
||||
}
|
||||
|
||||
while (branch.startsWith("/")) {
|
||||
branch = branch.substring(1);
|
||||
}
|
@ -27,7 +27,7 @@ public class MasterCommandModule extends CommandModule {
|
||||
|
||||
command(gerrit, "approve").to(ApproveCommand.class);
|
||||
command(gerrit, "create-account").to(AdminCreateAccount.class);
|
||||
command(gerrit, "create-project").to(AdminCreateProject.class);
|
||||
command(gerrit, "create-project").to(CreateProject.class);
|
||||
command(gerrit, "gsql").to(AdminQueryShell.class);
|
||||
command(gerrit, "receive-pack").to(Receive.class);
|
||||
command(gerrit, "replicate").to(AdminReplicate.class);
|
||||
|
Loading…
x
Reference in New Issue
Block a user