From 71fc765d011f1ff8fd0f7a5a7f0f8b82d2663fcb Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Thu, 14 Mar 2019 16:39:49 +0100 Subject: [PATCH] WIP - Inherits Conf.pm (#1661) --- _example/conf/lmConf-1.json | 4 - .../Lemonldap/NG/Common/Conf/DefaultValues.pm | 1 + .../lib/Lemonldap/NG/Manager.pm | 2 +- .../lib/Lemonldap/NG/Manager/Attributes.pm | 4 + .../Lemonldap/NG/Manager/Build/Attributes.pm | 5 + .../lib/Lemonldap/NG/Manager/Viewer.pm | 102 +----- .../site/coffee/viewer.coffee | 319 +----------------- .../site/htdocs/static/forms/home.html | 4 + .../site/templates/viewer.tpl | 19 +- lemonldap-ng-manager/t/80-attributes.t | 2 + 10 files changed, 36 insertions(+), 426 deletions(-) diff --git a/_example/conf/lmConf-1.json b/_example/conf/lmConf-1.json index 4a5c07426..8f31fd436 100644 --- a/_example/conf/lmConf-1.json +++ b/_example/conf/lmConf-1.json @@ -119,10 +119,6 @@ "namespace" : "lemonldap-ng-sessions" }, "locationRules" : { - "auth.example.com" : { - "(?#checkUser)/checkuser" : "$uid eq \"dwho\"", - "default" : "deny" - }, "manager.__DNSDOMAIN__" : { "(?#Configuration)^/(manager\\.html|conf/)" : "$uid eq \"dwho\"", "(?#Notifications)/notifications" : "$uid eq \"dwho\" or $uid eq \"rtyler\"", diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm index a80a441a8..284f09e8b 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm @@ -296,6 +296,7 @@ sub defaultValues { 'useRedirectOnError' => 1, 'useSafeJail' => 1, 'utotp2fActivation' => 0, + 'viewerAllowDiff' => 1, 'viewerHiddenPK' => 'virtualHosts', 'webIDAuthnLevel' => 1, 'webIDExportedVars' => {}, diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm index db6f37c11..02af21692 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm @@ -133,7 +133,7 @@ sub init { } sub tplParams { - return ( VERSION => $VERSION, ); + return ( VERSION => $VERSION, ALLOWDIFF => 0 ); } sub javascript { diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm index 0003db09d..d36ed602c 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm @@ -3558,6 +3558,10 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a- ], 'type' => 'select' }, + 'viewerAllowDiff' => { + 'default' => 1, + 'type' => 'bool' + }, 'viewerHiddenPK' => { 'default' => 'virtualHosts', 'type' => 'text' diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm index fd9bd527e..d3d1c092e 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm @@ -922,6 +922,11 @@ sub attributes { documentation => 'ConfTree hidden primary keys', flags => 'm', }, + viewerAllowDiff => { + type => 'bool', + default => 1, + documentation => 'Allow configuration comparator', + }, # Notification oldNotifFormat => { diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Viewer.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Viewer.pm index 80e419001..4e9d086ee 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Viewer.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Viewer.pm @@ -17,7 +17,7 @@ use URI::URL; use feature 'state'; -extends 'Lemonldap::NG::Common::Conf::RESTServer'; +extends 'Lemonldap::NG::Manager::Conf'; our $VERSION = '2.0.3'; @@ -52,18 +52,6 @@ sub addRoutes { # READ # Special keys - # ->addRoute( - # view => { - # ':cfgNum' => [ - # qw(virtualHosts samlIDPMetaDataNodes samlSPMetaDataNodes - # applicationList oidcOPMetaDataNodes oidcRPMetaDataNodes - # casSrvMetaDataNodes casAppMetaDataNodes - # authChoiceModules grantSessionRules combModules - # openIdIDPList) - # ] - # }, - # ['GET'] - # ) ->addRoute( view => { ':cfgNum' => \@enabledPK @@ -72,102 +60,22 @@ sub addRoutes { ) # Other keys - ->addRoute( view => { ':cfgNum' => { '*' => 'getKey' } }, ['GET'] ) - - # Difference between confs - ->addRoute( diff => { ':conf1' => { ':conf2' => 'diff' } } ) - ->addRoute( 'diff.html', undef, ['GET'] ); + ->addRoute( view => { ':cfgNum' => { '*' => 'getKey' } }, ['GET'] ); } -##@method public PSGI-JSON-response prx() -# Load file using posted URL and return its content -# -#@return PSGI JSON response sub prx { my ( $self, $req, @others ) = @_; - return $self->sendError( $req, 'There is no subkey for "prx"', 400 ) - if (@others); - my $query = $req->jsonBodyToObj; - return $self->sendError( $req, 'Missing parameter', 400 ) - unless ( $query->{url} ); - return $self->sendError( $req, 'Bad parameter', 400 ) - unless ( $query->{url} =~ m#^(?:f|ht)tps?://\w# ); - $self->ua->timeout(10); - - my $response = $self->ua->get( $query->{url} ); - unless ( $response->code == 200 ) { - return $self->sendError( $req, - $response->code . " (" . $response->message . ")", 400 ); - } - unless ( $response->header('Content-Type') =~ - m#^(?:application/json|(?:application|text)/.*xml).*$# ) - { - return $self->sendError( $req, - 'Content refused for security reason (neither XML or JSON)', 400 ); - } - return $self->sendJSONresponse( $req, { content => $response->content } ); + $self->SUPER::prx( $req, @others ); } -###################### -# IV. Upload methods # -###################### - -# - getConfByNum: override SUPER method to be able to use Zero - sub getConfByNum { my ( $self, $cfgNum, @args ) = @_; - unless ( %{ $self->currentConf } - and $cfgNum == $self->currentConf->{cfgNum} ) - { - my $tmp; - if ( $cfgNum == 0 ) { - require Lemonldap::NG::Manager::Conf::Zero; - $tmp = Lemonldap::NG::Manager::Conf::Zero::zeroConf(); - $self->currentConf($tmp); - } - else { - $tmp = $self->SUPER::getConfByNum( $cfgNum, @args ); - return undef unless ( defined $tmp ); - } - } - return $cfgNum; + $self->SUPER::getConfByNum( $cfgNum, @args ); } sub diff { my ( $self, $req, @path ) = @_; - return $self->sendError( $req, 'to many arguments in path info', 400 ) - if (@path); - my @cfgNum = - ( scalar( $req->param('conf1') ), scalar( $req->param('conf2') ) ); - my @conf; - $self->logger->debug(" Loading confs"); - - # Load the 2 configurations - for ( my $i = 0 ; $i < 2 ; $i++ ) { - if ( %{ $self->currentConf } - and $cfgNum[$i] == $self->currentConf->{cfgNum} ) - { - $conf[$i] = $self->currentConf; - } - else { - $conf[$i] = $self->confAcc->getConf( - { cfgNum => $cfgNum[$i], raw => 1, noCache => 1 } ); - return $self->sendError( - $req, -"Configuration $cfgNum[$i] not available $Lemonldap::NG::Common::Conf::msg", - 400 - ) unless ( $conf[$i] ); - } - } - require Lemonldap::NG::Manager::Conf::Diff; - return $self->sendJSONresponse( - $req, - [ - $self->Lemonldap::NG::Manager::Conf::Diff::diff( - $conf[0], $conf[1] - ) - ] - ); + $self->SUPER::diff( $req, @path ); } 1; diff --git a/lemonldap-ng-manager/site/coffee/viewer.coffee b/lemonldap-ng-manager/site/coffee/viewer.coffee index 6b2893c92..4cbe12211 100644 --- a/lemonldap-ng-manager/site/coffee/viewer.coffee +++ b/lemonldap-ng-manager/site/coffee/viewer.coffee @@ -169,40 +169,7 @@ llapp.controller 'TreeCtrl', [ $scope.downloadConf = () -> window.open $scope.viewPrefix + $scope.currentCfg.cfgNum + '?full=1' -# # Main save function -# $scope.save = -> -# $scope.showModal('save.html').then -> -# $scope.waiting = true -# $scope.data.push -# id: "cfgLog" -# title: "cfgLog" -# data: if $scope.result then $scope.result else '' -# $http.post("#{window.viewPrefix}?cfgNum=#{$scope.currentCfg.cfgNum}#{if $scope.forceSave then "&force=1" else ''}", $scope.data).then (response) -> -# $scope.data.pop() -# _checkSaveResponse response.data -# ,(response) -> -# readError response -# $scope.data.pop() -# , -> -# console.log 'Saving canceled' -# $scope.showM = false -# -# # Raw save function -# $scope.saveRawConf = ($fileContent) -> -# $scope.waiting = true -# $http.post("#{window.viewPrefix}/raw", $fileContent).then (response) -> -# _checkSaveResponse(response.data) -# , readError -# -# # Restore raw conffunction -# $scope.restore = -> -# $scope.currentNode = null -# $scope.form = 'restore' -# -# # Cancel save function -# $scope.cancel = -> -# $scope.currentNode.data = null -# $scope.getKey($scope.currentNode) + # NODES MANAGEMENT id = 1 @@ -219,203 +186,6 @@ llapp.controller 'TreeCtrl', [ cs = cs.$parentNodeScope return cs -# # Add grant rule entry -# $scope.newGrantRule = -> -# node = $scope._findContainer() -# l = node.nodes.length -# n = if l > 0 then l - 1 else 0 -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: 'New rule' -# re: 'Message' -# comment: 'New rule' -# data: '1' -# type: "grant" -# -# # Add rules entry -# $scope.newRule = -> -# node = $scope._findContainer() -# l = node.nodes.length -# n = if l > 0 then l - 1 else 0 -# node.nodes.splice n, 0, -# id: "#{node.id}/n#{id++}" -# title: 'New rule' -# re: '^/new' -# comment: 'New rule' -# data: 'accept' -# type: "rule" -# -# # Add form replay -# $scope.newPost = -> -# node = $scope._findContainer() -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: "/absolute/path/to/form" -# data: {} -# type: "post" -# -# $scope.newPostVar = -> -# $scope.currentNode.data.vars = [] unless $scope.currentNode.data.vars? -# $scope.currentNode.data.vars.push ['var1', '$uid'] -# -# # Add auth chain entry to authChoice -# $scope.newAuthChoice = -> -# node = $scope._findContainer() -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: "1_Key" -# data: ['Null', 'Null', 'Null'] -# type: "authChoice" -# $scope.execFilters $scope._findScopeByKey 'authParams' -# -# # Add hash entry -# $scope.newHashEntry = -> -# node = $scope._findContainer() -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: 'new' -# data: '' -# type: "keyText" -# -# # Menu cat entry -# $scope.newCat = -> -# cs = $scope.currentScope -# if cs.$modelValue.type == 'menuApp' -# cs = cs.$parentNodeScope -# cs.$modelValue.nodes.push -# id: "#{cs.$modelValue.id}/n#{id++}" -# title: "New category" -# type: "menuCat" -# nodes: [] -# -# # Menu app entry -# $scope.newApp = -> -# cs = $scope.currentScope -# if cs.$modelValue.type == 'menuApp' -# cs = cs.$parentNodeScope -# cs.$modelValue.nodes.push -# id: "#{cs.$modelValue.id}/n#{id++}" -# title: "New application" -# type: "menuApp" -# data: -# description: "New app description" -# uri: "https://test.example.com/" -# logo: "network.png" -# display: "auto" -# -# # Combination module -# $scope.newCmbMod = -> -# node = $scope._findContainer() -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: 'new' -# type: 'cmbModule' -# data: -# type: 'LDAP' -# for: '0' -# over: [] -# $scope.execFilters $scope._findScopeByKey 'authParams' -# -# $scope.newCmbOver = -> -# d = $scope.currentNode.data -# d.over = [] unless d.over -# d.over.push ["new#{id++}", ''] -# -# $scope.newChoiceOver = -> -# d = $scope.currentNode.data -# console.log "data", d -# d[5] = [] unless d[5] -# d[5].push ["new#{id++}", ''] -# -# # Add host -# $scope.addHost = () -> -# cn = $scope.currentNode -# cn.data=[] unless cn.data -# cn.data.push -# k: "newHost" -# h: [{"k":"key","v":"uid"}] -# -# # SAML attribute entry -# $scope.addSamlAttribute = -> -# node = $scope._findContainer() -# node.nodes.push -# id: "#{node.id}/n#{id++}" -# title: 'new' -# type: 'samlAttribute' -# data: ['0', 'New', '', ''] -# -# # Nodes with template -# $scope.addVhost = -> -# name = if $scope.domain then ".#{$scope.domain.data}" else '.example.com' -# $scope.message = -# title: 'virtualHostName' -# field: 'hostname' -# $scope.showModal('prompt.html', name).then -> -# n= $scope.result -# if n -# $scope.addTemplateNode n, 'virtualHost' -# -# $scope.duplicateVhost = -> -# name = if $scope.domain then ".#{$scope.domain.data}" else '.example.com' -# $scope.message = -# title: 'virtualHostName', -# field: 'hostname' -# $scope.showModal('prompt.html', name).then -> -# n = $scope.result -# return $scope.duplicateNode n, 'virtualHost', $scope.currentNode.title -# -# $scope.addSamlIDP = -> -# $scope.newTemplateNode 'samlIDPMetaDataNode', 'samlPartnerName', 'idp-example' -# -# $scope.addSamlSP = -> -# $scope.newTemplateNode 'samlSPMetaDataNode', 'samlPartnerName', 'sp-example' -# -# $scope.addOidcOp = -> -# $scope.newTemplateNode 'oidcOPMetaDataNode', 'oidcOPName', 'op-example' -# -# $scope.addOidcRp = -> -# $scope.newTemplateNode 'oidcRPMetaDataNode', 'oidcRPName', 'rp-example' -# -# $scope.addCasSrv = -> -# $scope.newTemplateNode 'casSrvMetaDataNode', 'casPartnerName', 'srv-example' -# -# $scope.addCasApp = -> -# $scope.newTemplateNode 'casAppMetaDataNode', 'casPartnerName', 'app-example' -# -# $scope.newTemplateNode = (type, title, init) -> -# $scope.message = -# title: title -# field: 'name' -# $scope.showModal('prompt.html', init).then -> -# name = $scope.result -# if (name) -# $scope.addTemplateNode name, type -# -# $scope.addTemplateNode = (name, type) -> -# cs = $scope.currentScope -# while cs.$modelValue.title != "#{type}s" -# cs = cs.$parentNodeScope -# t = -# id: "#{type}s/new__#{name}" -# title: name -# type: type -# nodes: templates type, "new__#{name}" -# setDefault t.nodes -# cs.$modelValue.nodes.push t -# cs.expand() -# return t - -# setDefault = (node) -> -# for n in node -# if n.cnodes and n.default -# delete n.cnodes -# n._nodes = n.default -# if n._nodes -# setDefault n._nodes -# else if n.default or n.default == 0 -# n.data = n.default -# node - _getAll = (node) -> d = $q.defer() d2 = $q.defer() @@ -439,25 +209,6 @@ llapp.controller 'TreeCtrl', [ d2.resolve() return d2.promise -# $scope.duplicateNode = (name, type, idkey) -> -# cs = $scope.currentScope -# _getAll($scope.currentNode).then -> -# while cs.$modelValue.title != "#{type}s" -# cs = cs.$parentNodeScope -# t = JSON.parse JSON.stringify($scope.currentNode).replace(new RegExp(idkey, 'g'), 'new__' + name) -# t.id = "#{type}s/new__#{name}" -# t.title = name -# cs.$modelValue.nodes.push(t) -# return t - -# $scope.del = (a, i) -> -# a.splice(i, 1) - -# $scope.deleteEntry = -> -# p = $scope.currentScope.$parentNodeScope -# $scope.currentScope.remove() -# $scope.displayForm p - $scope.down = -> id = $scope.currentNode.id p = $scope.currentScope.$parentNodeScope.$modelValue @@ -577,16 +328,6 @@ llapp.controller 'TreeCtrl', [ scope = scope.$parentNodeScope $scope.helpUrl = scope.$modelValue.help || 'start.html#configuration' - # Form management - # - # `currentNode` contains the last select node - # - # method `diplayForm()`: - # - set the `form` property to the name of the form to download - # (`text` by default or `home` for node without `type` property) - # - launch getKeys to set `node.data` - # - hide tree when in XS size - # $scope.displayForm = (scope) -> node = scope.$modelValue if node.cnodes @@ -608,45 +349,6 @@ llapp.controller 'TreeCtrl', [ $scope.showT = false setHelp scope -# $scope.keyWritable = (scope) -> -# node = scope.$modelValue -# # regexp-assemble of: -# # authChoice -# # keyText -# # cmbModule -# # virtualHost -# # rule -# # menuCat -# # menuApp -# # samlAttribute -# # samlIDPMetaDataNode -# # samlSPMetaDataNode -# return if node.type and node.type.match /^(?:(?:saml(?:(?:ID|S)PMetaDataNod|Attribut)|(?:cmbMod|r)ul|authChoic)e|(?:virtualHos|keyTex)t|menu(?:App|Cat))$/ then true else false -# - # RSA keys generation -# $scope.newRSAKey = -> -# $scope.showModal('password.html').then -> -# $scope.waiting = true -# currentNode = $scope.currentNode -# password = $scope.result -# $http.post("#{window.viewPrefix}/newRSAKey", {"password": password}).then (response) -> -# currentNode.data[0].data = response.data.private -# currentNode.data[1].data = password -# currentNode.data[2].data = response.data.public -# $scope.waiting = false -# , readError -# , -> -# console.log('New key cancelled') - -# $scope.newRSAKeyNoPassword = -> -# $scope.waiting = true -# currentNode = $scope.currentNode -# $http.post("#{window.viewPrefix}/newRSAKey", {"password": ''}).then (response) -> -# currentNode.data[0].data = response.data.private -# currentNode.data[1].data = response.data.public -# $scope.waiting = false -# , readError - # method `getKey()`: # - return a promise with the data: # - from node when set @@ -771,23 +473,4 @@ llapp.controller 'TreeCtrl', [ console.log "Redirecting to /view/latest" $location.path '/view/latest' - # File form function - #$scope.replaceContentByUrl = (node, url) -> - # $scope.waiting = true - # $http.post(window.scriptname + "prx", {url: url}).then (response) -> - # node.data = response.data.content - # $scope.waiting = false - # , readError - #$scope.replaceContent = (node, $fileContent) -> - # node.data = $fileContent - - ## Import Filesaver.js saveAs() - #$scope.saveAs = (content, type, filename) -> - # saveAs(new Blob([content], {"type": type}), filename) - - ## Save as pem, text,... - #$scope.saveAsPem = (cs,scope) -> - # scope.saveAs "#{cs.data[0].data}\n#{cs.data[2].data}", 'application/x-pem-file', "#{cs.title}.pem" - #$scope.saveAsText = (cs,scope) -> - # scope.saveAs cs.data, 'text/plain', "#{cs.title}.txt" ] diff --git a/lemonldap-ng-manager/site/htdocs/static/forms/home.html b/lemonldap-ng-manager/site/htdocs/static/forms/home.html index 00d94794b..e7b3150db 100644 --- a/lemonldap-ng-manager/site/htdocs/static/forms/home.html +++ b/lemonldap-ng-manager/site/htdocs/static/forms/home.html @@ -1,10 +1,14 @@
+

+ () +

+
diff --git a/lemonldap-ng-manager/site/templates/viewer.tpl b/lemonldap-ng-manager/site/templates/viewer.tpl index 0e537b6b7..cc91933f3 100644 --- a/lemonldap-ng-manager/site/templates/viewer.tpl +++ b/lemonldap-ng-manager/site/templates/viewer.tpl @@ -22,17 +22,15 @@