Merge branch 'stable-2.15' into stable-2.16
* stable-2.15: AccountIT: Add tests for email notification on adding SSH/GPG keys AccountApi: Add methods to generate and set the HTTP password Change-Id: Icf08d79a8f345132b2e4abb20601a5518b0eab5b
This commit is contained in:
@@ -114,6 +114,23 @@ public interface AccountApi {
|
|||||||
|
|
||||||
void setName(String name) throws RestApiException;
|
void setName(String name) throws RestApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new HTTP password.
|
||||||
|
*
|
||||||
|
* @return the generated password.
|
||||||
|
*/
|
||||||
|
String generateHttpPassword() throws RestApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a new HTTP password.
|
||||||
|
*
|
||||||
|
* <p>May only be invoked by administrators.
|
||||||
|
*
|
||||||
|
* @param httpPassword the new password, {@code null} to remove the password.
|
||||||
|
* @return the new password, {@code null} if the password was removed.
|
||||||
|
*/
|
||||||
|
String setHttpPassword(String httpPassword) throws RestApiException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default implementation which allows source compatibility when adding new methods to the
|
* A default implementation which allows source compatibility when adding new methods to the
|
||||||
* interface.
|
* interface.
|
||||||
@@ -317,5 +334,15 @@ public interface AccountApi {
|
|||||||
public void setName(String name) throws RestApiException {
|
public void setName(String name) throws RestApiException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateHttpPassword() throws RestApiException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String setHttpPassword(String httpPassword) throws RestApiException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import com.google.gerrit.extensions.common.ChangeInfo;
|
|||||||
import com.google.gerrit.extensions.common.EmailInfo;
|
import com.google.gerrit.extensions.common.EmailInfo;
|
||||||
import com.google.gerrit.extensions.common.GpgKeyInfo;
|
import com.google.gerrit.extensions.common.GpgKeyInfo;
|
||||||
import com.google.gerrit.extensions.common.GroupInfo;
|
import com.google.gerrit.extensions.common.GroupInfo;
|
||||||
|
import com.google.gerrit.extensions.common.HttpPasswordInput;
|
||||||
import com.google.gerrit.extensions.common.Input;
|
import com.google.gerrit.extensions.common.Input;
|
||||||
import com.google.gerrit.extensions.common.NameInput;
|
import com.google.gerrit.extensions.common.NameInput;
|
||||||
import com.google.gerrit.extensions.common.SshKeyInfo;
|
import com.google.gerrit.extensions.common.SshKeyInfo;
|
||||||
@@ -75,6 +76,7 @@ import com.google.gerrit.server.restapi.account.Index;
|
|||||||
import com.google.gerrit.server.restapi.account.PostWatchedProjects;
|
import com.google.gerrit.server.restapi.account.PostWatchedProjects;
|
||||||
import com.google.gerrit.server.restapi.account.PutActive;
|
import com.google.gerrit.server.restapi.account.PutActive;
|
||||||
import com.google.gerrit.server.restapi.account.PutAgreement;
|
import com.google.gerrit.server.restapi.account.PutAgreement;
|
||||||
|
import com.google.gerrit.server.restapi.account.PutHttpPassword;
|
||||||
import com.google.gerrit.server.restapi.account.PutName;
|
import com.google.gerrit.server.restapi.account.PutName;
|
||||||
import com.google.gerrit.server.restapi.account.PutStatus;
|
import com.google.gerrit.server.restapi.account.PutStatus;
|
||||||
import com.google.gerrit.server.restapi.account.SetDiffPreferences;
|
import com.google.gerrit.server.restapi.account.SetDiffPreferences;
|
||||||
@@ -135,6 +137,7 @@ public class AccountApiImpl implements AccountApi {
|
|||||||
private final GetGroups getGroups;
|
private final GetGroups getGroups;
|
||||||
private final EmailApiImpl.Factory emailApi;
|
private final EmailApiImpl.Factory emailApi;
|
||||||
private final PutName putName;
|
private final PutName putName;
|
||||||
|
private final PutHttpPassword putHttpPassword;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AccountApiImpl(
|
AccountApiImpl(
|
||||||
@@ -177,6 +180,7 @@ public class AccountApiImpl implements AccountApi {
|
|||||||
GetGroups getGroups,
|
GetGroups getGroups,
|
||||||
EmailApiImpl.Factory emailApi,
|
EmailApiImpl.Factory emailApi,
|
||||||
PutName putName,
|
PutName putName,
|
||||||
|
PutHttpPassword putPassword,
|
||||||
@Assisted AccountResource account) {
|
@Assisted AccountResource account) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.accountLoaderFactory = ailf;
|
this.accountLoaderFactory = ailf;
|
||||||
@@ -218,6 +222,7 @@ public class AccountApiImpl implements AccountApi {
|
|||||||
this.getGroups = getGroups;
|
this.getGroups = getGroups;
|
||||||
this.emailApi = emailApi;
|
this.emailApi = emailApi;
|
||||||
this.putName = putName;
|
this.putName = putName;
|
||||||
|
this.putHttpPassword = putPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -593,4 +598,31 @@ public class AccountApiImpl implements AccountApi {
|
|||||||
throw asRestApiException("Cannot set account name", e);
|
throw asRestApiException("Cannot set account name", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateHttpPassword() throws RestApiException {
|
||||||
|
HttpPasswordInput input = new HttpPasswordInput();
|
||||||
|
input.generate = true;
|
||||||
|
try {
|
||||||
|
// Response should never be 'none' for a generated password, but
|
||||||
|
// let's make sure.
|
||||||
|
Response<String> result = putHttpPassword.apply(account, input);
|
||||||
|
return result.isNone() ? null : result.value();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw asRestApiException("Cannot generate HTTP password", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String setHttpPassword(String password) throws RestApiException {
|
||||||
|
HttpPasswordInput input = new HttpPasswordInput();
|
||||||
|
input.generate = false;
|
||||||
|
input.httpPassword = password;
|
||||||
|
try {
|
||||||
|
Response<String> result = putHttpPassword.apply(account, input);
|
||||||
|
return result.isNone() ? null : result.value();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw asRestApiException("Cannot generate HTTP password", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1892,8 +1892,11 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
String id = key.getKeyIdString();
|
String id = key.getKeyIdString();
|
||||||
addExternalIdEmail(admin, "test1@example.com");
|
addExternalIdEmail(admin, "test1@example.com");
|
||||||
|
|
||||||
|
sender.clear();
|
||||||
assertKeyMapContains(key, addGpgKey(key.getPublicKeyArmored()));
|
assertKeyMapContains(key, addGpgKey(key.getPublicKeyArmored()));
|
||||||
assertKeys(key);
|
assertKeys(key);
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new GPG keys have been added");
|
||||||
|
|
||||||
setApiUser(user);
|
setApiUser(user);
|
||||||
exception.expect(ResourceNotFoundException.class);
|
exception.expect(ResourceNotFoundException.class);
|
||||||
@@ -1908,14 +1911,21 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
String id = key.getKeyIdString();
|
String id = key.getKeyIdString();
|
||||||
PGPPublicKey pk = key.getPublicKey();
|
PGPPublicKey pk = key.getPublicKey();
|
||||||
|
|
||||||
|
sender.clear();
|
||||||
GpgKeyInfo info = addGpgKey(armor(pk)).get(id);
|
GpgKeyInfo info = addGpgKey(armor(pk)).get(id);
|
||||||
assertThat(info.userIds).hasSize(2);
|
assertThat(info.userIds).hasSize(2);
|
||||||
assertIteratorSize(2, getOnlyKeyFromStore(key).getUserIDs());
|
assertIteratorSize(2, getOnlyKeyFromStore(key).getUserIDs());
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new GPG keys have been added");
|
||||||
|
|
||||||
pk = PGPPublicKey.removeCertification(pk, "foo:myId");
|
pk = PGPPublicKey.removeCertification(pk, "foo:myId");
|
||||||
|
sender.clear();
|
||||||
info = addGpgKeyNoReindex(armor(pk)).get(id);
|
info = addGpgKeyNoReindex(armor(pk)).get(id);
|
||||||
assertThat(info.userIds).hasSize(1);
|
assertThat(info.userIds).hasSize(1);
|
||||||
assertIteratorSize(1, getOnlyKeyFromStore(key).getUserIDs());
|
assertIteratorSize(1, getOnlyKeyFromStore(key).getUserIDs());
|
||||||
|
// TODO: Issue 10769: Adding an already existing key should not result in a notification email
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new GPG keys have been added");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -2030,27 +2040,37 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
accountIndexedCounter.assertNoReindex();
|
accountIndexedCounter.assertNoReindex();
|
||||||
|
|
||||||
// Add a new key
|
// Add a new key
|
||||||
|
sender.clear();
|
||||||
String newKey = TestSshKeys.publicKey(TestSshKeys.genSshKey(), admin.email);
|
String newKey = TestSshKeys.publicKey(TestSshKeys.genSshKey(), admin.email);
|
||||||
gApi.accounts().self().addSshKey(newKey);
|
gApi.accounts().self().addSshKey(newKey);
|
||||||
info = gApi.accounts().self().listSshKeys();
|
info = gApi.accounts().self().listSshKeys();
|
||||||
assertThat(info).hasSize(2);
|
assertThat(info).hasSize(2);
|
||||||
assertSequenceNumbers(info);
|
assertSequenceNumbers(info);
|
||||||
accountIndexedCounter.assertReindexOf(admin);
|
accountIndexedCounter.assertReindexOf(admin);
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new SSH keys have been added");
|
||||||
|
|
||||||
// Add an existing key (the request succeeds, but the key isn't added again)
|
// Add an existing key (the request succeeds, but the key isn't added again)
|
||||||
|
sender.clear();
|
||||||
gApi.accounts().self().addSshKey(inital);
|
gApi.accounts().self().addSshKey(inital);
|
||||||
info = gApi.accounts().self().listSshKeys();
|
info = gApi.accounts().self().listSshKeys();
|
||||||
assertThat(info).hasSize(2);
|
assertThat(info).hasSize(2);
|
||||||
assertSequenceNumbers(info);
|
assertSequenceNumbers(info);
|
||||||
accountIndexedCounter.assertNoReindex();
|
accountIndexedCounter.assertNoReindex();
|
||||||
|
// TODO: Issue 10769: Adding an already existing key should not result in a notification email
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new SSH keys have been added");
|
||||||
|
|
||||||
// Add another new key
|
// Add another new key
|
||||||
|
sender.clear();
|
||||||
String newKey2 = TestSshKeys.publicKey(TestSshKeys.genSshKey(), admin.email);
|
String newKey2 = TestSshKeys.publicKey(TestSshKeys.genSshKey(), admin.email);
|
||||||
gApi.accounts().self().addSshKey(newKey2);
|
gApi.accounts().self().addSshKey(newKey2);
|
||||||
info = gApi.accounts().self().listSshKeys();
|
info = gApi.accounts().self().listSshKeys();
|
||||||
assertThat(info).hasSize(3);
|
assertThat(info).hasSize(3);
|
||||||
assertSequenceNumbers(info);
|
assertSequenceNumbers(info);
|
||||||
accountIndexedCounter.assertReindexOf(admin);
|
accountIndexedCounter.assertReindexOf(admin);
|
||||||
|
assertThat(sender.getMessages()).hasSize(1);
|
||||||
|
assertThat(sender.getMessages().get(0).body()).contains("new SSH keys have been added");
|
||||||
|
|
||||||
// Delete second key
|
// Delete second key
|
||||||
gApi.accounts().self().deleteSshKey(2);
|
gApi.accounts().self().deleteSshKey(2);
|
||||||
@@ -2735,6 +2755,67 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCanGenerateNewHttpPassword() throws Exception {
|
||||||
|
String newPassword = gApi.accounts().self().generateHttpPassword();
|
||||||
|
assertThat(newPassword).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminCanGenerateNewHttpPasswordForUser() throws Exception {
|
||||||
|
setApiUser(admin);
|
||||||
|
String newPassword = gApi.accounts().id(user.username).generateHttpPassword();
|
||||||
|
assertThat(newPassword).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotGenerateNewHttpPasswordForOtherUser() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username).generateHttpPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotExplicitlySetHttpPassword() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().self().setHttpPassword("my-new-password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotExplicitlySetHttpPasswordForOtherUser() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username).setHttpPassword("my-new-password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCanRemoveHttpPassword() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
assertThat(gApi.accounts().self().setHttpPassword(null)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotRemoveHttpPasswordForOtherUser() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username).setHttpPassword(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminCanExplicitlySetHttpPasswordForUser() throws Exception {
|
||||||
|
setApiUser(admin);
|
||||||
|
String httpPassword = "new-password-for-user";
|
||||||
|
assertThat(gApi.accounts().id(user.username).setHttpPassword(httpPassword))
|
||||||
|
.isEqualTo(httpPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminCanRemoveHttpPasswordForUser() throws Exception {
|
||||||
|
setApiUser(admin);
|
||||||
|
assertThat(gApi.accounts().id(user.username).setHttpPassword(null)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
private void createDraft(PushOneCommit.Result r, String path, String message) throws Exception {
|
private void createDraft(PushOneCommit.Result r, String path, String message) throws Exception {
|
||||||
DraftInput in = new DraftInput();
|
DraftInput in = new DraftInput();
|
||||||
in.path = path;
|
in.path = path;
|
||||||
|
|||||||
Reference in New Issue
Block a user