Merge branch 'stable-3.0'
* stable-3.0: Fix single tab indentation in diff Add plugin-manager as core plugin Set version to 3.0.0-rc2 Update highlight.js to master branch Stop using deprecated SoyListData and SoyMapData PolyGerrit: Fix typos in comments gr-create-project-dialog: Fix typo in element id name AccountIT: Fix typo in variable name Set version to 2.16.9-SNAPSHOT AccountIT: Add tests for email notification on adding SSH/GPG keys AccountApi: Add methods to generate and set the HTTP password Change-Id: Ic9f174c5fbe38fa9e4de2bed58e541d94f1df9bd
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -41,6 +41,7 @@
|
|||||||
!/plugins/external_plugin_deps.bzl
|
!/plugins/external_plugin_deps.bzl
|
||||||
!/plugins/gitiles
|
!/plugins/gitiles
|
||||||
!/plugins/hooks
|
!/plugins/hooks
|
||||||
|
!/plugins/plugin-manager
|
||||||
!/plugins/replication
|
!/plugins/replication
|
||||||
!/plugins/reviewnotes
|
!/plugins/reviewnotes
|
||||||
!/plugins/singleusergroup
|
!/plugins/singleusergroup
|
||||||
|
|||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -28,6 +28,11 @@
|
|||||||
url = ../plugins/hooks
|
url = ../plugins/hooks
|
||||||
branch = .
|
branch = .
|
||||||
|
|
||||||
|
[submodule "plugins/plugin-manager"]
|
||||||
|
path = plugins/plugin-manager
|
||||||
|
url = ../plugins/plugin-manager
|
||||||
|
branch = .
|
||||||
|
|
||||||
[submodule "plugins/replication"]
|
[submodule "plugins/replication"]
|
||||||
path = plugins/replication
|
path = plugins/replication
|
||||||
url = ../plugins/replication
|
url = ../plugins/replication
|
||||||
|
|||||||
@@ -110,6 +110,20 @@ Documentation] |
|
|||||||
link:https://gerrit.googlesource.com/plugins/hooks/+doc/master/src/main/resources/Documentation/config.md[
|
link:https://gerrit.googlesource.com/plugins/hooks/+doc/master/src/main/resources/Documentation/config.md[
|
||||||
Configuration]
|
Configuration]
|
||||||
|
|
||||||
|
[[plugin-manager]]
|
||||||
|
=== plugin-manager
|
||||||
|
|
||||||
|
This plugins provides an initial wizard to discover and install Gerrit plugins.
|
||||||
|
Per default GerritForge CI is used to download the plugin artifacts from, but
|
||||||
|
this can be changed per plugin configuration.
|
||||||
|
|
||||||
|
link:https://gerrit-review.googlesource.com/admin/repos/plugins/plugin-manager[
|
||||||
|
Project]
|
||||||
|
link:https://gerrit.googlesource.com/plugins/plugin-manager/+doc/master/src/main/resources/Documentation/about.md[
|
||||||
|
Documentation]
|
||||||
|
link:https://gerrit.googlesource.com/plugins/plugin-manager/+doc/master/src/main/resources/Documentation/config.md[
|
||||||
|
Configuration]
|
||||||
|
|
||||||
[[replication]]
|
[[replication]]
|
||||||
=== replication
|
=== replication
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,14 @@ import com.google.common.io.Resources;
|
|||||||
import com.google.gerrit.common.Nullable;
|
import com.google.gerrit.common.Nullable;
|
||||||
import com.google.template.soy.SoyFileSet;
|
import com.google.template.soy.SoyFileSet;
|
||||||
import com.google.template.soy.data.SanitizedContent;
|
import com.google.template.soy.data.SanitizedContent;
|
||||||
import com.google.template.soy.data.SoyMapData;
|
|
||||||
import com.google.template.soy.data.UnsafeSanitizedContentOrdainer;
|
import com.google.template.soy.data.UnsafeSanitizedContentOrdainer;
|
||||||
import com.google.template.soy.tofu.SoyTofu;
|
import com.google.template.soy.tofu.SoyTofu;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -74,8 +75,8 @@ public class IndexServlet extends HttpServlet {
|
|||||||
return uri.getPath().replaceAll("/$", "");
|
return uri.getPath().replaceAll("/$", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SoyMapData getTemplateData(String canonicalURL, String cdnPath, String faviconPath)
|
static Map<String, String> getTemplateData(
|
||||||
throws URISyntaxException {
|
String canonicalURL, String cdnPath, String faviconPath) throws URISyntaxException {
|
||||||
String canonicalPath = computeCanonicalPath(canonicalURL);
|
String canonicalPath = computeCanonicalPath(canonicalURL);
|
||||||
|
|
||||||
String staticPath = "";
|
String staticPath = "";
|
||||||
@@ -91,9 +92,10 @@ public class IndexServlet extends HttpServlet {
|
|||||||
UnsafeSanitizedContentOrdainer.ordainAsSafe(
|
UnsafeSanitizedContentOrdainer.ordainAsSafe(
|
||||||
staticPath, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
|
staticPath, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
|
||||||
|
|
||||||
return new SoyMapData(
|
Map<String, String> data = new HashMap<>();
|
||||||
"canonicalPath", canonicalPath,
|
data.put("canonicalPath", canonicalPath);
|
||||||
"staticResourcePath", sanitizedStaticPath,
|
data.put("staticResourcePath", sanitizedStaticPath.coerceToString());
|
||||||
"faviconPath", faviconPath);
|
data.put("faviconPath", faviconPath);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ import com.google.gerrit.server.permissions.GlobalPermission;
|
|||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.project.ProjectState;
|
import com.google.gerrit.server.project.ProjectState;
|
||||||
import com.google.gerrit.server.query.change.ChangeData;
|
import com.google.gerrit.server.query.change.ChangeData;
|
||||||
import com.google.template.soy.data.SoyListData;
|
|
||||||
import com.google.template.soy.data.SoyMapData;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
@@ -560,11 +560,11 @@ public abstract class ChangeEmail extends NotificationEmail {
|
|||||||
* a 'type' key which maps to one of 'common', 'add' or 'remove' and a 'text' key which maps to
|
* a 'type' key which maps to one of 'common', 'add' or 'remove' and a 'text' key which maps to
|
||||||
* the line's content.
|
* the line's content.
|
||||||
*/
|
*/
|
||||||
private SoyListData getDiffTemplateData() {
|
private List<Map<String, String>> getDiffTemplateData() {
|
||||||
SoyListData result = new SoyListData();
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
Splitter lineSplitter = Splitter.on(System.getProperty("line.separator"));
|
Splitter lineSplitter = Splitter.on(System.getProperty("line.separator"));
|
||||||
for (String diffLine : lineSplitter.split(getUnifiedDiff())) {
|
for (String diffLine : lineSplitter.split(getUnifiedDiff())) {
|
||||||
SoyMapData lineData = new SoyMapData();
|
Map<String, String> lineData = new HashMap<>();
|
||||||
lineData.put("text", diffLine);
|
lineData.put("text", diffLine);
|
||||||
|
|
||||||
// Skip empty lines and lines that look like diff headers.
|
// Skip empty lines and lines that look like diff headers.
|
||||||
|
|||||||
@@ -1890,8 +1890,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");
|
||||||
|
|
||||||
requestScopeOperations.setApiUser(user.id());
|
requestScopeOperations.setApiUser(user.id());
|
||||||
exception.expect(ResourceNotFoundException.class);
|
exception.expect(ResourceNotFoundException.class);
|
||||||
@@ -1906,14 +1909,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
|
||||||
@@ -2023,32 +2033,42 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
assertSequenceNumbers(info);
|
assertSequenceNumbers(info);
|
||||||
SshKeyInfo key = info.get(0);
|
SshKeyInfo key = info.get(0);
|
||||||
KeyPair keyPair = sshKeys.getKeyPair(admin);
|
KeyPair keyPair = sshKeys.getKeyPair(admin);
|
||||||
String inital = TestSshKeys.publicKey(keyPair, admin.email());
|
String initial = TestSshKeys.publicKey(keyPair, admin.email());
|
||||||
assertThat(key.sshPublicKey).isEqualTo(inital);
|
assertThat(key.sshPublicKey).isEqualTo(initial);
|
||||||
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)
|
||||||
gApi.accounts().self().addSshKey(inital);
|
sender.clear();
|
||||||
|
gApi.accounts().self().addSshKey(initial);
|
||||||
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);
|
||||||
@@ -2718,6 +2738,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 {
|
||||||
|
requestScopeOperations.setApiUser(admin.id());
|
||||||
|
String newPassword = gApi.accounts().id(user.username()).generateHttpPassword();
|
||||||
|
assertThat(newPassword).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotGenerateNewHttpPasswordForOtherUser() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(user.id());
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username()).generateHttpPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotExplicitlySetHttpPassword() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(user.id());
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().self().setHttpPassword("my-new-password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotExplicitlySetHttpPasswordForOtherUser() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(user.id());
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username()).setHttpPassword("my-new-password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCanRemoveHttpPassword() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(user.id());
|
||||||
|
assertThat(gApi.accounts().self().setHttpPassword(null)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userCannotRemoveHttpPasswordForOtherUser() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(user.id());
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.accounts().id(admin.username()).setHttpPassword(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminCanExplicitlySetHttpPasswordForUser() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(admin.id());
|
||||||
|
String httpPassword = "new-password-for-user";
|
||||||
|
assertThat(gApi.accounts().id(user.username()).setHttpPassword(httpPassword))
|
||||||
|
.isEqualTo(httpPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminCanRemoveHttpPasswordForUser() throws Exception {
|
||||||
|
requestScopeOperations.setApiUser(admin.id());
|
||||||
|
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;
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import com.google.gerrit.testing.GerritBaseTests;
|
import com.google.gerrit.testing.GerritBaseTests;
|
||||||
import com.google.template.soy.data.SoyMapData;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Map;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class IndexServletTest extends GerritBaseTests {
|
public class IndexServletTest extends GerritBaseTests {
|
||||||
@@ -38,35 +38,34 @@ public class IndexServletTest extends GerritBaseTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noPathAndNoCDN() throws URISyntaxException {
|
public void noPathAndNoCDN() throws URISyntaxException {
|
||||||
SoyMapData data = IndexServlet.getTemplateData("http://example.com/", null, null);
|
Map<String, String> data = IndexServlet.getTemplateData("http://example.com/", null, null);
|
||||||
assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("");
|
assertThat(data.get("canonicalPath")).isEqualTo("");
|
||||||
assertThat(data.getSingle("staticResourcePath").stringValue()).isEqualTo("");
|
assertThat(data.get("staticResourcePath")).isEqualTo("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pathAndNoCDN() throws URISyntaxException {
|
public void pathAndNoCDN() throws URISyntaxException {
|
||||||
SoyMapData data = IndexServlet.getTemplateData("http://example.com/gerrit/", null, null);
|
Map<String, String> data =
|
||||||
assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("/gerrit");
|
IndexServlet.getTemplateData("http://example.com/gerrit/", null, null);
|
||||||
assertThat(data.getSingle("staticResourcePath").stringValue()).isEqualTo("/gerrit");
|
assertThat(data.get("canonicalPath")).isEqualTo("/gerrit");
|
||||||
|
assertThat(data.get("staticResourcePath")).isEqualTo("/gerrit");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noPathAndCDN() throws URISyntaxException {
|
public void noPathAndCDN() throws URISyntaxException {
|
||||||
SoyMapData data =
|
Map<String, String> data =
|
||||||
IndexServlet.getTemplateData("http://example.com/", "http://my-cdn.com/foo/bar/", null);
|
IndexServlet.getTemplateData("http://example.com/", "http://my-cdn.com/foo/bar/", null);
|
||||||
assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("");
|
assertThat(data.get("canonicalPath")).isEqualTo("");
|
||||||
assertThat(data.getSingle("staticResourcePath").stringValue())
|
assertThat(data.get("staticResourcePath")).isEqualTo("http://my-cdn.com/foo/bar/");
|
||||||
.isEqualTo("http://my-cdn.com/foo/bar/");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pathAndCDN() throws URISyntaxException {
|
public void pathAndCDN() throws URISyntaxException {
|
||||||
SoyMapData data =
|
Map<String, String> data =
|
||||||
IndexServlet.getTemplateData(
|
IndexServlet.getTemplateData(
|
||||||
"http://example.com/gerrit", "http://my-cdn.com/foo/bar/", null);
|
"http://example.com/gerrit", "http://my-cdn.com/foo/bar/", null);
|
||||||
assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("/gerrit");
|
assertThat(data.get("canonicalPath")).isEqualTo("/gerrit");
|
||||||
assertThat(data.getSingle("staticResourcePath").stringValue())
|
assertThat(data.get("staticResourcePath")).isEqualTo("http://my-cdn.com/foo/bar/");
|
||||||
.isEqualTo("http://my-cdn.com/foo/bar/");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
196
lib/highlightjs/highlight.min.js
vendored
196
lib/highlightjs/highlight.min.js
vendored
File diff suppressed because one or more lines are too long
1
plugins/plugin-manager
Submodule
1
plugins/plugin-manager
Submodule
Submodule plugins/plugin-manager added at e1cc65b2fd
@@ -85,7 +85,7 @@ limitations under the License.
|
|||||||
<span class="title">Create initial empty commit</span>
|
<span class="title">Create initial empty commit</span>
|
||||||
<span class="value">
|
<span class="value">
|
||||||
<gr-select
|
<gr-select
|
||||||
id="initalCommit"
|
id="initialCommit"
|
||||||
bind-value="{{_repoConfig.create_empty_commit}}">
|
bind-value="{{_repoConfig.create_empty_commit}}">
|
||||||
<select>
|
<select>
|
||||||
<option value="false">False</option>
|
<option value="false">False</option>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ limitations under the License.
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('default values are populated', () => {
|
test('default values are populated', () => {
|
||||||
assert.isTrue(element.$.initalCommit.bindValue);
|
assert.isTrue(element.$.initialCommit.bindValue);
|
||||||
assert.isFalse(element.$.parentRepo.bindValue);
|
assert.isFalse(element.$.parentRepo.bindValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ limitations under the License.
|
|||||||
element.$.repoNameInput.bindValue = configInputObj.name;
|
element.$.repoNameInput.bindValue = configInputObj.name;
|
||||||
element.$.rightsInheritFromInput.bindValue = configInputObj.parent;
|
element.$.rightsInheritFromInput.bindValue = configInputObj.parent;
|
||||||
element.$.ownerInput.text = configInputObj.owners[0];
|
element.$.ownerInput.text = configInputObj.owners[0];
|
||||||
element.$.initalCommit.bindValue =
|
element.$.initialCommit.bindValue =
|
||||||
configInputObj.create_empty_commit;
|
configInputObj.create_empty_commit;
|
||||||
element.$.parentRepo.bindValue =
|
element.$.parentRepo.bindValue =
|
||||||
configInputObj.permissions_only;
|
configInputObj.permissions_only;
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ limitations under the License.
|
|||||||
loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
|
loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
|
||||||
|
|
||||||
// Stub methods on the changeComments object after changeComments has
|
// Stub methods on the changeComments object after changeComments has
|
||||||
// been initalized.
|
// been initialized.
|
||||||
commentApiWrapper.loadComments().then(() => {
|
commentApiWrapper.loadComments().then(() => {
|
||||||
sandbox.stub(element.changeComments, 'getPaths').returns({});
|
sandbox.stub(element.changeComments, 'getPaths').returns({});
|
||||||
sandbox.stub(element.changeComments, 'getCommentsBySideForPath')
|
sandbox.stub(element.changeComments, 'getCommentsBySideForPath')
|
||||||
@@ -1451,7 +1451,7 @@ limitations under the License.
|
|||||||
sandbox.stub(element, '_reviewFile');
|
sandbox.stub(element, '_reviewFile');
|
||||||
|
|
||||||
// Stub methods on the changeComments object after changeComments has
|
// Stub methods on the changeComments object after changeComments has
|
||||||
// been initalized.
|
// been initialized.
|
||||||
commentApiWrapper.loadComments().then(() => {
|
commentApiWrapper.loadComments().then(() => {
|
||||||
sandbox.stub(element.changeComments, 'getPaths').returns({});
|
sandbox.stub(element.changeComments, 'getPaths').returns({});
|
||||||
sandbox.stub(element.changeComments, 'getCommentsBySideForPath')
|
sandbox.stub(element.changeComments, 'getCommentsBySideForPath')
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ limitations under the License.
|
|||||||
element.messages = messages;
|
element.messages = messages;
|
||||||
|
|
||||||
// Stub methods on the changeComments object after changeComments has
|
// Stub methods on the changeComments object after changeComments has
|
||||||
// been initalized.
|
// been initialized.
|
||||||
return commentApiWrapper.loadComments();
|
return commentApiWrapper.loadComments();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ limitations under the License.
|
|||||||
element.messages = messages;
|
element.messages = messages;
|
||||||
|
|
||||||
// Stub methods on the changeComments object after changeComments has
|
// Stub methods on the changeComments object after changeComments has
|
||||||
// been initalized.
|
// been initialized.
|
||||||
return commentApiWrapper.loadComments();
|
return commentApiWrapper.loadComments();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ limitations under the License.
|
|||||||
color: var(--diff-tab-indicator-color);
|
color: var(--diff-tab-indicator-color);
|
||||||
/* >> character */
|
/* >> character */
|
||||||
content: '\00BB';
|
content: '\00BB';
|
||||||
|
position: absolute;
|
||||||
}
|
}
|
||||||
/* Is defined after other background-colors, such that this
|
/* Is defined after other background-colors, such that this
|
||||||
rule wins in case of same specificity. */
|
rule wins in case of same specificity. */
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ limitations under the License.
|
|||||||
element = commentApiWrapper.$.patchRange;
|
element = commentApiWrapper.$.patchRange;
|
||||||
|
|
||||||
// Stub methods on the changeComments object after changeComments has
|
// Stub methods on the changeComments object after changeComments has
|
||||||
// been initalized.
|
// been initialized.
|
||||||
return commentApiWrapper.loadComments();
|
return commentApiWrapper.loadComments();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ CORE_PLUGINS = [
|
|||||||
"download-commands",
|
"download-commands",
|
||||||
"gitiles",
|
"gitiles",
|
||||||
"hooks",
|
"hooks",
|
||||||
|
"plugin-manager",
|
||||||
"replication",
|
"replication",
|
||||||
"reviewnotes",
|
"reviewnotes",
|
||||||
"singleusergroup",
|
"singleusergroup",
|
||||||
|
|||||||
Reference in New Issue
Block a user