Fixed staff dashboard showing

Added test method for services & authenticators
This commit is contained in:
Adolfo Gómez 2014-03-19 02:39:56 +00:00
parent 5d984fb94e
commit cf2051b8f2
8 changed files with 118 additions and 65 deletions

View File

@ -116,3 +116,17 @@ class Authenticators(ModelHandler):
return auth.searchGroups(term)
except:
self.invalidRequestException()
def test(self, type_):
from uds.core.Environment import Environment
authType = auths.factory().lookup(type_)
dct = self._params.copy()
dct['_request'] = self._request
res = authType.test(Environment.getTempEnv(), dct)
if res[0]:
return 'ok'
else:
return res[1]

View File

@ -109,3 +109,13 @@ class Providers(ModelHandler):
return DetailServices.serviceToDict(Service.objects.get(pk=self._args[1]), True)
except:
raise RequestError(ugettext('Service not found'))
def test(self, type_):
from uds.core.Environment import Environment
spType = services.factory().lookup(type_)
res = spType.test(Environment.getTempEnv(), self._params)
if res[0]:
return 'ok'
else:
return res[1]

View File

@ -83,8 +83,6 @@ def getServicesPoolsCounters(servicePool, counter_type):
class System(Handler):
needs_admin = True # By default, staff is lower level needed
def get(self):
logger.debug('args: {0}'.format(self._args))
if len(self._args) == 1:

View File

@ -176,6 +176,10 @@ class BaseModelHandler(Handler):
def success(self):
return 'done'
def test(self, type_):
logger.debug('Called base test for {0} --> {1}'.format(self.__class__.__name__, self._params))
return self.invalidMethodException()
# Details do not have types at all
# so, right now, we only process details petitions for Handling & tables info
@ -535,7 +539,7 @@ class ModelHandler(BaseModelHandler):
logger.debug('method POST for {0}, {1}'.format(self.__class__.__name__, self._args))
if len(self._args) == 2:
if self._args[0] == 'test':
return 'tested'
return self.test(self._args[1])
self.invalidMethodException()

View File

@ -5,7 +5,7 @@ gui.authenticators.link = (event) ->
# Button definition to trigger "Test" action
testButton = testButton:
text: gettext("Test authenticator")
text: gettext("Test")
css: "btn-info"

View File

@ -291,7 +291,11 @@
fields = gui.forms.read(form_selector)
gui.doLog "Fields: ", fields
rest.test type, fields, ((data) ->
gui.launchModal gettext("Test result"), data,
if data == 'ok'
text = gettext("Test passed successfully")
else
text = "<b class=\"text-danger\">Test failed: #{data}</b>"
gui.launchModal gettext("Test result"), text,
actionButton: " "
return

View File

@ -4,27 +4,27 @@
# Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@ -33,39 +33,41 @@
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.db import IntegrityError
from django.db import IntegrityError
from uds.models import Authenticator
from Groups import getRealGroups
from uds.xmlrpc.util.Helpers import dictFromData
from uds.xmlrpc.util.Exceptions import InsertException, ParametersException, FindException, ValidationException
from uds.core.auths.Exceptions import AuthenticatorException
from uds.core import auths
from uds.core import auths
from AdminAuth import needs_credentials
from uds.core.Environment import Environment
import logging
logger = logging.getLogger(__name__)
def dictFromAuthType(type_):
'''
Returns a dictionary that describes the authenticator, so the administration
interface has the info to handle it.
Args:
type_: Authenticator type (class) where to get information
Returns:
Dictionary describing the Authenticator type
'''
return { 'name' : type_.name(), 'type' : type_.type(), 'description' : type_.description(),
'icon' : type_.icon(), 'isExternalSource' : type_.isExternalSource,
'canSearchUsers' : type_.searchUsers != auths.Authenticator.searchUsers,
return { 'name' : type_.name(), 'type' : type_.type(), 'description' : type_.description(),
'icon' : type_.icon(), 'isExternalSource' : type_.isExternalSource,
'canSearchUsers' : type_.searchUsers != auths.Authenticator.searchUsers,
'canSearchGroups' : type_.searchGroups != auths.Authenticator.searchGroups,
'needsPassword' : type_.needsPassword, 'userNameLabel' : _(type_.userNameLabel),
'needsPassword' : type_.needsPassword, 'userNameLabel' : _(type_.userNameLabel),
'groupNameLabel' : _(type_.groupNameLabel), 'passwordLabel' : _(type_.passwordLabel),
'canCreateUsers' : type_.createUser != auths.Authenticator.createUser,
}
@needs_credentials
def getAuthenticatorsTypes(credentials):
'''
@ -76,6 +78,7 @@ def getAuthenticatorsTypes(credentials):
res.append(dictFromAuthType(_type))
return res
@needs_credentials
def getAuthenticators(credentials):
'''
@ -85,14 +88,15 @@ def getAuthenticators(credentials):
res = []
for auth in Authenticator.objects.all().order_by('priority'):
try:
val = { 'id' : str(auth.id), 'name' : auth.name, 'comments' : auth.comments, 'type' : auth.data_type, 'typeName' : auth.getInstance().name(),
val = { 'id' : str(auth.id), 'name' : auth.name, 'comments' : auth.comments, 'type' : auth.data_type, 'typeName' : auth.getInstance().name(),
'priority' : str(auth.priority), 'smallName' : auth.small_name }
res.append(val)
except Exception, e:
logger.debug("Exception: {0}".format(e))
return res
@needs_credentials
def getAuthenticatorType(credentials, id):
'''
@ -106,6 +110,7 @@ def getAuthenticatorType(credentials, id):
except Authenticator.DoesNotExist:
raise InsertException(_('Authenticator does not exists'))
@needs_credentials
def getAuthenticatorGui(credentials, type):
'''
@ -115,13 +120,14 @@ def getAuthenticatorGui(credentials, type):
authType = auths.factory().lookup(type)
return authType.guiDescription()
@needs_credentials
def getAuthenticator(credentials, id):
'''
Returns the specified authenticator (at database)
'''
data = Authenticator.objects.get(pk=id)
res = [
res = [
{ 'name' : 'name', 'value' : data.name },
{ 'name' : 'comments', 'value' : data.comments },
{ 'name' : 'priority', 'value' : str(data.priority)}
@ -134,12 +140,14 @@ def getAuthenticator(credentials, id):
res.append(val)
return res
@needs_credentials
def getAuthenticatorGroups(credentials, id):
'''
'''
return getRealGroups(id)
@needs_credentials
def createAuthenticator(credentials, type, data):
'''
@ -152,14 +160,14 @@ def createAuthenticator(credentials, type, data):
dict_['_request'] = credentials.request
auth = None
try:
auth = Authenticator.objects.create(name = dict_['name'], comments = dict_['comments'],
data_type = type, priority=int(dict_['priority']), small_name=dict_['smallName'])
auth = Authenticator.objects.create(name=dict_['name'], comments=dict_['comments'],
data_type=type, priority=int(dict_['priority']), small_name=dict_['smallName'])
auth.data = auth.getInstance(dict_).serialize()
auth.save()
except auths.Authenticator.ValidationException as e:
auth.delete()
raise ValidationException(str(e))
except IntegrityError: # Must be exception at creation
except IntegrityError: # Must be exception at creation
raise InsertException(_('Name %s already exists') % (dict_['name']))
except Exception as e:
logger.exception("Exception at createAuthenticator")
@ -167,10 +175,11 @@ def createAuthenticator(credentials, type, data):
if auth is not None:
auth.delete()
raise e
# Returns true always,
# Returns true always,
return True
@needs_credentials
def modifyAuthenticator(credentials, id, data):
'''
@ -194,9 +203,10 @@ def modifyAuthenticator(credentials, id, data):
except Exception as e:
logger.exception(e)
raise ValidationException(str(e))
return True
@needs_credentials
def removeAuthenticator(credentials, id):
'''
@ -205,19 +215,21 @@ def removeAuthenticator(credentials, id):
Authenticator.objects.get(pk=id).delete()
return True
@needs_credentials
def testAuthenticator(credentials, type, data):
def testAuthenticator(credentials, type_, data):
'''
invokes the test function of the specified authenticator type, with the suplied data
'''
logger.debug("Testing authenticator, type: {0}, data:{1}".format(type, data))
authType = auths.factory().lookup(type)
authType = auths.factory().lookup(type_)
# We need an "temporary" environment to test this service
dict_ = dictFromData(data)
dict_['_request'] = credentials.request
res = authType.test(Environment.getTempEnv(), dict_)
return {'ok' : res[0], 'message' : res[1]}
@needs_credentials
def checkAuthenticator(credentials, id):
'''
@ -227,6 +239,7 @@ def checkAuthenticator(credentials, id):
a = auth.getInstance()
return a.check()
@needs_credentials
def searchAuthenticator(credentials, id, srchUser, srchString):
'''
@ -239,14 +252,14 @@ def searchAuthenticator(credentials, id, srchUser, srchString):
if canDoSearch is False:
raise ParametersException(_('Authenticator do not supports search'))
if srchUser is True:
return auth.searchUsers(srchString)
return auth.searchUsers(srchString)
else:
return auth.searchGroups(srchString)
except Authenticator.DoesNotExist:
raise FindException(_('Specified authenticator do not exists anymore. Please, reload gui'))
except AuthenticatorException, e:
raise ParametersException(str(e))
raise FindException(_('BUG: Reached a point that should never have been reached!!!'))

View File

@ -4,35 +4,36 @@
# Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from django.utils.translation import ugettext as _
from django.db import IntegrityError
from django.db import IntegrityError
from uds.models import Provider
from uds.core.services.ServiceProviderFactory import ServiceProviderFactory
from ..util.Helpers import dictFromData
@ -44,6 +45,7 @@ from uds.core import services
logger = logging.getLogger(__name__)
@needs_credentials
def getServiceProvidersTypes(credentials):
'''
@ -55,6 +57,7 @@ def getServiceProvidersTypes(credentials):
res.append(val)
return res
@needs_credentials
def getServiceProviders(credentials):
'''
@ -69,6 +72,7 @@ def getServiceProviders(credentials):
pass
return res
@needs_credentials
def getServiceProviderGui(credentials, type_):
'''
@ -77,13 +81,14 @@ def getServiceProviderGui(credentials, type_):
spType = ServiceProviderFactory.factory().lookup(type_)
return spType.guiDescription()
@needs_credentials
def getServiceProvider(credentials, id_):
'''
Returns the specified service provider (at database)
'''
data = Provider.objects.get(pk=id_)
res = [
res = [
{ 'name' : 'name', 'value' : data.name },
{ 'name' : 'comments', 'value' : data.comments },
]
@ -95,6 +100,7 @@ def getServiceProvider(credentials, id_):
res.append(val)
return res
@needs_credentials
def createServiceProvider(credentials, type_, data):
'''
@ -105,19 +111,20 @@ def createServiceProvider(credentials, type_, data):
try:
dic = dictFromData(data)
# First create data without serialization, then serialies data with correct environment
sp = Provider.objects.create(name = dic['name'], comments = dic['comments'], data_type = type_)
sp = Provider.objects.create(name=dic['name'], comments=dic['comments'], data_type=type_)
sp.data = sp.getInstance(dic).serialize()
sp.save()
except services.ServiceProvider.ValidationException as e:
sp.delete()
raise ValidationException(str(e))
except IntegrityError: # Must be exception at creation
except IntegrityError: # Must be exception at creation
raise InsertException(_('Name %s already exists') % (dic['name']))
except Exception as e:
logger.exception('Unexpected exception')
raise ValidationException(str(e))
return True
@needs_credentials
def modifyServiceProvider(credentials, id_, data):
'''
@ -135,14 +142,15 @@ def modifyServiceProvider(credentials, id_, data):
prov.save()
except services.ServiceProvider.ValidationException as e:
raise ValidationException(str(e))
except IntegrityError: # Must be exception at creation
except IntegrityError: # Must be exception at creation
raise InsertException(_('Name %s already exists') % (dic['name']))
except Exception as e:
logger.exception('Unexpected exception')
raise ValidationException(str(e))
return True
@needs_credentials
def removeServiceProvider(credentials, id_):
'''
@ -157,6 +165,7 @@ def removeServiceProvider(credentials, id_):
raise FindException(_('Can\'t locate the service provider') + '.' + _('Please, refresh interface'))
return True
@needs_credentials
def getOffersFromServiceProvider(credentials, type_):
'''
@ -169,6 +178,7 @@ def getOffersFromServiceProvider(credentials, type_):
res.append(val)
return res
@needs_credentials
def testServiceProvider(credentials, type_, data):
'''
@ -181,6 +191,7 @@ def testServiceProvider(credentials, type_, data):
res = spType.test(Environment.getTempEnv(), dct)
return {'ok' : res[0], 'message' : res[1]}
@needs_credentials
def checkServiceProvider(credentials, id_):
'''
@ -189,7 +200,7 @@ def checkServiceProvider(credentials, id_):
prov = Provider.objects.get(id=id_)
sp = prov.getInstance()
return sp.check()
# Registers XML RPC Methods
def registerServiceProvidersFunctions(dispatcher):
@ -203,5 +214,4 @@ def registerServiceProvidersFunctions(dispatcher):
dispatcher.register_function(getOffersFromServiceProvider, 'getOffersFromServiceProvider')
dispatcher.register_function(testServiceProvider, 'testServiceProvider')
dispatcher.register_function(checkServiceProvider, 'checkServiceProvider')