From f87501399cd3a6ad2970606521daa2867313bfff Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 26 Jan 2016 15:46:59 +0100 Subject: [PATCH] SONAR-7231 Create new "Security" page in "My Space" --- .../src/test/java/it/Category1Suite.java | 4 +- .../test/java/it/user/MyAccountPageTest.java | 51 +++++--- .../should_change_password.html | 110 ++++++++++++++++++ .../sonar-web/src/main/js/apps/account/app.js | 2 + .../main/js/apps/account/components/Nav.js | 5 + .../js/apps/account/components/Password.js | 42 +++++++ .../js/apps/account/components/Security.js | 39 +++++++ .../main/js/apps/account/components/Tokens.js | 54 +++++++++ .../account/containers/SecurityContainer.js | 28 +++++ .../WEB-INF/app/views/account/index.html.erb | 1 + .../resources/org/sonar/l10n/core.properties | 1 + 11 files changed, 317 insertions(+), 20 deletions(-) create mode 100644 it/it-tests/src/test/resources/user/MyAccountPageTest/should_change_password.html create mode 100644 server/sonar-web/src/main/js/apps/account/components/Password.js create mode 100644 server/sonar-web/src/main/js/apps/account/components/Security.js create mode 100644 server/sonar-web/src/main/js/apps/account/components/Tokens.js create mode 100644 server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js diff --git a/it/it-tests/src/test/java/it/Category1Suite.java b/it/it-tests/src/test/java/it/Category1Suite.java index 16333217c23..5153eb1c298 100644 --- a/it/it-tests/src/test/java/it/Category1Suite.java +++ b/it/it-tests/src/test/java/it/Category1Suite.java @@ -65,6 +65,7 @@ import it.settings.PropertySetsTest; import it.settings.SettingsTest; import it.settings.SettingsTestRestartingOrchestrator; import it.settings.SubCategoriesTest; +import it.user.MyAccountPageTest; import org.junit.ClassRule; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -110,7 +111,8 @@ import static util.ItUtils.xooPlugin; TimeMachineTest.class, // action plan ActionPlanTest.class, - ActionPlanUiTest.class + ActionPlanUiTest.class, + MyAccountPageTest.class }) public class Category1Suite { diff --git a/it/it-tests/src/test/java/it/user/MyAccountPageTest.java b/it/it-tests/src/test/java/it/user/MyAccountPageTest.java index e3425497689..5188171ec23 100644 --- a/it/it-tests/src/test/java/it/user/MyAccountPageTest.java +++ b/it/it-tests/src/test/java/it/user/MyAccountPageTest.java @@ -22,26 +22,31 @@ package it.user; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.selenium.Selenese; import it.Category1Suite; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.sonar.wsclient.SonarClient; -import org.sonar.wsclient.user.UserParameters; +import org.junit.*; +import org.sonarqube.ws.client.PostRequest; +import org.sonarqube.ws.client.WsClient; import util.selenium.SeleneseTest; +import static util.ItUtils.newAdminWsClient; + public class MyAccountPageTest { @ClassRule public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + private static WsClient adminWsClient; @BeforeClass - public static void initUser() { + public static void setUp() { + adminWsClient = newAdminWsClient(orchestrator); + } + + @Before + public void initUser() { createUser("account-user", "User With Account", "user@example.com"); } - @AfterClass - public static void deleteTestUser() { + @After + public void deleteTestUser() { deactivateUser("account-user"); } @@ -53,19 +58,27 @@ public class MyAccountPageTest { new SeleneseTest(selenese).runOn(orchestrator); } + @Test + public void should_change_password() throws Exception { + Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("should_change_password", + "/user/MyAccountPageTest/should_change_password.html" + ).build(); + new SeleneseTest(selenese).runOn(orchestrator); + } + private static void createUser(String login, String name, String email) { - SonarClient client = orchestrator.getServer().adminWsClient(); - UserParameters userCreationParameters = UserParameters.create() - .login(login) - .name(name) - .email(email) - .password("password") - .passwordConfirmation("password"); - client.userClient().create(userCreationParameters); + adminWsClient.wsConnector().call( + new PostRequest("api/users/create") + .setParam("login", login) + .setParam("name", name) + .setParam("email", email) + .setParam("password", "password")); } - private static void deactivateUser(String user) { - orchestrator.getServer().adminWsClient().userClient().deactivate(user); + 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/user/MyAccountPageTest/should_change_password.html b/it/it-tests/src/test/resources/user/MyAccountPageTest/should_change_password.html new file mode 100644 index 00000000000..50da6be2ed7 --- /dev/null +++ b/it/it-tests/src/test/resources/user/MyAccountPageTest/should_change_password.html @@ -0,0 +1,110 @@ + + + + + + + should_change_password + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
should_change_password
open/sonar/sessions/login
typeloginaccount-user
typepasswordpassword
clickAndWaitcommit
open/sonar/account/security
waitForElementPresentid=change-password
clickid=change-password
waitForElementPresentid=old_password
typeid=old_passwordpassword
typeid=passwordnew_password
typeid=password_confirmationnew_password
clickcommit
open/sonar/sessions/logout
open/sonar/sessions/login
typeloginaccount-user
typepasswordnew_password
clickAndWaitcommit
waitForTextid=global-navigation*User With Account*
+ + diff --git a/server/sonar-web/src/main/js/apps/account/app.js b/server/sonar-web/src/main/js/apps/account/app.js index 4a78a6a04fb..fe969e8ad7d 100644 --- a/server/sonar-web/src/main/js/apps/account/app.js +++ b/server/sonar-web/src/main/js/apps/account/app.js @@ -27,6 +27,7 @@ import configureStore from './store/configureStore'; import AccountApp from './containers/AccountApp'; import Home from './components/Home'; import NotificationsContainer from './containers/NotificationsContainer'; +import SecurityContainer from './containers/SecurityContainer'; window.sonarqube.appStarted.then(options => { const el = document.querySelector(options.el); @@ -46,6 +47,7 @@ window.sonarqube.appStarted.then(options => { + diff --git a/server/sonar-web/src/main/js/apps/account/components/Nav.js b/server/sonar-web/src/main/js/apps/account/components/Nav.js index e19213d3062..4a49e1f7520 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Nav.js +++ b/server/sonar-web/src/main/js/apps/account/components/Nav.js @@ -43,6 +43,11 @@ const Nav = () => ( {translate('my_account.notifications')} +
  • + + {translate('my_account.security')} + +
  • diff --git a/server/sonar-web/src/main/js/apps/account/components/Password.js b/server/sonar-web/src/main/js/apps/account/components/Password.js new file mode 100644 index 00000000000..7da00b1e9f6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/Password.js @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React, { Component } from 'react'; + +import ChangePasswordView from '../change-password-view'; + +export default class Password extends Component { + handleChangePassword () { + new ChangePasswordView().render(); + } + + render () { + return ( +
    +

    Password

    + +
    + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/account/components/Security.js b/server/sonar-web/src/main/js/apps/account/components/Security.js new file mode 100644 index 00000000000..684fb74c56b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/Security.js @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; + +import Password from './Password'; +import Tokens from './Tokens'; + +export default function Security ({ user }) { + return ( +
    +
    + +
    + + {user.canChangePassword && ( +
    + +
    + )} +
    + ); +} diff --git a/server/sonar-web/src/main/js/apps/account/components/Tokens.js b/server/sonar-web/src/main/js/apps/account/components/Tokens.js new file mode 100644 index 00000000000..8c3170380ef --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/Tokens.js @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import Backbone from 'backbone'; +import React, { Component } from 'react'; + +import TokensView from '../tokens-view'; + +export default class Tokens extends Component { + componentDidMount () { + this.renderView(); + } + + componentWillUnmount () { + this.destroyView(); + } + + renderView () { + const account = new Backbone.Model({ + id: this.props.user.login + }); + + this.tokensView = new TokensView({ + el: this.refs.container, + model: account + }).render(); + } + + destroyView () { + if (this.destroyView) { + this.tokensView.destroy(); + } + } + + render () { + return
    ; + } +} diff --git a/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js b/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js new file mode 100644 index 00000000000..4fdb31f19bf --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js @@ -0,0 +1,28 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; + +import Security from './../components/Security'; + +export default function SecurityContainer () { + const { user } = window.sonarqube; + + return ; +} diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb index f5a9a100226..8a6209d7daa 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb @@ -4,6 +4,7 @@ login: '<%= escape_javascript current_user.login -%>', name: '<%= escape_javascript current_user.name -%>', email: '<%= escape_javascript current_user.email -%>', + canChangePassword: <%= User.editable_password? ? 'true' : 'false' -%>, groups: [ <% current_user.groups.sort.each do |group| -%> '<%= escape_javascript group.name -%>', diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index fad0339a29d..76b0d18e512 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2161,6 +2161,7 @@ my_account.favorite_issue_filters=Favorite Issue Filters my_account.favorite_measure_filters=Favorite Measure Filters my_account.notifications=Notifications my_account.no_project_notifications=You have not set project notifications yet. +my_account.security=Security -- 2.39.5