From: Stas Vilchik Date: Wed, 30 Mar 2016 08:09:32 +0000 (+0200) Subject: SONAR-7238 Display external identity information on user X-Git-Tag: 5.5-M12~23 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=737b9fdfcc2cd876c34620a9cc228fe760366c7b;p=sonarqube.git SONAR-7238 Display external identity information on user --- diff --git a/server/sonar-web/src/main/js/api/users.js b/server/sonar-web/src/main/js/api/users.js index ec4b778c623..6c00ea84945 100644 --- a/server/sonar-web/src/main/js/api/users.js +++ b/server/sonar-web/src/main/js/api/users.js @@ -34,3 +34,8 @@ export function changePassword (login, password, previousPassword) { return post(url, data); } + +export function getIdentityProviders () { + const url = window.baseUrl + '/api/users/identity_providers'; + return getJSON(url); +} diff --git a/server/sonar-web/src/main/js/apps/account/components/UserCard.js b/server/sonar-web/src/main/js/apps/account/components/UserCard.js index 0c848116e26..b680781a718 100644 --- a/server/sonar-web/src/main/js/apps/account/components/UserCard.js +++ b/server/sonar-web/src/main/js/apps/account/components/UserCard.js @@ -20,6 +20,7 @@ import React from 'react'; import { IndexLink } from 'react-router'; +import UserExternalIdentity from './UserExternalIdentity'; import Avatar from '../../../components/shared/avatar'; export default function UserCard ({ user }) { @@ -35,6 +36,11 @@ export default function UserCard ({ user }) {

{user.name}

{user.login} + {!user.local && ( + + + + )}
{user.email}
diff --git a/server/sonar-web/src/main/js/apps/account/components/UserExternalIdentity.js b/server/sonar-web/src/main/js/apps/account/components/UserExternalIdentity.js new file mode 100644 index 00000000000..c26d0418270 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/UserExternalIdentity.js @@ -0,0 +1,88 @@ +/* + * 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 { getIdentityProviders } from '../../../api/users'; + +export default class UserExternalIdentity extends React.Component { + state = { + loading: true + }; + + componentDidMount () { + this.mounted = true; + this.fetchIdentityProviders(); + } + + componentDidUpdate (nextProps) { + if (nextProps.user !== this.props.user) { + this.this.fetchIdentityProviders(); + } + } + + componentWillUnmount () { + this.mounted = false; + } + + fetchIdentityProviders () { + this.setState({ loading: true }); + getIdentityProviders() + .then(r => r.identityProviders) + .then(providers => { + if (this.mounted) { + const identityProvider = providers + .find(provider => provider.key === this.props.user.externalProvider); + this.setState({ loading: false, identityProvider }); + } + }) + .catch(() => { + if (this.mounted) { + this.setState({ loading: false }); + } + }); + } + + render () { + const { user } = this.props; + const { loading, identityProvider } = this.state; + + if (loading) { + return null; + } + + if (!identityProvider) { + return ( + + {user.externalProvider}{': '}{user.externalIdentity} + + ); + } + + return ( +
+ + {' '} + {user.externalIdentity} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/users/app.js b/server/sonar-web/src/main/js/apps/users/app.js index f8d25051478..fcbe54cafb8 100644 --- a/server/sonar-web/src/main/js/apps/users/app.js +++ b/server/sonar-web/src/main/js/apps/users/app.js @@ -18,15 +18,18 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Marionette from 'backbone.marionette'; + import Layout from './layout'; import Users from './users'; import HeaderView from './header-view'; import SearchView from './search-view'; import ListView from './list-view'; import ListFooterView from './list-footer-view'; +import { getIdentityProviders } from '../../api/users'; const App = new Marionette.Application(); -const init = function () { + +const init = function (providers) { const options = window.sonarqube; // Layout @@ -45,7 +48,7 @@ const init = function () { this.layout.searchRegion.show(this.searchView); // List View - this.listView = new ListView({ collection: this.users }); + this.listView = new ListView({ collection: this.users, providers }); this.layout.listRegion.show(this.listView); // List Footer View @@ -57,7 +60,7 @@ const init = function () { }; App.on('start', function () { - init.call(App); + getIdentityProviders().then(r => init.call(App, r.identityProviders)); }); window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/users/list-item-view.js b/server/sonar-web/src/main/js/apps/users/list-item-view.js index 6e06fd37557..e5b45bdaba7 100644 --- a/server/sonar-web/src/main/js/apps/users/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-item-view.js @@ -128,9 +128,16 @@ export default Marionette.ItemView.extend({ serializeData () { const scmAccounts = this.model.get('scmAccounts'); const scmAccountsLimit = scmAccounts.length > this.scmLimit ? this.scmLimit - 1 : this.scmLimit; + const groups = this.model.get('groups'); const groupsLimit = groups.length > this.groupsLimit ? this.groupsLimit - 1 : this.groupsLimit; + + const externalProvider = this.model.get('externalProvider'); + const identityProvider = this.model.get('local') ? null : + this.options.providers.find(provider => externalProvider === provider.key); + return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { + identityProvider, firstScmAccounts: _.first(scmAccounts, scmAccountsLimit), moreScmAccountsCount: scmAccounts.length - scmAccountsLimit, firstGroups: _.first(groups, groupsLimit), diff --git a/server/sonar-web/src/main/js/apps/users/list-view.js b/server/sonar-web/src/main/js/apps/users/list-view.js index 90f212af173..3bd5fd9060b 100644 --- a/server/sonar-web/src/main/js/apps/users/list-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-view.js @@ -33,6 +33,10 @@ export default Marionette.CompositeView.extend({ 'sync': 'hideLoading' }, + childViewOptions () { + return { providers: this.options.providers }; + }, + showLoading () { this.$el.addClass('new-loading'); }, diff --git a/server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs b/server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs index fb5987fbbd8..d59d649d1c8 100644 --- a/server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs +++ b/server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs @@ -9,7 +9,23 @@ {{name}} {{login}} -
{{email}}
+ + {{#if email}} +
{{email}}
+ {{/if}} + + {{#unless local}} +
+ {{#if identityProvider}} +
+ + {{externalIdentity}} +
+ {{else}} + {{externalProvider}}: {{externalIdentity}} + {{/if}} +
+ {{/unless}} @@ -46,7 +62,9 @@ - + {{#if local}} + + {{/if}} diff --git a/server/sonar-web/src/main/less/components/ui.less b/server/sonar-web/src/main/less/components/ui.less index 15f4bb163b5..a8916cb5e12 100644 --- a/server/sonar-web/src/main/less/components/ui.less +++ b/server/sonar-web/src/main/less/components/ui.less @@ -302,3 +302,13 @@ .flash-heavy.in { background-color: #ffe456; } + + +.identity-provider { + display: inline-block; + line-height: 14px; + padding: 3px 5px; + border-radius: 3px; + font-size: @smallFontSize; + color: #fff; +}