aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/Gruntfile.coffee1
-rw-r--r--server/sonar-web/src/main/coffee/apps/issues/models/issues.coffee21
-rw-r--r--server/sonar-web/src/main/coffee/components/issue/collections/issues.coffee5
-rw-r--r--server/sonar-web/src/main/coffee/components/issue/templates/issue.hbs17
-rw-r--r--server/sonar-web/src/main/js/apps/nav/global-navbar-view.js1
-rw-r--r--server/sonar-web/src/main/js/apps/nav/templates/nav-global-navbar.hbs2
-rw-r--r--server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs6
-rw-r--r--server/sonar-web/src/main/js/components/common/handlebars-extensions.js15
-rw-r--r--server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer.hbs6
-rw-r--r--server/sonar-web/src/main/js/libs/application.js14
-rw-r--r--server/sonar-web/src/main/js/libs/third-party/md5.js274
-rw-r--r--server/sonar-web/src/main/less/components/source.less7
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb14
-rw-r--r--server/sonar-web/src/test/views/layouts/main.jade11
-rw-r--r--sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java15
15 files changed, 373 insertions, 36 deletions
diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee
index 82a5708b8f9..3f33fd9dc95 100644
--- a/server/sonar-web/Gruntfile.coffee
+++ b/server/sonar-web/Gruntfile.coffee
@@ -66,6 +66,7 @@ module.exports = (grunt) ->
'<%= BUILD_PATH %>/js/libs/third-party/numeral-languages.js'
'<%= BUILD_PATH %>/js/libs/third-party/bootstrap/tooltip.js'
'<%= BUILD_PATH %>/js/libs/third-party/bootstrap/dropdown.js'
+ '<%= BUILD_PATH %>/js/libs/third-party/md5.js'
'<%= BUILD_PATH %>/js/libs/select2-jquery-ui-fix.js'
'<%= BUILD_PATH %>/js/libs/widgets/base.js'
diff --git a/server/sonar-web/src/main/coffee/apps/issues/models/issues.coffee b/server/sonar-web/src/main/coffee/apps/issues/models/issues.coffee
index 08926040335..d98b2632120 100644
--- a/server/sonar-web/src/main/coffee/apps/issues/models/issues.coffee
+++ b/server/sonar-web/src/main/coffee/apps/issues/models/issues.coffee
@@ -43,6 +43,7 @@ define [
project = find r.projects, issue.project
subProject = find r.components, issue.subProject
rule = find r.rules, issue.rule
+ assignee = find r.users, issue.assignee, 'login'
_.extend issue,
index: index
@@ -67,25 +68,9 @@ define [
_.extend issue,
ruleName: rule.name
- if _.isArray(issue.sources) && issue.sources.length > 0
- source = ''
- issue.sources.forEach (line) ->
- source = line[1] if line[0] == issue.line
- _.extend issue, source: source
-
-
- if _.isArray(issue.scm) && issue.scm.length > 0
- scmAuthor = ''
- scmDate = ''
-
- issue.scm.forEach (line) ->
- if line[0] == issue.line
- scmAuthor = line[1]
- scmDate = line[2]
-
+ if assignee
_.extend issue,
- scmAuthor: scmAuthor
- scmDate: scmDate
+ assigneeEmail: assignee.email
issue
diff --git a/server/sonar-web/src/main/coffee/components/issue/collections/issues.coffee b/server/sonar-web/src/main/coffee/components/issue/collections/issues.coffee
index ddce4332d2e..208a06ffb3b 100644
--- a/server/sonar-web/src/main/coffee/components/issue/collections/issues.coffee
+++ b/server/sonar-web/src/main/coffee/components/issue/collections/issues.coffee
@@ -47,6 +47,7 @@ define [
component = find r.components, issue.component
project = find r.projects, issue.project
rule = find r.rules, issue.rule
+ assignee = find r.users, issue.assignee, 'login'
if component
_.extend issue,
@@ -62,4 +63,8 @@ define [
_.extend issue,
ruleName: rule.name
+ if assignee
+ _.extend issue,
+ assigneeEmail: assignee.email
+
issue
diff --git a/server/sonar-web/src/main/coffee/components/issue/templates/issue.hbs b/server/sonar-web/src/main/coffee/components/issue/templates/issue.hbs
index dc47a49ddb9..b27f6b53c81 100644
--- a/server/sonar-web/src/main/coffee/components/issue/templates/issue.hbs
+++ b/server/sonar-web/src/main/coffee/components/issue/templates/issue.hbs
@@ -56,13 +56,20 @@
<div class="issue-meta">
{{#inArray actions "assign"}}
<a class="issue-action issue-action-with-options js-issue-assign">
- <span
- class="issue-meta-label">{{#if assignee}}{{default assigneeName assignee}}{{else}}{{t 'unassigned'}}{{/if}}</span>&nbsp;<i
- class="icon-dropdown"></i>
+ {{#if assignee}}
+ {{#ifShowAvatars}}
+ <span class="text-top">{{avatarHelper assigneeEmail 16}}</span>
+ {{/ifShowAvatars}}
+ {{/if}}
+ <span class="issue-meta-label">{{#if assignee}}{{default assigneeName assignee}}{{else}}{{t 'unassigned'}}{{/if}}</span>&nbsp;<i class="icon-dropdown"></i>
</a>
{{else}}
- <span
- class="issue-meta-label">{{#if assignee}}{{default assigneeName assignee}}{{else}}{{t 'unassigned'}}{{/if}}</span>
+ {{#if assignee}}
+ {{#ifShowAvatars}}
+ <span class="text-top">{{avatarHelper assigneeEmail 16}}</span>
+ {{/ifShowAvatars}}
+ {{/if}}
+ <span class="issue-meta-label">{{#if assignee}}{{default assigneeName assignee}}{{else}}{{t 'unassigned'}}{{/if}}</span>
{{/inArray}}
</div>
diff --git a/server/sonar-web/src/main/js/apps/nav/global-navbar-view.js b/server/sonar-web/src/main/js/apps/nav/global-navbar-view.js
index 9ee43d9fdfe..5a0915e7b20 100644
--- a/server/sonar-web/src/main/js/apps/nav/global-navbar-view.js
+++ b/server/sonar-web/src/main/js/apps/nav/global-navbar-view.js
@@ -85,6 +85,7 @@ define([
return _.extend(Marionette.Layout.prototype.serializeData.apply(this, arguments), {
user: window.SS.user,
userName: window.SS.userName,
+ userEmail: window.SS.userEmail,
isUserAdmin: window.SS.isUserAdmin,
canManageGlobalDashboards: !!window.SS.user,
diff --git a/server/sonar-web/src/main/js/apps/nav/templates/nav-global-navbar.hbs b/server/sonar-web/src/main/js/apps/nav/templates/nav-global-navbar.hbs
index fcaf9cc2672..11284eee4a9 100644
--- a/server/sonar-web/src/main/js/apps/nav/templates/nav-global-navbar.hbs
+++ b/server/sonar-web/src/main/js/apps/nav/templates/nav-global-navbar.hbs
@@ -71,7 +71,7 @@
{{#if user}}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{userName}}&nbsp;<span class="icon-dropdown"></span>
+ {{#ifShowAvatars}}<span class="little-spacer-right">{{avatarHelper userEmail 20}}&nbsp;{{/ifShowAvatars}}</span>{{userName}}&nbsp;<span class="icon-dropdown"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<li>
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 1cd782dd9ed..c3d34d75f53 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
@@ -5,6 +5,12 @@
<a class="js-user-deactivate icon-delete" title="Deactivate" data-toggle="tooltip" href="#"></a>
</div>
+{{#ifShowAvatars}}
+ <div class="display-inline-block text-top big-spacer-right">
+ {{avatarHelper email 36}}
+ </div>
+{{/ifShowAvatars}}
+
<div class="display-inline-block text-top width-30">
<div>
<strong class="js-user-name">{{name}}</strong>
diff --git a/server/sonar-web/src/main/js/components/common/handlebars-extensions.js b/server/sonar-web/src/main/js/components/common/handlebars-extensions.js
index 610d5425dc2..a92f2d19026 100644
--- a/server/sonar-web/src/main/js/components/common/handlebars-extensions.js
+++ b/server/sonar-web/src/main/js/components/common/handlebars-extensions.js
@@ -562,4 +562,19 @@
}
});
+ Handlebars.registerHelper('ifShowAvatars', function (options) {
+ var cond = window.SS && window.SS.lf && window.SS.lf.enableGravatar;
+ return cond ? options.fn(this) : options.inverse(this);
+ });
+
+ Handlebars.registerHelper('avatarHelper', function (email, size) {
+ var emailHash = window.md5((email || '').trim()),
+ url = ('' + window.SS.lf.gravatarServerUrl)
+ .replace('{EMAIL_MD5}', emailHash)
+ .replace('{SIZE}', size);
+ return new Handlebars.SafeString(
+ '<img src="' + url + '" width="' + size + '" height="' + size + '" alt="' + email + '">'
+ );
+ });
+
})();
diff --git a/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer.hbs b/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer.hbs
index 123d21e86a2..1f4c3ffeb19 100644
--- a/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer.hbs
+++ b/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer.hbs
@@ -13,7 +13,11 @@
<td class="source-meta source-line-scm" {{#if line}}data-line-number="{{line}}"{{/if}}>
{{#ifSCMChanged2 ../source line}}
- <div class="source-line-scm-inner" data-author="{{scmAuthor}}"></div>
+ <div class="source-line-scm-inner" data-author="{{scmAuthor}}">
+ {{#gt line 0}}
+ {{avatarHelper scmAuthor 16}}
+ {{/gt}}
+ </div>
{{/ifSCMChanged2}}
</td>
diff --git a/server/sonar-web/src/main/js/libs/application.js b/server/sonar-web/src/main/js/libs/application.js
index 2d16dd4ff5d..6b7fc913488 100644
--- a/server/sonar-web/src/main/js/libs/application.js
+++ b/server/sonar-web/src/main/js/libs/application.js
@@ -549,6 +549,20 @@ function closeModalWindow () {
return params;
};
+
+ /**
+ * Return an md5 hash of a string
+ * @param s
+ * @returns {*}
+ */
+ window.getMD5Hash = function (s) {
+ if (typeof s === 'string') {
+ return window.md5(s.trim());
+ } else {
+ return null;
+ }
+ };
+
})();
(function () {
diff --git a/server/sonar-web/src/main/js/libs/third-party/md5.js b/server/sonar-web/src/main/js/libs/third-party/md5.js
new file mode 100644
index 00000000000..f92ba37a4de
--- /dev/null
+++ b/server/sonar-web/src/main/js/libs/third-party/md5.js
@@ -0,0 +1,274 @@
+/*
+ * JavaScript MD5 1.0.1
+ * https://github.com/blueimp/JavaScript-MD5
+ *
+ * Copyright 2011, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ *
+ * Based on
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*jslint bitwise: true */
+/*global unescape, define */
+
+(function ($) {
+ 'use strict';
+
+ /*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+ function safe_add(x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+ msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+ function bit_rol(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ /*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+ function md5_cmn(q, a, b, x, s, t) {
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
+ }
+ function md5_ff(a, b, c, d, x, s, t) {
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+ }
+ function md5_gg(a, b, c, d, x, s, t) {
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+ }
+ function md5_hh(a, b, c, d, x, s, t) {
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+ }
+ function md5_ii(a, b, c, d, x, s, t) {
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+ }
+
+ /*
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ */
+ function binl_md5(x, len) {
+ /* append padding */
+ x[len >> 5] |= 0x80 << (len % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var i, olda, oldb, oldc, oldd,
+ a = 1732584193,
+ b = -271733879,
+ c = -1732584194,
+ d = 271733878;
+
+ for (i = 0; i < x.length; i += 16) {
+ olda = a;
+ oldb = b;
+ oldc = c;
+ oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i], 7, -680876936);
+ d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
+ d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
+ d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
+ d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
+ d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
+ c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
+ d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
+ c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
+ d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
+ c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
+ d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
+ c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
+ d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
+ d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
+ d = md5_hh(d, a, b, c, x[i], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
+ d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i], 6, -198630844);
+ d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
+ d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
+ d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
+ d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return [a, b, c, d];
+ }
+
+ /*
+ * Convert an array of little-endian words to a string
+ */
+ function binl2rstr(input) {
+ var i,
+ output = '';
+ for (i = 0; i < input.length * 32; i += 8) {
+ output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
+ }
+ return output;
+ }
+
+ /*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+ function rstr2binl(input) {
+ var i,
+ output = [];
+ output[(input.length >> 2) - 1] = undefined;
+ for (i = 0; i < output.length; i += 1) {
+ output[i] = 0;
+ }
+ for (i = 0; i < input.length * 8; i += 8) {
+ output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
+ }
+ return output;
+ }
+
+ /*
+ * Calculate the MD5 of a raw string
+ */
+ function rstr_md5(s) {
+ return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
+ }
+
+ /*
+ * Calculate the HMAC-MD5, of a key and some data (raw strings)
+ */
+ function rstr_hmac_md5(key, data) {
+ var i,
+ bkey = rstr2binl(key),
+ ipad = [],
+ opad = [],
+ hash;
+ ipad[15] = opad[15] = undefined;
+ if (bkey.length > 16) {
+ bkey = binl_md5(bkey, key.length * 8);
+ }
+ for (i = 0; i < 16; i += 1) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+ hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
+ return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
+ }
+
+ /*
+ * Convert a raw string to a hex string
+ */
+ function rstr2hex(input) {
+ var hex_tab = '0123456789abcdef',
+ output = '',
+ x,
+ i;
+ for (i = 0; i < input.length; i += 1) {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F) +
+ hex_tab.charAt(x & 0x0F);
+ }
+ return output;
+ }
+
+ /*
+ * Encode a string as utf-8
+ */
+ function str2rstr_utf8(input) {
+ return unescape(encodeURIComponent(input));
+ }
+
+ /*
+ * Take string arguments and return either raw or hex encoded strings
+ */
+ function raw_md5(s) {
+ return rstr_md5(str2rstr_utf8(s));
+ }
+ function hex_md5(s) {
+ return rstr2hex(raw_md5(s));
+ }
+ function raw_hmac_md5(k, d) {
+ return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));
+ }
+ function hex_hmac_md5(k, d) {
+ return rstr2hex(raw_hmac_md5(k, d));
+ }
+
+ function md5(string, key, raw) {
+ if (!key) {
+ if (!raw) {
+ return hex_md5(string);
+ }
+ return raw_md5(string);
+ }
+ if (!raw) {
+ return hex_hmac_md5(key, string);
+ }
+ return raw_hmac_md5(key, string);
+ }
+
+ if (typeof define === 'function' && define.amd) {
+ define(function () {
+ return md5;
+ });
+ } else {
+ $.md5 = md5;
+ }
+}(this));
diff --git a/server/sonar-web/src/main/less/components/source.less b/server/sonar-web/src/main/less/components/source.less
index 6e02fe6e7ad..c2f8237c638 100644
--- a/server/sonar-web/src/main/less/components/source.less
+++ b/server/sonar-web/src/main/less/components/source.less
@@ -193,13 +193,6 @@
.source-line-scm-inner {
max-width: 40px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-
- &:before {
- content: attr(data-author);
- }
}
.source-line-bar {
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
index 7c8dd530efa..322c7bcbbf8 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
@@ -24,10 +24,16 @@
<script>
var pageLang = '<%= I18n.locale.to_s.gsub(/-/, '_') -%>';
<%# The two lines below mean that before full removal of Rails, we have to find a way to handle config properties %>
- window.SS = typeof window.SS === 'object' ? window.SS : {};
- window.SS.hoursInDay = <%= configuration('sonar.technicalDebt.hoursInDay', 8) %>;
- window.SS.user = '<%= current_user.login if current_user -%>';
- window.SS.userName = '<%= current_user.name if current_user -%>';
+ window.SS = {
+ hoursInDay: <%= configuration('sonar.technicalDebt.hoursInDay', 8) %>,
+ user: '<%= current_user.login if current_user -%>',
+ userName: '<%= current_user.name if current_user -%>',
+ userEmail: '<%= current_user.email if current_user -%>',
+ lf: {
+ enableGravatar: <%= configuration('sonar.lf.enableGravatar', true) %>,
+ gravatarServerUrl: '<%= configuration('sonar.lf.gravatarServerUrl') %>'
+ }
+ };
</script>
<script src="<%= ApplicationController.root_context -%>/js/sonar.js?v=<%= sonar_version -%>"></script>
<script>
diff --git a/server/sonar-web/src/test/views/layouts/main.jade b/server/sonar-web/src/test/views/layouts/main.jade
index 5e4f16cff19..e1891e03b55 100644
--- a/server/sonar-web/src/test/views/layouts/main.jade
+++ b/server/sonar-web/src/test/views/layouts/main.jade
@@ -20,6 +20,7 @@ html
script(src='/js/libs/third-party/numeral-languages.js')
script(src='/js/libs/third-party/bootstrap/tooltip.js')
script(src='/js/libs/third-party/bootstrap/dropdown.js')
+ script(src='/js/libs/third-party/md5.js')
script(src='/js/libs/select2-jquery-ui-fix.js')
script(src='/js/libs/widgets/base.js')
script(src='/js/libs/widgets/widget.js')
@@ -53,6 +54,16 @@ html
jQuery.mockjaxSettings.contentType = 'text/json';
jQuery.mockjaxSettings.responseTime = 50;
jQuery(document).ready(function () { $j('.open-modal').modal(); });
+ window.SS = {
+ hoursInDay: 8,
+ user: '',
+ userName: '',
+ userEmail: '',
+ lf: {
+ enableGravatar: false,
+ gravatarServerUrl: ''
+ }
+ };
script.
requirejs.config({ baseUrl: baseUrl + '/js' });
diff --git a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java
index a6711488e2d..8a19cd775c7 100644
--- a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java
+++ b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java
@@ -59,6 +59,21 @@ public class CorePropertyDefinitions {
.category(CoreProperties.CATEGORY_GENERAL)
.subCategory(CoreProperties.SUBCATEGORY_LOOKNFEEL)
.build(),
+ PropertyDefinition.builder("sonar.lf.enableGravatar")
+ .name("Enable support of gravatars")
+ .description("Gravatars are profile pictures of users based on their email.")
+ .type(PropertyType.BOOLEAN)
+ .defaultValue("true")
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_LOOKNFEEL)
+ .build(),
+ PropertyDefinition.builder("sonar.lf.gravatarServerUrl")
+ .name("Gravatar URL")
+ .description("Optional URL of custom Gravatar service. Accepted variables are {EMAIL_MD5} for MD5 hash of email and {SIZE} for the picture size in pixels.")
+ .defaultValue("https://secure.gravatar.com/avatar/{EMAIL_MD5}.jpg?s={SIZE}&d=identicon")
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_LOOKNFEEL)
+ .build(),
// ISSUES
PropertyDefinition.builder(CoreProperties.DEFAULT_ISSUE_ASSIGNEE)