mirror of
https://github.com/dkmstr/openuds.git
synced 2025-02-09 09:57:36 +03:00
Merge remote-tracking branch 'origin/v2.2'
This commit is contained in:
commit
eacffbe20b
@ -13,7 +13,6 @@ pyOpenSSL==16.2.0
|
||||
mysqlclient==1.3.12
|
||||
python-ldap==3.0.0b4
|
||||
paramiko==2.3.1
|
||||
python-dateutil
|
||||
defusedxml==0.5.0
|
||||
python-dateutil==2.6.1
|
||||
requests==2.18.4
|
||||
|
@ -2,7 +2,9 @@
|
||||
"""
|
||||
Url patterns for UDS project (Django)
|
||||
"""
|
||||
from django.conf.urls import include, url
|
||||
from django.conf.urls import include
|
||||
from django.urls import path
|
||||
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
# from django.contrib import admin
|
||||
@ -10,5 +12,5 @@ from django.conf.urls import include, url
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^', include('uds.urls')),
|
||||
path('', include('uds.urls')),
|
||||
]
|
||||
|
@ -54,7 +54,7 @@ from uds.models import User
|
||||
import logging
|
||||
import six
|
||||
|
||||
__updated__ = '2018-01-05'
|
||||
__updated__ = '2018-02-26'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
authLogger = logging.getLogger('authLog')
|
||||
|
@ -132,8 +132,14 @@ class PublicationFinishChecker(DelayedTask):
|
||||
for old in servicePoolPub.deployed_service.publications.filter(state=State.USABLE):
|
||||
old.state = State.REMOVABLE
|
||||
old.save()
|
||||
pc = PublicationOldMachinesCleaner(old.id)
|
||||
pc.register(GlobalConfig.SESSION_EXPIRE_TIME.getInt(True) * 3600, 'pclean-' + str(old.id), True)
|
||||
|
||||
osm = servicePoolPub.deployed_service.osmanager
|
||||
# If os manager says "machine is persistent", do not tray to delete "previous version" assigned machines
|
||||
doPublicationCleanup = True if osm is None else not osm.getInstance().isPersistent()
|
||||
|
||||
if doPublicationCleanup:
|
||||
pc = PublicationOldMachinesCleaner(old.id)
|
||||
pc.register(GlobalConfig.SESSION_EXPIRE_TIME.getInt(True) * 3600, 'pclean-' + str(old.id), True)
|
||||
|
||||
servicePoolPub.setState(State.USABLE)
|
||||
servicePoolPub.deployed_service.markOldUserServicesAsRemovables(servicePoolPub)
|
||||
@ -205,7 +211,7 @@ class PublicationManager(object):
|
||||
"""
|
||||
Initiates the publication of a service pool, or raises an exception if this cannot be done
|
||||
:param servicePool: Service pool object (db object)
|
||||
:param changeLog: if not Noe, store change log string on "change log" table
|
||||
:param changeLog: if not None, store change log string on "change log" table
|
||||
"""
|
||||
if servicePool.publications.filter(state__in=State.PUBLISH_STATES).count() > 0:
|
||||
raise PublishException(_('Already publishing. Wait for previous publication to finish and try again'))
|
||||
|
@ -51,8 +51,6 @@ import requests
|
||||
import json
|
||||
import logging
|
||||
|
||||
__updated__ = '2018-02-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
traceLogger = logging.getLogger('traceLog')
|
||||
|
||||
@ -488,18 +486,20 @@ class UserServiceManager(object):
|
||||
This method is used by UserService when a request for setInUse(False) is made
|
||||
This checks that the service can continue existing or not
|
||||
"""
|
||||
remove = False
|
||||
# uService = UserService.objects.get(id=uService.id)
|
||||
with transaction.atomic():
|
||||
uService = UserService.objects.select_for_update().get(id=uService.id)
|
||||
if uService.publication is None:
|
||||
return
|
||||
if uService.publication.id != uService.deployed_service.activePublication().id:
|
||||
logger.debug('Old revision of user service, marking as removable: {0}'.format(uService))
|
||||
remove = True
|
||||
osm = uService.deployed_service.osmanager
|
||||
# If os manager says "machine is persistent", do not tray to delete "previous version" assigned machines
|
||||
doPublicationCleanup = True if osm is None else not osm.getInstance().isPersistent()
|
||||
|
||||
if remove:
|
||||
uService.remove()
|
||||
if doPublicationCleanup:
|
||||
remove = False
|
||||
with transaction.atomic():
|
||||
uService = UserService.objects.select_for_update().get(id=uService.id)
|
||||
if uService.publication not is None and uService.publication.id != uService.deployed_service.activePublication().id:
|
||||
logger.debug('Old revision of user service, marking as removable: {0}'.format(uService))
|
||||
remove = True
|
||||
|
||||
if remove:
|
||||
uService.remove()
|
||||
|
||||
def notifyReadyFromOsManager(self, uService, data):
|
||||
try:
|
||||
|
@ -42,7 +42,7 @@ from uds.core import Module
|
||||
|
||||
import six
|
||||
|
||||
__updated__ = '2017-10-02'
|
||||
__updated__ = '2018-03-02'
|
||||
|
||||
STORAGE_KEY = 'osmk'
|
||||
|
||||
@ -260,6 +260,13 @@ class OSManager(Module):
|
||||
if save:
|
||||
userService.save()
|
||||
|
||||
def isPersistent(self):
|
||||
'''
|
||||
When a publication if finished, old assigned machines will be removed if this value is True.
|
||||
Defaults to False
|
||||
'''
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return "Base OS Manager"
|
||||
|
||||
|
@ -48,7 +48,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2016-02-26'
|
||||
__updated__ = '2018-02-26'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
@ -176,6 +176,28 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
||||
"""
|
||||
return Authenticator.objects.all().order_by('priority')
|
||||
|
||||
@staticmethod
|
||||
def getByTag(tag=None):
|
||||
'''
|
||||
Gets authenticator by tag name.
|
||||
Special tag name "disabled" is used to exclude customAuth
|
||||
'''
|
||||
from uds.core.util.Config import GlobalConfig
|
||||
|
||||
auths = []
|
||||
if tag is not None:
|
||||
auths = Authenticator.objects.filter(small_name=tag).order_by('priority', 'name')
|
||||
if auths.count() == 0:
|
||||
auths = Authenticator.objects.all().order_by('priority', 'name')
|
||||
# If disallow global login (use all auths), get just the first by priority/name
|
||||
if GlobalConfig.DISALLOW_GLOBAL_LOGIN.getBool(False) is True:
|
||||
auths = auths[0:1]
|
||||
logger.debug(auths)
|
||||
else:
|
||||
auths = Authenticator.objects.all().order_by('priority', 'name')
|
||||
|
||||
return [auth for auth in auths if auth.getType().isCustom() is False or tag != 'disabled']
|
||||
|
||||
@staticmethod
|
||||
def beforeDelete(sender, **kwargs):
|
||||
"""
|
||||
@ -206,5 +228,6 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
||||
def __str__(self):
|
||||
return u"{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id)
|
||||
|
||||
|
||||
# Connects a pre deletion signal to Authenticator
|
||||
signals.pre_delete.connect(Authenticator.beforeDelete, sender=Authenticator)
|
||||
|
@ -201,6 +201,9 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
if self._onLogout == 'remove':
|
||||
userService.release()
|
||||
|
||||
def isPersistent(self):
|
||||
return not self._onLogout == 'remove'
|
||||
|
||||
def checkState(self, service):
|
||||
logger.debug('Checking state for service {0}'.format(service))
|
||||
return State.RUNNING
|
||||
|
@ -244,6 +244,9 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
if self._onLogout == 'remove':
|
||||
userService.release()
|
||||
|
||||
def isPersistent(self):
|
||||
return not self._onLogout == 'remove'
|
||||
|
||||
def checkState(self, service):
|
||||
logger.debug('Checking state for service {0}'.format(service))
|
||||
return State.RUNNING
|
||||
|
@ -33,33 +33,26 @@
|
||||
# pylint: disable=maybe-no-member,protected-access
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from uds.core.util.Cache import Cache
|
||||
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
import dateutil.parser
|
||||
import hashlib
|
||||
import six
|
||||
|
||||
|
||||
__updated__ = '2017-11-13'
|
||||
__updated__ = '2018-03-02'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Required: Authentication v3
|
||||
|
||||
|
||||
# This is a vary basic implementation for what we need from openstack
|
||||
# This is an implementation for what we need from openstack
|
||||
# This does not includes (nor it is intention) full API implementation, just the parts we need
|
||||
# Theese are related to auth, compute & network basically
|
||||
|
||||
# In case we Cache time for endpoints. This is more likely to not change never, so we will tray to keep it as long as we can (1 hour for example?)
|
||||
# ENDPOINTS_TIMEOUT = 1 * 3600
|
||||
# These are related to auth, compute & network basically
|
||||
|
||||
# Do not verify SSL conections right now
|
||||
VERIFY_SSL = False
|
||||
|
||||
|
||||
# Helpers
|
||||
def ensureResponseIsValid(response, errMsg=None):
|
||||
if response.ok is False:
|
||||
@ -96,28 +89,30 @@ def getRecurringUrlJson(url, headers, key, params=None, errMsg=None, timeout=10)
|
||||
|
||||
# Decorators
|
||||
def authRequired(func):
|
||||
|
||||
def ensurer(obj, *args, **kwargs):
|
||||
obj.ensureAuthenticated()
|
||||
try:
|
||||
return func(obj, *args, **kwargs)
|
||||
except Exception as e:
|
||||
logger.error('Got error {} for openstack'.format(e))
|
||||
obj._cleanCache() # On any request error, force next time auth
|
||||
raise
|
||||
|
||||
return ensurer
|
||||
|
||||
|
||||
def authProjectRequired(func):
|
||||
|
||||
def ensurer(obj, *args, **kwargs):
|
||||
if obj._projectId is None:
|
||||
raise Exception('Need a project for method {}'.format(func))
|
||||
obj.ensureAuthenticated()
|
||||
return func(obj, *args, **kwargs)
|
||||
|
||||
return ensurer
|
||||
|
||||
|
||||
class Client(object):
|
||||
cache = Cache('uds-openstack')
|
||||
|
||||
PUBLIC = 'public'
|
||||
PRIVATE = 'private'
|
||||
INTERNAL = 'url'
|
||||
@ -138,18 +133,6 @@ class Client(object):
|
||||
|
||||
self._authUrl = 'http{}://{}:{}/'.format('s' if useSSL else '', host, port)
|
||||
|
||||
# Generates a hash for auth + credentials
|
||||
h = hashlib.md5()
|
||||
h.update(six.binary_type(host))
|
||||
h.update(six.binary_type(port))
|
||||
h.update(six.binary_type(domain))
|
||||
h.update(six.binary_type(username))
|
||||
h.update(six.binary_type(password))
|
||||
h.update(six.binary_type(useSSL))
|
||||
h.update(six.binary_type(projectId))
|
||||
h.update(six.binary_type(region))
|
||||
self._cacheKey = h.hexdigest()
|
||||
|
||||
def _getEndpointFor(self, type_): # If no region is indicatad, first endpoint is returned
|
||||
for i in self._catalog:
|
||||
if i['type'] == type_:
|
||||
@ -164,38 +147,7 @@ class Client(object):
|
||||
|
||||
return headers
|
||||
|
||||
def _getFromCache(self):
|
||||
cached = self.cache.get(self._cacheKey)
|
||||
if cached is not None:
|
||||
self._authenticated = True
|
||||
self._tokenId = cached['tokenId']
|
||||
# Extract the token id
|
||||
self._userId = cached['userId']
|
||||
self._projectId = cached['projectId']
|
||||
self._catalog = cached['catalog']
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _saveToCache(self, validity=600):
|
||||
self.cache.put(self._cacheKey,
|
||||
{
|
||||
'tokenId': self._tokenId,
|
||||
'userId': self._userId,
|
||||
'projectId': self._projectId,
|
||||
'catalog': self._catalog
|
||||
},
|
||||
validity - 60) # We substract some seconds to allow some time desynchronization
|
||||
|
||||
def _clearCache(self):
|
||||
self.cache.remove(self._cacheKey)
|
||||
|
||||
def authPassword(self):
|
||||
# If cached data exists, use it as auth
|
||||
if self._getFromCache() is True:
|
||||
return
|
||||
|
||||
data = {
|
||||
'auth': {
|
||||
'identity': {
|
||||
@ -239,20 +191,16 @@ class Client(object):
|
||||
self._userId = token['user']['id']
|
||||
validity = (dateutil.parser.parse(token['expires_at']).replace(tzinfo=None) - dateutil.parser.parse(token['issued_at']).replace(tzinfo=None)).seconds - 60
|
||||
|
||||
|
||||
logger.debug('The token {} will be valid for {}'.format(self._tokenId, validity))
|
||||
|
||||
# Now, if endpoints are present (only if tenant was specified), store & cache them
|
||||
# Now, if endpoints are present (only if tenant was specified), store them
|
||||
if self._projectId is not None:
|
||||
self._catalog = token['catalog']
|
||||
|
||||
self._saveToCache(validity)
|
||||
|
||||
def ensureAuthenticated(self):
|
||||
if self._authenticated is False:
|
||||
self.authPassword()
|
||||
|
||||
|
||||
@authRequired
|
||||
def listProjects(self):
|
||||
return getRecurringUrlJson(self._authUrl + 'v3/users/{user_id}/projects'.format(user_id=self._userId),
|
||||
@ -261,7 +209,6 @@ class Client(object):
|
||||
errMsg='List Projects',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authRequired
|
||||
def listRegions(self):
|
||||
return getRecurringUrlJson(self._authUrl + 'v3/regions/',
|
||||
@ -270,7 +217,6 @@ class Client(object):
|
||||
errMsg='List Regions',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listServers(self, detail=False, params=None):
|
||||
path = '/servers/' + 'detail' if detail is True else ''
|
||||
@ -281,7 +227,6 @@ class Client(object):
|
||||
errMsg='List Vms',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listImages(self):
|
||||
return getRecurringUrlJson(self._getEndpointFor('image') + '/v2/images?status=active',
|
||||
@ -290,7 +235,6 @@ class Client(object):
|
||||
errMsg='List Images',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listVolumeTypes(self):
|
||||
return getRecurringUrlJson(self._getEndpointFor('volumev2') + '/types',
|
||||
@ -299,7 +243,6 @@ class Client(object):
|
||||
errMsg='List Volume Types',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listVolumes(self):
|
||||
# self._getEndpointFor('volumev2') + '/volumes'
|
||||
@ -309,7 +252,6 @@ class Client(object):
|
||||
errMsg='List Volumes',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listVolumeSnapshots(self, volumeId=None):
|
||||
for s in getRecurringUrlJson(self._getEndpointFor('volumev2') + '/snapshots',
|
||||
@ -320,7 +262,6 @@ class Client(object):
|
||||
if volumeId is None or s['volume_id'] == volumeId:
|
||||
yield s
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listAvailabilityZones(self):
|
||||
for az in getRecurringUrlJson(self._getEndpointFor('compute') + '/os-availability-zone',
|
||||
@ -331,7 +272,6 @@ class Client(object):
|
||||
if az['zoneState']['available'] is True:
|
||||
yield az['zoneName']
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listFlavors(self):
|
||||
return getRecurringUrlJson(self._getEndpointFor('compute') + '/flavors',
|
||||
@ -340,7 +280,6 @@ class Client(object):
|
||||
errMsg='List Flavors',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def listNetworks(self):
|
||||
return getRecurringUrlJson(self._getEndpointFor('network') + '/v2.0/networks',
|
||||
@ -372,7 +311,6 @@ class Client(object):
|
||||
errMsg='List security groups',
|
||||
timeout=self._timeout)
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def getServer(self, serverId):
|
||||
r = requests.get(self._getEndpointFor('compute') + '/servers/{server_id}'.format(server_id=serverId),
|
||||
@ -396,7 +334,6 @@ class Client(object):
|
||||
|
||||
return v
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def getSnapshot(self, snapshotId):
|
||||
"""
|
||||
@ -414,7 +351,6 @@ class Client(object):
|
||||
|
||||
return v
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def updateSnapshot(self, snapshotId, name=None, description=None):
|
||||
data = { 'snapshot': {} }
|
||||
@ -436,7 +372,6 @@ class Client(object):
|
||||
|
||||
return v
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def createVolumeSnapshot(self, volumeId, name, description=None):
|
||||
description = 'UDS Snapshot' if description is None else description
|
||||
@ -461,7 +396,6 @@ class Client(object):
|
||||
|
||||
return r.json()['snapshot']
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def createVolumeFromSnapshot(self, snapshotId, name, description=None):
|
||||
description = 'UDS Volume' if description is None else description
|
||||
@ -520,7 +454,6 @@ class Client(object):
|
||||
|
||||
return r.json()['server']
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def deleteServer(self, serverId):
|
||||
r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId),
|
||||
@ -533,7 +466,6 @@ class Client(object):
|
||||
|
||||
# This does not returns anything
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def deleteSnapshot(self, snapshotId):
|
||||
r = requests.delete(self._getEndpointFor('volumev2') + '/snapshots/{snapshot_id}'.format(snapshot_id=snapshotId),
|
||||
@ -545,7 +477,6 @@ class Client(object):
|
||||
|
||||
# Does not returns a message body
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def startServer(self, serverId):
|
||||
r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId),
|
||||
@ -558,7 +489,6 @@ class Client(object):
|
||||
|
||||
# This does not returns anything
|
||||
|
||||
|
||||
@authProjectRequired
|
||||
def stopServer(self, serverId):
|
||||
r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId),
|
||||
@ -589,7 +519,6 @@ class Client(object):
|
||||
|
||||
ensureResponseIsValid(r, 'Resuming server')
|
||||
|
||||
|
||||
def testConnection(self):
|
||||
# First, ensure requested api is supported
|
||||
# We need api version 3.2 or greater
|
||||
|
@ -1,9 +1,11 @@
|
||||
{% extends "uds/html5/templates/base.html" %}
|
||||
{% load i18n static html5 %}
|
||||
{% load i18n static html5 uds %}
|
||||
|
||||
{% block title %}{% trans 'Welcome to UDS' %}{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{% javascript_auths authenticators %}
|
||||
|
||||
<script type="text/javascript">
|
||||
function chkNonStandardAuth(val, nonStandard) {
|
||||
if( $.inArray(val, nonStandard) >= 0) {
|
||||
|
@ -82,15 +82,7 @@ class LoginForm(forms.Form):
|
||||
nonStandard = []
|
||||
standard = []
|
||||
|
||||
auths = None
|
||||
if tag is not None:
|
||||
auths = Authenticator.objects.filter(small_name=tag).order_by('priority', 'name')
|
||||
if auths.count() == 0:
|
||||
auths = Authenticator.objects.all().order_by('priority', 'name')[0:1]
|
||||
logger.debug(auths)
|
||||
logger.debug(list(auths))
|
||||
else:
|
||||
auths = Authenticator.objects.all().order_by('priority', 'name')
|
||||
auths = Authenticator.getByTag(tag)
|
||||
|
||||
for a in auths:
|
||||
if a.getType() is None:
|
||||
|
@ -80,12 +80,13 @@ def login(request, tag=None):
|
||||
|
||||
logger.debug('Tag: {0}'.format(tag))
|
||||
|
||||
logger.debug(request.method)
|
||||
if request.method == 'POST':
|
||||
if 'uds' not in request.COOKIES:
|
||||
logger.debug('Request does not have uds cookie')
|
||||
return errors.errorView(request, errors.COOKIES_NEEDED) # We need cookies to keep session data
|
||||
request.session.cycle_key()
|
||||
|
||||
# Get data from form
|
||||
form = LoginForm(request.POST, tag=tag)
|
||||
if form.is_valid():
|
||||
os = request.os
|
||||
@ -140,6 +141,7 @@ def login(request, tag=None):
|
||||
theme.template('login.html'),
|
||||
{
|
||||
'form': form,
|
||||
'authenticators': Authenticator.getByTag(tag),
|
||||
'customHtml': GlobalConfig.CUSTOM_HTML_LOGIN.get(True),
|
||||
'version': VERSION
|
||||
|
||||
|
@ -20,6 +20,98 @@
|
||||
<script src="/_static_/js/login.js"></script>
|
||||
<!-- AUTHS -->
|
||||
<!-- All of this will be translated on production, se we can replace it with server generated variables on production -->
|
||||
<script type="text/javascript">
|
||||
var authenticators = [
|
||||
{
|
||||
"priority": -2,
|
||||
"authId": "9803FC06-D8B3-5F11-9A6E-EEC905C017FD",
|
||||
"auth": "Interna",
|
||||
"authSmallName": "int",
|
||||
"type": "InternalDBAuth",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "fbf0727a-e754-5f17-a0fd-bd8c1850b355",
|
||||
"auth": "AD",
|
||||
"authSmallName": "ad",
|
||||
"type": "ActiveDirectoryAuthenticator",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "9EB0689D-DF66-54FF-8E7A-3C11E3F42A1A",
|
||||
"auth": "different",
|
||||
"authSmallName": "differ",
|
||||
"type": "InternalDBAuth",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "53a53965-8a90-5e3b-96c4-91937d0042f0",
|
||||
"auth": "Ldap AD por RegEx",
|
||||
"authSmallName": "read",
|
||||
"type": "RegexLdapAuthenticator",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "729b2db5-115f-5aa6-8c0a-32f3fbacf1d4",
|
||||
"auth": "Ldap AUTH",
|
||||
"authSmallName": "sldap",
|
||||
"type": "SimpleLdapAuthenticator",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "4A574A66-65DD-5B6B-8D6F-5A53B95A0A58",
|
||||
"auth": "LDAP UCA",
|
||||
"authSmallName": "luca",
|
||||
"type": "RegexLdapAuthenticator",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "9f111569-d608-5426-b9f7-a9b4b928fd2d",
|
||||
"auth": "Red invalida",
|
||||
"authSmallName": "inval",
|
||||
"type": "IPAuth",
|
||||
"isCustom": true
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "8bbd4337-5eb1-5de5-88b5-203cdcc85ec2",
|
||||
"auth": "SAML Louvain",
|
||||
"authSmallName": "louvain",
|
||||
"type": "SAML20Authenticator",
|
||||
"isCustom": true
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "cd996fec-fd5a-59eb-9eb4-ec28af3cc8f7",
|
||||
"auth": "SAMLOCAL",
|
||||
"authSmallName": "saml",
|
||||
"type": "SAML20Authenticator",
|
||||
"isCustom": true
|
||||
},
|
||||
{
|
||||
"priority": 1,
|
||||
"authId": "3EAC3F30-0148-5041-986D-CE25737FEF81",
|
||||
"auth": "test",
|
||||
"authSmallName": "test",
|
||||
"type": "InternalDBAuth",
|
||||
"isCustom": false
|
||||
},
|
||||
{
|
||||
"priority": 2,
|
||||
"authId": "3613aa7e-e32a-5d05-bcfe-4e2c3e735ee3",
|
||||
"auth": "Casa",
|
||||
"authSmallName": "casa",
|
||||
"type": "IPAuth",
|
||||
"isCustom": true
|
||||
}
|
||||
];
|
||||
</script>
|
||||
<!-- END_AUTHS -->
|
||||
</head>
|
||||
<body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user