Merge "Add REST endpoint to set username"
This commit is contained in:
@@ -253,6 +253,30 @@ Retrieves the username of an account.
|
|||||||
|
|
||||||
If the account does not have a username the response is "`404 Not Found`".
|
If the account does not have a username the response is "`404 Not Found`".
|
||||||
|
|
||||||
|
[[set-username]]
|
||||||
|
=== Set Username
|
||||||
|
--
|
||||||
|
'PUT /accounts/link:#account-id[\{account-id\}]/username'
|
||||||
|
--
|
||||||
|
|
||||||
|
The new username must be provided in the request body inside
|
||||||
|
a link:#username-input[UsernameInput] entity.
|
||||||
|
|
||||||
|
Once set, the username cannot be changed or deleted. If attempted this
|
||||||
|
fails with "`405 Method Not Allowed`".
|
||||||
|
|
||||||
|
.Request
|
||||||
|
----
|
||||||
|
PUT /accounts/self/name HTTP/1.0
|
||||||
|
Content-Type: application/json; charset=UTF-8
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "jdoe"
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
As response the new username is returned.
|
||||||
|
|
||||||
[[get-active]]
|
[[get-active]]
|
||||||
=== Get Active
|
=== Get Active
|
||||||
--
|
--
|
||||||
@@ -1690,6 +1714,17 @@ user.
|
|||||||
|`valid` ||Whether the SSH key is valid.
|
|`valid` ||Whether the SSH key is valid.
|
||||||
|=============================
|
|=============================
|
||||||
|
|
||||||
|
[[username-input]]
|
||||||
|
=== UsernameInput
|
||||||
|
The `UsernameInput` entity contains information for setting the
|
||||||
|
username for an account.
|
||||||
|
|
||||||
|
[options="header",cols="1,6"]
|
||||||
|
|=======================
|
||||||
|
|Field Name |Description
|
||||||
|
|`username` |The new username of the account.
|
||||||
|
|=======================
|
||||||
|
|
||||||
|
|
||||||
GERRIT
|
GERRIT
|
||||||
------
|
------
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (C) 2015 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.rest.account;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||||
|
import com.google.gerrit.acceptance.RestResponse;
|
||||||
|
import com.google.gerrit.common.TimeUtil;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.account.PutUsername;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.gwtorm.server.SchemaFactory;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class PutUsernameIT extends AbstractDaemonTest {
|
||||||
|
@Inject
|
||||||
|
private SchemaFactory<ReviewDb> reviewDbProvider;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void set() throws Exception {
|
||||||
|
PutUsername.Input in = new PutUsername.Input();
|
||||||
|
in.username = "myUsername";
|
||||||
|
RestResponse r =
|
||||||
|
adminSession.put("/accounts/" + createUser().get() + "/username", in);
|
||||||
|
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
|
assertThat(newGson().fromJson(r.getReader(), String.class)).isEqualTo(
|
||||||
|
in.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setExisting_Conflict() throws Exception {
|
||||||
|
PutUsername.Input in = new PutUsername.Input();
|
||||||
|
in.username = admin.username;
|
||||||
|
RestResponse r =
|
||||||
|
adminSession.put("/accounts/" + createUser().get() + "/username", in);
|
||||||
|
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNew_MethodNotAllowed() throws Exception {
|
||||||
|
PutUsername.Input in = new PutUsername.Input();
|
||||||
|
in.username = "newUsername";
|
||||||
|
RestResponse r =
|
||||||
|
adminSession.put("/accounts/" + admin.username + "/username", in);
|
||||||
|
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_METHOD_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void delete_MethodNotAllowed() throws Exception {
|
||||||
|
RestResponse r =
|
||||||
|
adminSession.put("/accounts/" + admin.username + "/username");
|
||||||
|
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_METHOD_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Account.Id createUser() throws OrmException {
|
||||||
|
try (ReviewDb db = reviewDbProvider.open()) {
|
||||||
|
Account.Id id = new Account.Id(db.nextAccountId());
|
||||||
|
Account a = new Account(id, TimeUtil.nowTs());
|
||||||
|
db.accounts().insert(Collections.singleton(a));
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,10 +30,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
@RpcImpl(version = Version.V2_0)
|
@RpcImpl(version = Version.V2_0)
|
||||||
public interface AccountSecurity extends RemoteJsonService {
|
public interface AccountSecurity extends RemoteJsonService {
|
||||||
@Audit
|
|
||||||
@SignInRequired
|
|
||||||
void changeUserName(String newName, AsyncCallback<VoidResult> callback);
|
|
||||||
|
|
||||||
@SignInRequired
|
@SignInRequired
|
||||||
void myExternalIds(AsyncCallback<List<AccountExternalId>> callback);
|
void myExternalIds(AsyncCallback<List<AccountExternalId>> callback);
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,14 @@ public class AccountApi {
|
|||||||
new RestApi("/accounts/").id(account).view("username").get(cb);
|
new RestApi("/accounts/").id(account).view("username").get(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set the username */
|
||||||
|
public static void setUsername(String account, String username,
|
||||||
|
AsyncCallback<NativeString> cb) {
|
||||||
|
UsernameInput input = UsernameInput.create();
|
||||||
|
input.username(username);
|
||||||
|
new RestApi("/accounts/").id(account).view("username").put(input, cb);
|
||||||
|
}
|
||||||
|
|
||||||
/** Retrieve email addresses */
|
/** Retrieve email addresses */
|
||||||
public static void getEmails(String account,
|
public static void getEmails(String account,
|
||||||
AsyncCallback<JsArray<EmailInfo>> cb) {
|
AsyncCallback<JsArray<EmailInfo>> cb) {
|
||||||
@@ -128,4 +136,15 @@ public class AccountApi {
|
|||||||
protected HttpPasswordInput() {
|
protected HttpPasswordInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class UsernameInput extends JavaScriptObject {
|
||||||
|
final native void username(String u) /*-{ if(u)this.username=u; }-*/;
|
||||||
|
|
||||||
|
static UsernameInput create() {
|
||||||
|
return createObject().cast();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UsernameInput() {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ import com.google.gerrit.client.ConfirmationDialog;
|
|||||||
import com.google.gerrit.client.ErrorDialog;
|
import com.google.gerrit.client.ErrorDialog;
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
|
import com.google.gerrit.client.rpc.NativeString;
|
||||||
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.client.ui.OnEditEnabler;
|
import com.google.gerrit.client.ui.OnEditEnabler;
|
||||||
import com.google.gerrit.common.errors.InvalidUserNameException;
|
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
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;
|
||||||
@@ -34,7 +35,6 @@ import com.google.gwt.user.client.ui.TextBox;
|
|||||||
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
||||||
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
||||||
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
|
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
|
||||||
import com.google.gwtjsonrpc.common.VoidResult;
|
|
||||||
|
|
||||||
class UsernameField extends Composite {
|
class UsernameField extends Composite {
|
||||||
private CopyableLabel userNameLbl;
|
private CopyableLabel userNameLbl;
|
||||||
@@ -114,27 +114,27 @@ class UsernameField extends Composite {
|
|||||||
}
|
}
|
||||||
final String newUserName = newName;
|
final String newUserName = newName;
|
||||||
|
|
||||||
Util.ACCOUNT_SEC.changeUserName(newUserName,
|
AccountApi.setUsername("self", newUserName,
|
||||||
new GerritCallback<VoidResult>() {
|
new GerritCallback<NativeString>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(VoidResult result) {
|
public void onSuccess(NativeString result) {
|
||||||
Gerrit.getUserAccount().username(newUserName);
|
Gerrit.getUserAccount().username(newUserName);
|
||||||
userNameLbl.setText(newUserName);
|
userNameLbl.setText(newUserName);
|
||||||
userNameLbl.setVisible(true);
|
userNameLbl.setVisible(true);
|
||||||
userNameTxt.setVisible(false);
|
userNameTxt.setVisible(false);
|
||||||
setUserName.setVisible(false);
|
setUserName.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(final Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
enableUI(true);
|
enableUI(true);
|
||||||
if (caught instanceof InvalidUserNameException) {
|
if (RestApi.isExpected(422 /* Unprocessable Entity */)) {
|
||||||
new ErrorDialog(Util.C.invalidUserName()).center();
|
new ErrorDialog(Util.C.invalidUserName()).center();
|
||||||
} else {
|
} else {
|
||||||
super.onFailure(caught);
|
super.onFailure(caught);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableUI(final boolean on) {
|
private void enableUI(final boolean on) {
|
||||||
|
|||||||
@@ -21,11 +21,9 @@ import com.google.gerrit.common.TimeUtil;
|
|||||||
import com.google.gerrit.common.data.AccountSecurity;
|
import com.google.gerrit.common.data.AccountSecurity;
|
||||||
import com.google.gerrit.common.data.ContributorAgreement;
|
import com.google.gerrit.common.data.ContributorAgreement;
|
||||||
import com.google.gerrit.common.errors.ContactInformationStoreException;
|
import com.google.gerrit.common.errors.ContactInformationStoreException;
|
||||||
import com.google.gerrit.common.errors.InvalidUserNameException;
|
|
||||||
import com.google.gerrit.common.errors.NoSuchEntityException;
|
import com.google.gerrit.common.errors.NoSuchEntityException;
|
||||||
import com.google.gerrit.common.errors.PermissionDeniedException;
|
import com.google.gerrit.common.errors.PermissionDeniedException;
|
||||||
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
|
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
|
||||||
import com.google.gerrit.httpd.rpc.Handler;
|
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
@@ -38,7 +36,6 @@ import com.google.gerrit.server.account.AccountByEmailCache;
|
|||||||
import com.google.gerrit.server.account.AccountCache;
|
import com.google.gerrit.server.account.AccountCache;
|
||||||
import com.google.gerrit.server.account.AccountException;
|
import com.google.gerrit.server.account.AccountException;
|
||||||
import com.google.gerrit.server.account.AccountManager;
|
import com.google.gerrit.server.account.AccountManager;
|
||||||
import com.google.gerrit.server.account.ChangeUserName;
|
|
||||||
import com.google.gerrit.server.account.GroupCache;
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
import com.google.gerrit.server.account.Realm;
|
import com.google.gerrit.server.account.Realm;
|
||||||
import com.google.gerrit.server.contact.ContactStore;
|
import com.google.gerrit.server.contact.ContactStore;
|
||||||
@@ -66,7 +63,6 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
private final AccountManager accountManager;
|
private final AccountManager accountManager;
|
||||||
private final boolean useContactInfo;
|
private final boolean useContactInfo;
|
||||||
|
|
||||||
private final ChangeUserName.CurrentUser changeUserNameFactory;
|
|
||||||
private final DeleteExternalIds.Factory deleteExternalIdsFactory;
|
private final DeleteExternalIds.Factory deleteExternalIdsFactory;
|
||||||
private final ExternalIdDetailFactory.Factory externalIdDetailFactory;
|
private final ExternalIdDetailFactory.Factory externalIdDetailFactory;
|
||||||
|
|
||||||
@@ -81,7 +77,6 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
final EmailTokenVerifier etv, final ProjectCache pc,
|
final EmailTokenVerifier etv, final ProjectCache pc,
|
||||||
final AccountByEmailCache abec, final AccountCache uac,
|
final AccountByEmailCache abec, final AccountCache uac,
|
||||||
final AccountManager am,
|
final AccountManager am,
|
||||||
final ChangeUserName.CurrentUser changeUserNameFactory,
|
|
||||||
final DeleteExternalIds.Factory deleteExternalIdsFactory,
|
final DeleteExternalIds.Factory deleteExternalIdsFactory,
|
||||||
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
|
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
|
||||||
final ChangeHooks hooks, final GroupCache groupCache,
|
final ChangeHooks hooks, final GroupCache groupCache,
|
||||||
@@ -99,27 +94,12 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
|
|||||||
|
|
||||||
useContactInfo = contactStore != null && contactStore.isEnabled();
|
useContactInfo = contactStore != null && contactStore.isEnabled();
|
||||||
|
|
||||||
this.changeUserNameFactory = changeUserNameFactory;
|
|
||||||
this.deleteExternalIdsFactory = deleteExternalIdsFactory;
|
this.deleteExternalIdsFactory = deleteExternalIdsFactory;
|
||||||
this.externalIdDetailFactory = externalIdDetailFactory;
|
this.externalIdDetailFactory = externalIdDetailFactory;
|
||||||
this.hooks = hooks;
|
this.hooks = hooks;
|
||||||
this.groupCache = groupCache;
|
this.groupCache = groupCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changeUserName(final String newName,
|
|
||||||
final AsyncCallback<VoidResult> callback) {
|
|
||||||
if (realm.allowsEdit(Account.FieldName.USER_NAME)) {
|
|
||||||
if (newName == null || !newName.matches(Account.USER_NAME_PATTERN)) {
|
|
||||||
callback.onFailure(new InvalidUserNameException());
|
|
||||||
}
|
|
||||||
Handler.wrap(changeUserNameFactory.create(newName)).to(callback);
|
|
||||||
} else {
|
|
||||||
callback.onFailure(
|
|
||||||
new PermissionDeniedException("Not allowed to change username"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void myExternalIds(AsyncCallback<List<AccountExternalId>> callback) {
|
public void myExternalIds(AsyncCallback<List<AccountExternalId>> callback) {
|
||||||
externalIdDetailFactory.create().to(callback);
|
externalIdDetailFactory.create().to(callback);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import com.google.gwtjsonrpc.common.VoidResult;
|
|||||||
import com.google.gwtorm.server.OrmDuplicateKeyException;
|
import com.google.gwtorm.server.OrmDuplicateKeyException;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,28 +38,12 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
/** Operation to change the username of an account. */
|
/** Operation to change the username of an account. */
|
||||||
public class ChangeUserName implements Callable<VoidResult> {
|
public class ChangeUserName implements Callable<VoidResult> {
|
||||||
|
public static final String USERNAME_CANNOT_BE_CHANGED =
|
||||||
|
"Username cannot be changed.";
|
||||||
|
|
||||||
private static final Pattern USER_NAME_PATTERN =
|
private static final Pattern USER_NAME_PATTERN =
|
||||||
Pattern.compile(Account.USER_NAME_PATTERN);
|
Pattern.compile(Account.USER_NAME_PATTERN);
|
||||||
|
|
||||||
/** Factory to change the username for the current user. */
|
|
||||||
public static class CurrentUser {
|
|
||||||
private final Factory factory;
|
|
||||||
private final Provider<ReviewDb> db;
|
|
||||||
private final Provider<IdentifiedUser> user;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
CurrentUser(Factory factory, Provider<ReviewDb> db,
|
|
||||||
Provider<IdentifiedUser> user) {
|
|
||||||
this.factory = factory;
|
|
||||||
this.db = db;
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChangeUserName create(String newUsername) {
|
|
||||||
return factory.create(db.get(), user.get(), newUsername);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generic factory to change any user's username. */
|
/** Generic factory to change any user's username. */
|
||||||
public interface Factory {
|
public interface Factory {
|
||||||
ChangeUserName create(ReviewDb db, IdentifiedUser user, String newUsername);
|
ChangeUserName create(ReviewDb db, IdentifiedUser user, String newUsername);
|
||||||
@@ -92,7 +75,7 @@ public class ChangeUserName implements Callable<VoidResult> {
|
|||||||
InvalidUserNameException {
|
InvalidUserNameException {
|
||||||
final Collection<AccountExternalId> old = old();
|
final Collection<AccountExternalId> old = old();
|
||||||
if (!old.isEmpty()) {
|
if (!old.isEmpty()) {
|
||||||
throw new IllegalStateException("Username cannot be changed.");
|
throw new IllegalStateException(USERNAME_CANNOT_BE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newUsername != null && !newUsername.isEmpty()) {
|
if (newUsername != null && !newUsername.isEmpty()) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class Module extends RestApiModule {
|
|||||||
put(ACCOUNT_KIND, "name").to(PutName.class);
|
put(ACCOUNT_KIND, "name").to(PutName.class);
|
||||||
delete(ACCOUNT_KIND, "name").to(PutName.class);
|
delete(ACCOUNT_KIND, "name").to(PutName.class);
|
||||||
get(ACCOUNT_KIND, "username").to(GetUsername.class);
|
get(ACCOUNT_KIND, "username").to(GetUsername.class);
|
||||||
|
put(ACCOUNT_KIND, "username").to(PutUsername.class);
|
||||||
get(ACCOUNT_KIND, "active").to(GetActive.class);
|
get(ACCOUNT_KIND, "active").to(GetActive.class);
|
||||||
put(ACCOUNT_KIND, "active").to(PutActive.class);
|
put(ACCOUNT_KIND, "active").to(PutActive.class);
|
||||||
delete(ACCOUNT_KIND, "active").to(DeleteActive.class);
|
delete(ACCOUNT_KIND, "active").to(DeleteActive.class);
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (C) 2015 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.account;
|
||||||
|
|
||||||
|
import com.google.gerrit.common.errors.InvalidUserNameException;
|
||||||
|
import com.google.gerrit.common.errors.NameAlreadyUsedException;
|
||||||
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
|
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
import com.google.gerrit.server.account.PutUsername.Input;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class PutUsername implements RestModifyView<AccountResource, Input> {
|
||||||
|
public static class Input {
|
||||||
|
@DefaultInput
|
||||||
|
public String username;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Provider<CurrentUser> self;
|
||||||
|
private final ChangeUserName.Factory changeUserNameFactory;
|
||||||
|
private final Realm realm;
|
||||||
|
private final Provider<ReviewDb> db;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PutUsername(Provider<CurrentUser> self,
|
||||||
|
ChangeUserName.Factory changeUserNameFactory,
|
||||||
|
Realm realm,
|
||||||
|
Provider<ReviewDb> db) {
|
||||||
|
this.self = self;
|
||||||
|
this.changeUserNameFactory = changeUserNameFactory;
|
||||||
|
this.realm = realm;
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(AccountResource rsrc, Input input) throws AuthException,
|
||||||
|
MethodNotAllowedException, UnprocessableEntityException,
|
||||||
|
ResourceConflictException, OrmException {
|
||||||
|
if (self.get() != rsrc.getUser()
|
||||||
|
&& !self.get().getCapabilities().canAdministrateServer()) {
|
||||||
|
throw new AuthException("not allowed to set username");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!realm.allowsEdit(Account.FieldName.USER_NAME)) {
|
||||||
|
throw new MethodNotAllowedException("realm does not allow editing username");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null) {
|
||||||
|
input = new Input();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
changeUserNameFactory.create(db.get(), rsrc.getUser(), input.username).call();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
if (ChangeUserName.USERNAME_CANNOT_BE_CHANGED.equals(e.getMessage())) {
|
||||||
|
throw new MethodNotAllowedException(e.getMessage());
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} catch (InvalidUserNameException e) {
|
||||||
|
throw new UnprocessableEntityException("invalid username");
|
||||||
|
} catch (NameAlreadyUsedException e) {
|
||||||
|
throw new ResourceConflictException("username already used");
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.username;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -302,7 +302,6 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
factory(SubmoduleSectionParser.Factory.class);
|
factory(SubmoduleSectionParser.Factory.class);
|
||||||
|
|
||||||
bind(AccountManager.class);
|
bind(AccountManager.class);
|
||||||
bind(ChangeUserName.CurrentUser.class);
|
|
||||||
factory(ChangeUserName.Factory.class);
|
factory(ChangeUserName.Factory.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<List<CommentLinkInfo>>() {})
|
bind(new TypeLiteral<List<CommentLinkInfo>>() {})
|
||||||
|
|||||||
Reference in New Issue
Block a user