Cleanup access checks in account REST API implementations

The more common pattern is to compare IdentifiedUser using reference
equality. If they are the same object instance in the JVM then its
the same user. This happens when the URL was "/accounts/self/..." and
thus is very clearly for the calling user.

Don't allow registering new emails if the realm doesn't permit it.
Some realms may disable this feature because they want only the
address from the LDAP directory to be used on the server.

Load emails from the cached AccountState, rather than pulling them
from the database. This is the set the user's commits are verified
against so its a more accurate view to show to the user. If the
server cache is behind the database table the API will now reflect
its actually behind.

Shorten a few error messages, avoiding some line wrapping.

Change-Id: I3d644735117ccea3a120c49ace85b992f3ead6d6
This commit is contained in:
Shawn Pearce
2013-05-23 08:41:35 -07:00
parent 8150dadaf4
commit b2249e90f9
8 changed files with 67 additions and 75 deletions

View File

@@ -18,13 +18,14 @@ import com.google.gerrit.common.errors.EmailException;
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.ResourceConflictException;
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.AuthType;
import com.google.gerrit.reviewdb.client.Account.FieldName;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.CreateEmail.Input;
import com.google.gerrit.server.account.GetEmails.EmailInfo;
import com.google.gerrit.server.config.AuthConfig;
@@ -52,6 +53,7 @@ public class CreateEmail implements RestModifyView<AccountResource, Input> {
}
private final Provider<CurrentUser> self;
private final Realm realm;
private final AuthConfig authConfig;
private final AccountManager accountManager;
private final RegisterNewEmailSender.Factory registerNewEmailFactory;
@@ -59,11 +61,15 @@ public class CreateEmail implements RestModifyView<AccountResource, Input> {
private final String email;
@Inject
CreateEmail(Provider<CurrentUser> self, AuthConfig authConfig,
CreateEmail(Provider<CurrentUser> self,
Realm realm,
AuthConfig authConfig,
AccountManager accountManager,
RegisterNewEmailSender.Factory registerNewEmailFactory,
Provider<PutPreferred> putPreferredProvider, @Assisted String email) {
Provider<PutPreferred> putPreferredProvider,
@Assisted String email) {
this.self = self;
this.realm = realm;
this.authConfig = authConfig;
this.accountManager = accountManager;
this.registerNewEmailFactory = registerNewEmailFactory;
@@ -74,21 +80,28 @@ public class CreateEmail implements RestModifyView<AccountResource, Input> {
@Override
public Object apply(AccountResource rsrc, Input input) throws AuthException,
BadRequestException, ResourceConflictException,
ResourceNotFoundException, OrmException, EmailException {
IdentifiedUser s = (IdentifiedUser) self.get();
if (s.getAccountId().get() != rsrc.getUser().getAccountId().get()
ResourceNotFoundException, OrmException, EmailException,
MethodNotAllowedException {
if (self.get() != rsrc.getUser()
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to add email address");
}
if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
throw new MethodNotAllowedException("realm does not allow adding emails");
}
if (input == null) {
input = new Input();
}
if (input.email != null && !email.equals(input.email)) {
throw new BadRequestException("email address must match URL");
}
if (input.noConfirmation && !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to add email address without confirmation, "
+ "need to be Gerrit administrator");
if (input.noConfirmation
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("must be administrator to use no_confirmation");
}
EmailInfo info = new EmailInfo();
@@ -105,7 +118,7 @@ public class CreateEmail implements RestModifyView<AccountResource, Input> {
putPreferredProvider.get().apply(
new AccountResource.Email(rsrc.getUser(), email),
null);
info.setPreferred(true);
info.preferred = true;
}
} else {
try {