From 51186397d73fd3ffd4aad333c47c05d62571a929 Mon Sep 17 00:00:00 2001 From: Torkel Odegaard Date: Wed, 22 Jan 2014 22:19:58 +0100 Subject: [PATCH] Fixes #16 (Basic Authentication), set graphiteUrl: http://username:password@domain.com and it should work, but requires special CORS settings in apache2 --- src/app/components/require.config.js | 5 +++++ src/app/components/settings.js | 17 +++++++++++++++-- src/app/services/graphite/graphiteSrv.js | 24 ++++++++++++++++++------ src/config.js | 5 +++++ src/vendor/crypto.min.js | 10 ++++++++++ 5 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/vendor/crypto.min.js diff --git a/src/app/components/require.config.js b/src/app/components/require.config.js index 15bc2b297bd..d1c036d8b0b 100644 --- a/src/app/components/require.config.js +++ b/src/app/components/require.config.js @@ -21,6 +21,7 @@ require.config({ timepicker: '../vendor/angular/timepicker', datepicker: '../vendor/angular/datepicker', bindonce: '../vendor/angular/bindonce', + crypto: '../vendor/crypto.min', underscore: 'components/underscore.extended', 'underscore-src': '../vendor/underscore', @@ -49,6 +50,10 @@ require.config({ exports: '_' }, + crypto: { + exports: 'Crypto' + }, + angular: { deps: ['jquery','config'], exports: 'angular' diff --git a/src/app/components/settings.js b/src/app/components/settings.js index 43040657e3d..13ed33468ea 100644 --- a/src/app/components/settings.js +++ b/src/app/components/settings.js @@ -1,5 +1,8 @@ -define(['underscore'], -function (_) { +define([ + 'underscore', + 'crypto', +], +function (_, crypto) { "use strict"; return function Settings (options) { @@ -24,6 +27,16 @@ function (_) { settings[key] = typeof options[key] !== 'undefined' ? options[key] : defaults[key]; }); + var url = settings.graphiteUrl; + var passwordAt = url.indexOf('@'); + if (passwordAt > 0) { + var userStart = url.indexOf('//') + 2; + var userAndPassword = url.substring(userStart, passwordAt); + var bytes = crypto.charenc.Binary.stringToBytes(userAndPassword); + var base64 = crypto.util.bytesToBase64(bytes); + settings.graphiteBasicAuth = base64; + } + return settings; }; }); diff --git a/src/app/services/graphite/graphiteSrv.js b/src/app/services/graphite/graphiteSrv.js index 9afe082bb20..9a11eab5a21 100644 --- a/src/app/services/graphite/graphiteSrv.js +++ b/src/app/services/graphite/graphiteSrv.js @@ -2,7 +2,7 @@ define([ 'angular', 'underscore', 'jquery', - 'config' + 'config', ], function (angular, _, $, config) { 'use strict'; @@ -22,11 +22,13 @@ function (angular, _, $, config) { var params = buildGraphitePostParams(graphOptions); - return $http({ + return doGraphiteRequest({ method: 'POST', url: config.graphiteUrl + '/render/', data: params.join('&'), - headers: {'Content-Type': 'application/x-www-form-urlencoded'} + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + } }); } catch(err) { @@ -76,7 +78,7 @@ function (angular, _, $, config) { } var url = config.graphiteUrl + '/metrics/find/?query=' + interpolated; - return $http.get(url) + return doGraphiteRequest({method: 'GET', url: url}) .then(function(results) { return _.map(results.data, function(metric) { return { @@ -89,7 +91,7 @@ function (angular, _, $, config) { this.listDashboards = function(query) { var url = config.graphiteUrl + '/dashboard/find/'; - return $http.get(url, {params: {query: query || ''}}) + return doGraphiteRequest({ method: 'GET', url: url, params: {query: query || ''} }) .then(function(results) { return results.data.dashboards; }); @@ -97,9 +99,19 @@ function (angular, _, $, config) { this.loadDashboard = function(dashName) { var url = config.graphiteUrl + '/dashboard/load/' + encodeURIComponent(dashName); - return $http.get(url); + return doGraphiteRequest({method: 'GET', url: url}); }; + function doGraphiteRequest(options) { + if (config.graphiteBasicAuth) { + options.withCredentials = true; + options.headers = options.headers || {}; + options.headers.Authorization = 'Basic ' + config.graphiteBasicAuth; + } + + return $http(options); + } + function buildGraphitePostParams(options) { var clean_options = []; var graphite_options = ['target', 'targets', 'from', 'until', 'rawData', 'format', 'maxDataPoints']; diff --git a/src/config.js b/src/config.js index afbc6a7b824..35abc565831 100644 --- a/src/config.js +++ b/src/config.js @@ -11,6 +11,11 @@ function (Settings) { elasticsearch: "http://"+window.location.hostname+":9200", + /** + * For Basic authentication use: http://username:password@domain.com + * Basic authentication requires special nginx or apache2 headers for cross origin comain to work + * Check install documentation on github + */ graphiteUrl: "http://"+window.location.hostname+":8080", default_route: '/dashboard/file/default.json', diff --git a/src/vendor/crypto.min.js b/src/vendor/crypto.min.js new file mode 100644 index 00000000000..f97dcd63ac9 --- /dev/null +++ b/src/vendor/crypto.min.js @@ -0,0 +1,10 @@ +/* + * Crypto-JS v2.5.3 + * http://code.google.com/p/crypto-js/ + * (c) 2009-2012 by Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ +(typeof Crypto=="undefined"||!Crypto.util)&&function(){var e=window.Crypto={},g=e.util={rotl:function(a,b){return a<>>32-b},rotr:function(a,b){return a<<32-b|a>>>b},endian:function(a){if(a.constructor==Number)return g.rotl(a,8)&16711935|g.rotl(a,24)&4278255360;for(var b=0;b0;a--)b.push(Math.floor(Math.random()*256));return b},bytesToWords:function(a){for(var b=[],c=0,d=0;c>>5]|=(a[c]&255)<< +24-d%32;return b},wordsToBytes:function(a){for(var b=[],c=0;c>>5]>>>24-c%32&255);return b},bytesToHex:function(a){for(var b=[],c=0;c>>4).toString(16)),b.push((a[c]&15).toString(16));return b.join("")},hexToBytes:function(a){for(var b=[],c=0;c>>6*(3-e)&63)):b.push("=");return b.join("")},base64ToBytes:function(a){if(typeof atob=="function")return f.stringToBytes(atob(a));for(var a=a.replace(/[^A-Z0-9+\/]/ig,""),b=[],c=0,d=0;c>> +6-d*2);return b}},e=e.charenc={};e.UTF8={stringToBytes:function(a){return f.stringToBytes(unescape(encodeURIComponent(a)))},bytesToString:function(a){return decodeURIComponent(escape(f.bytesToString(a)))}};var f=e.Binary={stringToBytes:function(a){for(var b=[],c=0;c