diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-02-01 15:04:13 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-02-01 16:36:00 +0100 |
commit | 1d52c906629322026b3ddaea26b37d7c0da38f7e (patch) | |
tree | 8a36684cf87190b75288e9df92e8ae65d41c258d | |
parent | 5bb48033451b0ba9ca51fcdd2513e3554d34c007 (diff) | |
download | sonarqube-1d52c906629322026b3ddaea26b37d7c0da38f7e.tar.gz sonarqube-1d52c906629322026b3ddaea26b37d7c0da38f7e.zip |
SONAR-7011 For admin, it is impossible to change its own password in the "Users" page
-rw-r--r-- | it/it-tests/src/test/java/it/Category1Suite.java | 4 | ||||
-rw-r--r-- | it/it-tests/src/test/java/it/administration/UsersPageTest.java (renamed from it/it-tests/src/test/java/it/administration/UsersUITest.java) | 47 | ||||
-rw-r--r-- | it/it-tests/src/test/resources/administration/UsersUITest/admin_should_change_its_own_password.html | 135 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/users/change-password-view.js | 9 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs | 8 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/users/user.js | 14 |
6 files changed, 208 insertions, 9 deletions
diff --git a/it/it-tests/src/test/java/it/Category1Suite.java b/it/it-tests/src/test/java/it/Category1Suite.java index 5153eb1c298..f9b138e88af 100644 --- a/it/it-tests/src/test/java/it/Category1Suite.java +++ b/it/it-tests/src/test/java/it/Category1Suite.java @@ -40,7 +40,7 @@ package it;/* import com.sonar.orchestrator.Orchestrator; import it.actionPlan.ActionPlanTest; import it.actionPlan.ActionPlanUiTest; -import it.administration.UsersUITest; +import it.administration.UsersPageTest; import it.authorisation.BaseIdentityProviderTest; import it.authorisation.ExecuteAnalysisPermissionTest; import it.authorisation.IssuePermissionTest; @@ -76,7 +76,7 @@ import static util.ItUtils.xooPlugin; @RunWith(Suite.class) @Suite.SuiteClasses({ // administration - UsersUITest.class, + UsersPageTest.class, // project administration BulkDeletionTest.class, ProjectAdministrationTest.class, diff --git a/it/it-tests/src/test/java/it/administration/UsersUITest.java b/it/it-tests/src/test/java/it/administration/UsersPageTest.java index bad39aa55f6..ea203aa6e39 100644 --- a/it/it-tests/src/test/java/it/administration/UsersUITest.java +++ b/it/it-tests/src/test/java/it/administration/UsersPageTest.java @@ -22,14 +22,25 @@ package it.administration; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.selenium.Selenese; import it.Category1Suite; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; +import org.sonarqube.ws.client.PostRequest; +import org.sonarqube.ws.client.WsClient; import util.selenium.SeleneseTest; -public class UsersUITest { +import static util.ItUtils.newAdminWsClient; + +public class UsersPageTest { @ClassRule public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + private static WsClient adminWsClient; + + @BeforeClass + public static void setUp() { + adminWsClient = newAdminWsClient(orchestrator); + } @Test public void generate_and_revoke_user_token() throws Exception { @@ -38,4 +49,38 @@ public class UsersUITest { ).build(); new SeleneseTest(selenese).runOn(orchestrator); } + + @Test + public void admin_should_change_its_own_password() throws Exception { + createUser("users-page-user", "User"); + makeAdmin("users-page-user"); + + Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("admin_should_change_its_own_password", + "/administration/UsersUITest/admin_should_change_its_own_password.html" + ).build(); + new SeleneseTest(selenese).runOn(orchestrator); + + deactivateUser("users-page-user"); + } + + private static void createUser(String login, String name) { + adminWsClient.wsConnector().call( + new PostRequest("api/users/create") + .setParam("login", login) + .setParam("name", name) + .setParam("password", "password")); + } + + private static void makeAdmin(String login) { + adminWsClient.wsConnector().call( + new PostRequest("api/permissions/add_user") + .setParam("login", login) + .setParam("permission", "admin")); + } + + private static void deactivateUser(String login) { + adminWsClient.wsConnector().call( + new PostRequest("api/users/deactivate") + .setParam("login", login)); + } } diff --git a/it/it-tests/src/test/resources/administration/UsersUITest/admin_should_change_its_own_password.html b/it/it-tests/src/test/resources/administration/UsersUITest/admin_should_change_its_own_password.html new file mode 100644 index 00000000000..0e361e285fc --- /dev/null +++ b/it/it-tests/src/test/resources/administration/UsersUITest/admin_should_change_its_own_password.html @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + <link rel="selenium.base" href="http://localhost:49506"/> + <title>should_change_password</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr> +<td rowspan="1" colspan="3">should_change_password</td> +</tr> +</thead> +<tbody> +<tr> + <td>open</td> + <td>/sessions/login</td> + <td></td> +</tr> +<tr> + <td>type</td> + <td>login</td> + <td>users-page-user</td> +</tr> +<tr> + <td>type</td> + <td>password</td> + <td>password</td> +</tr> +<tr> + <td>clickAndWait</td> + <td>commit</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/users</td> + <td></td> +</tr> +<tr> + <td>waitForElementPresent</td> + <td>css=[data-login="users-page-user"]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>css=[data-login="admin"] .js-user-change-password</td> + <td></td> +</tr> +<tr> + <td>waitForElementPresent</td> + <td>css=.modal</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>id=change-user-password-old-password</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>css=.js-modal-close</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>css=[data-login="users-page-user"] .js-user-change-password</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>id=change-user-password-old-password</td> + <td></td> +</tr> +<tr> + <td>type</td> + <td>id=change-user-password-old-password</td> + <td>password</td> +</tr> +<tr> + <td>type</td> + <td>id=change-user-password-password</td> + <td>qwerty</td> +</tr> +<tr> + <td>type</td> + <td>id=change-user-password-password-confirmation</td> + <td>qwerty</td> +</tr> +<tr> + <td>click</td> + <td>id=change-user-password-submit</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>css=.modal</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/sessions/logout</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/sessions/login</td> + <td></td> +</tr> +<tr> + <td>type</td> + <td>login</td> + <td>users-page-user</td> +</tr> +<tr> + <td>type</td> + <td>password</td> + <td>qwerty</td> +</tr> +<tr> + <td>clickAndWait</td> + <td>commit</td> + <td></td> +</tr> +<tr> + <td>waitForText</td> + <td>id=global-navigation</td> + <td>*User*</td> +</tr> +</tbody> +</table> +</body> +</html> diff --git a/server/sonar-web/src/main/js/apps/users/change-password-view.js b/server/sonar-web/src/main/js/apps/users/change-password-view.js index 27cc8b34c8f..19c2176aa8b 100644 --- a/server/sonar-web/src/main/js/apps/users/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/users/change-password-view.js @@ -30,6 +30,7 @@ export default ModalForm.extend({ sendRequest: function () { var that = this, + oldPassword = this.$('#change-user-password-old-password').val(), password = this.$('#change-user-password-password').val(), confirmation = this.$('#change-user-password-password-confirmation').val(); if (password !== confirmation) { @@ -37,7 +38,7 @@ export default ModalForm.extend({ return; } this.disableForm(); - return this.model.changePassword(password, { + return this.model.changePassword(oldPassword, password, { statusCode: { // do not show global error 400: null @@ -48,6 +49,12 @@ export default ModalForm.extend({ that.enableForm(); that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); }); + }, + + serializeData: function () { + return Object.assign({}, ModalForm.prototype.serializeData.apply(this, arguments), { + isOwnPassword: window.SS.user === this.model.id + }); } }); diff --git a/server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs b/server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs index 22684806543..90b7c8cb138 100644 --- a/server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs +++ b/server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs @@ -4,6 +4,14 @@ </div> <div class="modal-body"> <div class="js-modal-messages"></div> + {{#if isOwnPassword}} + <div class="modal-field"> + <label for="change-user-password-old-password">Old Password<em class="mandatory">*</em></label> + {{! keep this fake field to hack browser autofill }} + <input id="change-user-password-old-password-fake" name="old-password-fake" type="password" class="hidden"> + <input id="change-user-password-old-password" name="old-password" type="password" size="50" maxlength="50" required> + </div> + {{/if}} <div class="modal-field"> <label for="change-user-password-password">New Password<em class="mandatory">*</em></label> {{! keep this fake field to hack browser autofill }} diff --git a/server/sonar-web/src/main/js/apps/users/user.js b/server/sonar-web/src/main/js/apps/users/user.js index 1b10cd39f45..ef4406966d1 100644 --- a/server/sonar-web/src/main/js/apps/users/user.js +++ b/server/sonar-web/src/main/js/apps/users/user.js @@ -75,14 +75,18 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); }, - changePassword: function (password, options) { + changePassword: function (oldPassword, password, options) { + const data = { + login: this.id, + password: password + }; + if (oldPassword != null) { + data.previousPassword = oldPassword; + } var opts = _.defaults(options || {}, { url: this.urlRoot() + '/change_password', type: 'POST', - data: { - login: this.id, - password: password - } + data: data }); return Backbone.ajax(opts); } |