Révision 28577537
Ajouté par Josué Kouka il y a plus de 7 ans
getlasso.sh | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
# Get venv site-packages path |
|
4 |
DSTDIR=`python -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'` |
|
5 |
|
|
6 |
# Get not venv site-packages path |
|
7 |
# Remove first path (assuming that is the venv path) |
|
8 |
NONPATH=`echo $PATH | sed 's/^[^:]*://'` |
|
9 |
SRCDIR=`PATH=$NONPATH python -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'` |
|
10 |
|
|
11 |
# Clean up |
|
12 |
rm -f $DSTDIR/lasso.* |
|
13 |
rm -f $DSTDIR/_lasso.* |
|
14 |
|
|
15 |
# Link |
|
16 |
ln -sv $SRCDIR/lasso.py $DSTDIR |
|
17 |
ln -sv $SRCDIR/_lasso.* $DSTDIR |
|
18 |
|
|
19 |
exit 0 |
jenkins.sh | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
set -e |
|
4 |
|
|
5 |
rm -f coverage.xml |
|
6 |
rm -f test_results.xml |
|
7 |
|
|
8 |
pip install --upgrade tox |
|
9 |
tox -r |
pylint.sh | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
set -e -x |
|
4 |
env |
|
5 |
if [ -f /var/lib/jenkins/pylint.django.rc ]; then |
|
6 |
PYLINT_RC=/var/lib/jenkins/pylint.django.rc |
|
7 |
elif [ -f pylint.django.rc ]; then |
|
8 |
PYLINT_RC=pylint.django.rc |
|
9 |
else |
|
10 |
echo No pylint RC found |
|
11 |
exit 0 |
|
12 |
fi |
|
13 |
|
|
14 |
test -f pylint.out && cp pylint.out pylint.out.prev |
|
15 |
pylint -f parseable --rcfile ${PYLINT_RC} "$@" | tee pylint.out || /bin/true |
|
16 |
test -f pylint.out.prev && (diff pylint.out.prev pylint.out | grep '^[><]' | grep .py) || /bin/true¶ |
setup.py | ||
---|---|---|
66 | 66 |
continue |
67 | 67 |
curdir = os.getcwd() |
68 | 68 |
os.chdir(os.path.realpath(path)) |
69 |
call_command('compilemessages') |
|
70 |
os.chdir(curdir) |
|
69 |
try: |
|
70 |
call_command('compilemessages') |
|
71 |
finally: |
|
72 |
os.chdir(curdir) |
|
71 | 73 |
except ImportError: |
72 | 74 |
sys.stderr.write('!!! Please install Django >= 1.4 to build translations\n') |
73 | 75 |
|
... | ... | |
103 | 105 |
'Programming Language :: Python', |
104 | 106 |
'Programming Language :: Python :: 2', |
105 | 107 |
], |
106 |
install_requires=['django>=1.7, <1.8',
|
|
108 |
install_requires=['django>=1.8, <1.9',
|
|
107 | 109 |
'gadjo', |
108 | 110 |
'django-jsonfield', |
109 | 111 |
'python-ldap', |
110 | 112 |
'pycrypto', |
111 | 113 |
'requests', |
112 |
'djangorestframework' |
|
114 |
'djangorestframework', |
|
115 |
'django-mellon' |
|
113 | 116 |
], |
114 | 117 |
zip_safe=False, |
115 | 118 |
cmdclass={ |
tests/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from django.conf import settings |
|
4 |
from django.core.urlresolvers import reverse |
|
5 |
|
|
6 |
from rest_framework.test import APIClient |
|
7 |
|
|
8 |
from utils import create_user, create_credentials |
|
9 |
|
|
10 |
pytestmark = pytest.mark.django_db |
|
11 |
|
|
12 |
|
|
13 |
if settings.HOBO: |
|
14 |
from hobo import signature |
|
15 |
|
|
16 |
|
|
17 |
@pytest.fixture |
|
18 |
def admin(db): |
|
19 |
return create_user( |
|
20 |
username='admin', |
|
21 |
first_name='admin', |
|
22 |
last_name='admin', |
|
23 |
email='admin@example.net', |
|
24 |
is_superuser=True, |
|
25 |
is_staff=True, |
|
26 |
is_active=True |
|
27 |
) |
|
28 |
|
|
29 |
|
|
30 |
@pytest.fixture |
|
31 |
def user_john(db): |
|
32 |
return create_user(username='john') |
|
33 |
|
|
34 |
|
|
35 |
@pytest.fixture |
|
36 |
def cred_john(db, user_john): |
|
37 |
return create_credentials(user_john, { |
|
38 |
"login": "john", |
|
39 |
"password": "john password"}) |
|
40 |
|
|
41 |
|
|
42 |
@pytest.fixture(params=['cred_john']) |
|
43 |
def credentials(request, cred_john): |
|
44 |
return locals().get(request.param) |
|
45 |
|
|
46 |
|
|
47 |
# MIGRATION COMMAND |
|
48 |
def cmd(*args, **kwargs): |
|
49 |
cmd = type( |
|
50 |
'Cmd', |
|
51 |
(object,), |
|
52 |
{ |
|
53 |
'name': 'migrate-users', |
|
54 |
'args': args, |
|
55 |
'opts': kwargs |
|
56 |
} |
|
57 |
) |
|
58 |
return cmd |
|
59 |
|
|
60 |
|
|
61 |
@pytest.fixture |
|
62 |
def command_ldap(): |
|
63 |
return cmd('tests/ldap_users.txt', ldap=True) |
|
64 |
|
|
65 |
|
|
66 |
@pytest.fixture |
|
67 |
def command_csv(): |
|
68 |
return cmd('tests/csv_users.csv', csv=True) |
|
69 |
|
|
70 |
|
|
71 |
@pytest.fixture(params=['command_ldap', 'command_csv']) |
|
72 |
def command(request, command_ldap, command_csv): |
|
73 |
return locals().get(request.param) |
|
74 |
|
|
75 |
|
|
76 |
@pytest.fixture |
|
77 |
def url(): |
|
78 |
return reverse('api') |
|
79 |
|
|
80 |
|
|
81 |
def create_signed_url(secret, orig): |
|
82 |
url = signature.sign_url(reverse('api'), secret) |
|
83 |
url += '&orig={}'.format(orig) |
|
84 |
return type( |
|
85 |
'signed_url', |
|
86 |
(object,), |
|
87 |
{'url': url, 'orig': orig} |
|
88 |
) |
|
89 |
|
|
90 |
|
|
91 |
@pytest.fixture |
|
92 |
def url_signed_testserver_service(): |
|
93 |
return create_signed_url( |
|
94 |
settings.SECRET_KEY, |
|
95 |
'testserver' |
|
96 |
) |
|
97 |
|
|
98 |
|
|
99 |
@pytest.fixture |
|
100 |
def url_signed_unknown_service(): |
|
101 |
return create_signed_url( |
|
102 |
settings.SECRET_KEY, |
|
103 |
'lol' |
|
104 |
) |
|
105 |
|
|
106 |
|
|
107 |
@pytest.fixture(params=['url_signed_testserver_service', 'url_signed_unknown_service']) |
|
108 |
def url_signed(request, url_signed_testserver_service, url_signed_unknown_service): |
|
109 |
return locals().get(request.param) |
|
110 |
|
|
111 |
|
|
112 |
@pytest.fixture |
|
113 |
def client_service(): |
|
114 |
return APIClient() |
|
115 |
|
|
116 |
|
|
117 |
@pytest.fixture |
|
118 |
def client_anonymous(): |
|
119 |
return APIClient() |
|
120 |
|
|
121 |
|
|
122 |
@pytest.fixture |
|
123 |
def client_logged(admin): |
|
124 |
client = APIClient() |
|
125 |
client.login(username='admin', password='admin') |
|
126 |
return client |
|
127 |
|
|
128 |
|
|
129 |
@pytest.fixture(params=['client_anonymous', 'client_logged']) |
|
130 |
def client(request, client_anonymous, client_logged): |
|
131 |
return locals().get(request.param) |
|
132 |
|
|
133 |
|
|
134 |
@pytest.fixture |
|
135 |
def kevin_payload(): |
|
136 |
return { |
|
137 |
'name_id_content': '12345', |
|
138 |
'email': 'kevin@fake.com', |
|
139 |
'first_name': 'kevin', |
|
140 |
'last_name': 'fake', |
|
141 |
'locators': { |
|
142 |
'login': 'fake', |
|
143 |
'password': 'fake' |
|
144 |
} |
|
145 |
} |
|
146 |
|
|
147 |
|
|
148 |
@pytest.fixture |
|
149 |
def josh_payload(): |
|
150 |
return { |
|
151 |
'name_id_content': '77777', |
|
152 |
'email': 'josh@loking.com', |
|
153 |
'first_name': 'josh', |
|
154 |
'last_name': 'loking', |
|
155 |
'locators': { |
|
156 |
'login': 'josh', |
|
157 |
'password': 'josh password' |
|
158 |
} |
|
159 |
} |
|
160 |
|
|
161 |
|
|
162 |
@pytest.fixture(params=['kevin_payload', 'josh_payload']) |
|
163 |
def payload(request, kevin_payload, josh_payload): |
|
164 |
return locals().get(request.param) |
tests/settings.py | ||
---|---|---|
1 |
from django.conf import settings |
|
2 |
from rest_framework.settings import api_settings |
|
3 |
|
|
4 |
try: |
|
5 |
import hobo |
|
6 |
except(ImportError,): |
|
7 |
hobo = None |
|
8 |
|
|
9 |
HOBO = hobo |
|
10 |
|
|
11 |
MELLON_IDENTITY_PROVIDERS = [ |
|
12 |
{ |
|
13 |
'METADATA_URL': 'http://testsever.org/idp/saml2/metadata' |
|
14 |
} |
|
15 |
] |
|
16 |
|
|
17 |
SITE_APP = 'mandayejs.applications.Test' |
|
18 |
SECRET_KEY = 'od5cei4aeveel8dui4lei2ou9ahsei2A' |
|
19 |
|
|
20 |
KNOWN_SERVICES = { |
|
21 |
"service":{ |
|
22 |
"testserver": { |
|
23 |
"title": "testserver", |
|
24 |
"orig": "testserver", |
|
25 |
"url": "http://testserver", |
|
26 |
"secret": "od5cei4aeveel8dui4lei2ou9ahsei2A", |
|
27 |
"verif_orig": "testserver" |
|
28 |
} |
|
29 |
} |
|
30 |
} |
|
31 |
|
|
32 |
HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser' |
|
33 |
|
|
34 |
# REST FRAMEWORK SETTINGS |
|
35 |
if hobo: |
|
36 |
AUTHENTICATION_CLASSES = ( |
|
37 |
'rest_framework.authentication.SessionAuthentication', |
|
38 |
'rest_framework.authentication.BasicAuthentication', |
|
39 |
'hobo.rest_authentication.PublikAuthentication', |
|
40 |
) |
|
41 |
else: |
|
42 |
AUTHENTICATION_CLASSES = ( |
|
43 |
'rest_framework.authentication.SessionAuthentication', |
|
44 |
'rest_framework.authentication.BasicAuthentication', |
|
45 |
) |
|
46 |
|
|
47 |
api_settings.user_settings.update({ |
|
48 |
'DEFAULT_AUTHENTICATION_CLASSES' : AUTHENTICATION_CLASSES, |
|
49 |
}) |
tests/test_mandayejs.py | ||
---|---|---|
1 |
import mock |
|
2 |
import pytest |
|
3 |
|
|
4 |
from django.conf import settings |
|
5 |
from django.core.management import call_command |
|
6 |
|
|
7 |
from mandayejs.mandaye.models import UserCredentials |
|
8 |
|
|
9 |
from utils import create_user, create_credentials, get_uuid, get_user |
|
10 |
|
|
11 |
pytestmark = pytest.mark.django_db |
|
12 |
|
|
13 |
|
|
14 |
# ENCRYPTION/DECRYPTION |
|
15 |
def test_encryption(credentials): |
|
16 |
decrypted = credentials.decrypt() |
|
17 |
assert decrypted.get('password') == 'john password' |
|
18 |
|
|
19 |
|
|
20 |
@pytest.fixture(params=['command_ldap', 'command_csv']) |
|
21 |
def command(request, command_ldap, command_csv): |
|
22 |
return locals().get(request.param) |
|
23 |
|
|
24 |
|
|
25 |
@mock.patch('mandayejs.mandaye.management.commands.migrate-users.get_idps') |
|
26 |
def test_command_migrate_users(mocked_idps, command): |
|
27 |
mocked_idps.return_value = iter(settings.MELLON_IDENTITY_PROVIDERS) |
|
28 |
call_command(command.name, *command.args, **command.opts) |
|
29 |
if command.opts.get('ldap'): |
|
30 |
credentials = UserCredentials.objects.filter(user__last_name__in=[ |
|
31 |
'ldap_user1', |
|
32 |
'ldap_user2', |
|
33 |
'ldap_user3']) |
|
34 |
|
|
35 |
assert len(credentials) == 3 |
|
36 |
|
|
37 |
for cred in credentials: |
|
38 |
assert cred.to_login_info(decrypt=True)['#password'] == 'password_{}'.format(cred.user.last_name) |
|
39 |
else: |
|
40 |
credentials = UserCredentials.objects.all().exclude(user__last_name__in=[ |
|
41 |
'ldap_user1', |
|
42 |
'ldap_user2', |
|
43 |
'ldap_user3' |
|
44 |
]) |
|
45 |
|
|
46 |
assert len(credentials) == 4 |
|
47 |
|
|
48 |
for cred in credentials: |
|
49 |
assert cred.to_login_info(decrypt=True)['#password'] == cred.to_login_info()['#username'] |
|
50 |
|
|
51 |
|
|
52 |
# MANDAYE API |
|
53 |
|
|
54 |
# GET |
|
55 |
def test_api_get(client, url): |
|
56 |
response = client.get(url) |
|
57 |
if client.session.values(): |
|
58 |
status_code = 200 |
|
59 |
else: |
|
60 |
status_code = 403 |
|
61 |
|
|
62 |
assert response.status_code == status_code |
|
63 |
|
|
64 |
if status_code == 200: |
|
65 |
assert {'login': '', 'password': ''} == response.data |
|
66 |
|
|
67 |
|
|
68 |
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required") |
|
69 |
def test_signed_api_get(client_service, url_signed): |
|
70 |
response = client_service.get(url_signed.url) |
|
71 |
if url_signed.orig == 'testserver': |
|
72 |
status_code = 200 |
|
73 |
else: |
|
74 |
status_code = 403 |
|
75 |
|
|
76 |
assert response.status_code == status_code |
|
77 |
|
|
78 |
if status_code == 200: |
|
79 |
assert {'login': '', 'password': ''} == response.data |
|
80 |
|
|
81 |
|
|
82 |
# POST |
|
83 |
@mock.patch('mandayejs.mandaye.api.exec_phantom') |
|
84 |
def test_api_post(mock_phantomjs_result, client, url, payload): |
|
85 |
|
|
86 |
if client.session.values(): |
|
87 |
status_code = {'success': 200, 'failure': 401} |
|
88 |
else: |
|
89 |
status_code = {'success': 403, 'failure': 403} |
|
90 |
|
|
91 |
if payload.get('name_id_content') == '12345': |
|
92 |
response = client.post(url, data=payload, format='json') |
|
93 |
|
|
94 |
assert response.status_code == status_code['failure'] |
|
95 |
|
|
96 |
if client.session.values(): |
|
97 |
kevin = get_user(first_name='kevin') |
|
98 |
assert kevin.username == payload['name_id_content'] |
|
99 |
|
|
100 |
kevin_uuid = get_uuid(name_id=payload['name_id_content']) |
|
101 |
assert kevin_uuid.name_id == '12345' |
|
102 |
else: |
|
103 |
mock_phantomjs_result.return_value = {"result": "ok"} |
|
104 |
|
|
105 |
response = client.post(url, data=payload, format='json') |
|
106 |
|
|
107 |
assert response.status_code == status_code['success'] |
|
108 |
|
|
109 |
if client.session.values(): |
|
110 |
josh = get_user(username='77777') |
|
111 |
josh_creds = UserCredentials.objects.filter(user=josh)[0] |
|
112 |
|
|
113 |
assert josh_creds.to_login_info()['#login'] == 'josh' |
|
114 |
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password' |
|
115 |
|
|
116 |
|
|
117 |
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required") |
|
118 |
@mock.patch('mandayejs.mandaye.api.exec_phantom') |
|
119 |
def test_signed_api_post(mock_phantomjs_result, client_service, url_signed, payload): |
|
120 |
if url_signed.orig == 'testserver': |
|
121 |
status_code = {'success': 200, 'failure': 401} |
|
122 |
else: |
|
123 |
status_code = {'success': 403, 'failure': 403} |
|
124 |
|
|
125 |
if payload.get('name_id_content') == '12345': |
|
126 |
response = client_service.post(url_signed.url, data=payload, format='json') |
|
127 |
|
|
128 |
assert response.status_code == status_code['failure'] |
|
129 |
|
|
130 |
if url_signed.orig == 'testserver': |
|
131 |
kevin = get_user(first_name='kevin') |
|
132 |
assert kevin.username == payload['name_id_content'] |
|
133 |
|
|
134 |
kevin_uuid = get_uuid(name_id=payload['name_id_content']) |
|
135 |
assert kevin_uuid.name_id == '12345' |
|
136 |
else: |
|
137 |
mock_phantomjs_result.return_value = {"result": "ok"} |
|
138 |
|
|
139 |
response = client_service.post(url_signed.url, data=payload, format='json') |
|
140 |
|
|
141 |
assert response.status_code == status_code['success'] |
|
142 |
|
|
143 |
if url_signed.orig == 'testserver': |
|
144 |
josh = get_user(username='77777') |
|
145 |
josh_creds = UserCredentials.objects.filter(user=josh)[0] |
|
146 |
|
|
147 |
assert josh_creds.to_login_info()['#login'] == 'josh' |
|
148 |
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password' |
|
149 |
|
|
150 |
|
|
151 |
# DELETE |
|
152 |
def test_api_delete(client, url): |
|
153 |
if client.session.values(): |
|
154 |
status_code = {'success': 200, 'failure': 404} |
|
155 |
else: |
|
156 |
status_code = {'success': 403, 'failure': 403} |
|
157 |
|
|
158 |
kevin = get_user(first_name='kevin') |
|
159 |
assert UserCredentials.objects.filter(user=kevin).exists() is False |
|
160 |
response = client.delete(url, data={'name_id_content': '12345'}, format='json') |
|
161 |
assert response.status_code == status_code['failure'] |
|
162 |
|
|
163 |
josh = create_user(username='77777') |
|
164 |
create_credentials(josh, { |
|
165 |
'login': 'josh', |
|
166 |
'password': 'josh password'}) |
|
167 |
|
|
168 |
assert UserCredentials.objects.filter(user=josh).exists() is True |
|
169 |
response = client.delete(url, data={'name_id_content': '77777'}, format='json') |
|
170 |
assert response.status_code == status_code['success'] |
|
171 |
if client.session.values(): |
|
172 |
assert UserCredentials.objects.filter(user=josh).exists() is False |
|
173 |
|
|
174 |
|
|
175 |
@pytest.mark.skipif(settings.HOBO is None, reason="hobo is required") |
|
176 |
def test_signed_api_delete(client_service, url_signed): |
|
177 |
if url_signed.orig == 'testserver': |
|
178 |
status_code = {'success': 200, 'failure': 404} |
|
179 |
else: |
|
180 |
status_code = {'success': 403, 'failure': 403} |
|
181 |
|
|
182 |
kevin = get_user(first_name='kevin') |
|
183 |
assert UserCredentials.objects.filter(user=kevin).exists() is False |
|
184 |
response = client_service.delete(url_signed.url, data={'name_id_content': '12345'}, format='json') |
|
185 |
assert response.status_code == status_code['failure'] |
|
186 |
|
|
187 |
josh = create_user(username='77777') |
|
188 |
create_credentials(josh, { |
|
189 |
'login': 'josh', |
|
190 |
'password': 'josh password' |
|
191 |
}) |
|
192 |
|
|
193 |
assert UserCredentials.objects.filter(user=josh).exists() is True |
|
194 |
response = client_service.delete(url_signed.url, data={'name_id_content': '77777'}, format='json') |
|
195 |
assert response.status_code == status_code['success'] |
|
196 |
if url_signed.orig == 'testserver': |
|
197 |
assert UserCredentials.objects.filter(user=josh).exists() is False |
tests/tests.py | ||
---|---|---|
1 |
import mock |
|
2 |
import pytest |
|
3 |
|
|
4 |
from django.conf import settings |
|
5 |
from django.core.urlresolvers import reverse |
|
6 |
from django.contrib.auth.models import User |
|
7 |
from django.core.management import call_command |
|
8 |
|
|
9 |
from rest_framework.test import APIClient |
|
10 |
from rest_framework.settings import api_settings |
|
11 |
|
|
12 |
from mandayejs.applications import get_app_settings |
|
13 |
from mandayejs.mandaye.models import UserCredentials |
|
14 |
from mandayejs.mandaye import utils |
|
15 |
|
|
16 |
from mellon.models import UserSAMLIdentifier |
|
17 |
|
|
18 |
try: |
|
19 |
import hobo |
|
20 |
from hobo import signature |
|
21 |
except(ImportError,): |
|
22 |
hobo = None |
|
23 |
|
|
24 |
pytestmark = pytest.mark.django_db |
|
25 |
|
|
26 |
settings.MELLON_IDENTITY_PROVIDERS = [ |
|
27 |
{ |
|
28 |
'METADATA_URL': 'http://testsever.org/idp/saml2/metadata' |
|
29 |
} |
|
30 |
] |
|
31 |
|
|
32 |
settings.SITE_APP = 'mandayejs.applications.Test' |
|
33 |
settings.SECRET_KEY = 'od5cei4aeveel8dui4lei2ou9ahsei2A' |
|
34 |
|
|
35 |
settings.KNOWN_SERVICES = { |
|
36 |
"service":{ |
|
37 |
"testserver": { |
|
38 |
"title": "testserver", |
|
39 |
"orig": "testserver", |
|
40 |
"url": "http://testserver", |
|
41 |
"secret": "od5cei4aeveel8dui4lei2ou9ahsei2A", |
|
42 |
"verif_orig": "testserver" |
|
43 |
} |
|
44 |
} |
|
45 |
} |
|
46 |
|
|
47 |
settings.HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser' |
|
48 |
|
|
49 |
# REST FRAMEWORK SETTINGS |
|
50 |
if hobo: |
|
51 |
AUTHENTICATION_CLASSES = ( |
|
52 |
'rest_framework.authentication.SessionAuthentication', |
|
53 |
'rest_framework.authentication.BasicAuthentication', |
|
54 |
'hobo.rest_authentication.PublikAuthentication', |
|
55 |
) |
|
56 |
else: |
|
57 |
AUTHENTICATION_CLASSES = ( |
|
58 |
'rest_framework.authentication.SessionAuthentication', |
|
59 |
'rest_framework.authentication.BasicAuthentication', |
|
60 |
) |
|
61 |
|
|
62 |
api_settings.user_settings.update({ |
|
63 |
'DEFAULT_AUTHENTICATION_CLASSES' : AUTHENTICATION_CLASSES, |
|
64 |
}) |
|
65 |
|
|
66 |
|
|
67 |
# ENCRYPTION/DECRYPTION |
|
68 |
def create_user(**kwargs): |
|
69 |
password = kwargs.pop('password', None) or kwargs.get('username') |
|
70 |
user, created = User.objects.get_or_create(**kwargs) |
|
71 |
if password: |
|
72 |
user.set_password(password) |
|
73 |
user.save() |
|
74 |
return user |
|
75 |
|
|
76 |
def get_user(**kwargs): |
|
77 |
try: |
|
78 |
user = User.objects.get(**kwargs) |
|
79 |
return user |
|
80 |
except (User.DoesNotExist,): |
|
81 |
return None |
|
82 |
|
|
83 |
def get_uuid(**kwargs): |
|
84 |
try: |
|
85 |
uuid = UserSAMLIdentifier.objects.get(**kwargs) |
|
86 |
return uuid |
|
87 |
except (UserSAMLIdentifier.DoesNotExist): |
|
88 |
return None |
|
89 |
|
|
90 |
|
|
91 |
def create_credentials(user, credentials): |
|
92 |
cred, created = UserCredentials.objects.get_or_create(user=user, locators=credentials) |
|
93 |
return cred |
|
94 |
|
|
95 |
@pytest.fixture |
|
96 |
def admin(db): |
|
97 |
return create_user( |
|
98 |
username='admin', |
|
99 |
first_name='admin', |
|
100 |
last_name='admin', |
|
101 |
email='admin@example.net', |
|
102 |
is_superuser=True, |
|
103 |
is_staff=True, |
|
104 |
is_active=True |
|
105 |
) |
|
106 |
|
|
107 |
@pytest.fixture |
|
108 |
def user_john(db): |
|
109 |
return create_user(username='john') |
|
110 |
|
|
111 |
@pytest.fixture |
|
112 |
def cred_john(db,user_john): |
|
113 |
return create_credentials(user_john, { |
|
114 |
"login": "john", |
|
115 |
"password": "john password" |
|
116 |
}) |
|
117 |
|
|
118 |
@pytest.fixture(params=['cred_john']) |
|
119 |
def credentials(request, cred_john): |
|
120 |
return locals().get(request.param) |
|
121 |
|
|
122 |
|
|
123 |
def test_encryption(credentials): |
|
124 |
decrypted = credentials.decrypt() |
|
125 |
assert decrypted.get('password') == 'john password' |
|
126 |
|
|
127 |
|
|
128 |
# MIGRATION COMMAND |
|
129 |
def cmd(*args, **kwargs): |
|
130 |
cmd = type( |
|
131 |
'Cmd', |
|
132 |
(object,), |
|
133 |
{ |
|
134 |
'name': 'migrate-users', |
|
135 |
'args': args, |
|
136 |
'opts': kwargs |
|
137 |
} |
|
138 |
) |
|
139 |
return cmd |
|
140 |
|
|
141 |
@pytest.fixture |
|
142 |
def command_ldap(): |
|
143 |
return cmd( |
|
144 |
'tests/ldap_users.txt', |
|
145 |
ldap= True |
|
146 |
) |
|
147 |
|
|
148 |
@pytest.fixture |
|
149 |
def command_csv(): |
|
150 |
return cmd( |
|
151 |
'tests/csv_users.csv', |
|
152 |
csv= True |
|
153 |
) |
|
154 |
|
|
155 |
@pytest.fixture(params=['command_ldap', 'command_csv']) |
|
156 |
def command(request, command_ldap, command_csv): |
|
157 |
return locals().get(request.param) |
|
158 |
|
|
159 |
def test_command_migrate_users(command): |
|
160 |
call_command(command.name, *command.args, **command.opts) |
|
161 |
if command.opts.get('ldap'): |
|
162 |
credentials = UserCredentials.objects.filter(user__last_name__in=[ |
|
163 |
'ldap_user1', |
|
164 |
'ldap_user2', |
|
165 |
'ldap_user3' |
|
166 |
]) |
|
167 |
|
|
168 |
assert len(credentials) == 3 |
|
169 |
|
|
170 |
for cred in credentials: |
|
171 |
assert cred.to_login_info(decrypt=True)['#password'] == 'password_{}'.format(cred.user.last_name) |
|
172 |
else: |
|
173 |
credentials = UserCredentials.objects.all().exclude(user__last_name__in=[ |
|
174 |
'ldap_user1', |
|
175 |
'ldap_user2', |
|
176 |
'ldap_user3' |
|
177 |
]) |
|
178 |
|
|
179 |
assert len(credentials) == 4 |
|
180 |
|
|
181 |
for cred in credentials: |
|
182 |
assert cred.to_login_info(decrypt=True)['#password'] == cred.to_login_info()['#username'] |
|
183 |
|
|
184 |
|
|
185 |
# MANDAYE API |
|
186 |
@pytest.fixture |
|
187 |
def url(): |
|
188 |
return reverse('api') |
|
189 |
|
|
190 |
def create_signed_url(secret, orig): |
|
191 |
url = signature.sign_url(reverse('api'), secret) |
|
192 |
url += '&orig={}'.format(orig) |
|
193 |
return type( |
|
194 |
'signed_url', |
|
195 |
(object,), |
|
196 |
{'url': url, 'orig': orig} |
|
197 |
) |
|
198 |
|
|
199 |
@pytest.fixture |
|
200 |
def url_signed_testserver_service(): |
|
201 |
return create_signed_url( |
|
202 |
settings.SECRET_KEY, |
|
203 |
'testserver' |
|
204 |
) |
|
205 |
|
|
206 |
@pytest.fixture |
|
207 |
def url_signed_unknown_service(): |
|
208 |
return create_signed_url( |
|
209 |
settings.SECRET_KEY, |
|
210 |
'lol' |
|
211 |
) |
|
212 |
|
|
213 |
@pytest.fixture(params=['url_signed_testserver_service', 'url_signed_unknown_service']) |
|
214 |
def url_signed(request, url_signed_testserver_service, url_signed_unknown_service): |
|
215 |
return locals().get(request.param) |
|
216 |
|
|
217 |
@pytest.fixture |
|
218 |
def client_service(): |
|
219 |
return APIClient() |
|
220 |
|
|
221 |
@pytest.fixture |
|
222 |
def client_anonymous(): |
|
223 |
return APIClient() |
|
224 |
|
|
225 |
@pytest.fixture |
|
226 |
def client_logged(admin): |
|
227 |
client = APIClient() |
|
228 |
client.login( |
|
229 |
username='admin',password='admin' |
|
230 |
) |
|
231 |
return client |
|
232 |
|
|
233 |
@pytest.fixture(params=['client_anonymous', 'client_logged']) |
|
234 |
def client(request, client_anonymous, client_logged): |
|
235 |
return locals().get(request.param) |
|
236 |
|
|
237 |
@pytest.fixture |
|
238 |
def kevin_payload(): |
|
239 |
return { |
|
240 |
'name_id_content': '12345', |
|
241 |
'email': 'kevin@fake.com', |
|
242 |
'first_name': 'kevin', |
|
243 |
'last_name': 'fake', |
|
244 |
'locators': { |
|
245 |
'login': 'fake', |
|
246 |
'password': 'fake' |
|
247 |
} |
|
248 |
} |
|
249 |
|
|
250 |
@pytest.fixture |
|
251 |
def josh_payload(): |
|
252 |
return { |
|
253 |
'name_id_content': '77777', |
|
254 |
'email': 'josh@loking.com', |
|
255 |
'first_name': 'josh', |
|
256 |
'last_name': 'loking', |
|
257 |
'locators': { |
|
258 |
'login': 'josh', |
|
259 |
'password': 'josh password' |
|
260 |
} |
|
261 |
} |
|
262 |
|
|
263 |
@pytest.fixture(params=['kevin_payload', 'josh_payload']) |
|
264 |
def payload(request, kevin_payload, josh_payload): |
|
265 |
return locals().get(request.param) |
|
266 |
|
|
267 |
# GET |
|
268 |
def test_api_get(client, url): |
|
269 |
|
|
270 |
response = client.get(url) |
|
271 |
if client.session: |
|
272 |
status_code = 200 |
|
273 |
else: |
|
274 |
status_code = 403 |
|
275 |
|
|
276 |
assert response.status_code == status_code |
|
277 |
|
|
278 |
if status_code == 200: |
|
279 |
assert {'login': '', 'password': ''} == response.data |
|
280 |
|
|
281 |
@pytest.mark.skipif(hobo == None, reason="hobo is required") |
|
282 |
def test_signed_api_get(client_service, url_signed): |
|
283 |
response = client_service.get(url_signed.url) |
|
284 |
if url_signed.orig == 'testserver': |
|
285 |
status_code = 200 |
|
286 |
else: |
|
287 |
status_code = 403 |
|
288 |
|
|
289 |
assert response.status_code == status_code |
|
290 |
|
|
291 |
if status_code == 200: |
|
292 |
assert {'login': '', 'password': ''} == response.data |
|
293 |
|
|
294 |
|
|
295 |
# POST |
|
296 |
@mock.patch('mandayejs.mandaye.api.exec_phantom') |
|
297 |
def test_api_post(mock_phantomjs_result, client, url, payload): |
|
298 |
|
|
299 |
if client.session : |
|
300 |
status_code = {'success': 200, 'failure': 401} |
|
301 |
else: |
|
302 |
status_code = {'success': 403, 'failure': 403} |
|
303 |
|
|
304 |
if payload.get('name_id_content') == '12345': |
|
305 |
response = client.post(url, data=payload, format='json') |
|
306 |
|
|
307 |
assert response.status_code == status_code['failure'] |
|
308 |
|
|
309 |
if client.session: |
|
310 |
kevin = get_user(first_name='kevin') |
|
311 |
assert kevin.username == payload['name_id_content'] |
|
312 |
|
|
313 |
kevin_uuid = get_uuid(name_id=payload['name_id_content']) |
|
314 |
assert kevin_uuid.name_id == '12345' |
|
315 |
else: |
|
316 |
mock_phantomjs_result.return_value = {"result": "ok"} |
|
317 |
|
|
318 |
response = client.post(url, data=payload, format='json') |
|
319 |
|
|
320 |
assert response.status_code == status_code['success'] |
|
321 |
|
|
322 |
if client.session: |
|
323 |
josh = get_user(username='77777') |
|
324 |
josh_creds = UserCredentials.objects.filter(user=josh)[0] |
|
325 |
|
|
326 |
assert josh_creds.to_login_info()['#login'] == 'josh' |
|
327 |
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password' |
|
328 |
|
|
329 |
@pytest.mark.skipif(hobo == None, reason="hobo is required") |
|
330 |
@mock.patch('mandayejs.mandaye.api.exec_phantom') |
|
331 |
def test_signed_api_post(mock_phantomjs_result, client_service, url_signed, payload): |
|
332 |
if url_signed.orig == 'testserver' : |
|
333 |
status_code = {'success': 200, 'failure': 401} |
|
334 |
else: |
|
335 |
status_code = {'success': 403, 'failure': 403} |
|
336 |
|
|
337 |
if payload.get('name_id_content') == '12345': |
|
338 |
response = client_service.post(url_signed.url, data=payload, format='json') |
|
339 |
|
|
340 |
assert response.status_code == status_code['failure'] |
|
341 |
|
|
342 |
if url_signed.orig == 'testserver' : |
|
343 |
kevin = get_user(first_name='kevin') |
|
344 |
assert kevin.username == payload['name_id_content'] |
|
345 |
|
|
346 |
kevin_uuid = get_uuid(name_id=payload['name_id_content']) |
|
347 |
assert kevin_uuid.name_id == '12345' |
|
348 |
else: |
|
349 |
mock_phantomjs_result.return_value = {"result": "ok"} |
|
350 |
|
|
351 |
response = client_service.post(url_signed.url, data=payload, format='json') |
|
352 |
|
|
353 |
assert response.status_code == status_code['success'] |
|
354 |
|
|
355 |
if url_signed.orig == 'testserver': |
|
356 |
josh = get_user(username='77777') |
|
357 |
josh_creds = UserCredentials.objects.filter(user=josh)[0] |
|
358 |
|
|
359 |
assert josh_creds.to_login_info()['#login'] == 'josh' |
|
360 |
assert josh_creds.to_login_info(decrypt=True)['#password'] == 'josh password' |
|
361 |
|
|
362 |
# DELETE |
|
363 |
def test_api_delete(client, url): |
|
364 |
if client.session : |
|
365 |
status_code = {'success': 200, 'failure': 404} |
|
366 |
else: |
|
367 |
status_code = {'success': 403, 'failure': 403} |
|
368 |
|
|
369 |
kevin = get_user(first_name='kevin') |
|
370 |
assert UserCredentials.objects.filter(user=kevin).exists() == False |
|
371 |
response = client.delete(url, data={'name_id_content': '12345'}, format='json') |
|
372 |
assert response.status_code == status_code['failure'] |
|
373 |
|
|
374 |
josh = create_user(username='77777') |
|
375 |
create_credentials(josh,{ |
|
376 |
'login':'josh', |
|
377 |
'password': 'josh password' |
|
378 |
}) |
|
379 |
|
|
380 |
assert UserCredentials.objects.filter(user=josh).exists() == True |
|
381 |
response = client.delete(url, data={'name_id_content': '77777'}, format='json') |
|
382 |
assert response.status_code == status_code['success'] |
|
383 |
if client.session: |
|
384 |
assert UserCredentials.objects.filter(user=josh).exists() == False |
|
385 |
|
|
386 |
@pytest.mark.skipif(hobo == None, reason="hobo is required") |
|
387 |
def test_signed_api_delete(client_service, url_signed): |
|
388 |
if url_signed.orig == 'testserver' : |
|
389 |
status_code = {'success': 200, 'failure': 404} |
|
390 |
else: |
|
391 |
status_code = {'success': 403, 'failure': 403} |
|
392 |
|
|
393 |
kevin = get_user(first_name='kevin') |
|
394 |
assert UserCredentials.objects.filter(user=kevin).exists() == False |
|
395 |
response = client_service.delete(url_signed.url, data={'name_id_content': '12345'}, format='json') |
|
396 |
assert response.status_code == status_code['failure'] |
|
397 |
|
|
398 |
josh = create_user(username='77777') |
|
399 |
create_credentials(josh,{ |
|
400 |
'login':'josh', |
|
401 |
'password': 'josh password' |
|
402 |
}) |
|
403 |
|
|
404 |
assert UserCredentials.objects.filter(user=josh).exists() == True |
|
405 |
response = client_service.delete(url_signed.url, data={'name_id_content': '77777'}, format='json') |
|
406 |
assert response.status_code == status_code['success'] |
|
407 |
if url_signed.orig == 'testserver': |
|
408 |
assert UserCredentials.objects.filter(user=josh).exists() == False |
|
409 |
|
tests/utils.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from django.contrib.auth.models import User |
|
4 |
from mellon.models import UserSAMLIdentifier |
|
5 |
|
|
6 |
from mandayejs.mandaye.models import UserCredentials |
|
7 |
|
|
8 |
pytestmark = pytest.mark.django_db |
|
9 |
|
|
10 |
|
|
11 |
def create_user(**kwargs): |
|
12 |
password = kwargs.pop('password', None) or kwargs.get('username') |
|
13 |
user, created = User.objects.get_or_create(**kwargs) |
|
14 |
if password: |
|
15 |
user.set_password(password) |
|
16 |
user.save() |
|
17 |
return user |
|
18 |
|
|
19 |
|
|
20 |
def get_user(**kwargs): |
|
21 |
try: |
|
22 |
user = User.objects.get(**kwargs) |
|
23 |
return user |
|
24 |
except (User.DoesNotExist,): |
|
25 |
return None |
|
26 |
|
|
27 |
|
|
28 |
def get_uuid(**kwargs): |
|
29 |
try: |
|
30 |
uuid = UserSAMLIdentifier.objects.get(**kwargs) |
|
31 |
return uuid |
|
32 |
except (UserSAMLIdentifier.DoesNotExist): |
|
33 |
return None |
|
34 |
|
|
35 |
|
|
36 |
def create_credentials(user, credentials): |
|
37 |
cred, created = UserCredentials.objects.get_or_create(user=user, locators=credentials) |
|
38 |
return cred |
tox.ini | ||
---|---|---|
1 | 1 |
[tox] |
2 |
envlist = django17 |
|
2 |
envlist = coverage-django17-pylint,coverage-django18 |
|
3 |
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/mandayejs/ |
|
3 | 4 |
|
4 |
[testenv:django17] |
|
5 |
setenv = DJANGO_SETTINGS_MODULE=mandayejs.settings |
|
6 |
usedevelop = True |
|
5 |
[testenv] |
|
6 |
usedevelop = |
|
7 |
coverage: True |
|
8 |
setenv = |
|
9 |
DJANGO_SETTINGS_MODULE=mandayejs.settings |
|
10 |
MANDAYEJS_SETTINGS_FILE=tests/settings.py |
|
11 |
coverage: COVERAGE=--junitxml=test_results.xml --cov-report xml --cov=mandayejs/ --cov-config .coveragerc |
|
12 |
deps = |
|
13 |
django17: django>1.7,<1.8 |
|
14 |
django18: django>=1.8,<1.9 |
|
15 |
pytest-cov |
|
16 |
pytest-django |
|
17 |
pytest |
|
18 |
pytest-capturelog |
|
19 |
pylint |
|
20 |
pylint-django |
|
21 |
mock |
|
22 |
djangorestframework>=3.3,<3.4 |
|
7 | 23 |
commands = |
8 |
./getlasso.sh |
|
9 |
coverage run --source=mandayejs -m pytest -vs tests/tests.py |
|
10 |
coverage report -m |
|
11 |
|
|
12 |
deps = django>1.7,<1.8 |
|
13 |
requests |
|
14 |
pycrypto |
|
15 |
django-mellon |
|
16 |
djangorestframework |
|
17 |
python-ldap |
|
18 |
pytest |
|
19 |
pytest-django |
|
20 |
mock |
|
21 |
coverage |
|
22 |
|
|
23 |
[testenv:pylint] |
|
24 |
usedevelop = True |
|
25 |
commands = pylint mandayejs |
|
26 |
deps = pylint |
|
24 |
./getlasso.sh |
|
25 |
py.test {env:COVERAGE:} {posargs:tests/} |
|
26 |
pylint: ./pylint.sh mandayejs/ |
Formats disponibles : Unified diff
setup tests for jenkins' build (#13272)