* Updated sample to add secondary auth

* Removed unused comments
* Added sypport for login using REST for any authenticator
* Added new icon (good one) to UDS
This commit is contained in:
Adolfo Gómez 2014-06-30 12:10:20 +00:00
parent b10a0ac386
commit d4c065355c
6 changed files with 51 additions and 44 deletions

View File

@ -6,6 +6,7 @@ encoding//documentation/_downloads/samples/services/SampleUserDeploymentOne.py=u
encoding//documentation/_downloads/samples/services/SampleUserDeploymentTwo.py=utf-8 encoding//documentation/_downloads/samples/services/SampleUserDeploymentTwo.py=utf-8
encoding//documentation/_downloads/samples/services/__init__.py=utf-8 encoding//documentation/_downloads/samples/services/__init__.py=utf-8
encoding//documentation/conf.py=utf-8 encoding//documentation/conf.py=utf-8
encoding//samples/REST1.py=utf-8
encoding//src/server/enterprise_settings.py=utf-8 encoding//src/server/enterprise_settings.py=utf-8
encoding//src/server/settings.py=utf-8 encoding//src/server/settings.py=utf-8
encoding//src/server/urls.py=utf-8 encoding//src/server/urls.py=utf-8

View File

@ -45,7 +45,8 @@ def login():
global headers global headers
h = Http() h = Http()
parameters = '{ "auth": "admin", "username": "root", "password": "temporal" }' # parameters = '{ "auth": "admin", "username": "root", "password": "temporal" }'
parameters = '{ "auth": "interna", "username": "admin", "password": "temporal" }'
resp, content = h.request(rest_url + 'auth/login', method='POST', body=parameters) resp, content = h.request(rest_url + 'auth/login', method='POST', body=parameters)
@ -117,7 +118,7 @@ def request_service_info(provider_id, service_id):
return json.loads(content) return json.loads(content)
if __name__ == '__main__': if __name__ == '__main__':
request_pools() # Not logged in, this will generate an error # request_pools() # Not logged in, this will generate an error
if login() == 0: # If we can log in, will get the pools correctly if login() == 0: # If we can log in, will get the pools correctly
res = request_pools() res = request_pools()

View File

@ -100,32 +100,13 @@ class Dispatcher(View):
args = path args = path
# try:
# lang = request.LANGUAGE_CODE
# except:
# lang = None
# Inspect url to see if it contains a language
# if len(args) > 0:
# for l in settings.LANGUAGES:
# if args[-1] == l[0]:
# lang = l[0]
# activate(lang)
# logger.error('Found lang {0}'.format(l))
# args = args[:-1]
# break
# Instantiate method handler and locate http_method dispatcher
try: try:
handler = cls(request, full_path, http_method, processor.processParameters(), *args, **kwargs) handler = cls(request, full_path, http_method, processor.processParameters(), *args, **kwargs)
# If no lang on request, try to get the one from
# if lang is None:
# activate(handler.getValue('locale'))
# else:
# handler.setValue('locale', lang) # Update Locale if request had one
operation = getattr(handler, http_method) operation = getattr(handler, http_method)
except processors.ParametersException as e: except processors.ParametersException as e:
return http.HttpResponseServerError('Invalid parameters invoking {0}: {1}'.format(path[0], e)) logger.debug('Path: {0}'.format(full_path))
logger.debug('Error: {0}'.format(e))
return http.HttpResponseServerError('Invalid parameters invoking {0}: {1}'.format(full_path, e))
except AttributeError: except AttributeError:
allowedMethods = [] allowedMethods = []
for n in ['get', 'post', 'put', 'delete']: for n in ['get', 'post', 'put', 'delete']:

View File

@ -34,6 +34,7 @@ from __future__ import unicode_literals
from uds.core.util.Config import GlobalConfig from uds.core.util.Config import GlobalConfig
from uds.models import Authenticator from uds.models import Authenticator
from uds.core.auths.auth import authenticate
from uds.REST import Handler from uds.REST import Handler
@ -58,11 +59,12 @@ class Login(Handler):
username: username:
password: password:
auth: auth:
optional:
locale: (defaults to "en")
Result: Result:
on success: { 'result': 'ok', 'auth': [auth_code] } on success: { 'result': 'ok', 'auth': [auth_code] }
on error: { 'result: 'error', 'error': [error string] } on error: { 'result: 'error', 'error': [error string] }
Locale comes on "Header", as any HTTP Request (Accept-Language header)
Calls to any method of REST that must be authenticated needs to be called with "X-Auth-Token" Header added
''' '''
try: try:
username, auth, password = self._params['username'], self._params['auth'], self._params['password'] username, auth, password = self._params['username'], self._params['auth'], self._params['password']
@ -73,6 +75,20 @@ class Login(Handler):
return{'result': 'ok', 'token': self.getAuthToken()} return{'result': 'ok', 'token': self.getAuthToken()}
else: else:
raise Exception('Invalid credentials') raise Exception('Invalid credentials')
else:
try:
logger.debug('Auth: {0}'.format(auth))
auth = Authenticator.objects.get(name=auth)
logger.debug('Auth obj: {0}'.format(auth))
user = authenticate(username, password, auth)
if user is None: # invalid credentials
raise Exception()
self.genAuthToken(auth.id, user.name, locale, user.is_admin, user.staff_member)
return{'result': 'ok', 'token': self.getAuthToken()}
except:
logger.exception('Credentials ')
raise Exception('Invalid Credentials (invalid authenticator)')
raise Exception('Invalid Credentials') raise Exception('Invalid Credentials')
except Exception as e: except Exception as e:
logger.exception('exception') logger.exception('exception')
@ -106,12 +122,3 @@ class Auths(Handler):
def get(self): def get(self):
return list(self.auths()) return list(self.auths())
class Locale(Handler):
authenticated = True
def get(self):
if len(self._args) > 0:
self.setValue('locale', self._args[1])
return ''

View File

@ -4,6 +4,28 @@
# Copyright (c) 2012 Virtual Cable S.L. # Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved. # All rights reserved.
# #
# 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,
# 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
# 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
# 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
# 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
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''' '''
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
@ -29,7 +51,6 @@ class LinuxRandomPassManager(LinuxOsManager):
# Apart form data from linux os manager, we need also domain and credentials # Apart form data from linux os manager, we need also domain and credentials
userAccount = gui.TextField(length=64, label=_('Account'), order=2, tooltip=_('User account to change password'), required=True) userAccount = gui.TextField(length=64, label=_('Account'), order=2, tooltip=_('User account to change password'), required=True)
password = gui.PasswordField(length=64, label=_('Password'), order=3, tooltip=_('Current (template) password of the user account'), required=True)
# Inherits base "onLogout" # Inherits base "onLogout"
onLogout = LinuxOsManager.onLogout onLogout = LinuxOsManager.onLogout
@ -42,10 +63,8 @@ class LinuxRandomPassManager(LinuxOsManager):
if values['password'] == '': if values['password'] == '':
raise osmanagers.OSManager.ValidationException(_('Must provide a password for the account!!!')) raise osmanagers.OSManager.ValidationException(_('Must provide a password for the account!!!'))
self._userAccount = values['userAccount'] self._userAccount = values['userAccount']
self._password = values['password']
else: else:
self._userAccount = '' self._userAccount = ''
self._password = ""
def release(self, service): def release(self, service):
super(LinuxRandomPassManager, self).release(service) super(LinuxRandomPassManager, self).release(service)
@ -65,27 +84,25 @@ class LinuxRandomPassManager(LinuxOsManager):
return randomPass return randomPass
def infoVal(self, service): def infoVal(self, service):
return 'rename:{0}\t{1}\t{2}\t{3}'.format(self.getName(service), self._userAccount, self._password, self.genPassword(service)) return 'rename:{0}\t{1}\t{2}\t{3}'.format(self.getName(service), self._userAccount, self.genPassword(service))
def infoValue(self, service): def infoValue(self, service):
return 'rename\r{0}\t{1}\t{2}\t{3}'.format(self.getName(service), self._userAccount, self._password, self.genPassword(service)) return 'rename\r{0}\t{1}\t{2}\t{3}'.format(self.getName(service), self._userAccount, self.genPassword(service))
def marshal(self): def marshal(self):
base = super(LinuxRandomPassManager, self).marshal() base = super(LinuxRandomPassManager, self).marshal()
''' '''
Serializes the os manager data so we can store it in database Serializes the os manager data so we can store it in database
''' '''
return '\t'.join(['v1', self._userAccount, CryptoManager.manager().encrypt(self._password), base.encode('hex')]) return '\t'.join(['v1', self._userAccount, base.encode('hex')])
def unmarshal(self, s): def unmarshal(self, s):
data = s.split('\t') data = s.split('\t')
if data[0] == 'v1': if data[0] == 'v1':
self._userAccount = data[1] self._userAccount = data[1]
self._password = CryptoManager.manager().decrypt(data[2])
super(LinuxRandomPassManager, self).unmarshal(data[3].decode('hex')) super(LinuxRandomPassManager, self).unmarshal(data[3].decode('hex'))
def valuesDict(self): def valuesDict(self):
dic = super(LinuxRandomPassManager, self).valuesDict() dic = super(LinuxRandomPassManager, self).valuesDict()
dic['userAccount'] = self._userAccount dic['userAccount'] = self._userAccount
dic['password'] = self._password
return dic return dic

View File

@ -11,7 +11,7 @@
<meta name="robots" content="noindex, nofollow" /> <meta name="robots" content="noindex, nofollow" />
{% block meta %}{% endblock %} {% block meta %}{% endblock %}
{% block icon %}<link href="{% get_static_prefix %}img/favicon.png" rel="icon" type="image/x-icon" />{% endblock %} {% block icon %}<link href="{% get_static_prefix %}img/favicon.png?v=2" rel="icon" type="image/x-icon" />{% endblock %}
<!-- Bootstrap --> <!-- Bootstrap -->
{% compress css %} {% compress css %}