Support deletion of email address via REST

Change-Id: I3637a7f4497ddc2f88523728e5315ff56da92b8f
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
Edwin Kempin
2013-05-17 14:15:16 +02:00
parent 18fdb9d0ac
commit 4fbf70f0aa
5 changed files with 122 additions and 30 deletions

View File

@@ -267,6 +267,24 @@ link:#email-info[EmailInfo] entity.
} }
---- ----
[[delete-account-email]]
Delete Account Email
~~~~~~~~~~~~~~~~~~~~
[verse]
'DELETE /accounts/link:#account-id[\{account-id\}]/emails/link:#email-id[\{email-id\}]'
Deletes an email address of an account.
.Request
----
DELETE /accounts/self/emails/john.doe@example.com HTTP/1.0
----
.Response
----
HTTP/1.1 204 No Content
----
[[set-preferred-email]] [[set-preferred-email]]
Set Preferred Email Set Preferred Email
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~

View File

@@ -435,42 +435,38 @@ public class AccountManager {
* cannot be unlinked at this time. * cannot be unlinked at this time.
*/ */
public AuthResult unlink(final Account.Id from, AuthRequest who) public AuthResult unlink(final Account.Id from, AuthRequest who)
throws AccountException { throws AccountException, OrmException {
final ReviewDb db = schema.open();
try { try {
final ReviewDb db = schema.open(); who = realm.unlink(db, from, who);
try {
who = realm.unlink(db, from, who);
final AccountExternalId.Key key = id(who); final AccountExternalId.Key key = id(who);
AccountExternalId extId = db.accountExternalIds().get(key); AccountExternalId extId = db.accountExternalIds().get(key);
if (extId != null) { if (extId != null) {
if (!extId.getAccountId().equals(from)) { if (!extId.getAccountId().equals(from)) {
throw new AccountException("Identity in use by another account"); throw new AccountException("Identity in use by another account");
}
db.accountExternalIds().delete(Collections.singleton(extId));
if (who.getEmailAddress() != null) {
final Account a = db.accounts().get(from);
if (a.getPreferredEmail() != null
&& a.getPreferredEmail().equals(who.getEmailAddress())) {
a.setPreferredEmail(null);
db.accounts().update(Collections.singleton(a));
} }
db.accountExternalIds().delete(Collections.singleton(extId)); byEmailCache.evict(who.getEmailAddress());
byIdCache.evict(from);
if (who.getEmailAddress() != null) {
final Account a = db.accounts().get(from);
if (a.getPreferredEmail() != null
&& a.getPreferredEmail().equals(who.getEmailAddress())) {
a.setPreferredEmail(null);
db.accounts().update(Collections.singleton(a));
}
byEmailCache.evict(who.getEmailAddress());
byIdCache.evict(from);
}
} else {
throw new AccountException("Identity not found");
} }
return new AuthResult(from, key, false); } else {
throw new AccountException("Identity not found");
} finally {
db.close();
} }
} catch (OrmException e) {
throw new AccountException("Cannot unlink identity", e); return new AuthResult(from, key, false);
} finally {
db.close();
} }
} }

View File

@@ -0,0 +1,75 @@
// 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.account;
import com.google.gerrit.extensions.restapi.AuthException;
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.Account.FieldName;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.DeleteEmail.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class DeleteEmail implements RestModifyView<AccountResource.Email, Input> {
static class Input {
}
private final Provider<CurrentUser> self;
private final Realm realm;
private final Provider<ReviewDb> dbProvider;
private final AccountManager accountManager;
@Inject
DeleteEmail(Provider<CurrentUser> self, Realm realm,
Provider<ReviewDb> dbProvider, AccountManager accountManager) {
this.self = self;
this.realm = realm;
this.dbProvider = dbProvider;
this.accountManager = accountManager;
}
@Override
public Object apply(AccountResource.Email rsrc, Input input)
throws AuthException, ResourceNotFoundException,
ResourceConflictException, MethodNotAllowedException, OrmException {
if (self.get() != rsrc.getUser()
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to delete email address");
}
if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
throw new MethodNotAllowedException("realm does not allow deleting emails");
}
AccountExternalId.Key key = new AccountExternalId.Key(
AccountExternalId.SCHEME_MAILTO, rsrc.getEmail());
AccountExternalId extId = dbProvider.get().accountExternalIds().get(key);
if (extId == null) {
throw new ResourceNotFoundException(rsrc.getEmail());
}
try {
accountManager.unlink(rsrc.getUser().getAccountId(),
AuthRequest.forEmail(rsrc.getEmail()));
} catch (AccountException e) {
throw new ResourceConflictException(e.getMessage());
}
return Response.none();
}
}

View File

@@ -40,6 +40,7 @@ public class Module extends RestApiModule {
child(ACCOUNT_KIND, "emails").to(Emails.class); child(ACCOUNT_KIND, "emails").to(Emails.class);
get(EMAIL_KIND).to(GetEmail.class); get(EMAIL_KIND).to(GetEmail.class);
put(EMAIL_KIND).to(PutEmail.class); put(EMAIL_KIND).to(PutEmail.class);
delete(EMAIL_KIND).to(DeleteEmail.class);
put(EMAIL_KIND, "preferred").to(PutPreferred.class); put(EMAIL_KIND, "preferred").to(PutPreferred.class);
get(ACCOUNT_KIND, "avatar").to(GetAvatar.class); get(ACCOUNT_KIND, "avatar").to(GetAvatar.class);
get(ACCOUNT_KIND, "avatar.change.url").to(GetAvatarChangeUrl.class); get(ACCOUNT_KIND, "avatar.change.url").to(GetAvatarChangeUrl.class);

View File

@@ -260,6 +260,8 @@ final class SetAccountCommand extends BaseCommand {
manager.unlink(id, AuthRequest.forEmail(mailAddress)); manager.unlink(id, AuthRequest.forEmail(mailAddress));
} catch (AccountException ex) { } catch (AccountException ex) {
throw die(ex.getMessage()); throw die(ex.getMessage());
} catch (OrmException ex) {
throw die(ex.getMessage());
} }
} }