Support creation of groups via REST
A new group can now be created by POST on '/groups/'. The WebUI was adapted to create groups via REST. Change-Id: Ib11150cc4aa7944c5e79fff194fe97797cb77de2 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
@@ -20,12 +20,13 @@ import com.google.gerrit.client.Dispatcher;
|
|||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.NotFoundScreen;
|
import com.google.gerrit.client.NotFoundScreen;
|
||||||
import com.google.gerrit.client.account.AccountCapabilities;
|
import com.google.gerrit.client.account.AccountCapabilities;
|
||||||
|
import com.google.gerrit.client.groups.GroupApi;
|
||||||
|
import com.google.gerrit.client.groups.GroupInfo;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
import com.google.gerrit.client.ui.OnEditEnabler;
|
import com.google.gerrit.client.ui.OnEditEnabler;
|
||||||
import com.google.gerrit.client.ui.Screen;
|
import com.google.gerrit.client.ui.Screen;
|
||||||
import com.google.gerrit.client.ui.SmallHeading;
|
import com.google.gerrit.client.ui.SmallHeading;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
import com.google.gwt.event.dom.client.ClickHandler;
|
||||||
import com.google.gwt.event.dom.client.KeyCodes;
|
import com.google.gwt.event.dom.client.KeyCodes;
|
||||||
@@ -106,9 +107,10 @@ public class CreateGroupScreen extends Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addNew.setEnabled(false);
|
addNew.setEnabled(false);
|
||||||
Util.GROUP_SVC.createGroup(newName, new GerritCallback<AccountGroup.Id>() {
|
GroupApi.createGroup(newName, new GerritCallback<GroupInfo>() {
|
||||||
public void onSuccess(final AccountGroup.Id result) {
|
public void onSuccess(final GroupInfo result) {
|
||||||
History.newItem(Dispatcher.toGroup(result, AccountGroupScreen.MEMBERS));
|
History.newItem(Dispatcher.toGroup(result.getGroupId(),
|
||||||
|
AccountGroupScreen.MEMBERS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class GroupApi {
|
public class GroupApi {
|
||||||
|
|
||||||
|
/** Create a new group */
|
||||||
|
public static void createGroup(String groupName, AsyncCallback<GroupInfo> cb) {
|
||||||
|
GroupInput in = GroupInput.create();
|
||||||
|
in.name(groupName);
|
||||||
|
new RestApi("/groups/").data(in).post(cb);
|
||||||
|
}
|
||||||
|
|
||||||
/** Add member to a group. */
|
/** Add member to a group. */
|
||||||
public static void addMember(AccountGroup.UUID groupUUID,
|
public static void addMember(AccountGroup.UUID groupUUID,
|
||||||
String member, AsyncCallback<MemberInfo> cb) {
|
String member, AsyncCallback<MemberInfo> cb) {
|
||||||
@@ -101,4 +108,15 @@ public class GroupApi {
|
|||||||
protected MemberInput() {
|
protected MemberInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class GroupInput extends JavaScriptObject {
|
||||||
|
final native void name(String n) /*-{ if(n)this.name=n; }-*/;
|
||||||
|
|
||||||
|
static GroupInput create() {
|
||||||
|
return (GroupInput) createObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected GroupInput() {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,6 @@ class CreateGroup extends Handler<AccountGroup.Id> {
|
|||||||
final PerformCreateGroup performCreateGroup = performCreateGroupFactory.create();
|
final PerformCreateGroup performCreateGroup = performCreateGroupFactory.create();
|
||||||
final Account.Id me = user.getAccountId();
|
final Account.Id me = user.getAccountId();
|
||||||
return performCreateGroup.createGroup(groupName, null, visibleToAll, null,
|
return performCreateGroup.createGroup(groupName, null, visibleToAll, null,
|
||||||
Collections.singleton(me), null);
|
Collections.singleton(me), null).getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public class PerformCreateGroup {
|
|||||||
* name already exists
|
* name already exists
|
||||||
* @throws PermissionDeniedException user cannot create a group.
|
* @throws PermissionDeniedException user cannot create a group.
|
||||||
*/
|
*/
|
||||||
public AccountGroup.Id createGroup(final String groupName,
|
public AccountGroup createGroup(final String groupName,
|
||||||
final String groupDescription, final boolean visibleToAll,
|
final String groupDescription, final boolean visibleToAll,
|
||||||
final AccountGroup.Id ownerGroupId,
|
final AccountGroup.Id ownerGroupId,
|
||||||
final Collection<? extends Account.Id> initialMembers,
|
final Collection<? extends Account.Id> initialMembers,
|
||||||
@@ -133,7 +133,7 @@ public class PerformCreateGroup {
|
|||||||
|
|
||||||
groupCache.onCreateGroup(nameKey);
|
groupCache.onCreateGroup(nameKey);
|
||||||
|
|
||||||
return groupId;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMembers(final AccountGroup.Id groupId,
|
private void addMembers(final AccountGroup.Id groupId,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import com.google.gerrit.server.account.GroupIncludeCacheImpl;
|
|||||||
import com.google.gerrit.server.account.GroupInfoCacheFactory;
|
import com.google.gerrit.server.account.GroupInfoCacheFactory;
|
||||||
import com.google.gerrit.server.account.IncludingGroupMembership;
|
import com.google.gerrit.server.account.IncludingGroupMembership;
|
||||||
import com.google.gerrit.server.account.InternalGroupBackend;
|
import com.google.gerrit.server.account.InternalGroupBackend;
|
||||||
|
import com.google.gerrit.server.account.PerformCreateGroup;
|
||||||
import com.google.gerrit.server.account.Realm;
|
import com.google.gerrit.server.account.Realm;
|
||||||
import com.google.gerrit.server.account.UniversalGroupBackend;
|
import com.google.gerrit.server.account.UniversalGroupBackend;
|
||||||
import com.google.gerrit.server.auth.AuthBackend;
|
import com.google.gerrit.server.auth.AuthBackend;
|
||||||
@@ -159,6 +160,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
factory(ChangeQueryBuilder.Factory.class);
|
factory(ChangeQueryBuilder.Factory.class);
|
||||||
factory(GroupInfoCacheFactory.Factory.class);
|
factory(GroupInfoCacheFactory.Factory.class);
|
||||||
factory(GroupDetailFactory.Factory.class);
|
factory(GroupDetailFactory.Factory.class);
|
||||||
|
factory(PerformCreateGroup.Factory.class);
|
||||||
factory(InternalUser.Factory.class);
|
factory(InternalUser.Factory.class);
|
||||||
factory(ProjectNode.Factory.class);
|
factory(ProjectNode.Factory.class);
|
||||||
factory(ProjectState.Factory.class);
|
factory(ProjectState.Factory.class);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import com.google.gerrit.server.ApprovalsUtil;
|
|||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.RequestCleanup;
|
import com.google.gerrit.server.RequestCleanup;
|
||||||
import com.google.gerrit.server.account.GroupMembers;
|
import com.google.gerrit.server.account.GroupMembers;
|
||||||
import com.google.gerrit.server.account.PerformCreateGroup;
|
|
||||||
import com.google.gerrit.server.account.PerformRenameGroup;
|
import com.google.gerrit.server.account.PerformRenameGroup;
|
||||||
import com.google.gerrit.server.changedetail.DeleteDraftPatchSet;
|
import com.google.gerrit.server.changedetail.DeleteDraftPatchSet;
|
||||||
import com.google.gerrit.server.changedetail.PublishDraft;
|
import com.google.gerrit.server.changedetail.PublishDraft;
|
||||||
@@ -79,7 +78,6 @@ public class GerritRequestModule extends FactoryModule {
|
|||||||
factory(RemoveReviewer.Factory.class);
|
factory(RemoveReviewer.Factory.class);
|
||||||
factory(MergedSender.Factory.class);
|
factory(MergedSender.Factory.class);
|
||||||
factory(MergeFailSender.Factory.class);
|
factory(MergeFailSender.Factory.class);
|
||||||
factory(PerformCreateGroup.Factory.class);
|
|
||||||
factory(PerformRenameGroup.Factory.class);
|
factory(PerformRenameGroup.Factory.class);
|
||||||
factory(GroupMembers.Factory.class);
|
factory(GroupMembers.Factory.class);
|
||||||
factory(CreateProject.Factory.class);
|
factory(CreateProject.Factory.class);
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (C) 2013 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.google.gerrit.server.group;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.gerrit.common.data.GroupDescriptions;
|
||||||
|
import com.google.gerrit.common.errors.NameAlreadyUsedException;
|
||||||
|
import com.google.gerrit.common.errors.PermissionDeniedException;
|
||||||
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
|
import com.google.gerrit.extensions.restapi.TopLevelResource;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
|
import com.google.gerrit.server.account.PerformCreateGroup;
|
||||||
|
import com.google.gerrit.server.group.CreateGroup.Input;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class CreateGroup implements RestModifyView<TopLevelResource, Input> {
|
||||||
|
static class Input {
|
||||||
|
@DefaultInput
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final PerformCreateGroup.Factory performCreateGroupFactory;
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
private final Provider<CurrentUser> self;
|
||||||
|
final boolean visibleToAll;
|
||||||
|
|
||||||
|
CreateGroup(final PerformCreateGroup.Factory performCreateGroupFactory,
|
||||||
|
final GroupCache groupCache, final Provider<CurrentUser> self,
|
||||||
|
final Config cfg) {
|
||||||
|
this.performCreateGroupFactory = performCreateGroupFactory;
|
||||||
|
this.groupCache = groupCache;
|
||||||
|
this.self = self;
|
||||||
|
this.visibleToAll = cfg.getBoolean("groups", "newGroupsVisibleToAll", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Input> inputType() {
|
||||||
|
return Input.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupInfo apply(TopLevelResource resource, Input input)
|
||||||
|
throws AuthException, BadRequestException, OrmException,
|
||||||
|
NameAlreadyUsedException {
|
||||||
|
final IdentifiedUser me = ((IdentifiedUser) self.get());
|
||||||
|
if (!me.getCapabilities().canCreateGroup()) {
|
||||||
|
throw new AuthException("Cannot create group");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null || Strings.isNullOrEmpty(input.name)) {
|
||||||
|
throw new BadRequestException("group name missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountGroup group = groupCache.get(new AccountGroup.NameKey(input.name));
|
||||||
|
if (group != null) {
|
||||||
|
return new GroupInfo(GroupDescriptions.forAccountGroup(group));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
group = performCreateGroupFactory.create().createGroup(input.name, null,
|
||||||
|
visibleToAll, null, Collections.singleton(me.getAccountId()), null);
|
||||||
|
} catch (PermissionDeniedException e) {
|
||||||
|
throw new AuthException(e.getMessage());
|
||||||
|
}
|
||||||
|
return new GroupInfo(GroupDescriptions.forAccountGroup(group));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.google.gerrit.common.data.GroupReference;
|
import com.google.gerrit.common.data.GroupReference;
|
||||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
|
import com.google.gerrit.extensions.restapi.AcceptsPost;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
import com.google.gerrit.extensions.restapi.RestCollection;
|
import com.google.gerrit.extensions.restapi.RestCollection;
|
||||||
@@ -28,32 +29,45 @@ import com.google.gerrit.server.AnonymousUser;
|
|||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.account.GroupBackend;
|
import com.google.gerrit.server.account.GroupBackend;
|
||||||
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
import com.google.gerrit.server.account.GroupControl;
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
|
import com.google.gerrit.server.account.PerformCreateGroup;
|
||||||
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.util.Url;
|
import com.google.gerrit.server.util.Url;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
|
||||||
public class GroupsCollection implements
|
public class GroupsCollection implements
|
||||||
RestCollection<TopLevelResource, GroupResource> {
|
RestCollection<TopLevelResource, GroupResource>,
|
||||||
|
AcceptsPost<TopLevelResource> {
|
||||||
private final DynamicMap<RestView<GroupResource>> views;
|
private final DynamicMap<RestView<GroupResource>> views;
|
||||||
private final Provider<ListGroups> list;
|
private final Provider<ListGroups> list;
|
||||||
private final GroupControl.Factory groupControlFactory;
|
private final GroupControl.Factory groupControlFactory;
|
||||||
private final GroupBackend groupBackend;
|
private final GroupBackend groupBackend;
|
||||||
private final Provider<CurrentUser> self;
|
private final Provider<CurrentUser> self;
|
||||||
|
private final PerformCreateGroup.Factory performCreateGroupFactory;
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
private final Config cfg;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupsCollection(final DynamicMap<RestView<GroupResource>> views,
|
GroupsCollection(final DynamicMap<RestView<GroupResource>> views,
|
||||||
final Provider<ListGroups> list,
|
final Provider<ListGroups> list,
|
||||||
final GroupControl.Factory groupControlFactory,
|
final GroupControl.Factory groupControlFactory,
|
||||||
final GroupBackend groupBackend,
|
final GroupBackend groupBackend,
|
||||||
final Provider<CurrentUser> self) {
|
final Provider<CurrentUser> self,
|
||||||
|
final PerformCreateGroup.Factory performCreateGroupFactory,
|
||||||
|
final GroupCache groupCache, @GerritServerConfig final Config cfg) {
|
||||||
this.views = views;
|
this.views = views;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
this.groupControlFactory = groupControlFactory;
|
this.groupControlFactory = groupControlFactory;
|
||||||
this.groupBackend = groupBackend;
|
this.groupBackend = groupBackend;
|
||||||
this.self = self;
|
this.self = self;
|
||||||
|
this.performCreateGroupFactory = performCreateGroupFactory;
|
||||||
|
this.groupCache = groupCache;
|
||||||
|
this.cfg = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,6 +134,12 @@ public class GroupsCollection implements
|
|||||||
throw new ResourceNotFoundException(urlId);
|
throw new ResourceNotFoundException(urlId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public CreateGroup post(TopLevelResource parent) {
|
||||||
|
return new CreateGroup(performCreateGroupFactory, groupCache, self, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DynamicMap<RestView<GroupResource>> views() {
|
public DynamicMap<RestView<GroupResource>> views() {
|
||||||
return views;
|
return views;
|
||||||
|
|||||||
Reference in New Issue
Block a user