Fix permissions checks on Gerrit API on current user

When the current user is using GerritApi, a new user object
with the same user-id of CurrentUser gets created on-the-fly.

Even though the user accountId is the same, the user instances
are different and will fail all the REST API permissions checks.

Turn instance checks with accountId checks to allow user to
execute GerritApi on themselves without the requirement of being
Gerrit administrators.

NOTE: GerritApi are mostly used in plugins, so this change allows
other plugins to function properly.

Change-Id: Iaeb204dda3791eb2757d89fe6bce6994c6305e04
This commit is contained in:
Luca Milanesio 2018-05-10 17:17:12 +01:00
parent 8f708b8cc0
commit 5872780a5a
32 changed files with 77 additions and 35 deletions

View File

@ -219,7 +219,7 @@ public class GpgKeys implements ChildCollection<AccountResource, GpgKey> {
if (!BouncyCastleUtil.havePGP()) { if (!BouncyCastleUtil.havePGP()) {
throw new ResourceNotFoundException("GPG not enabled"); throw new ResourceNotFoundException("GPG not enabled");
} }
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }
} }

View File

@ -158,4 +158,17 @@ public abstract class CurrentUser {
public ExternalId.Key getLastLoginExternalIdKey() { public ExternalId.Key getLastLoginExternalIdKey() {
return get(lastLoginExternalIdPropertyKey); return get(lastLoginExternalIdPropertyKey);
} }
/**
* Checks if the current user has the same account id of another.
*
* <p>Provide a generic interface for allowing subclasses to define whether two accounts represent
* the same account id.
*
* @param other user to compare
* @return true if the two users have the same account id
*/
public boolean hasSameAccountId(CurrentUser other) {
return false;
}
} }

View File

@ -498,6 +498,11 @@ public class IdentifiedUser extends CurrentUser {
realUser); realUser);
} }
@Override
public boolean hasSameAccountId(CurrentUser other) {
return getAccountId().get() == other.getAccountId().get();
}
private String guessHost() { private String guessHost() {
String host = null; String host = null;
SocketAddress remotePeer = null; SocketAddress remotePeer = null;

View File

@ -69,7 +69,8 @@ public class AddSshKey implements RestModifyView<AccountResource, Input> {
@Override @Override
public Response<SshKeyInfo> apply(AccountResource rsrc, Input input) public Response<SshKeyInfo> apply(AccountResource rsrc, Input input)
throws AuthException, BadRequestException, OrmException, IOException, ConfigInvalidException { throws AuthException, BadRequestException, OrmException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to add SSH keys"); throw new AuthException("not allowed to add SSH keys");
} }
return apply(rsrc.getUser(), input); return apply(rsrc.getUser(), input);

View File

@ -51,7 +51,8 @@ class Capabilities implements ChildCollection<AccountResource, AccountResource.C
@Override @Override
public Capability parse(AccountResource parent, IdString id) public Capability parse(AccountResource parent, IdString id)
throws ResourceNotFoundException, AuthException { throws ResourceNotFoundException, AuthException {
if (self.get() != parent.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(parent.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("restricted to administrator"); throw new AuthException("restricted to administrator");
} }

View File

@ -79,7 +79,8 @@ public class CreateEmail implements RestModifyView<AccountResource, EmailInput>
throws AuthException, BadRequestException, ResourceConflictException, throws AuthException, BadRequestException, ResourceConflictException,
ResourceNotFoundException, OrmException, EmailException, MethodNotAllowedException, ResourceNotFoundException, OrmException, EmailException, MethodNotAllowedException,
IOException, ConfigInvalidException { IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to add email address"); throw new AuthException("not allowed to add email address");
} }

View File

@ -60,7 +60,8 @@ public class DeleteEmail implements RestModifyView<AccountResource.Email, Input>
public Response<?> apply(AccountResource.Email rsrc, Input input) public Response<?> apply(AccountResource.Email rsrc, Input input)
throws AuthException, ResourceNotFoundException, ResourceConflictException, throws AuthException, ResourceNotFoundException, ResourceConflictException,
MethodNotAllowedException, OrmException, IOException, ConfigInvalidException { MethodNotAllowedException, OrmException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to delete email address"); throw new AuthException("not allowed to delete email address");
} }
return apply(rsrc.getUser(), rsrc.getEmail()); return apply(rsrc.getUser(), rsrc.getEmail());

View File

@ -60,7 +60,7 @@ public class DeleteExternalIds implements RestModifyView<AccountResource, List<S
@Override @Override
public Response<?> apply(AccountResource resource, List<String> externalIds) public Response<?> apply(AccountResource resource, List<String> externalIds)
throws RestApiException, IOException, OrmException, ConfigInvalidException { throws RestApiException, IOException, OrmException, ConfigInvalidException {
if (self.get() != resource.getUser()) { if (!self.get().hasSameAccountId(resource.getUser())) {
throw new AuthException("not allowed to delete external IDs"); throw new AuthException("not allowed to delete external IDs");
} }

View File

@ -50,7 +50,8 @@ public class DeleteSshKey implements RestModifyView<AccountResource.SshKey, Inpu
public Response<?> apply(AccountResource.SshKey rsrc, Input input) public Response<?> apply(AccountResource.SshKey rsrc, Input input)
throws AuthException, OrmException, RepositoryNotFoundException, IOException, throws AuthException, OrmException, RepositoryNotFoundException, IOException,
ConfigInvalidException { ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to delete SSH keys"); throw new AuthException("not allowed to delete SSH keys");
} }

View File

@ -52,7 +52,8 @@ public class DeleteWatchedProjects
public Response<?> apply(AccountResource rsrc, List<ProjectWatchInfo> input) public Response<?> apply(AccountResource rsrc, List<ProjectWatchInfo> input)
throws AuthException, UnprocessableEntityException, OrmException, IOException, throws AuthException, UnprocessableEntityException, OrmException, IOException,
ConfigInvalidException { ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("It is not allowed to edit project watches of other users"); throw new AuthException("It is not allowed to edit project watches of other users");
} }
if (input == null) { if (input == null) {

View File

@ -78,7 +78,8 @@ class GetCapabilities implements RestReadView<AccountResource> {
@Override @Override
public Object apply(AccountResource resource) throws AuthException { public Object apply(AccountResource resource) throws AuthException {
if (self.get() != resource.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(resource.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("restricted to administrator"); throw new AuthException("restricted to administrator");
} }

View File

@ -57,7 +57,8 @@ public class GetDiffPreferences implements RestReadView<AccountResource> {
@Override @Override
public DiffPreferencesInfo apply(AccountResource rsrc) public DiffPreferencesInfo apply(AccountResource rsrc)
throws AuthException, ConfigInvalidException, IOException { throws AuthException, ConfigInvalidException, IOException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("restricted to administrator"); throw new AuthException("restricted to administrator");
} }

View File

@ -49,7 +49,8 @@ public class GetEditPreferences implements RestReadView<AccountResource> {
@Override @Override
public EditPreferencesInfo apply(AccountResource rsrc) public EditPreferencesInfo apply(AccountResource rsrc)
throws AuthException, IOException, ConfigInvalidException { throws AuthException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("requires Modify Account capability"); throw new AuthException("requires Modify Account capability");
} }

View File

@ -49,7 +49,7 @@ public class GetExternalIds implements RestReadView<AccountResource> {
@Override @Override
public List<AccountExternalIdInfo> apply(AccountResource resource) public List<AccountExternalIdInfo> apply(AccountResource resource)
throws RestApiException, OrmException { throws RestApiException, OrmException {
if (self.get() != resource.getUser()) { if (!self.get().hasSameAccountId(resource.getUser())) {
throw new AuthException("not allowed to get external IDs"); throw new AuthException("not allowed to get external IDs");
} }

View File

@ -50,7 +50,7 @@ class GetOAuthToken implements RestReadView<AccountResource> {
@Override @Override
public OAuthTokenInfo apply(AccountResource rsrc) public OAuthTokenInfo apply(AccountResource rsrc)
throws AuthException, ResourceNotFoundException { throws AuthException, ResourceNotFoundException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed to get access token"); throw new AuthException("not allowed to get access token");
} }
Account a = rsrc.getUser().getAccount(); Account a = rsrc.getUser().getAccount();

View File

@ -36,7 +36,8 @@ public class GetPreferences implements RestReadView<AccountResource> {
@Override @Override
public GeneralPreferencesInfo apply(AccountResource rsrc) throws AuthException { public GeneralPreferencesInfo apply(AccountResource rsrc) throws AuthException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("requires Modify Account capability"); throw new AuthException("requires Modify Account capability");
} }

View File

@ -47,7 +47,8 @@ public class GetSshKeys implements RestReadView<AccountResource> {
public List<SshKeyInfo> apply(AccountResource rsrc) public List<SshKeyInfo> apply(AccountResource rsrc)
throws AuthException, OrmException, RepositoryNotFoundException, IOException, throws AuthException, OrmException, RepositoryNotFoundException, IOException,
ConfigInvalidException { ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to get SSH keys"); throw new AuthException("not allowed to get SSH keys");
} }
return apply(rsrc.getUser()); return apply(rsrc.getUser());

View File

@ -51,7 +51,8 @@ public class GetWatchedProjects implements RestReadView<AccountResource> {
@Override @Override
public List<ProjectWatchInfo> apply(AccountResource rsrc) public List<ProjectWatchInfo> apply(AccountResource rsrc)
throws OrmException, AuthException, IOException, ConfigInvalidException { throws OrmException, AuthException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("It is not allowed to list project watches of other users"); throw new AuthException("It is not allowed to list project watches of other users");
} }
Account.Id accountId = rsrc.getUser().getAccountId(); Account.Id accountId = rsrc.getUser().getAccountId();

View File

@ -39,7 +39,8 @@ public class Index implements RestModifyView<AccountResource, Input> {
@Override @Override
public Response<?> apply(AccountResource rsrc, Input input) throws IOException, AuthException { public Response<?> apply(AccountResource rsrc, Input input) throws IOException, AuthException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to index account"); throw new AuthException("not allowed to index account");
} }

View File

@ -63,7 +63,8 @@ public class PostWatchedProjects
@Override @Override
public List<ProjectWatchInfo> apply(AccountResource rsrc, List<ProjectWatchInfo> input) public List<ProjectWatchInfo> apply(AccountResource rsrc, List<ProjectWatchInfo> input)
throws OrmException, RestApiException, IOException, ConfigInvalidException { throws OrmException, RestApiException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to edit project watches"); throw new AuthException("not allowed to edit project watches");
} }
Account.Id accountId = rsrc.getUser().getAccountId(); Account.Id accountId = rsrc.getUser().getAccountId();

View File

@ -72,7 +72,7 @@ public class PutAgreement implements RestModifyView<AccountResource, AgreementIn
throw new MethodNotAllowedException("contributor agreements disabled"); throw new MethodNotAllowedException("contributor agreements disabled");
} }
if (self.get() != resource.getUser()) { if (!self.get().hasSameAccountId(resource.getUser())) {
throw new AuthException("not allowed to enter contributor agreement"); throw new AuthException("not allowed to enter contributor agreement");
} }

View File

@ -77,13 +77,15 @@ public class PutHttpPassword implements RestModifyView<AccountResource, Input> {
String newPassword; String newPassword;
if (input.generate) { if (input.generate) {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to generate HTTP password"); throw new AuthException("not allowed to generate HTTP password");
} }
newPassword = generate(); newPassword = generate();
} else if (input.httpPassword == null) { } else if (input.httpPassword == null) {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to clear HTTP password"); throw new AuthException("not allowed to clear HTTP password");
} }
newPassword = null; newPassword = null;

View File

@ -61,7 +61,8 @@ public class PutName implements RestModifyView<AccountResource, Input> {
public Response<String> apply(AccountResource rsrc, Input input) public Response<String> apply(AccountResource rsrc, Input input)
throws AuthException, MethodNotAllowedException, ResourceNotFoundException, OrmException, throws AuthException, MethodNotAllowedException, ResourceNotFoundException, OrmException,
IOException { IOException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to change name"); throw new AuthException("not allowed to change name");
} }
return apply(rsrc.getUser(), input); return apply(rsrc.getUser(), input);

View File

@ -50,7 +50,8 @@ public class PutPreferred implements RestModifyView<AccountResource.Email, Input
@Override @Override
public Response<String> apply(AccountResource.Email rsrc, Input input) public Response<String> apply(AccountResource.Email rsrc, Input input)
throws AuthException, ResourceNotFoundException, OrmException, IOException { throws AuthException, ResourceNotFoundException, OrmException, IOException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to set preferred email address"); throw new AuthException("not allowed to set preferred email address");
} }
return apply(rsrc.getUser(), rsrc.getEmail()); return apply(rsrc.getUser(), rsrc.getEmail());

View File

@ -58,7 +58,8 @@ public class PutStatus implements RestModifyView<AccountResource, Input> {
@Override @Override
public Response<String> apply(AccountResource rsrc, Input input) public Response<String> apply(AccountResource rsrc, Input input)
throws AuthException, ResourceNotFoundException, OrmException, IOException { throws AuthException, ResourceNotFoundException, OrmException, IOException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("not allowed to set status"); throw new AuthException("not allowed to set status");
} }
return apply(rsrc.getUser(), input); return apply(rsrc.getUser(), input);

View File

@ -59,7 +59,8 @@ public class PutUsername implements RestModifyView<AccountResource, Input> {
public String apply(AccountResource rsrc, Input input) public String apply(AccountResource rsrc, Input input)
throws AuthException, MethodNotAllowedException, UnprocessableEntityException, throws AuthException, MethodNotAllowedException, UnprocessableEntityException,
ResourceConflictException, OrmException, IOException, ConfigInvalidException { ResourceConflictException, OrmException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to set username"); throw new AuthException("not allowed to set username");
} }

View File

@ -59,7 +59,8 @@ public class SetDiffPreferences implements RestModifyView<AccountResource, DiffP
public DiffPreferencesInfo apply(AccountResource rsrc, DiffPreferencesInfo in) public DiffPreferencesInfo apply(AccountResource rsrc, DiffPreferencesInfo in)
throws AuthException, BadRequestException, ConfigInvalidException, throws AuthException, BadRequestException, ConfigInvalidException,
RepositoryNotFoundException, IOException { RepositoryNotFoundException, IOException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("requires Modify Account capability"); throw new AuthException("requires Modify Account capability");
} }

View File

@ -59,7 +59,8 @@ public class SetEditPreferences implements RestModifyView<AccountResource, EditP
public EditPreferencesInfo apply(AccountResource rsrc, EditPreferencesInfo in) public EditPreferencesInfo apply(AccountResource rsrc, EditPreferencesInfo in)
throws AuthException, BadRequestException, RepositoryNotFoundException, IOException, throws AuthException, BadRequestException, RepositoryNotFoundException, IOException,
ConfigInvalidException { ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("requires Modify Account capability"); throw new AuthException("requires Modify Account capability");
} }

View File

@ -75,7 +75,8 @@ public class SetPreferences implements RestModifyView<AccountResource, GeneralPr
@Override @Override
public GeneralPreferencesInfo apply(AccountResource rsrc, GeneralPreferencesInfo i) public GeneralPreferencesInfo apply(AccountResource rsrc, GeneralPreferencesInfo i)
throws AuthException, BadRequestException, IOException, ConfigInvalidException { throws AuthException, BadRequestException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new AuthException("requires Modify Account capability"); throw new AuthException("requires Modify Account capability");
} }

View File

@ -56,7 +56,8 @@ public class SshKeys implements ChildCollection<AccountResource, AccountResource
@Override @Override
public AccountResource.SshKey parse(AccountResource rsrc, IdString id) public AccountResource.SshKey parse(AccountResource rsrc, IdString id)
throws ResourceNotFoundException, OrmException, IOException, ConfigInvalidException { throws ResourceNotFoundException, OrmException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canModifyAccount()) { if (!self.get().hasSameAccountId(rsrc.getUser())
&& !self.get().getCapabilities().canModifyAccount()) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }
return parse(rsrc.getUser(), id); return parse(rsrc.getUser(), id);

View File

@ -130,7 +130,7 @@ public class StarredChanges
@Override @Override
public Response<?> apply(AccountResource rsrc, EmptyInput in) public Response<?> apply(AccountResource rsrc, EmptyInput in)
throws AuthException, OrmException, IOException { throws AuthException, OrmException, IOException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed to add starred change"); throw new AuthException("not allowed to add starred change");
} }
try { try {
@ -159,7 +159,7 @@ public class StarredChanges
@Override @Override
public Response<?> apply(AccountResource.StarredChange rsrc, EmptyInput in) public Response<?> apply(AccountResource.StarredChange rsrc, EmptyInput in)
throws AuthException { throws AuthException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed update starred changes"); throw new AuthException("not allowed update starred changes");
} }
return Response.none(); return Response.none();
@ -180,7 +180,7 @@ public class StarredChanges
@Override @Override
public Response<?> apply(AccountResource.StarredChange rsrc, EmptyInput in) public Response<?> apply(AccountResource.StarredChange rsrc, EmptyInput in)
throws AuthException, OrmException, IOException { throws AuthException, OrmException, IOException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed remove starred change"); throw new AuthException("not allowed remove starred change");
} }
starredChangesUtil.star( starredChangesUtil.star(

View File

@ -97,7 +97,7 @@ public class Stars implements ChildCollection<AccountResource, AccountResource.S
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<ChangeInfo> apply(AccountResource rsrc) public List<ChangeInfo> apply(AccountResource rsrc)
throws BadRequestException, AuthException, OrmException { throws BadRequestException, AuthException, OrmException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed to list stars of another account"); throw new AuthException("not allowed to list stars of another account");
} }
QueryChanges query = changes.list(); QueryChanges query = changes.list();
@ -119,7 +119,7 @@ public class Stars implements ChildCollection<AccountResource, AccountResource.S
@Override @Override
public SortedSet<String> apply(AccountResource.Star rsrc) throws AuthException, OrmException { public SortedSet<String> apply(AccountResource.Star rsrc) throws AuthException, OrmException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed to get stars of another account"); throw new AuthException("not allowed to get stars of another account");
} }
return starredChangesUtil.getLabels(self.get().getAccountId(), rsrc.getChange().getId()); return starredChangesUtil.getLabels(self.get().getAccountId(), rsrc.getChange().getId());
@ -140,7 +140,7 @@ public class Stars implements ChildCollection<AccountResource, AccountResource.S
@Override @Override
public Collection<String> apply(AccountResource.Star rsrc, StarsInput in) public Collection<String> apply(AccountResource.Star rsrc, StarsInput in)
throws AuthException, BadRequestException, OrmException { throws AuthException, BadRequestException, OrmException {
if (self.get() != rsrc.getUser()) { if (!self.get().hasSameAccountId(rsrc.getUser())) {
throw new AuthException("not allowed to update stars of another account"); throw new AuthException("not allowed to update stars of another account");
} }
try { try {