Просмотр исходного кода

Fixes #16 (Basic Authentication), set graphiteUrl: http://username:password@domain.com and it should work, but requires special CORS settings in apache2

Torkel Odegaard 12 лет назад
Родитель
Сommit
51186397d7

+ 5 - 0
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'

+ 15 - 2
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;
   };
 });

+ 18 - 6
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'];

+ 5 - 0
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',

+ 10 - 0
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<<b|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;b<a.length;b++)a[b]=g.endian(a[b]);return a},randomBytes:function(a){for(var b=[];a>0;a--)b.push(Math.floor(Math.random()*256));return b},bytesToWords:function(a){for(var b=[],c=0,d=0;c<a.length;c++,d+=8)b[d>>>5]|=(a[c]&255)<<
+24-d%32;return b},wordsToBytes:function(a){for(var b=[],c=0;c<a.length*32;c+=8)b.push(a[c>>>5]>>>24-c%32&255);return b},bytesToHex:function(a){for(var b=[],c=0;c<a.length;c++)b.push((a[c]>>>4).toString(16)),b.push((a[c]&15).toString(16));return b.join("")},hexToBytes:function(a){for(var b=[],c=0;c<a.length;c+=2)b.push(parseInt(a.substr(c,2),16));return b},bytesToBase64:function(a){if(typeof btoa=="function")return btoa(f.bytesToString(a));for(var b=[],c=0;c<a.length;c+=3)for(var d=a[c]<<16|a[c+1]<<
+8|a[c+2],e=0;e<4;e++)c*8+e*6<=a.length*8?b.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>>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<a.length;d=++c%4)d!=0&&b.push(("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(c-1))&Math.pow(2,-2*d+8)-1)<<d*2|"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(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<a.length;c++)b.push(a.charCodeAt(c)&255);return b},bytesToString:function(a){for(var b=[],c=0;c<a.length;c++)b.push(String.fromCharCode(a[c]));return b.join("")}}}();