aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-05-11 12:24:44 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2017-05-12 12:37:19 +0200
commit555c7dd62475cac4e96bfa9ffbed6dd523ea8ad1 (patch)
treeb1b807f9bfb8cdd8e5cd210ccb93e3202a0e3204
parent8b20d9b681313b7b6b9bf0071e9169995d434912 (diff)
downloadsonarqube-555c7dd62475cac4e96bfa9ffbed6dd523ea8ad1.tar.gz
sonarqube-555c7dd62475cac4e96bfa9ffbed6dd523ea8ad1.zip
SONAR-8822 Show the administration menu only to authorized users
-rw-r--r--server/sonar-web/src/main/js/app/components/AdminContainer.js15
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js3
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js18
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap74
-rw-r--r--server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js10
-rw-r--r--server/sonar-web/src/main/js/helpers/users.js27
6 files changed, 103 insertions, 44 deletions
diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.js b/server/sonar-web/src/main/js/app/components/AdminContainer.js
index da8c9376dbc..86d867a2c5e 100644
--- a/server/sonar-web/src/main/js/app/components/AdminContainer.js
+++ b/server/sonar-web/src/main/js/app/components/AdminContainer.js
@@ -21,8 +21,7 @@ import React from 'react';
import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import SettingsNav from './nav/settings/SettingsNav';
-import { getCurrentUser, getAppState } from '../../store/rootReducer';
-import { isUserAdmin } from '../../helpers/users';
+import { getAppState } from '../../store/rootReducer';
import { onFail } from '../../store/rootActions';
import { getSettingsNavigation } from '../../api/nav';
import { setAdminPages } from '../../store/appState/duck';
@@ -30,7 +29,7 @@ import { translate } from '../../helpers/l10n';
class AdminContainer extends React.PureComponent {
componentDidMount() {
- if (!isUserAdmin(this.props.currentUser)) {
+ if (!this.props.appState.canAdmin) {
// workaround cyclic dependencies
const handleRequiredAuthorization = require('../utils/handleRequiredAuthorization').default;
handleRequiredAuthorization();
@@ -46,14 +45,17 @@ class AdminContainer extends React.PureComponent {
}
render() {
- if (!isUserAdmin(this.props.currentUser) || !this.props.adminPages) {
+ const { adminPages } = this.props.appState;
+
+ // Check that the adminPages are loaded
+ if (!adminPages) {
return null;
}
return (
<div>
<Helmet title={translate('layout.settings')} />
- <SettingsNav location={this.props.location} extensions={this.props.adminPages} />
+ <SettingsNav location={this.props.location} extensions={adminPages} />
{this.props.children}
</div>
);
@@ -61,8 +63,7 @@ class AdminContainer extends React.PureComponent {
}
const mapStateToProps = state => ({
- adminPages: getAppState(state).adminPages,
- currentUser: getCurrentUser(state)
+ appState: getAppState(state)
});
const mapDispatchToProps = { setAdminPages };
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js
index 1cedcf94211..0a88701f045 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js
+++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js
@@ -20,7 +20,6 @@
import React from 'react';
import { Link } from 'react-router';
import { translate } from '../../../../helpers/l10n';
-import { isUserAdmin } from '../../../../helpers/users';
import { isMySet } from '../../../../apps/issues/utils';
export default class GlobalNavMenu extends React.PureComponent {
@@ -106,7 +105,7 @@ export default class GlobalNavMenu extends React.PureComponent {
}
renderAdministrationLink() {
- if (!isUserAdmin(this.props.currentUser)) {
+ if (!this.props.appState.canAdmin) {
return null;
}
return (
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js
index 99b97c82c4f..33546be3731 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js
+++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js
@@ -27,8 +27,22 @@ it('should work with extensions', () => {
qualifiers: ['TRK']
};
const currentUser = {
- isLoggedIn: false,
- permissions: { global: [] }
+ isLoggedIn: false
+ };
+ const wrapper = shallow(
+ <GlobalNavMenu appState={appState} currentUser={currentUser} location={{ pathname: '' }} />
+ );
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should show administration menu if the user has the rights', () => {
+ const appState = {
+ canAdmin: true,
+ globalPages: [],
+ qualifiers: ['TRK']
+ };
+ const currentUser = {
+ isLoggedIn: false
};
const wrapper = shallow(
<GlobalNavMenu appState={appState} currentUser={currentUser} location={{ pathname: '' }} />
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap
index bc69019f7a0..bb21d44b23e 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNavMenu-test.js.snap
@@ -1,5 +1,79 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`should show administration menu if the user has the rights 1`] = `
+<ul
+ className="nav navbar-nav"
+>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/projects"
+ >
+ projects.page
+ </Link>
+ </li>
+ <li>
+ <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/issues",
+ "query": Object {
+ "resolved": "false",
+ },
+ }
+ }
+ >
+ issues.page
+ </Link>
+ </li>
+ <li>
+ <Link
+ className={null}
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/coding_rules"
+ >
+ coding_rules.page
+ </Link>
+ </li>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/profiles"
+ >
+ quality_profiles.page
+ </Link>
+ </li>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/quality_gates"
+ >
+ quality_gates.page
+ </Link>
+ </li>
+ <li>
+ <Link
+ activeClassName="active"
+ className="navbar-admin-link"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/settings"
+ >
+ layout.settings
+ </Link>
+ </li>
+</ul>
+`;
+
exports[`should work with extensions 1`] = `
<ul
className="nav navbar-nav"
diff --git a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js
index 82e5fb84797..1aebb594952 100644
--- a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js
+++ b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js
@@ -25,16 +25,15 @@ import { Link } from 'react-router';
import OrganizationsList from './OrganizationsList';
import { translate } from '../../../helpers/l10n';
import { fetchIfAnyoneCanCreateOrganizations, fetchMyOrganizations } from './actions';
-import { getMyOrganizations, getSettingValue, getCurrentUser } from '../../../store/rootReducer';
+import { getAppState, getMyOrganizations, getSettingValue } from '../../../store/rootReducer';
import type { Organization } from '../../../store/organizations/duck';
-import { isUserAdmin } from '../../../helpers/users';
class UserOrganizations extends React.PureComponent {
mounted: boolean;
props: {
anyoneCanCreate?: { value: string },
- currentUser: Object,
+ canAdmin: boolean,
children?: React.Element<*>,
organizations: Array<Organization>,
fetchIfAnyoneCanCreateOrganizations: () => Promise<*>,
@@ -65,8 +64,7 @@ class UserOrganizations extends React.PureComponent {
const anyoneCanCreate =
this.props.anyoneCanCreate != null && this.props.anyoneCanCreate.value === 'true';
- const canCreateOrganizations =
- !this.state.loading && (anyoneCanCreate || isUserAdmin(this.props.currentUser));
+ const canCreateOrganizations = !this.state.loading && (anyoneCanCreate || this.props.canAdmin);
return (
<div className="account-body account-container">
@@ -101,7 +99,7 @@ class UserOrganizations extends React.PureComponent {
const mapStateToProps = state => ({
anyoneCanCreate: getSettingValue(state, 'sonar.organizations.anyoneCanCreate'),
- currentUser: getCurrentUser(state),
+ canAdmin: getAppState(state).canAdmin,
organizations: getMyOrganizations(state)
});
diff --git a/server/sonar-web/src/main/js/helpers/users.js b/server/sonar-web/src/main/js/helpers/users.js
deleted file mode 100644
index cebcbf556b4..00000000000
--- a/server/sonar-web/src/main/js/helpers/users.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.
- */
-// @flow
-type User = {
- permissions: {
- global: Array<string>
- }
-};
-
-export const isUserAdmin = (user: User): boolean => user.permissions.global.includes('admin');