diff --git a/resources/frontend_client/app/controllers.js b/resources/frontend_client/app/controllers.js index c4597cbc03ae58da2fc969dfebc522767f7a408a..a018e9e6d649f008bd5563b643c6d5948fdaf08f 100644 --- a/resources/frontend_client/app/controllers.js +++ b/resources/frontend_client/app/controllers.js @@ -10,6 +10,7 @@ var CorvusControllers = angular.module('corvus.controllers', ['corvus.services', CorvusControllers.controller('Corvus', ['$scope', '$location', 'CorvusCore', 'CorvusAlert', 'AppState', function($scope, $location, CorvusCore, CorvusAlert, AppState) { var clearState = function() { + $scope.siteName = undefined; $scope.user = undefined; $scope.userIsSuperuser = false; }; @@ -23,6 +24,11 @@ CorvusControllers.controller('Corvus', ['$scope', '$location', 'CorvusCore', 'Co $scope.alerts = CorvusAlert.alerts; + $scope.$on("appstate:site-settings", function(event, settings) { + // change in global settings + $scope.siteName = settings['site-name'].value; + }); + $scope.$on("appstate:user", function(event, user) { // change in current user $scope.user = user; diff --git a/resources/frontend_client/app/services.js b/resources/frontend_client/app/services.js index 3b398524256ee393fcc025694c0f9b9d94dedc6a..2fb84b2ab7a0087294b068fee6b23160e721db9f 100644 --- a/resources/frontend_client/app/services.js +++ b/resources/frontend_client/app/services.js @@ -5,8 +5,8 @@ var CorvusServices = angular.module('corvus.services', ['http-auth-interceptor', 'ipCookie', 'corvus.core.services']); -CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', 'ipCookie', 'Session', 'User', - function($rootScope, $q, $location, $timeout, ipCookie, Session, User) { +CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', 'ipCookie', 'Session', 'User', 'Settings', + function($rootScope, $q, $location, $timeout, ipCookie, Session, User, Settings) { // this is meant to be a global service used for keeping track of our overall app state // we fire 2 events as things change in the app // 1. appstate:user @@ -19,6 +19,7 @@ CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', model: { setupToken: null, currentUser: null, + siteSettings: null, appContext: 'unknown' }, @@ -28,6 +29,9 @@ CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', var deferred = $q.defer(); initPromise = deferred.promise; + // grab our global settings + service.refreshSiteSettings(); + // just make sure we grab the current user service.refreshCurrentUser().then(function(user) { deferred.resolve(); @@ -42,6 +46,7 @@ CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', clearState: function() { currentUserPromise = null; service.model.currentUser = null; + service.model.siteSettings = null; // clear any existing session cookies if they exist ipCookie.remove('metabase.SESSION_ID'); @@ -66,6 +71,23 @@ CorvusServices.factory('AppState', ['$rootScope', '$q', '$location', '$timeout', return currentUserPromise; }, + refreshSiteSettings: function() { + + var settingsRefresh = Settings.list(function(result) { + + var settings = _.indexBy(result, 'key'); + + service.model.siteSettings = settings; + + $rootScope.$broadcast('appstate:site-settings', settings); + + }, function(error) { + console.log('unable to get site settings', error); + }); + + return settingsRefresh.$promise; + }, + // This function performs whatever state cleanup and next steps are required when a user tries to access // something they are not allowed to. invalidAccess: function(user, url, message) { @@ -827,6 +849,33 @@ CoreServices.factory('User', ['$resource', '$cookies', function($resource, $cook }); }]); +CoreServices.factory('Settings', ['$resource', function($resource) { + return $resource('/api/setting', {}, { + list: { + url: '/api/setting', + method: 'GET', + isArray: true + }, + + // POST endpoint handles create + update in this case + put: { + url: '/api/setting/:key', + method: 'PUT', + params: { + key: '@key' + } + }, + + delete: { + url: '/api/setting/:key', + method: 'DELETE', + params: { + key: '@key' + } + } + }); +}]); + CoreServices.factory('PermissionViolation', ['$resource', '$cookies', function($resource, $cookies) { return $resource('/api/permissions_violation', {}, { create: { diff --git a/resources/frontend_client/index.html b/resources/frontend_client/index.html index 1c0992c87ab28a32e1b316fdf084110f0b4513eb..8058fd80e76439061fe6f1f4199c9b1423966259 100644 --- a/resources/frontend_client/index.html +++ b/resources/frontend_client/index.html @@ -21,20 +21,10 @@ <!-- MAIN NAV --> <nav class="CoreNav clearfix" ng-show="nav === 'main'"> <div class="col col-sm-12"> - <div class="NavItem float-left" ng-if="!user.is_multi_org"> - <span class="NavItem-text">{{currentOrg.name}}</span> - </div> - <div class="NavItem Dropdown float-left" dropdown on-toggle="toggled(open)" ng-if="user.is_multi_org"> - <span dropdown-toggle> - <span class="NavItem-text" ng-bind="currentOrg.name"></span> - <cv-chevron-down-icon width="8px" height="8px"></cv-chevron-down-icon> - </span> - <ul class="Dropdown-content"> - <li ng-repeat="organization in userMemberOf"> - <a class="link block py1" href="#" ng-click="changeCurrOrg(organization.slug)">{{organization.name}}</a> - </li> - </ul> + <div class="NavItem float-left"> + <span class="NavItem-text">{{siteName}}</span> </div> + <ul class="float-left ml4"> <li class="inline-block"> <a class="NavItem NavItem-withIcon" href="/dash/" selectable-nav-item="dashboards"> @@ -61,6 +51,7 @@ </a> </li> </ul> + <ul class="float-right"> <li class="Dropdown inline-block" dropdown on-toggle="toggled(open)"> <a class="NavItem" selectable-nav-item="settings" dropdown-toggle> diff --git a/src/metabase/api/setting.clj b/src/metabase/api/setting.clj index 88a5574b9af8042e4d24c592f7052b165e2341d4..c14f2e3d7b0db7dd1e738ced307e29e2ff9bc2ce 100644 --- a/src/metabase/api/setting.clj +++ b/src/metabase/api/setting.clj @@ -5,10 +5,12 @@ (metabase.models [setting :as setting]))) (defendpoint GET "/" - "Get all `Settings` and their values. You must be a superuser to do this." + "Get all `Settings` and their values. Superusers get all settings, normal users get public settings only." [] - (check-superuser) - (setting/all-with-descriptions)) + (if (:is_superuser @*current-user*) + (setting/all-with-descriptions) + ;; TODO - we could make this a little more dynamic + (filter #(= (:key %) :site-name) (setting/all-with-descriptions)))) (defendpoint GET "/:key" "Fetch a single `Setting`. You must be a superuser to do this." diff --git a/test/metabase/api/setting_test.clj b/test/metabase/api/setting_test.clj index 6ca73cea4f07a7c3aec521ac6d5202740ba3f64f..ad30afbab5b4a0ba6f1db1a1e22920153522367b 100644 --- a/test/metabase/api/setting_test.clj +++ b/test/metabase/api/setting_test.clj @@ -26,8 +26,12 @@ (fetch-all-settings))) ;; Check that a non-superuser can't read settings -(expect "You don't have permissions to do that." - ((user->client :rasta) :get 403 "setting")) +(expect + [{:value nil + :key "site-name" + :description "The name used for this instance of Metabase." + :default "Metabase"}] + ((user->client :rasta) :get 200 "setting")) ;; ## GET /api/setting/:key