setup tests for jenkins' build (#13272)
This commit is contained in:
parent
27faf42f1d
commit
28577537ab
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Get venv site-packages path
|
||||||
|
DSTDIR=`python -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'`
|
||||||
|
|
||||||
|
# Get not venv site-packages path
|
||||||
|
# Remove first path (assuming that is the venv path)
|
||||||
|
NONPATH=`echo $PATH | sed 's/^[^:]*://'`
|
||||||
|
SRCDIR=`PATH=$NONPATH python -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'`
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -f $DSTDIR/lasso.*
|
||||||
|
rm -f $DSTDIR/_lasso.*
|
||||||
|
|
||||||
|
# Link
|
||||||
|
ln -sv $SRCDIR/lasso.py $DSTDIR
|
||||||
|
ln -sv $SRCDIR/_lasso.* $DSTDIR
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
rm -f coverage.xml
|
||||||
|
rm -f test_results.xml
|
||||||
|
|
||||||
|
pip install --upgrade tox
|
||||||
|
tox -r
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e -x
|
||||||
|
env
|
||||||
|
if [ -f /var/lib/jenkins/pylint.django.rc ]; then
|
||||||
|
PYLINT_RC=/var/lib/jenkins/pylint.django.rc
|
||||||
|
elif [ -f pylint.django.rc ]; then
|
||||||
|
PYLINT_RC=pylint.django.rc
|
||||||
|
else
|
||||||
|
echo No pylint RC found
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -f pylint.out && cp pylint.out pylint.out.prev
|
||||||
|
pylint -f parseable --rcfile ${PYLINT_RC} "$@" | tee pylint.out || /bin/true
|
||||||
|
test -f pylint.out.prev && (diff pylint.out.prev pylint.out | grep '^[><]' | grep .py) || /bin/true¶
|
11
setup.py
11
setup.py
|
@ -66,8 +66,10 @@ class compile_translations(Command):
|
||||||
continue
|
continue
|
||||||
curdir = os.getcwd()
|
curdir = os.getcwd()
|
||||||
os.chdir(os.path.realpath(path))
|
os.chdir(os.path.realpath(path))
|
||||||
call_command('compilemessages')
|
try:
|
||||||
os.chdir(curdir)
|
call_command('compilemessages')
|
||||||
|
finally:
|
||||||
|
os.chdir(curdir)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.stderr.write('!!! Please install Django >= 1.4 to build translations\n')
|
sys.stderr.write('!!! Please install Django >= 1.4 to build translations\n')
|
||||||
|
|
||||||
|
@ -103,13 +105,14 @@ setup(
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2',
|
'Programming Language :: Python :: 2',
|
||||||
],
|
],
|
||||||
install_requires=['django>=1.7, <1.8',
|
install_requires=['django>=1.8, <1.9',
|
||||||
'gadjo',
|
'gadjo',
|
||||||
'django-jsonfield',
|
'django-jsonfield',
|
||||||
'python-ldap',
|
'python-ldap',
|
||||||
'pycrypto',
|
'pycrypto',
|
||||||
'requests',
|
'requests',
|
||||||
'djangorestframework'
|
'djangorestframework',
|
||||||
|
'django-mellon'
|
||||||
],
|
],
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
cmdclass={
|
cmdclass={
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from utils import create_user, create_credentials
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
if settings.HOBO:
|
||||||
|
from hobo import signature
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def admin(db):
|
||||||
|
return create_user(
|
||||||
|
username='admin',
|
||||||
|
first_name='admin',
|
||||||
|
last_name='admin',
|
||||||
|
email='admin@example.net',
|
||||||
|
is_superuser=True,
|
||||||
|
is_staff=True,
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def user_john(db):
|
||||||
|
return create_user(username='john')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def cred_john(db, user_john):
|
||||||
|
return create_credentials(user_john, {
|
||||||
|
"login": "john",
|
||||||
|
"password": "john password"})
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['cred_john'])
|
||||||
|
def credentials(request, cred_john):
|
||||||
|
return locals().get(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
# MIGRATION COMMAND
|
||||||
|
def cmd(*args, **kwargs):
|
||||||
|
cmd = type(
|
||||||
|
'Cmd',
|
||||||
|
(object,),
|
||||||
|
{
|
||||||
|
'name': 'migrate-users',
|
||||||
|
'args': args,
|
||||||
|
'opts': kwargs
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def command_ldap():
|
||||||
|
return cmd('tests/ldap_users.txt', ldap=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def command_csv():
|
||||||
|
return cmd('tests/csv_users.csv', csv=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['command_ldap', 'command_csv'])
|
||||||
|
def command(request, command_ldap, command_csv):
|
||||||
|
return locals().get(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def url():
|
||||||
|
return reverse('api')
|
||||||
|
|
||||||
|
|
||||||
|
def create_signed_url(secret, orig):
|
||||||
|
url = signature.sign_url(reverse('api'), secret)
|
||||||
|
url += '&orig={}'.format(orig)
|
||||||
|
return type(
|
||||||
|
'signed_url',
|
||||||
|
(object,),
|
||||||
|
{'url': url, 'orig': orig}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def url_signed_testserver_service():
|
||||||
|
return create_signed_url(
|
||||||
|
settings.SECRET_KEY,
|
||||||
|
'testserver'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def url_signed_unknown_service():
|
||||||
|
return create_signed_url(
|
||||||
|
settings.SECRET_KEY,
|
||||||
|
'lol'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['url_signed_testserver_service', 'url_signed_unknown_service'])
|
||||||
|
def url_signed(request, url_signed_testserver_service, url_signed_unknown_service):
|
||||||
|
return locals().get(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client_service():
|
||||||
|
return APIClient()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client_anonymous():
|
||||||
|
return APIClient()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client_logged(admin):
|
||||||
|
client = APIClient()
|
||||||
|
client.login(username='admin', password='admin')
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['client_anonymous', 'client_logged'])
|
||||||
|
def client(request, client_anonymous, client_logged):
|
||||||
|
return locals().get(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def kevin_payload():
|
||||||
|
return {
|
||||||
|
'name_id_content': '12345',
|
||||||
|
'email': 'kevin@fake.com',
|
||||||
|
'first_name': 'kevin',
|
||||||
|
'last_name': 'fake',
|
||||||
|
'locators': {
|
||||||
|
'login': 'fake',
|
||||||
|
'password': 'fake'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def josh_payload():
|
||||||
|
return {
|
||||||
|
'name_id_content': '77777',
|
||||||
|
'email': 'josh@loking.com',
|
||||||
|
'first_name': 'josh',
|
||||||
|
'last_name': 'loking',
|
||||||
|
'locators': {
|
||||||
|
'login': 'josh',
|
||||||
|
'password': 'josh password'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['kevin_payload', 'josh_payload'])
|
||||||
|
def payload(request, kevin_payload, josh_payload):
|
||||||
|
return locals().get(request.param)
|
|
@ -0,0 +1,49 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from rest_framework.settings import api_settings
|
||||||
|
|
||||||
|
try:
|
||||||
|
import hobo
|
||||||
|
except(ImportError,):
|
||||||
|
hobo = None
|
||||||
|
|
||||||
|
HOBO = hobo
|
||||||
|
|
||||||
|
MELLON_IDENTITY_PROVIDERS = [
|
||||||
|
{
|
||||||
|
'METADATA_URL': 'http://testsever.org/idp/saml2/metadata'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
SITE_APP = 'mandayejs.applications.Test'
|
||||||
|
SECRET_KEY = 'od5cei4aeveel8dui4lei2ou9ahsei2A'
|
||||||
|
|
||||||
|
KNOWN_SERVICES = {
|
||||||
|
"service":{
|
||||||
|
"testserver": {
|
||||||
|
"title": "testserver",
|
||||||
|
"orig": "testserver",
|
||||||
|
"url": "http://testserver",
|
||||||
|
"secret": "od5cei4aeveel8dui4lei2ou9ahsei2A",
|
||||||
|
"verif_orig": "testserver"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser'
|
||||||
|
|
||||||
|
# REST FRAMEWORK SETTINGS
|
||||||
|
if hobo:
|
||||||
|
AUTHENTICATION_CLASSES = (
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
'rest_framework.authentication.BasicAuthentication',
|
||||||
|
'hobo.rest_authentication.PublikAuthentication',
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
AUTHENTICATION_CLASSES = (
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
'rest_framework.authentication.BasicAuthentication',
|
||||||
|
)
|
||||||
|
|
||||||
|
api_settings.user_settings.update({
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES' : AUTHENTICATION_CLASSES,
|
||||||
|
})
|
|
@ -0,0 +1,197 @@
|
||||||
|
import mock
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.management import call_command
|
||||||
|
|
||||||
|
from mandayejs.mandaye.models import UserCredentials
|
||||||
|
|
||||||
|
from utils import create_user, create_credentials, get_uuid, get_user
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
# ENCRYPTION/DECRYPTION
|
||||||
|
def test_encryption(credentials):
|
||||||
|
decrypted = credentials.decrypt()
|
||||||
|
assert decrypted.get('password') == 'john password'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=['command_ldap', 'command_csv'])
|
||||||
|
def command(request, command_ldap, command_csv):
|
||||||
|
return locals().get(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('mandayejs.mandaye.management.commands.migrate-users.get_idps')
|
||||||
|
def test_command_migrate_users(mocked_idps, command):
|
||||||
|
mocked_idps.return_value = iter(settings.MELLON_IDENTITY_PROVIDERS)
|
||||||
|
call_command(command.name, *command.args, **command.opts)
|
||||||
|
if command.opts.get('ldap'):
|
||||||
|
credentials = UserCredentials.objects.filter(user__last_name__in=[
|
||||||
|
'ldap_user1',
|
||||||
|
'ldap_user2',
|
||||||
|
'ldap_user3'])
|
||||||
|
|
||||||
|
assert len(credentials) == 3
|
||||||
|
|
||||||
|
for cred in credentials:
|
||||||
|
assert cred.to_login_info(decrypt=True)['#password'] == 'password_{}'.format(cred.user.last_name)
|
||||||
|
else:
|
||||||
|
credentials = UserCredentials.objects.all().exclude(user__last_name__in=[
|
||||||
|
'ldap_user1',
|
||||||
|
'ldap_user2',
|
||||||
|
'ldap_user3'
|
||||||
|
])
|
||||||
|
|
||||||
|
assert len(credentials) == 4
|
||||||
|
|
||||||
|
for cred in credentials:
|
||||||
|
assert cred.to_login_info(decrypt=True)['#password'] == cred.to_login_info()['#username']
|
||||||
|
|
||||||
|
|
||||||
|
# MANDAYE API
|
||||||
|
|
||||||
|
# GET
|
||||||
|
def test_api_get(client, url):
|
||||||
|
response = client.get(url)
|
||||||
|
if client.session.values():
|
||||||
|
status_code = 200
|
||||||
|
else:
|
||||||
|
status_code = 403
|
||||||
|
|
||||||
|
assert response.status_code == status_code
|
||||||
|
|
||||||
|
if status_code == 200:
|
||||||
|
assert {'login': '', 'password': ''} == response.data
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required")
|
||||||
|
def test_signed_api_get(client_service, url_signed):
|
||||||
|
response = client_service.get(url_signed.url)
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
status_code = 200
|
||||||
|
else:
|
||||||
|
status_code = 403
|
||||||
|
|
||||||
|
assert response.status_code == status_code
|
||||||
|
|
||||||
|
if status_code == 200:
|
||||||
|
assert {'login': '', 'password': ''} == response.data
|
||||||
|
|
||||||
|
|
||||||
|
# POST
|
||||||
|
@mock.patch('mandayejs.mandaye.api.exec_phantom')
|
||||||
|
def test_api_post(mock_phantomjs_result, client, url, payload):
|
||||||
|
|
||||||
|
if client.session.values():
|
||||||
|
status_code = {'success': 200, 'failure': 401}
|
||||||
|
else:
|
||||||
|
status_code = {'success': 403, 'failure': 403}
|
||||||
|
|
||||||
|
if payload.get('name_id_content') == '12345':
|
||||||
|
response = client.post(url, data=payload, format='json')
|
||||||
|
|
||||||
|
assert response.status_code == status_code['failure']
|
||||||
|
|
||||||
|
if client.session.values():
|
||||||
|
kevin = get_user(first_name='kevin')
|
||||||
|
assert kevin.username == payload['name_id_content']
|
||||||
|
|
||||||
|
kevin_uuid = get_uuid(name_id=payload['name_id_content'])
|
||||||
|
assert kevin_uuid.name_id == '12345'
|
||||||
|
else:
|
||||||
|
mock_phantomjs_result.return_value = {"result": "ok"}
|
||||||
|
|
||||||
|
response = client.post(url, data=payload, format='json')
|
||||||
|
|
||||||
|
assert response.status_code == status_code['success']
|
||||||
|
|
||||||
|
if client.session.values():
|
||||||
|
josh = get_user(username='77777')
|
||||||
|
josh_creds = UserCredentials.objects.filter(user=josh)[0]
|
||||||
|
|
||||||
|
assert josh_creds.to_login_info()['#login'] == 'josh'
|
||||||
|
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required")
|
||||||
|
@mock.patch('mandayejs.mandaye.api.exec_phantom')
|
||||||
|
def test_signed_api_post(mock_phantomjs_result, client_service, url_signed, payload):
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
status_code = {'success': 200, 'failure': 401}
|
||||||
|
else:
|
||||||
|
status_code = {'success': 403, 'failure': 403}
|
||||||
|
|
||||||
|
if payload.get('name_id_content') == '12345':
|
||||||
|
response = client_service.post(url_signed.url, data=payload, format='json')
|
||||||
|
|
||||||
|
assert response.status_code == status_code['failure']
|
||||||
|
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
kevin = get_user(first_name='kevin')
|
||||||
|
assert kevin.username == payload['name_id_content']
|
||||||
|
|
||||||
|
kevin_uuid = get_uuid(name_id=payload['name_id_content'])
|
||||||
|
assert kevin_uuid.name_id == '12345'
|
||||||
|
else:
|
||||||
|
mock_phantomjs_result.return_value = {"result": "ok"}
|
||||||
|
|
||||||
|
response = client_service.post(url_signed.url, data=payload, format='json')
|
||||||
|
|
||||||
|
assert response.status_code == status_code['success']
|
||||||
|
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
josh = get_user(username='77777')
|
||||||
|
josh_creds = UserCredentials.objects.filter(user=josh)[0]
|
||||||
|
|
||||||
|
assert josh_creds.to_login_info()['#login'] == 'josh'
|
||||||
|
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password'
|
||||||
|
|
||||||
|
|
||||||
|
# DELETE
|
||||||
|
def test_api_delete(client, url):
|
||||||
|
if client.session.values():
|
||||||
|
status_code = {'success': 200, 'failure': 404}
|
||||||
|
else:
|
||||||
|
status_code = {'success': 403, 'failure': 403}
|
||||||
|
|
||||||
|
kevin = get_user(first_name='kevin')
|
||||||
|
assert UserCredentials.objects.filter(user=kevin).exists() is False
|
||||||
|
response = client.delete(url, data={'name_id_content': '12345'}, format='json')
|
||||||
|
assert response.status_code == status_code['failure']
|
||||||
|
|
||||||
|
josh = create_user(username='77777')
|
||||||
|
create_credentials(josh, {
|
||||||
|
'login': 'josh',
|
||||||
|
'password': 'josh password'})
|
||||||
|
|
||||||
|
assert UserCredentials.objects.filter(user=josh).exists() is True
|
||||||
|
response = client.delete(url, data={'name_id_content': '77777'}, format='json')
|
||||||
|
assert response.status_code == status_code['success']
|
||||||
|
if client.session.values():
|
||||||
|
assert UserCredentials.objects.filter(user=josh).exists() is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required")
|
||||||
|
def test_signed_api_delete(client_service, url_signed):
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
status_code = {'success': 200, 'failure': 404}
|
||||||
|
else:
|
||||||
|
status_code = {'success': 403, 'failure': 403}
|
||||||
|
|
||||||
|
kevin = get_user(first_name='kevin')
|
||||||
|
assert UserCredentials.objects.filter(user=kevin).exists() is False
|
||||||
|
response = client_service.delete(url_signed.url, data={'name_id_content': '12345'}, format='json')
|
||||||
|
assert response.status_code == status_code['failure']
|
||||||
|
|
||||||
|
josh = create_user(username='77777')
|
||||||
|
create_credentials(josh, {
|
||||||
|
'login': 'josh',
|
||||||
|
'password': 'josh password'
|
||||||
|
})
|
||||||
|
|
||||||
|
assert UserCredentials.objects.filter(user=josh).exists() is True
|
||||||
|
response = client_service.delete(url_signed.url, data={'name_id_content': '77777'}, format='json')
|
||||||
|
assert response.status_code == status_code['success']
|
||||||
|
if url_signed.orig == 'testserver':
|
||||||
|
assert UserCredentials.objects.filter(user=josh).exists() is False
|
409
tests/tests.py
409
tests/tests.py
|
@ -1,409 +0,0 @@
|
||||||
import mock
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.management import call_command
|
|
||||||
|
|
||||||
from rest_framework.test import APIClient
|
|
||||||
from rest_framework.settings import api_settings
|
|
||||||
|
|
||||||
from mandayejs.applications import get_app_settings
|
|
||||||
from mandayejs.mandaye.models import UserCredentials
|
|
||||||
from mandayejs.mandaye import utils
|
|
||||||
|
|
||||||
from mellon.models import UserSAMLIdentifier
|
|
||||||
|
|
||||||
try:
|
|
||||||
import hobo
|
|
||||||
from hobo import signature
|
|
||||||
except(ImportError,):
|
|
||||||
hobo = None
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
|
||||||
|
|
||||||
settings.MELLON_IDENTITY_PROVIDERS = [
|
|
||||||
{
|
|
||||||
'METADATA_URL': 'http://testsever.org/idp/saml2/metadata'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
settings.SITE_APP = 'mandayejs.applications.Test'
|
|
||||||
settings.SECRET_KEY = 'od5cei4aeveel8dui4lei2ou9ahsei2A'
|
|
||||||
|
|
||||||
settings.KNOWN_SERVICES = {
|
|
||||||
"service":{
|
|
||||||
"testserver": {
|
|
||||||
"title": "testserver",
|
|
||||||
"orig": "testserver",
|
|
||||||
"url": "http://testserver",
|
|
||||||
"secret": "od5cei4aeveel8dui4lei2ou9ahsei2A",
|
|
||||||
"verif_orig": "testserver"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser'
|
|
||||||
|
|
||||||
# REST FRAMEWORK SETTINGS
|
|
||||||
if hobo:
|
|
||||||
AUTHENTICATION_CLASSES = (
|
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
|
||||||
'rest_framework.authentication.BasicAuthentication',
|
|
||||||
'hobo.rest_authentication.PublikAuthentication',
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
AUTHENTICATION_CLASSES = (
|
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
|
||||||
'rest_framework.authentication.BasicAuthentication',
|
|
||||||
)
|
|
||||||
|
|
||||||
api_settings.user_settings.update({
|
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES' : AUTHENTICATION_CLASSES,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
# ENCRYPTION/DECRYPTION
|
|
||||||
def create_user(**kwargs):
|
|
||||||
password = kwargs.pop('password', None) or kwargs.get('username')
|
|
||||||
user, created = User.objects.get_or_create(**kwargs)
|
|
||||||
if password:
|
|
||||||
user.set_password(password)
|
|
||||||
user.save()
|
|
||||||
return user
|
|
||||||
|
|
||||||
def get_user(**kwargs):
|
|
||||||
try:
|
|
||||||
user = User.objects.get(**kwargs)
|
|
||||||
return user
|
|
||||||
except (User.DoesNotExist,):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_uuid(**kwargs):
|
|
||||||
try:
|
|
||||||
uuid = UserSAMLIdentifier.objects.get(**kwargs)
|
|
||||||
return uuid
|
|
||||||
except (UserSAMLIdentifier.DoesNotExist):
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def create_credentials(user, credentials):
|
|
||||||
cred, created = UserCredentials.objects.get_or_create(user=user, locators=credentials)
|
|
||||||
return cred
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def admin(db):
|
|
||||||
return create_user(
|
|
||||||
username='admin',
|
|
||||||
first_name='admin',
|
|
||||||
last_name='admin',
|
|
||||||
email='admin@example.net',
|
|
||||||
is_superuser=True,
|
|
||||||
is_staff=True,
|
|
||||||
is_active=True
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def user_john(db):
|
|
||||||
return create_user(username='john')
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def cred_john(db,user_john):
|
|
||||||
return create_credentials(user_john, {
|
|
||||||
"login": "john",
|
|
||||||
"password": "john password"
|
|
||||||
})
|
|
||||||
|
|
||||||
@pytest.fixture(params=['cred_john'])
|
|
||||||
def credentials(request, cred_john):
|
|
||||||
return locals().get(request.param)
|
|
||||||
|
|
||||||
|
|
||||||
def test_encryption(credentials):
|
|
||||||
decrypted = credentials.decrypt()
|
|
||||||
assert decrypted.get('password') == 'john password'
|
|
||||||
|
|
||||||
|
|
||||||
# MIGRATION COMMAND
|
|
||||||
def cmd(*args, **kwargs):
|
|
||||||
cmd = type(
|
|
||||||
'Cmd',
|
|
||||||
(object,),
|
|
||||||
{
|
|
||||||
'name': 'migrate-users',
|
|
||||||
'args': args,
|
|
||||||
'opts': kwargs
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def command_ldap():
|
|
||||||
return cmd(
|
|
||||||
'tests/ldap_users.txt',
|
|
||||||
ldap= True
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def command_csv():
|
|
||||||
return cmd(
|
|
||||||
'tests/csv_users.csv',
|
|
||||||
csv= True
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture(params=['command_ldap', 'command_csv'])
|
|
||||||
def command(request, command_ldap, command_csv):
|
|
||||||
return locals().get(request.param)
|
|
||||||
|
|
||||||
def test_command_migrate_users(command):
|
|
||||||
call_command(command.name, *command.args, **command.opts)
|
|
||||||
if command.opts.get('ldap'):
|
|
||||||
credentials = UserCredentials.objects.filter(user__last_name__in=[
|
|
||||||
'ldap_user1',
|
|
||||||
'ldap_user2',
|
|
||||||
'ldap_user3'
|
|
||||||
])
|
|
||||||
|
|
||||||
assert len(credentials) == 3
|
|
||||||
|
|
||||||
for cred in credentials:
|
|
||||||
assert cred.to_login_info(decrypt=True)['#password'] == 'password_{}'.format(cred.user.last_name)
|
|
||||||
else:
|
|
||||||
credentials = UserCredentials.objects.all().exclude(user__last_name__in=[
|
|
||||||
'ldap_user1',
|
|
||||||
'ldap_user2',
|
|
||||||
'ldap_user3'
|
|
||||||
])
|
|
||||||
|
|
||||||
assert len(credentials) == 4
|
|
||||||
|
|
||||||
for cred in credentials:
|
|
||||||
assert cred.to_login_info(decrypt=True)['#password'] == cred.to_login_info()['#username']
|
|
||||||
|
|
||||||
|
|
||||||
# MANDAYE API
|
|
||||||
@pytest.fixture
|
|
||||||
def url():
|
|
||||||
return reverse('api')
|
|
||||||
|
|
||||||
def create_signed_url(secret, orig):
|
|
||||||
url = signature.sign_url(reverse('api'), secret)
|
|
||||||
url += '&orig={}'.format(orig)
|
|
||||||
return type(
|
|
||||||
'signed_url',
|
|
||||||
(object,),
|
|
||||||
{'url': url, 'orig': orig}
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def url_signed_testserver_service():
|
|
||||||
return create_signed_url(
|
|
||||||
settings.SECRET_KEY,
|
|
||||||
'testserver'
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def url_signed_unknown_service():
|
|
||||||
return create_signed_url(
|
|
||||||
settings.SECRET_KEY,
|
|
||||||
'lol'
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.fixture(params=['url_signed_testserver_service', 'url_signed_unknown_service'])
|
|
||||||
def url_signed(request, url_signed_testserver_service, url_signed_unknown_service):
|
|
||||||
return locals().get(request.param)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def client_service():
|
|
||||||
return APIClient()
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def client_anonymous():
|
|
||||||
return APIClient()
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def client_logged(admin):
|
|
||||||
client = APIClient()
|
|
||||||
client.login(
|
|
||||||
username='admin',password='admin'
|
|
||||||
)
|
|
||||||
return client
|
|
||||||
|
|
||||||
@pytest.fixture(params=['client_anonymous', 'client_logged'])
|
|
||||||
def client(request, client_anonymous, client_logged):
|
|
||||||
return locals().get(request.param)
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def kevin_payload():
|
|
||||||
return {
|
|
||||||
'name_id_content': '12345',
|
|
||||||
'email': 'kevin@fake.com',
|
|
||||||
'first_name': 'kevin',
|
|
||||||
'last_name': 'fake',
|
|
||||||
'locators': {
|
|
||||||
'login': 'fake',
|
|
||||||
'password': 'fake'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def josh_payload():
|
|
||||||
return {
|
|
||||||
'name_id_content': '77777',
|
|
||||||
'email': 'josh@loking.com',
|
|
||||||
'first_name': 'josh',
|
|
||||||
'last_name': 'loking',
|
|
||||||
'locators': {
|
|
||||||
'login': 'josh',
|
|
||||||
'password': 'josh password'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@pytest.fixture(params=['kevin_payload', 'josh_payload'])
|
|
||||||
def payload(request, kevin_payload, josh_payload):
|
|
||||||
return locals().get(request.param)
|
|
||||||
|
|
||||||
# GET
|
|
||||||
def test_api_get(client, url):
|
|
||||||
|
|
||||||
response = client.get(url)
|
|
||||||
if client.session:
|
|
||||||
status_code = 200
|
|
||||||
else:
|
|
||||||
status_code = 403
|
|
||||||
|
|
||||||
assert response.status_code == status_code
|
|
||||||
|
|
||||||
if status_code == 200:
|
|
||||||
assert {'login': '', 'password': ''} == response.data
|
|
||||||
|
|
||||||
@pytest.mark.skipif(hobo == None, reason="hobo is required")
|
|
||||||
def test_signed_api_get(client_service, url_signed):
|
|
||||||
response = client_service.get(url_signed.url)
|
|
||||||
if url_signed.orig == 'testserver':
|
|
||||||
status_code = 200
|
|
||||||
else:
|
|
||||||
status_code = 403
|
|
||||||
|
|
||||||
assert response.status_code == status_code
|
|
||||||
|
|
||||||
if status_code == 200:
|
|
||||||
assert {'login': '', 'password': ''} == response.data
|
|
||||||
|
|
||||||
|
|
||||||
# POST
|
|
||||||
@mock.patch('mandayejs.mandaye.api.exec_phantom')
|
|
||||||
def test_api_post(mock_phantomjs_result, client, url, payload):
|
|
||||||
|
|
||||||
if client.session :
|
|
||||||
status_code = {'success': 200, 'failure': 401}
|
|
||||||
else:
|
|
||||||
status_code = {'success': 403, 'failure': 403}
|
|
||||||
|
|
||||||
if payload.get('name_id_content') == '12345':
|
|
||||||
response = client.post(url, data=payload, format='json')
|
|
||||||
|
|
||||||
assert response.status_code == status_code['failure']
|
|
||||||
|
|
||||||
if client.session:
|
|
||||||
kevin = get_user(first_name='kevin')
|
|
||||||
assert kevin.username == payload['name_id_content']
|
|
||||||
|
|
||||||
kevin_uuid = get_uuid(name_id=payload['name_id_content'])
|
|
||||||
assert kevin_uuid.name_id == '12345'
|
|
||||||
else:
|
|
||||||
mock_phantomjs_result.return_value = {"result": "ok"}
|
|
||||||
|
|
||||||
response = client.post(url, data=payload, format='json')
|
|
||||||
|
|
||||||
assert response.status_code == status_code['success']
|
|
||||||
|
|
||||||
if client.session:
|
|
||||||
josh = get_user(username='77777')
|
|
||||||
josh_creds = UserCredentials.objects.filter(user=josh)[0]
|
|
||||||
|
|
||||||
assert josh_creds.to_login_info()['#login'] == 'josh'
|
|
||||||
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password'
|
|
||||||
|
|
||||||
@pytest.mark.skipif(hobo == None, reason="hobo is required")
|
|
||||||
@mock.patch('mandayejs.mandaye.api.exec_phantom')
|
|
||||||
def test_signed_api_post(mock_phantomjs_result, client_service, url_signed, payload):
|
|
||||||
if url_signed.orig == 'testserver' :
|
|
||||||
status_code = {'success': 200, 'failure': 401}
|
|
||||||
else:
|
|
||||||
status_code = {'success': 403, 'failure': 403}
|
|
||||||
|
|
||||||
if payload.get('name_id_content') == '12345':
|
|
||||||
response = client_service.post(url_signed.url, data=payload, format='json')
|
|
||||||
|
|
||||||
assert response.status_code == status_code['failure']
|
|
||||||
|
|
||||||
if url_signed.orig == 'testserver' :
|
|
||||||
kevin = get_user(first_name='kevin')
|
|
||||||
assert kevin.username == payload['name_id_content']
|
|
||||||
|
|
||||||
kevin_uuid = get_uuid(name_id=payload['name_id_content'])
|
|
||||||
assert kevin_uuid.name_id == '12345'
|
|
||||||
else:
|
|
||||||
mock_phantomjs_result.return_value = {"result": "ok"}
|
|
||||||
|
|
||||||
response = client_service.post(url_signed.url, data=payload, format='json')
|
|
||||||
|
|
||||||
assert response.status_code == status_code['success']
|
|
||||||
|
|
||||||
if url_signed.orig == 'testserver':
|
|
||||||
josh = get_user(username='77777')
|
|
||||||
josh_creds = UserCredentials.objects.filter(user=josh)[0]
|
|
||||||
|
|
||||||
assert josh_creds.to_login_info()['#login'] == 'josh'
|
|
||||||
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password'
|
|
||||||
|
|
||||||
# DELETE
|
|
||||||
def test_api_delete(client, url):
|
|
||||||
if client.session :
|
|
||||||
status_code = {'success': 200, 'failure': 404}
|
|
||||||
else:
|
|
||||||
status_code = {'success': 403, 'failure': 403}
|
|
||||||
|
|
||||||
kevin = get_user(first_name='kevin')
|
|
||||||
assert UserCredentials.objects.filter(user=kevin).exists() == False
|
|
||||||
response = client.delete(url, data={'name_id_content': '12345'}, format='json')
|
|
||||||
assert response.status_code == status_code['failure']
|
|
||||||
|
|
||||||
josh = create_user(username='77777')
|
|
||||||
create_credentials(josh,{
|
|
||||||
'login':'josh',
|
|
||||||
'password': 'josh password'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert UserCredentials.objects.filter(user=josh).exists() == True
|
|
||||||
response = client.delete(url, data={'name_id_content': '77777'}, format='json')
|
|
||||||
assert response.status_code == status_code['success']
|
|
||||||
if client.session:
|
|
||||||
assert UserCredentials.objects.filter(user=josh).exists() == False
|
|
||||||
|
|
||||||
@pytest.mark.skipif(hobo == None, reason="hobo is required")
|
|
||||||
def test_signed_api_delete(client_service, url_signed):
|
|
||||||
if url_signed.orig == 'testserver' :
|
|
||||||
status_code = {'success': 200, 'failure': 404}
|
|
||||||
else:
|
|
||||||
status_code = {'success': 403, 'failure': 403}
|
|
||||||
|
|
||||||
kevin = get_user(first_name='kevin')
|
|
||||||
assert UserCredentials.objects.filter(user=kevin).exists() == False
|
|
||||||
response = client_service.delete(url_signed.url, data={'name_id_content': '12345'}, format='json')
|
|
||||||
assert response.status_code == status_code['failure']
|
|
||||||
|
|
||||||
josh = create_user(username='77777')
|
|
||||||
create_credentials(josh,{
|
|
||||||
'login':'josh',
|
|
||||||
'password': 'josh password'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert UserCredentials.objects.filter(user=josh).exists() == True
|
|
||||||
response = client_service.delete(url_signed.url, data={'name_id_content': '77777'}, format='json')
|
|
||||||
assert response.status_code == status_code['success']
|
|
||||||
if url_signed.orig == 'testserver':
|
|
||||||
assert UserCredentials.objects.filter(user=josh).exists() == False
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from mellon.models import UserSAMLIdentifier
|
||||||
|
|
||||||
|
from mandayejs.mandaye.models import UserCredentials
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def create_user(**kwargs):
|
||||||
|
password = kwargs.pop('password', None) or kwargs.get('username')
|
||||||
|
user, created = User.objects.get_or_create(**kwargs)
|
||||||
|
if password:
|
||||||
|
user.set_password(password)
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def get_user(**kwargs):
|
||||||
|
try:
|
||||||
|
user = User.objects.get(**kwargs)
|
||||||
|
return user
|
||||||
|
except (User.DoesNotExist,):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_uuid(**kwargs):
|
||||||
|
try:
|
||||||
|
uuid = UserSAMLIdentifier.objects.get(**kwargs)
|
||||||
|
return uuid
|
||||||
|
except (UserSAMLIdentifier.DoesNotExist):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def create_credentials(user, credentials):
|
||||||
|
cred, created = UserCredentials.objects.get_or_create(user=user, locators=credentials)
|
||||||
|
return cred
|
46
tox.ini
46
tox.ini
|
@ -1,26 +1,26 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = django17
|
envlist = coverage-django17-pylint,coverage-django18
|
||||||
|
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/mandayejs/
|
||||||
|
|
||||||
[testenv:django17]
|
[testenv]
|
||||||
setenv = DJANGO_SETTINGS_MODULE=mandayejs.settings
|
usedevelop =
|
||||||
usedevelop = True
|
coverage: True
|
||||||
|
setenv =
|
||||||
|
DJANGO_SETTINGS_MODULE=mandayejs.settings
|
||||||
|
MANDAYEJS_SETTINGS_FILE=tests/settings.py
|
||||||
|
coverage: COVERAGE=--junitxml=test_results.xml --cov-report xml --cov=mandayejs/ --cov-config .coveragerc
|
||||||
|
deps =
|
||||||
|
django17: django>1.7,<1.8
|
||||||
|
django18: django>=1.8,<1.9
|
||||||
|
pytest-cov
|
||||||
|
pytest-django
|
||||||
|
pytest
|
||||||
|
pytest-capturelog
|
||||||
|
pylint
|
||||||
|
pylint-django
|
||||||
|
mock
|
||||||
|
djangorestframework>=3.3,<3.4
|
||||||
commands =
|
commands =
|
||||||
./getlasso.sh
|
./getlasso.sh
|
||||||
coverage run --source=mandayejs -m pytest -vs tests/tests.py
|
py.test {env:COVERAGE:} {posargs:tests/}
|
||||||
coverage report -m
|
pylint: ./pylint.sh mandayejs/
|
||||||
|
|
||||||
deps = django>1.7,<1.8
|
|
||||||
requests
|
|
||||||
pycrypto
|
|
||||||
django-mellon
|
|
||||||
djangorestframework
|
|
||||||
python-ldap
|
|
||||||
pytest
|
|
||||||
pytest-django
|
|
||||||
mock
|
|
||||||
coverage
|
|
||||||
|
|
||||||
[testenv:pylint]
|
|
||||||
usedevelop = True
|
|
||||||
commands = pylint mandayejs
|
|
||||||
deps = pylint
|
|
||||||
|
|
Reference in New Issue