TG-35 : Structure TU + TU LoginAPI
This commit is contained in:
parent
c96d6ad0f8
commit
1b6d51516d
@ -1,6 +1,6 @@
|
||||
from flask import session
|
||||
from flask.ext.restful.reqparse import RequestParser
|
||||
from flask_restful import Resource
|
||||
from flask_restful.reqparse import RequestParser
|
||||
|
||||
from app.model import *
|
||||
|
||||
@ -20,14 +20,24 @@ class LoginAPI(Resource):
|
||||
|
||||
if userInfo is not None:
|
||||
query = USER.select(USER.c.login == userInfo["login"])
|
||||
res = query.execute()
|
||||
user = res.first()
|
||||
# TODO : check si le user fait partie d'un group actif
|
||||
if query.count() == 1:
|
||||
session['user'] = query.select().execute().first()
|
||||
if user is not None:
|
||||
session['user'] = user.id
|
||||
return {'AUTH_RESULT': 'OK'}, 200
|
||||
else:
|
||||
return {'AUTH_RESULT': 'NOT_ALLOWED'}, 403
|
||||
else:
|
||||
return {'AUTH_RESULT': 'AUTHENTICATION_FAILED'}, 401
|
||||
|
||||
def delete(self):
|
||||
session['user'] = None
|
||||
return {'AUTH_RESULT': 'OK'}, 200
|
||||
|
||||
def getUserInfoFromCAS(self, login, password):
|
||||
pass
|
||||
# TODO : A implémenter
|
||||
if (login == "admin" or login == "toto") and password == login:
|
||||
return {"login": login}
|
||||
else:
|
||||
return None
|
||||
|
@ -2,6 +2,9 @@ import random
|
||||
import string
|
||||
from hashlib import sha512
|
||||
|
||||
from flask import json
|
||||
from sqlalchemy.ext.declarative import DeclarativeMeta
|
||||
|
||||
SIMPLE_CHARS = string.ascii_letters + string.digits
|
||||
|
||||
|
||||
@ -13,3 +16,38 @@ def get_random_hash(length=64):
|
||||
hash = sha512()
|
||||
hash.update(get_random_string())
|
||||
return hash.hexdigest()[:length]
|
||||
|
||||
|
||||
def new_alchemy_encoder(revisit_self=False, fields_to_expand=[]):
|
||||
_visited_objs = []
|
||||
|
||||
class AlchemyEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj.__class__, DeclarativeMeta):
|
||||
# don't re-visit self
|
||||
if revisit_self:
|
||||
if obj in _visited_objs:
|
||||
return None
|
||||
_visited_objs.append(obj)
|
||||
|
||||
# go through each field in this SQLalchemy class
|
||||
fields = {}
|
||||
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']:
|
||||
val = obj.__getattribute__(field)
|
||||
|
||||
# is this field another SQLalchemy object, or a list of SQLalchemy objects?
|
||||
if isinstance(val.__class__, DeclarativeMeta) or (
|
||||
isinstance(val, list) and len(val) > 0 and isinstance(val[0].__class__, DeclarativeMeta)):
|
||||
# unless we're expanding this field, stop here
|
||||
if field not in fields_to_expand:
|
||||
# not expanding this field: set it to None and continue
|
||||
fields[field] = None
|
||||
continue
|
||||
|
||||
fields[field] = val
|
||||
# a json-encodable dict
|
||||
return fields
|
||||
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
return AlchemyEncoder
|
||||
|
@ -25,7 +25,7 @@ else:
|
||||
Config.configure_app(config="prod")
|
||||
|
||||
core = importlib.import_module("app.core")
|
||||
model = importlib.import_module("backend.app.model")
|
||||
model = importlib.import_module("app.model")
|
||||
|
||||
manager = Manager(core.app)
|
||||
manager.add_option("-d", "--debug",
|
||||
@ -75,7 +75,6 @@ manager.add_command('checkdb', CheckDB())
|
||||
class RunTests(Command):
|
||||
"""Seed the db """
|
||||
def run(self):
|
||||
Config.configure_app(config="test")
|
||||
test_loader = unittest.defaultTestLoader
|
||||
test_runner = unittest.TextTestRunner()
|
||||
test_suite = test_loader.discover('tests')
|
||||
|
0
backend/tests/api/__init__.py
Normal file
0
backend/tests/api/__init__.py
Normal file
@ -1,7 +1,8 @@
|
||||
import unittest
|
||||
|
||||
from flask import json
|
||||
|
||||
from backend.app.core import app
|
||||
import unittest
|
||||
from app.core import app
|
||||
|
||||
|
||||
class AuthTestCase(unittest.TestCase):
|
||||
|
54
backend/tests/api/test_loginAPI.py
Normal file
54
backend/tests/api/test_loginAPI.py
Normal file
@ -0,0 +1,54 @@
|
||||
import unittest
|
||||
|
||||
from flask import json
|
||||
|
||||
from app.core import app
|
||||
|
||||
|
||||
class AuthTestCase(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
self.app = app.test_client()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def login(self, email, password):
|
||||
return self.app.post('/api/login',
|
||||
data=json.dumps(
|
||||
dict(
|
||||
login=email,
|
||||
password=password
|
||||
)
|
||||
), content_type='application/json')
|
||||
|
||||
def logout(self):
|
||||
return self.app.delete('/api/login')
|
||||
|
||||
def test_login_logout(self):
|
||||
rv = self.login('admin', 'admin')
|
||||
self.assertEqual(rv.status_code, 200, 'Login as admin Failed')
|
||||
|
||||
rv = self.logout()
|
||||
self.assertEqual(rv.status_code, 200, 'Logout Failed')
|
||||
|
||||
rv = self.login('adminx', 'admin')
|
||||
self.assertEqual(rv.status_code, 401, 'Authentication from CAS has not failed for the invalid user xadmin !')
|
||||
|
||||
rv = self.login('admin', 'adminx')
|
||||
self.assertEqual(rv.status_code, 401,
|
||||
'Authentication from CAS has not failed for the invalid password xadmin !')
|
||||
|
||||
rv = self.login('toto', 'toto')
|
||||
self.assertEqual(rv.status_code, 403, 'Authentication shouldn\'t be allowed for user toto !')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
0
backend/tests/tools/__init__.py
Normal file
0
backend/tests/tools/__init__.py
Normal file
0
backend/tests/tools/pdfjinja/__init__.py
Normal file
0
backend/tests/tools/pdfjinja/__init__.py
Normal file
@ -7,7 +7,7 @@ skipsdist = True
|
||||
|
||||
[testenv]
|
||||
commands=
|
||||
coverage run --source app/api app/tools --omit app/api/*/model.py manage.py runtests
|
||||
coverage run --source app/api,app/tools manage.py -t runtests
|
||||
coverage report -m
|
||||
coverage xml
|
||||
coverage html
|
||||
|
Reference in New Issue
Block a user