diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java index 494a362193..490056f8fa 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupInfoScreen.java @@ -140,9 +140,9 @@ public class AccountGroupInfoScreen extends AccountGroupScreen { public void onClick(final ClickEvent event) { final String newOwner = ownerTxt.getText().trim(); if (newOwner.length() > 0) { - Util.GROUP_SVC.changeGroupOwner(getGroupId(), newOwner, - new GerritCallback() { - public void onSuccess(final VoidResult result) { + GroupApi.setGroupOwner(getGroupUUID(), newOwner, + new GerritCallback() { + public void onSuccess(final com.google.gerrit.client.VoidResult result) { saveOwner.setEnabled(false); } }); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java index d6a5dfb081..a540d46046 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java @@ -48,6 +48,14 @@ public class GroupApi { } } + /** Set owner for a group */ + public static void setGroupOwner(AccountGroup.UUID group, + String owner, AsyncCallback cb) { + GroupInput in = GroupInput.create(); + in.owner(owner); + group(group).view("owner").put(in, cb); + } + /** Add member to a group. */ public static void addMember(AccountGroup.UUID group, String member, AsyncCallback cb) { @@ -143,6 +151,7 @@ public class GroupApi { private static class GroupInput extends JavaScriptObject { final native void description(String d) /*-{ if(d)this.description=d; }-*/; + final native void owner(String o) /*-{ if(o)this.owner=o; }-*/; static GroupInput create() { return (GroupInput) createObject(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GetOwner.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetOwner.java new file mode 100644 index 0000000000..15ac4f6ce0 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetOwner.java @@ -0,0 +1,46 @@ +// 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.gerrit.common.errors.NoSuchGroupException; +import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestReadView; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.server.account.GroupControl; +import com.google.inject.Inject; + +public class GetOwner implements RestReadView { + + private final GroupControl.Factory controlFactory; + + @Inject + GetOwner(GroupControl.Factory controlFactory) { + this.controlFactory = controlFactory; + } + + @Override + public Object apply(GroupResource resource) throws ResourceNotFoundException { + AccountGroup group = resource.toAccountGroup(); + if (group == null) { + throw new ResourceNotFoundException(); + } + try { + GroupControl c = controlFactory.validateFor(group.getOwnerGroupUUID()); + return new GroupInfo(c.getGroup()); + } catch (NoSuchGroupException e) { + throw new ResourceNotFoundException(); + } + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java index 4bc3177dbe..40a05c7453 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java @@ -43,6 +43,8 @@ public class Module extends RestApiModule { get(GROUP_KIND, "description").to(GetDescription.class); put(GROUP_KIND, "description").to(PutDescription.class); delete(GROUP_KIND, "description").to(PutDescription.class); + get(GROUP_KIND, "owner").to(GetOwner.class); + put(GROUP_KIND, "owner").to(PutOwner.class); child(GROUP_KIND, "members").to(MembersCollection.class); get(MEMBER_KIND).to(GetMember.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/PutOwner.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/PutOwner.java new file mode 100644 index 0000000000..ce6bc25daf --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/PutOwner.java @@ -0,0 +1,96 @@ +// 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.GroupReference; +import com.google.gerrit.common.errors.NoSuchGroupException; +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.MethodNotAllowedException; +import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestModifyView; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.account.GroupBackend; +import com.google.gerrit.server.account.GroupBackends; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupControl; +import com.google.gerrit.server.group.PutOwner.Input; +import com.google.gwtorm.server.OrmException; +import com.google.inject.Inject; + +import java.util.Collections; + +public class PutOwner implements RestModifyView { + static class Input { + @DefaultInput + String owner; + } + + private final GroupBackend groupBackend; + private final GroupCache groupCache; + private final GroupControl.Factory controlFactory; + private final ReviewDb db; + + @Inject + PutOwner(GroupBackend groupBackend, GroupCache groupCache, + GroupControl.Factory controlFactory, ReviewDb db) { + this.groupBackend = groupBackend; + this.groupCache = groupCache; + this.controlFactory = controlFactory; + this.db = db; + } + + @Override + public GroupInfo apply(GroupResource resource, Input input) + throws MethodNotAllowedException, AuthException, BadRequestException, + ResourceNotFoundException, OrmException { + AccountGroup group = resource.toAccountGroup(); + if (group == null) { + throw new MethodNotAllowedException(); + } else if (!resource.getControl().isOwner()) { + throw new AuthException("Not group owner"); + } + + if (input == null || Strings.isNullOrEmpty(input.owner)) { + throw new BadRequestException("owner is required"); + } + + GroupReference owner = + GroupBackends.findExactSuggestion(groupBackend, input.owner); + if (owner == null) { + throw new BadRequestException(String.format("No such group: %s", input.owner)); + } + + try { + GroupControl c = controlFactory.validateFor(owner.getUUID()); + group = db.accountGroups().get(group.getId()); + if (group == null) { + throw new ResourceNotFoundException(); + } + + if (!group.getOwnerGroupUUID().equals(owner.getUUID())) { + group.setOwnerGroupUUID(owner.getUUID()); + db.accountGroups().update(Collections.singleton(group)); + groupCache.evict(group); + } + return new GroupInfo(c.getGroup()); + } catch (NoSuchGroupException e) { + throw new BadRequestException(String.format("No such group: %s", input.owner)); + } + } +}