From cd1f125ac71cdb084103ab9c18be08be84986572 Mon Sep 17 00:00:00 2001 From: Svilen Velikov <51084653+svilenvelikov@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:04:29 +0200 Subject: [PATCH] GDB-11134 fix issues in users and settings view when in cluster mode (#1649) * GDB-11134 fix issues in users and settings view when in cluster mode ## What * Activating free access mode in a cluster in secondary mode results in incorrect state of the checkbox in the ui. ## Why * When trying to activate free access in a node from secondary cluster group, there is 412 error response from the backend which is not properly handled in the UI which results in incorrect state of the checkbox. ## How * Fixed two thing here. First: properly handle the error state to prevent an error in result of incorrect extraction of the error message from the backend response. Second: moved the initialization of the `freeAccess` property in the jwt-auth.service.js to happen after the success response and not before. * ## What * Trying to disable the security while in cluster secondary mode (which is not strictly needed, but the operation fails in this case too) results in weird page reload without change in the checkbox status after that. ## Why * This happens because the reload was actually triggered after each click on the toggle security checkbox, regardless if actually there was a change in the state after the operation. ## How * Fixed by storing a local variable for the security mode before invoking the backend and changed the condition to reload the view only if there was an actual change in the state. --- .../angular/core/services/jwt-auth.service.js | 24 ++--- src/js/angular/security/controllers.js | 95 ++++++++++--------- 2 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/js/angular/core/services/jwt-auth.service.js b/src/js/angular/core/services/jwt-auth.service.js index 0e841a71a..26f2f96e7 100644 --- a/src/js/angular/core/services/jwt-auth.service.js +++ b/src/js/angular/core/services/jwt-auth.service.js @@ -236,21 +236,22 @@ angular.module('graphdb.framework.core.services.jwtauth', [ this.toggleSecurity = function (enabled) { if (enabled !== this.securityEnabled) { - return SecurityRestService.toggleSecurity(enabled).then(function () { - toastr.success($translate.instant('jwt.auth.security.status', {status: ($translate.instant(enabled ? 'enabled.status' : 'disabled.status'))})); - AuthTokenService.clearAuthToken(); - that.initSecurity(); - that.securityEnabled = enabled; - }, function (err) { - toastr.error(err.data, $translate.instant('common.error')); - }); + return SecurityRestService.toggleSecurity(enabled) + .then(function () { + toastr.success($translate.instant('jwt.auth.security.status', {status: ($translate.instant(enabled ? 'enabled.status' : 'disabled.status'))})); + AuthTokenService.clearAuthToken(); + that.initSecurity(); + that.securityEnabled = enabled; + }) + .catch(function (err) { + toastr.error(err.data, $translate.instant('common.error')); + }); } return Promise.resolve(); }; this.toggleFreeAccess = function (enabled, authorities, appSettings, updateFreeAccess) { if (enabled !== this.freeAccess || updateFreeAccess) { - this.freeAccess = enabled; if (enabled) { this.freeAccessPrincipal = {authorities: authorities, appSettings: appSettings}; } else { @@ -261,13 +262,14 @@ angular.module('graphdb.framework.core.services.jwtauth', [ authorities: authorities, appSettings: appSettings }).then(function () { + this.freeAccess = enabled; if (updateFreeAccess) { toastr.success($translate.instant('jwt.auth.free.access.updated.msg')); } else { toastr.success($translate.instant('jwt.auth.free.access.status', {status: ($translate.instant(enabled ? 'enabled.status' : 'disabled.status'))})); } - }, function (err) { - toastr.error(err.data.error.message, $translate.instant('common.error')); + }).catch((err) => { + toastr.error(err.data, $translate.instant('common.error')); }); $rootScope.$broadcast('securityInit', this.securityEnabled, this.hasExplicitAuthentication(), this.freeAccess); } diff --git a/src/js/angular/security/controllers.js b/src/js/angular/security/controllers.js index e34db06ce..c063616ad 100644 --- a/src/js/angular/security/controllers.js +++ b/src/js/angular/security/controllers.js @@ -216,9 +216,12 @@ securityCtrl.controller('UsersCtrl', ['$scope', '$uibModal', 'toastr', '$window' }); $scope.toggleSecurity = function () { - $jwtAuth.toggleSecurity(!$jwtAuth.isSecurityEnabled()) + const isSecurityEnabled = $jwtAuth.isSecurityEnabled(); + $jwtAuth.toggleSecurity(!isSecurityEnabled) .then(() => { - if ($jwtAuth.isSecurityEnabled()) { + // reload UI only if security status has changed + // TODO: Not sure if we really need to reload the page here. The UI state is updated just fine. But maybe the reload is needed for something else? + if (isSecurityEnabled !== $jwtAuth.isSecurityEnabled()) { $window.location.reload(); } }); @@ -227,60 +230,64 @@ securityCtrl.controller('UsersCtrl', ['$scope', '$uibModal', 'toastr', '$window' $scope.toggleFreeAccess = function (updateFreeAccess) { if (!$jwtAuth.isFreeAccessEnabled() || ($jwtAuth.isFreeAccessEnabled() && updateFreeAccess)) { SecurityRestService.getFreeAccess().then(function (res) { - let authorities = res.data.authorities; - let appSettings = res.data.appSettings || { + const authorities = res.data.authorities; + const appSettings = res.data.appSettings || { 'DEFAULT_SAMEAS': true, 'DEFAULT_INFERENCE': true, 'EXECUTE_COUNT': true, 'IGNORE_SHARED_QUERIES': false, 'DEFAULT_VIS_GRAPH_SCHEMA': true }; - const modalInstance = $uibModal.open({ - templateUrl: 'js/angular/security/templates/modal/default-authorities.html', - controller: 'DefaultAuthoritiesCtrl', - resolve: { - data: function () { - return { - // converts the array rights to hash ones. why, oh, why do we have both formats? - defaultAuthorities: function () { - const defaultAuthorities = { - [READ_REPO]: {}, - [WRITE_REPO]: {} - }; - // We might have old (no longer existing) repositories so we have to check that - const repoIds = _.mapKeys($scope.getRepositories(), function (r) { - return createUniqueKey(r); - }); - _.each(authorities, function (a) { - // indexOf works in IE 11, startsWith doesn't - if (a.indexOf(WRITE_REPO_PREFIX) === 0) { - if (repoIds.hasOwnProperty(a.substr(11))) { - defaultAuthorities[WRITE_REPO][a.substr(11)] = true; - } - } else if (a.indexOf(READ_REPO_PREFIX) === 0) { - if (repoIds.hasOwnProperty(a.substr(10))) { - defaultAuthorities[READ_REPO][a.substr(10)] = true; - } - } - }); - return defaultAuthorities; - }, - appSettings: appSettings - }; - } - } - }); - modalInstance.result.then(function (data) { - authorities = data.authorities; - appSettings = data.appSettings; - $jwtAuth.toggleFreeAccess(updateFreeAccess || !$jwtAuth.isFreeAccessEnabled(), authorities, appSettings, updateFreeAccess); - }); + configureFreeAccess(appSettings, authorities, updateFreeAccess); }); } else { $jwtAuth.toggleFreeAccess(!$jwtAuth.isFreeAccessEnabled(), []); } }; + const configureFreeAccess = (appSettings, authorities, updateFreeAccess) => { + const modalInstance = $uibModal.open({ + templateUrl: 'js/angular/security/templates/modal/default-authorities.html', + controller: 'DefaultAuthoritiesCtrl', + resolve: { + data: function () { + return { + // converts the array rights to hash ones. why, oh, why do we have both formats? + defaultAuthorities: function () { + const defaultAuthorities = { + [READ_REPO]: {}, + [WRITE_REPO]: {} + }; + // We might have old (no longer existing) repositories so we have to check that + const repoIds = _.mapKeys($scope.getRepositories(), function (r) { + return createUniqueKey(r); + }); + _.each(authorities, function (a) { + // indexOf works in IE 11, startsWith doesn't + if (a.indexOf(WRITE_REPO_PREFIX) === 0) { + if (repoIds.hasOwnProperty(a.substr(11))) { + defaultAuthorities[WRITE_REPO][a.substr(11)] = true; + } + } else if (a.indexOf(READ_REPO_PREFIX) === 0) { + if (repoIds.hasOwnProperty(a.substr(10))) { + defaultAuthorities[READ_REPO][a.substr(10)] = true; + } + } + }); + return defaultAuthorities; + }, + appSettings: appSettings + }; + } + } + }); + modalInstance.result.then(function (data) { + authorities = data.authorities; + appSettings = data.appSettings; + $jwtAuth.toggleFreeAccess(updateFreeAccess || !$jwtAuth.isFreeAccessEnabled(), authorities, appSettings, updateFreeAccess); + }); + }; + $scope.editFreeAccess = function () { $scope.toggleFreeAccess(true); };