Add API portion of account status
Adds PutStatus.java and GetStatus.java for modification of the logged-in user's status field. Feature: Issue 4394 Change-Id: Id13241dcd98c46101cea2f2337c1fb731d0465a0
This commit is contained in:
parent
f3837bd5df
commit
eb64a0ae1e
@ -285,6 +285,66 @@ Deletes the name of an account.
|
||||
HTTP/1.1 204 No Content
|
||||
----
|
||||
|
||||
[[get-account-status]]
|
||||
=== Get Account Status
|
||||
--
|
||||
'GET /accounts/link:#account-id[\{account-id\}]/status'
|
||||
--
|
||||
|
||||
Retrieves the status of an account.
|
||||
|
||||
.Request
|
||||
----
|
||||
GET /accounts/self/status HTTP/1.0
|
||||
----
|
||||
|
||||
.Response
|
||||
----
|
||||
HTTP/1.1 200 OK
|
||||
Content-Disposition: attachment
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
)]}'
|
||||
"Available"
|
||||
----
|
||||
|
||||
If the account does not have a status an empty string is returned.
|
||||
|
||||
[[set-account-status]]
|
||||
=== Set Account Status
|
||||
--
|
||||
'PUT /accounts/link:#account-id[\{account-id\}]/status'
|
||||
--
|
||||
|
||||
Sets the status of an account.
|
||||
|
||||
The new account status must be provided in the request body inside
|
||||
an link:#account-status-input[AccountStatusInput] entity.
|
||||
|
||||
.Request
|
||||
----
|
||||
PUT /accounts/self/status HTTP/1.0
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"status": "Out Of Office"
|
||||
}
|
||||
----
|
||||
|
||||
As response the new account status is returned.
|
||||
|
||||
.Response
|
||||
----
|
||||
HTTP/1.1 200 OK
|
||||
Content-Disposition: attachment
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
)]}'
|
||||
"Out Of Office"
|
||||
----
|
||||
|
||||
If the name was deleted the response is "`204 No Content`".
|
||||
|
||||
[[get-username]]
|
||||
=== Get Username
|
||||
--
|
||||
@ -2173,6 +2233,18 @@ for an account.
|
||||
If not set or if set to an empty string, the account name is deleted.
|
||||
|=============================
|
||||
|
||||
[[account-status-input]]
|
||||
=== AccountStatusInput
|
||||
The `AccountStatusInput` entity contains information for setting a status
|
||||
for an account.
|
||||
|
||||
[options="header",cols="1,^2,4"]
|
||||
|=============================
|
||||
|Field Name ||Description
|
||||
|`status` |optional|The new status of the account. +
|
||||
If not set or if set to an empty string, the account status is deleted.
|
||||
|=============================
|
||||
|
||||
[[capability-info]]
|
||||
=== CapabilityInfo
|
||||
The `CapabilityInfo` entity contains information about the global
|
||||
|
@ -51,6 +51,7 @@ public class TestAccount {
|
||||
public final String fullName;
|
||||
public final KeyPair sshKey;
|
||||
public final String httpPassword;
|
||||
public String status;
|
||||
|
||||
TestAccount(Account.Id id, String username, String email, String fullName,
|
||||
KeyPair sshKey, String httpPassword) {
|
||||
|
@ -421,6 +421,19 @@ public class AccountIT extends AbstractDaemonTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putStatus() throws Exception {
|
||||
List<String> statuses = ImmutableList.of(
|
||||
"OOO", "Busy");
|
||||
AccountInfo info;
|
||||
for (String status : statuses) {
|
||||
gApi.accounts().self().setStatus(status);
|
||||
admin.status = status;
|
||||
info = gApi.accounts().self().get();
|
||||
assertUser(info, admin);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addInvalidEmail() throws Exception {
|
||||
List<String> emails = ImmutableList.of(
|
||||
@ -877,5 +890,6 @@ public class AccountIT extends AbstractDaemonTest {
|
||||
assertThat(info.name).isEqualTo(account.fullName);
|
||||
assertThat(info.email).isEqualTo(account.email);
|
||||
assertThat(info.username).isEqualTo(account.username);
|
||||
assertThat(info.status).isEqualTo(account.status);
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ public interface AccountApi {
|
||||
|
||||
void addEmail(EmailInput input) throws RestApiException;
|
||||
|
||||
void setStatus(String status) throws RestApiException;
|
||||
|
||||
List<SshKeyInfo> listSshKeys() throws RestApiException;
|
||||
SshKeyInfo addSshKey(String key) throws RestApiException;
|
||||
void deleteSshKey(int seq) throws RestApiException;
|
||||
@ -184,6 +186,11 @@ public interface AccountApi {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(String status) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SshKeyInfo> listSshKeys() {
|
||||
throw new NotImplementedException();
|
||||
|
@ -24,6 +24,7 @@ public class AccountInfo {
|
||||
public String username;
|
||||
public List<AvatarInfo> avatars;
|
||||
public Boolean _moreAccounts;
|
||||
public String status;
|
||||
|
||||
public AccountInfo(Integer id) {
|
||||
this._accountId = id;
|
||||
|
@ -42,7 +42,10 @@ public abstract class AccountDirectory {
|
||||
USERNAME,
|
||||
|
||||
/** Numeric account ID, may be deprecated. */
|
||||
ID
|
||||
ID,
|
||||
|
||||
/** The user-settable status of this account (e.g. busy, OOO, available) */
|
||||
STATUS
|
||||
}
|
||||
|
||||
public abstract void fillAccountInfo(
|
||||
|
@ -42,6 +42,7 @@ public class AccountLoader {
|
||||
FillOptions.NAME,
|
||||
FillOptions.EMAIL,
|
||||
FillOptions.USERNAME,
|
||||
FillOptions.STATUS,
|
||||
FillOptions.AVATARS));
|
||||
|
||||
public interface Factory {
|
||||
|
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2017 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.common.base.Strings;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class GetStatus implements RestReadView<AccountResource> {
|
||||
@Override
|
||||
public String apply(AccountResource rsrc) {
|
||||
return Strings.nullToEmpty(rsrc.getUser().getAccount().getStatus());
|
||||
}
|
||||
}
|
@ -103,6 +103,11 @@ public class InternalAccountDirectory extends AccountDirectory {
|
||||
? AccountState.getUserName(externalIds)
|
||||
: null;
|
||||
}
|
||||
|
||||
if (options.contains(FillOptions.STATUS)) {
|
||||
info.status = account.getStatus();
|
||||
}
|
||||
|
||||
if (options.contains(FillOptions.AVATARS)) {
|
||||
AvatarProvider ap = avatar.get();
|
||||
if (ap != null) {
|
||||
|
@ -44,6 +44,8 @@ public class Module extends RestApiModule {
|
||||
get(ACCOUNT_KIND, "name").to(GetName.class);
|
||||
put(ACCOUNT_KIND, "name").to(PutName.class);
|
||||
delete(ACCOUNT_KIND, "name").to(PutName.class);
|
||||
get(ACCOUNT_KIND, "status").to(GetStatus.class);
|
||||
put(ACCOUNT_KIND, "status").to(PutStatus.class);
|
||||
get(ACCOUNT_KIND, "username").to(GetUsername.class);
|
||||
put(ACCOUNT_KIND, "username").to(PutUsername.class);
|
||||
get(ACCOUNT_KIND, "active").to(GetActive.class);
|
||||
|
@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2017 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.common.base.Strings;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.Response;
|
||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||
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.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.PutStatus.Input;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Singleton
|
||||
public class PutStatus implements RestModifyView<AccountResource, Input> {
|
||||
public static class Input {
|
||||
@DefaultInput
|
||||
String status;
|
||||
|
||||
public Input(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Input() {
|
||||
}
|
||||
}
|
||||
|
||||
private final Provider<CurrentUser> self;
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final AccountCache byIdCache;
|
||||
|
||||
@Inject
|
||||
PutStatus(Provider<CurrentUser> self, Provider<ReviewDb> dbProvider,
|
||||
AccountCache byIdCache) {
|
||||
this.self = self;
|
||||
this.dbProvider = dbProvider;
|
||||
this.byIdCache = byIdCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response<String> apply(AccountResource rsrc, Input input)
|
||||
throws AuthException,
|
||||
ResourceNotFoundException, OrmException, IOException {
|
||||
if (self.get() != rsrc.getUser()
|
||||
&& !self.get().getCapabilities().canModifyAccount()) {
|
||||
throw new AuthException("not allowed to set status");
|
||||
}
|
||||
return apply(rsrc.getUser(), input);
|
||||
}
|
||||
|
||||
public Response<String> apply(IdentifiedUser user, Input input)
|
||||
throws ResourceNotFoundException, OrmException,
|
||||
IOException {
|
||||
if (input == null) {
|
||||
input = new Input();
|
||||
}
|
||||
|
||||
Account a = dbProvider.get().accounts().get(user.getAccountId());
|
||||
if (a == null) {
|
||||
throw new ResourceNotFoundException("account not found");
|
||||
}
|
||||
a.setStatus(Strings.nullToEmpty(input.status));
|
||||
dbProvider.get().accounts().update(Collections.singleton(a));
|
||||
byIdCache.evict(a.getId());
|
||||
return Strings.isNullOrEmpty(a.getStatus())
|
||||
? Response.none()
|
||||
: Response.ok(a.getStatus());
|
||||
}
|
||||
}
|
@ -59,6 +59,7 @@ import com.google.gerrit.server.account.Index;
|
||||
import com.google.gerrit.server.account.PostWatchedProjects;
|
||||
import com.google.gerrit.server.account.PutActive;
|
||||
import com.google.gerrit.server.account.PutAgreement;
|
||||
import com.google.gerrit.server.account.PutStatus;
|
||||
import com.google.gerrit.server.account.SetDiffPreferences;
|
||||
import com.google.gerrit.server.account.SetEditPreferences;
|
||||
import com.google.gerrit.server.account.SetPreferences;
|
||||
@ -115,6 +116,7 @@ public class AccountApiImpl implements AccountApi {
|
||||
private final Index index;
|
||||
private final GetExternalIds getExternalIds;
|
||||
private final DeleteExternalIds deleteExternalIds;
|
||||
private final PutStatus putStatus;
|
||||
|
||||
@Inject
|
||||
AccountApiImpl(AccountLoader.Factory ailf,
|
||||
@ -148,6 +150,7 @@ public class AccountApiImpl implements AccountApi {
|
||||
Index index,
|
||||
GetExternalIds getExternalIds,
|
||||
DeleteExternalIds deleteExternalIds,
|
||||
PutStatus putStatus,
|
||||
@Assisted AccountResource account) {
|
||||
this.account = account;
|
||||
this.accountLoaderFactory = ailf;
|
||||
@ -181,6 +184,7 @@ public class AccountApiImpl implements AccountApi {
|
||||
this.index = index;
|
||||
this.getExternalIds = getExternalIds;
|
||||
this.deleteExternalIds = deleteExternalIds;
|
||||
this.putStatus = putStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -373,6 +377,16 @@ public class AccountApiImpl implements AccountApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(String status) throws RestApiException {
|
||||
PutStatus.Input in = new PutStatus.Input(status);
|
||||
try {
|
||||
putStatus.apply(account, in);
|
||||
} catch (OrmException | IOException e) {
|
||||
throw new RestApiException("Cannot set status", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SshKeyInfo> listSshKeys() throws RestApiException {
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user