2016-03-14 23:22:09 +01:00
|
|
|
###
|
|
|
|
LemonLDAP::NG Manager client
|
|
|
|
|
|
|
|
This is the main app file. Other are:
|
|
|
|
- struct.json and js/confTree.js that contains the full tree
|
|
|
|
- translate.json that contains the keywords translation
|
|
|
|
|
|
|
|
This file contains:
|
|
|
|
- the AngularJS controller
|
|
|
|
###
|
|
|
|
|
|
|
|
llapp = angular.module 'llngManager', ['ui.tree', 'ui.bootstrap', 'llApp', 'ngCookies']
|
|
|
|
|
|
|
|
###
|
|
|
|
Main AngularJS controller
|
|
|
|
###
|
|
|
|
|
|
|
|
llapp.controller 'TreeCtrl', [
|
|
|
|
'$scope', '$http', '$location', '$q', '$uibModal', '$translator', '$cookies', '$htmlParams',
|
|
|
|
($scope, $http, $location, $q, $uibModal, $translator, $cookies, $htmlParams) ->
|
|
|
|
$scope.links = window.links
|
|
|
|
$scope.menu = $htmlParams.menu
|
|
|
|
$scope.menulinks = window.menulinks
|
|
|
|
$scope.staticPrefix = window.staticPrefix
|
|
|
|
$scope.formPrefix = window.formPrefix
|
|
|
|
$scope.availableLanguages = window.availableLanguages
|
|
|
|
$scope.waiting = true
|
|
|
|
$scope.showM = false
|
|
|
|
$scope.showT = false
|
|
|
|
$scope.form = 'home'
|
|
|
|
$scope.currentCfg = {}
|
|
|
|
$scope.confPrefix = window.confPrefix
|
|
|
|
$scope.message = {}
|
|
|
|
$scope.result = ''
|
|
|
|
|
|
|
|
# Import translations functions
|
|
|
|
$scope.translateTitle = (node) ->
|
|
|
|
return $translator.translateField node, 'title'
|
|
|
|
$scope.translateP = $translator.translateP
|
|
|
|
$scope.translate = $translator.translate
|
|
|
|
|
|
|
|
# HELP DISPLAY
|
|
|
|
$scope.helpUrl = 'start.html#configuration'
|
|
|
|
$scope.setShowHelp = (val) ->
|
|
|
|
val = !$scope.showH unless val?
|
|
|
|
$scope.showH = val
|
|
|
|
d = new Date(Date.now())
|
|
|
|
d.setFullYear(d.getFullYear() + 1)
|
|
|
|
$cookies.put 'showhelp', (if val then 'true' else 'false'), {"expires": d}
|
|
|
|
$scope.showH = if $cookies.get('showhelp') == 'false' then false else true
|
|
|
|
$scope.setShowHelp(true) unless $scope.showH?
|
|
|
|
|
|
|
|
# INTERCEPT AJAX ERRORS
|
|
|
|
readError = (response) ->
|
|
|
|
e = response.status
|
|
|
|
j = response.statusLine
|
|
|
|
$scope.waiting = false
|
|
|
|
if e == 403
|
|
|
|
$scope.message =
|
|
|
|
title: 'forbidden'
|
|
|
|
message: ''
|
|
|
|
items: []
|
|
|
|
else if e == 401
|
|
|
|
console.log 'Authentication needed'
|
|
|
|
$scope.message =
|
|
|
|
title: 'authenticationNeeded'
|
|
|
|
message: '__waitOrF5__'
|
|
|
|
items: []
|
|
|
|
else if e == 400
|
|
|
|
$scope.message =
|
|
|
|
title: 'badRequest'
|
|
|
|
message: j
|
|
|
|
items: []
|
|
|
|
else if e > 0
|
|
|
|
$scope.message =
|
|
|
|
title: 'badRequest'
|
|
|
|
message: j
|
|
|
|
items: []
|
|
|
|
else
|
|
|
|
$scope.message =
|
|
|
|
title: 'networkProblem'
|
|
|
|
message: ''
|
|
|
|
items: []
|
|
|
|
return $scope.showModal 'message.html'
|
|
|
|
|
|
|
|
# Modal launcher
|
|
|
|
$scope.showModal = (tpl, init) ->
|
|
|
|
modalInstance = $uibModal.open
|
|
|
|
templateUrl: tpl
|
|
|
|
controller: 'ModalInstanceCtrl'
|
|
|
|
size: 'lg'
|
|
|
|
resolve:
|
|
|
|
elem: ->
|
|
|
|
return (s) ->
|
|
|
|
return $scope[s]
|
|
|
|
set: ->
|
|
|
|
return (f, s) ->
|
|
|
|
$scope[f] = s
|
|
|
|
init: ->
|
|
|
|
return init
|
|
|
|
d = $q.defer()
|
|
|
|
modalInstance.result.then (msgok) ->
|
|
|
|
$scope.message =
|
|
|
|
title: ''
|
|
|
|
message: ''
|
|
|
|
items: []
|
|
|
|
d.resolve msgok
|
|
|
|
,(msgnok) ->
|
|
|
|
$scope.message =
|
|
|
|
title: ''
|
|
|
|
message: ''
|
|
|
|
items: []
|
|
|
|
d.reject msgnok
|
2016-03-21 18:52:50 +01:00
|
|
|
return d.promise
|
2016-03-14 23:22:09 +01:00
|
|
|
|
|
|
|
# FORM DISPLAY FUNCTIONS
|
|
|
|
|
|
|
|
# Function called when a menu item is selected. It launch function stored in
|
|
|
|
# "action" or "title"
|
|
|
|
$scope.menuClick = (button) ->
|
|
|
|
if button.popup
|
|
|
|
window.open button.popup
|
|
|
|
else
|
|
|
|
button.action = button.title unless button.action
|
|
|
|
switch typeof button.action
|
|
|
|
when 'function'
|
|
|
|
button.action $scope.currentNode, $scope
|
|
|
|
when 'string'
|
|
|
|
$scope[button.action]()
|
|
|
|
else
|
|
|
|
console.log typeof button.action
|
|
|
|
$scope.showM = false
|
|
|
|
|
|
|
|
# Display main form
|
|
|
|
$scope.home = ->
|
|
|
|
$scope.form = 'home'
|
|
|
|
$scope.showM = false
|
|
|
|
|
|
|
|
# SAVE FUNCTIONS
|
|
|
|
|
|
|
|
# Private method called by $scope.save()
|
|
|
|
_checkSaveResponse = (data) ->
|
|
|
|
$scope.message =
|
|
|
|
title: ''
|
|
|
|
message: ''
|
|
|
|
items: []
|
2019-04-21 21:32:21 +02:00
|
|
|
itemsE:[]
|
|
|
|
itemsNC: []
|
|
|
|
itemsW: []
|
2018-12-27 23:06:59 +01:00
|
|
|
$scope.confirmNeeded = true if data.needConfirm
|
2016-03-14 23:22:09 +01:00
|
|
|
$scope.message.message = data.message if data.message
|
2019-04-21 21:32:21 +02:00
|
|
|
# Sort messages
|
2016-03-14 23:22:09 +01:00
|
|
|
if data.details
|
|
|
|
for m of data.details when m != '__changes__'
|
2018-12-30 18:55:14 +01:00
|
|
|
if m == '__needConfirmation__'
|
2019-04-21 21:32:21 +02:00
|
|
|
$scope.message.itemsNC.push
|
2018-12-30 18:55:14 +01:00
|
|
|
message: m
|
|
|
|
items: data.details[m]
|
2019-04-21 21:32:21 +02:00
|
|
|
console.log 'NeedConfirmation:', $scope.message.itemsNC
|
|
|
|
else if m == '__warnings__'
|
|
|
|
$scope.message.itemsW.push
|
|
|
|
message: m
|
|
|
|
items: data.details[m]
|
|
|
|
console.log 'Warnings:', $scope.message.itemsW
|
2018-12-30 18:55:14 +01:00
|
|
|
else
|
2019-04-21 21:32:21 +02:00
|
|
|
$scope.message.itemsE.push
|
2018-12-30 18:55:14 +01:00
|
|
|
message: m
|
|
|
|
items: data.details[m]
|
2019-04-21 21:32:21 +02:00
|
|
|
console.log 'Errors:', $scope.message.itemsE
|
|
|
|
$scope.message.items = $scope.message.itemsE.concat $scope.message.itemsNC.concat $scope.message.itemsW
|
2016-03-14 23:22:09 +01:00
|
|
|
$scope.waiting = false
|
|
|
|
if data.result == 1
|
|
|
|
# Force reloading page
|
|
|
|
$location.path '/confs/'
|
|
|
|
$scope.message.title = 'successfullySaved'
|
|
|
|
else
|
|
|
|
$scope.message.title = 'saveReport'
|
|
|
|
$scope.showModal 'message.html'
|
|
|
|
|
2017-01-18 00:17:23 +01:00
|
|
|
# Download raw conf
|
2017-03-13 17:27:47 +01:00
|
|
|
$scope.downloadConf = () ->
|
|
|
|
window.open $scope.confPrefix + $scope.currentCfg.cfgNum + '?full=1'
|
2017-01-18 00:17:23 +01:00
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
# 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 ''
|
2021-05-03 22:38:10 +02:00
|
|
|
$http.post("#{window.confPrefix}?cfgNum=#{$scope.currentCfg.cfgNum}&cfgDate=#{$scope.currentCfg.cfgDate}#{if $scope.forceSave then "&force=1" else ''}", $scope.data).then (response) ->
|
2016-03-14 23:22:09 +01:00
|
|
|
$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.confPrefix}/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
|
2019-12-19 07:22:21 +01:00
|
|
|
idinc = 1
|
2016-03-14 23:22:09 +01:00
|
|
|
$scope._findContainer = ->
|
|
|
|
return $scope._findScopeContainer().$modelValue
|
|
|
|
$scope._findScopeContainer = ->
|
|
|
|
cs = $scope.currentScope
|
|
|
|
while not cs.$modelValue.type.match(/Container$/)
|
|
|
|
cs = cs.$parentNodeScope
|
|
|
|
return cs
|
|
|
|
$scope._findScopeByKey = (k) ->
|
|
|
|
cs = $scope.currentScope
|
|
|
|
while not (cs.$modelValue.title == k)
|
|
|
|
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
|
2018-10-01 22:28:04 +02:00
|
|
|
node.nodes.push
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
title: 'New rule'
|
2018-10-01 16:20:30 +02:00
|
|
|
re: 'Message'
|
2016-03-14 23:22:09 +01:00
|
|
|
comment: 'New rule'
|
2018-10-01 16:20:30 +02:00
|
|
|
data: '1'
|
2016-03-14 23:22:09 +01:00
|
|
|
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,
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
title: 'New rule'
|
|
|
|
re: '^/new'
|
|
|
|
comment: 'New rule'
|
|
|
|
data: 'accept'
|
|
|
|
type: "rule"
|
|
|
|
|
|
|
|
# Add form replay
|
|
|
|
$scope.newPost = ->
|
|
|
|
node = $scope._findContainer()
|
|
|
|
node.nodes.push
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
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
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
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
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
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
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{cs.$modelValue.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
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
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{cs.$modelValue.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
title: "New application"
|
|
|
|
type: "menuApp"
|
|
|
|
data:
|
|
|
|
description: "New app description"
|
|
|
|
uri: "https://test.example.com/"
|
2020-04-08 22:40:16 +02:00
|
|
|
tooltip: "New app tooltip"
|
2016-03-14 23:22:09 +01:00
|
|
|
logo: "network.png"
|
|
|
|
display: "auto"
|
|
|
|
|
2017-02-06 07:42:22 +01:00
|
|
|
# Combination module
|
|
|
|
$scope.newCmbMod = ->
|
|
|
|
node = $scope._findContainer()
|
|
|
|
node.nodes.push
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2017-02-06 07:42:22 +01:00
|
|
|
title: 'new'
|
|
|
|
type: 'cmbModule'
|
|
|
|
data:
|
|
|
|
type: 'LDAP'
|
2018-12-16 00:46:32 +01:00
|
|
|
for: '0'
|
2017-02-06 18:40:17 +01:00
|
|
|
over: []
|
2017-02-06 19:04:07 +01:00
|
|
|
$scope.execFilters $scope._findScopeByKey 'authParams'
|
2017-02-06 07:42:22 +01:00
|
|
|
|
2019-07-18 22:41:24 +02:00
|
|
|
$scope.newSfExtra = ->
|
|
|
|
node = $scope._findContainer()
|
|
|
|
node.nodes.push
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2019-07-18 22:41:24 +02:00
|
|
|
title: 'new'
|
|
|
|
type: 'sfExtra'
|
|
|
|
data:
|
|
|
|
type: ''
|
|
|
|
rule: ''
|
2019-08-01 17:27:14 +02:00
|
|
|
logo: ''
|
2020-04-15 17:09:18 +02:00
|
|
|
level: ''
|
2019-08-01 17:27:14 +02:00
|
|
|
label: ''
|
2019-07-18 22:41:24 +02:00
|
|
|
over: []
|
|
|
|
|
|
|
|
|
|
|
|
$scope.newSfOver = ->
|
|
|
|
d = $scope.currentNode.data
|
|
|
|
d.over = [] unless d.over
|
2019-12-19 07:22:21 +01:00
|
|
|
d.over.push ["new#{idinc++}", '']
|
2019-07-18 22:41:24 +02:00
|
|
|
|
2017-02-06 07:42:22 +01:00
|
|
|
$scope.newCmbOver = ->
|
2017-02-06 18:40:17 +01:00
|
|
|
d = $scope.currentNode.data
|
|
|
|
d.over = [] unless d.over
|
2019-12-19 07:22:21 +01:00
|
|
|
d.over.push ["new#{idinc++}", '']
|
2017-02-06 07:42:22 +01:00
|
|
|
|
2018-10-08 16:57:24 +02:00
|
|
|
$scope.newChoiceOver = ->
|
|
|
|
d = $scope.currentNode.data
|
|
|
|
console.log "data", d
|
|
|
|
d[5] = [] unless d[5]
|
2019-12-19 07:22:21 +01:00
|
|
|
d[5].push ["new#{idinc++}", '']
|
2018-10-08 16:57:24 +02:00
|
|
|
|
2017-01-18 00:17:23 +01:00
|
|
|
# Add host
|
2017-05-17 10:56:29 +02:00
|
|
|
$scope.addHost = () ->
|
|
|
|
cn = $scope.currentNode
|
2017-01-18 00:17:23 +01:00
|
|
|
cn.data=[] unless cn.data
|
|
|
|
cn.data.push
|
|
|
|
k: "newHost"
|
|
|
|
h: [{"k":"key","v":"uid"}]
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
# SAML attribute entry
|
|
|
|
$scope.addSamlAttribute = ->
|
|
|
|
node = $scope._findContainer()
|
|
|
|
node.nodes.push
|
2019-12-19 07:22:21 +01:00
|
|
|
id: "#{node.id}/n#{idinc++}"
|
2016-03-14 23:22:09 +01:00
|
|
|
title: 'new'
|
|
|
|
type: 'samlAttribute'
|
2019-01-31 21:23:27 +01:00
|
|
|
data: ['0', 'New', '', '']
|
2016-03-14 23:22:09 +01:00
|
|
|
|
2020-11-05 21:01:52 +01:00
|
|
|
# OIDC attribute entry
|
|
|
|
$scope.addOidcAttribute = ->
|
|
|
|
node = $scope._findContainer()
|
|
|
|
node.nodes.push
|
|
|
|
id: "#{node.id}/n#{idinc++}"
|
|
|
|
title: 'new'
|
|
|
|
type: 'oidcAttribute'
|
|
|
|
data: ['', 'string', 'auto']
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
# 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
|
2018-03-14 20:52:25 +01:00
|
|
|
$scope.addTemplateNode n, 'virtualHost'
|
2016-03-14 23:22:09 +01:00
|
|
|
|
|
|
|
$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'
|
|
|
|
|
2017-04-12 18:45:49 +02:00
|
|
|
$scope.addCasSrv = ->
|
|
|
|
$scope.newTemplateNode 'casSrvMetaDataNode', 'casPartnerName', 'srv-example'
|
|
|
|
|
|
|
|
$scope.addCasApp = ->
|
|
|
|
$scope.newTemplateNode 'casAppMetaDataNode', 'casPartnerName', 'app-example'
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
$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}"
|
2018-03-14 20:52:25 +01:00
|
|
|
setDefault t.nodes
|
2016-03-14 23:22:09 +01:00
|
|
|
cs.$modelValue.nodes.push t
|
|
|
|
cs.expand()
|
|
|
|
return t
|
|
|
|
|
2018-03-14 20:52:25 +01:00
|
|
|
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
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
_getAll = (node) ->
|
|
|
|
d = $q.defer()
|
|
|
|
d2 = $q.defer()
|
|
|
|
if node._nodes
|
|
|
|
_stoggle node
|
|
|
|
d.resolve()
|
|
|
|
else if node.cnodes
|
|
|
|
_download(node).then ->
|
|
|
|
d.resolve()
|
|
|
|
else if node.nodes or node.data
|
|
|
|
d.resolve()
|
|
|
|
else
|
|
|
|
$scope.getKey(node).then ->
|
|
|
|
d.resolve()
|
|
|
|
d.promise.then ->
|
|
|
|
t = []
|
|
|
|
if node.nodes
|
|
|
|
for n in node.nodes
|
|
|
|
t.push _getAll(n)
|
|
|
|
$q.all(t).then ->
|
|
|
|
d2.resolve()
|
|
|
|
return d2.promise
|
|
|
|
|
2016-03-22 08:41:04 +01:00
|
|
|
$scope.duplicateNode = (name, type, idkey) ->
|
2016-03-14 23:22:09 +01:00
|
|
|
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
|
|
|
|
ind = p.nodes.length
|
|
|
|
for n, i in p.nodes
|
|
|
|
if n.id == id then ind = i
|
|
|
|
if ind < p.nodes.length - 1
|
|
|
|
tmp = p.nodes[ind]
|
|
|
|
p.nodes[ind] = p.nodes[ind + 1]
|
|
|
|
p.nodes[ind + 1] = tmp
|
|
|
|
ind
|
|
|
|
|
|
|
|
$scope.up = ->
|
|
|
|
id = $scope.currentNode.id
|
|
|
|
p = $scope.currentScope.$parentNodeScope.$modelValue
|
|
|
|
ind = -1
|
|
|
|
for n, i in p.nodes
|
|
|
|
if n.id == id then ind = i
|
|
|
|
if ind > 0
|
|
|
|
tmp = p.nodes[ind]
|
|
|
|
p.nodes[ind] = p.nodes[ind - 1]
|
|
|
|
p.nodes[ind - 1] = tmp
|
|
|
|
ind
|
|
|
|
|
|
|
|
# test if value is in select
|
|
|
|
$scope.inSelect = (value) ->
|
|
|
|
for n in $scope.currentNode.select
|
|
|
|
return true if n.k == value
|
|
|
|
return false
|
|
|
|
|
|
|
|
# This is for rule form: title = comment if defined, else title = re
|
|
|
|
$scope.changeRuleTitle = (node) ->
|
|
|
|
node.title = if node.comment.length > 0 then node.comment else node.re
|
|
|
|
|
|
|
|
# Node opening
|
|
|
|
|
|
|
|
# authParams mechanism: show used auth modules only (launched by stoggle)
|
|
|
|
$scope.filters = {}
|
|
|
|
$scope.execFilters = (scope) ->
|
|
|
|
scope = if scope then scope else $scope
|
|
|
|
for filter,func of $scope.filters
|
|
|
|
if $scope.filters.hasOwnProperty(filter)
|
2017-04-27 09:51:50 +02:00
|
|
|
return window.filterFunctions[filter](scope, $q, func)
|
2016-03-14 23:22:09 +01:00
|
|
|
false
|
|
|
|
|
|
|
|
# To avoid binding all the tree, nodes are pushed in DOM only when opened
|
|
|
|
$scope.stoggle = (scope) ->
|
|
|
|
node = scope.$modelValue
|
|
|
|
_stoggle node
|
|
|
|
scope.toggle()
|
|
|
|
_stoggle = (node) ->
|
|
|
|
for n in ['nodes', 'nodes_cond']
|
|
|
|
if node["_#{n}"]
|
|
|
|
node[n] = []
|
|
|
|
for a in node["_#{n}"]
|
|
|
|
node[n].push a
|
|
|
|
delete node["_#{n}"]
|
|
|
|
# Call execFilter for authParams
|
|
|
|
if node._nodes_filter
|
|
|
|
if node.nodes
|
|
|
|
for n in node.nodes
|
|
|
|
n.onChange = $scope.execFilters
|
|
|
|
$scope.filters[node._nodes_filter] = node
|
|
|
|
$scope.execFilters()
|
|
|
|
|
|
|
|
# Simple toggle management
|
|
|
|
$scope.toggle = (scope) ->
|
|
|
|
scope.toggle()
|
|
|
|
|
|
|
|
# cnodes management: hash keys/values are loaded when parent node is opened
|
|
|
|
$scope.download = (scope) ->
|
|
|
|
node = scope.$modelValue
|
|
|
|
return _download(node)
|
|
|
|
_download = (node) ->
|
|
|
|
d = $q.defer()
|
|
|
|
d.notify 'Trying to get datas'
|
|
|
|
$scope.waiting = true
|
2020-11-15 13:43:35 +01:00
|
|
|
console.log "Trying to get key #{node.cnodes}"
|
2020-11-15 16:50:37 +01:00
|
|
|
uri = encodeURI node.cnodes
|
|
|
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{uri}").then (response) ->
|
2016-03-14 23:22:09 +01:00
|
|
|
data = response.data
|
|
|
|
# Manage datas errors
|
|
|
|
if not data
|
|
|
|
d.reject 'Empty response from server'
|
|
|
|
else if data.error
|
|
|
|
if data.error.match(/setDefault$/)
|
|
|
|
if node['default']
|
|
|
|
node.nodes = node['default'].slice(0)
|
|
|
|
else
|
|
|
|
node.nodes = []
|
|
|
|
delete node.cnodes
|
|
|
|
d.resolve 'Set data to default value'
|
|
|
|
else
|
|
|
|
d.reject "Server return an error: #{data.error}"
|
|
|
|
else
|
|
|
|
# Store datas
|
|
|
|
delete node.cnodes
|
|
|
|
if not node.type
|
|
|
|
node.type = 'keyTextContainer'
|
|
|
|
node.nodes = []
|
|
|
|
# TODO: try/catch
|
|
|
|
for a in data
|
|
|
|
if a.template
|
|
|
|
a._nodes = templates a.template, a.title
|
|
|
|
node.nodes.push a
|
2019-10-27 17:15:48 +01:00
|
|
|
if a.type.match /^rule$/
|
|
|
|
console.log "Parse rule AuthnLevel as integer"
|
|
|
|
if a.level and typeof a.level == 'string'
|
|
|
|
a.level = parseInt(a.level, 10)
|
2016-03-14 23:22:09 +01:00
|
|
|
d.resolve 'OK'
|
|
|
|
$scope.waiting = false
|
|
|
|
, (response) ->
|
|
|
|
readError response
|
|
|
|
d.reject ''
|
|
|
|
return d.promise
|
|
|
|
|
|
|
|
$scope.openCnode = (scope) ->
|
|
|
|
$scope.download(scope).then ->
|
|
|
|
scope.toggle()
|
|
|
|
|
|
|
|
setHelp = (scope) ->
|
|
|
|
while !scope.$modelValue.help and scope.$parentNodeScope
|
|
|
|
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
|
|
|
|
$scope.download scope
|
|
|
|
if node._nodes
|
|
|
|
$scope.stoggle scope
|
|
|
|
$scope.currentNode = node
|
|
|
|
$scope.currentScope = scope
|
|
|
|
f = if node.type then node.type else 'text'
|
|
|
|
if node.nodes || node._nodes || node.cnodes
|
|
|
|
$scope.form = if f != 'text' then f else 'mini'
|
|
|
|
else
|
|
|
|
$scope.form = f
|
|
|
|
# Get datas
|
|
|
|
$scope.getKey node
|
|
|
|
if node.type and node.type == 'simpleInputContainer'
|
|
|
|
for n in node.nodes
|
|
|
|
$scope.getKey(n)
|
|
|
|
$scope.showT = false
|
|
|
|
setHelp scope
|
|
|
|
|
|
|
|
$scope.keyWritable = (scope) ->
|
|
|
|
node = scope.$modelValue
|
2017-02-06 18:40:17 +01:00
|
|
|
# regexp-assemble of:
|
|
|
|
# authChoice
|
|
|
|
# cmbModule
|
2019-07-18 22:41:24 +02:00
|
|
|
# keyText
|
2017-02-06 18:40:17 +01:00
|
|
|
# menuApp
|
2019-07-18 22:41:24 +02:00
|
|
|
# menuCat
|
|
|
|
# rule
|
2017-02-06 18:40:17 +01:00
|
|
|
# samlAttribute
|
|
|
|
# samlIDPMetaDataNode
|
|
|
|
# samlSPMetaDataNode
|
2019-07-18 22:41:24 +02:00
|
|
|
# sfExtra
|
|
|
|
# virtualHost
|
|
|
|
return if node.type and node.type.match /^(?:s(?:aml(?:(?:ID|S)PMetaDataNod|Attribut)e|fExtra)|(?:(?:cmbMod|r)ul|authChoic)e|(?:virtualHos|keyTex)t|menu(?:App|Cat))$/ then true else false
|
2016-03-14 23:22:09 +01:00
|
|
|
|
2020-09-09 16:39:36 +02:00
|
|
|
# Send test Email
|
|
|
|
$scope.sendTestMail = ->
|
|
|
|
$scope.message =
|
|
|
|
title: 'sendTestMail'
|
|
|
|
field: 'dest'
|
|
|
|
$scope.showModal('prompt.html').then ->
|
|
|
|
n= $scope.result
|
|
|
|
$scope.waiting = true
|
|
|
|
dest = $scope.result
|
|
|
|
$http.post("#{window.confPrefix}/sendTestMail", {"dest": dest}).then (response) ->
|
|
|
|
success = response.data.success
|
|
|
|
error = response.data.error
|
|
|
|
$scope.waiting = false
|
|
|
|
if success
|
|
|
|
$scope.message =
|
|
|
|
title: 'ok'
|
|
|
|
message: '__sendTestMailSuccess__'
|
|
|
|
items: []
|
|
|
|
else
|
|
|
|
$scope.message =
|
|
|
|
title: 'error'
|
|
|
|
message: error
|
|
|
|
items: []
|
|
|
|
|
|
|
|
$scope.showModal 'message.html'
|
|
|
|
, readError
|
|
|
|
, ->
|
|
|
|
console.log('Error sending test email')
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
# RSA keys generation
|
2020-09-22 17:10:48 +02:00
|
|
|
$scope.newCertificate = ->
|
|
|
|
$scope.showModal('password.html').then ->
|
|
|
|
$scope.waiting = true
|
|
|
|
currentNode = $scope.currentNode
|
|
|
|
password = $scope.result
|
|
|
|
$http.post("#{window.confPrefix}/newCertificate", {"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')
|
2016-03-14 23:22:09 +01:00
|
|
|
$scope.newRSAKey = ->
|
|
|
|
$scope.showModal('password.html').then ->
|
|
|
|
$scope.waiting = true
|
|
|
|
currentNode = $scope.currentNode
|
|
|
|
password = $scope.result
|
|
|
|
$http.post("#{window.confPrefix}/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.confPrefix}/newRSAKey", {"password": ''}).then (response) ->
|
|
|
|
currentNode.data[0].data = response.data.private
|
|
|
|
currentNode.data[1].data = response.data.public
|
2021-01-20 00:31:55 +01:00
|
|
|
currentNode.data[2].data = response.data.hash
|
2016-03-14 23:22:09 +01:00
|
|
|
$scope.waiting = false
|
|
|
|
, readError
|
|
|
|
|
|
|
|
# method `getKey()`:
|
|
|
|
# - return a promise with the data:
|
|
|
|
# - from node when set
|
|
|
|
# - after downloading else
|
|
|
|
#
|
|
|
|
$scope.getKey = (node) ->
|
|
|
|
d = $q.defer()
|
|
|
|
if !node.data
|
|
|
|
$scope.waiting = true
|
|
|
|
if node.get and typeof(node.get) == 'object'
|
|
|
|
node.data = []
|
|
|
|
tmp = []
|
|
|
|
for n, i in node.get
|
|
|
|
node.data[i] =
|
|
|
|
title: n
|
|
|
|
id: n
|
|
|
|
tmp.push $scope.getKey(node.data[i])
|
|
|
|
$q.all(tmp).then ->
|
|
|
|
d.resolve(node.data)
|
|
|
|
,(response) ->
|
|
|
|
d.reject response.statusLine
|
|
|
|
$scope.waiting = false
|
|
|
|
else
|
2020-11-15 16:50:37 +01:00
|
|
|
uri = ''
|
2020-11-15 14:02:26 +01:00
|
|
|
if node.get
|
|
|
|
console.log "Trying to get key #{node.get}"
|
2020-11-15 16:50:37 +01:00
|
|
|
uri = encodeURI node.get
|
2020-11-15 14:02:26 +01:00
|
|
|
else
|
|
|
|
console.log "Trying to get title #{node.title}"
|
2020-11-15 16:50:37 +01:00
|
|
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{if node.get then uri else node.title}").then (response) ->
|
2016-03-14 23:22:09 +01:00
|
|
|
# Set default value if response is null or if asked by server
|
|
|
|
data = response.data
|
|
|
|
if (data.value == null or (data.error and data.error.match /setDefault$/ ) ) and node['default'] != null
|
|
|
|
node.data = node['default']
|
|
|
|
else
|
|
|
|
node.data = data.value
|
|
|
|
# Cast int as int (remember that booleans are int for Perl)
|
2019-04-15 21:39:21 +02:00
|
|
|
if node.type and node.type.match /^(bool|trool|boolOrExpr)$/
|
|
|
|
if typeof node.data == 'string' and node.data.match /^(?:-1|0|1)$/
|
|
|
|
node.data = parseInt(node.data, 10)
|
2019-01-31 22:55:15 +01:00
|
|
|
if node.type and node.type.match /^int$/
|
2019-05-11 18:06:15 +02:00
|
|
|
node.data = parseInt(node.data, 10)
|
|
|
|
if node.type and node.type.match /^select$/
|
|
|
|
node.data = node.data.toString()
|
2018-06-30 18:23:07 +02:00
|
|
|
# Split SAML types
|
2016-03-14 23:22:09 +01:00
|
|
|
else if node.type and node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) and not (typeof node.data == 'object')
|
|
|
|
node.data = node.data.split ';'
|
|
|
|
$scope.waiting = false
|
|
|
|
d.resolve node.data
|
|
|
|
, (response) ->
|
|
|
|
readError response
|
|
|
|
d.reject response.status
|
|
|
|
else
|
|
|
|
d.resolve node.data
|
|
|
|
return d.promise
|
|
|
|
|
|
|
|
# function `pathEvent(event, next; current)`:
|
|
|
|
# Called when $location.path() change, launch getCfg() with the new
|
|
|
|
# configuration number
|
|
|
|
pathEvent = (event, next, current) ->
|
2018-06-21 21:07:46 +02:00
|
|
|
n = next.match(new RegExp('#!?/confs/(latest|[0-9]+)'))
|
2016-03-14 23:22:09 +01:00
|
|
|
if n == null
|
|
|
|
$location.path '/confs/latest'
|
|
|
|
else
|
|
|
|
console.log "Trying to get cfg number #{n[1]}"
|
|
|
|
$scope.getCfg n[1]
|
|
|
|
$scope.$on '$locationChangeSuccess', pathEvent
|
|
|
|
|
2016-03-21 18:52:46 +01:00
|
|
|
# function `getCfg(n)`:
|
2016-03-14 23:22:09 +01:00
|
|
|
# Download configuration metadatas
|
|
|
|
$scope.getCfg = (n) ->
|
|
|
|
if $scope.currentCfg.cfgNum != n
|
|
|
|
$http.get("#{window.confPrefix}#{n}").then (response) ->
|
|
|
|
$scope.currentCfg = response.data
|
|
|
|
d = new Date $scope.currentCfg.cfgDate * 1000
|
|
|
|
$scope.currentCfg.date = d.toLocaleString()
|
|
|
|
console.log "Metadatas of cfg #{n} loaded"
|
|
|
|
$location.path "/confs/#{n}"
|
|
|
|
$scope.init()
|
|
|
|
, (response) ->
|
|
|
|
readError(response).then ->
|
|
|
|
$scope.currentCfg.cfgNum = 0
|
|
|
|
$scope.init()
|
|
|
|
else
|
|
|
|
$scope.waiting = false
|
|
|
|
|
|
|
|
# method `getLanguage(lang)`
|
|
|
|
# Launch init() after setting current language
|
|
|
|
$scope.getLanguage = (lang) ->
|
|
|
|
$scope.lang = lang
|
|
|
|
# Force reload home
|
|
|
|
$scope.form = 'white'
|
|
|
|
$scope.init()
|
|
|
|
$scope.showM = false
|
|
|
|
|
|
|
|
# Initialization
|
|
|
|
|
|
|
|
# Load JSON files:
|
|
|
|
# - struct.json: the main tree
|
|
|
|
# - languages/<lang>.json: the chosen language datas
|
|
|
|
$scope.init = ->
|
|
|
|
tmp = null
|
|
|
|
$scope.waiting = true
|
|
|
|
$scope.data = []
|
|
|
|
$scope.confirmNeeded = false
|
|
|
|
$scope.forceSave = false
|
|
|
|
$q.all [
|
|
|
|
$translator.init($scope.lang),
|
|
|
|
$http.get("#{window.staticPrefix}struct.json").then (response) ->
|
|
|
|
tmp = response.data
|
|
|
|
console.log("Structure loaded")
|
|
|
|
]
|
|
|
|
.then ->
|
|
|
|
console.log("Starting structure binding")
|
|
|
|
$scope.data = tmp
|
|
|
|
tmp = null
|
|
|
|
if $scope.currentCfg.cfgNum != 0
|
|
|
|
setScopeVars $scope
|
|
|
|
else
|
|
|
|
$scope.message =
|
|
|
|
title: 'emptyConf'
|
|
|
|
message: '__zeroConfExplanations__'
|
|
|
|
$scope.showModal 'message.html'
|
|
|
|
$scope.form = 'home'
|
|
|
|
$scope.waiting = false
|
|
|
|
, readError
|
2018-04-29 22:38:11 +02:00
|
|
|
# Colorized link
|
2018-04-28 22:02:07 +02:00
|
|
|
$scope.activeModule = "conf"
|
|
|
|
$scope.myStyle = {color: '#ffb84d'}
|
|
|
|
|
2016-03-14 23:22:09 +01:00
|
|
|
c = $location.path().match(new RegExp('^/confs/(latest|[0-9]+)'))
|
|
|
|
unless c
|
|
|
|
console.log "Redirecting to /confs/latest"
|
|
|
|
$location.path '/confs/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)
|
2017-01-18 00:17:23 +01:00
|
|
|
|
|
|
|
# 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"
|
2016-03-14 23:22:09 +01:00
|
|
|
]
|