Revision dd53338a
b/api/fixtures/api_test_data.json | ||
---|---|---|
358 | 358 |
"machines" : [1003,1004] |
359 | 359 |
} |
360 | 360 |
} |
361 |
|
|
362 | 361 |
] |
b/api/middleware.py | ||
---|---|---|
1 | 1 |
from django.conf import settings |
2 | 2 |
from django.http import HttpResponse, HttpResponseRedirect |
3 |
from synnefo.api.errors import Unauthorized |
|
4 | 3 |
from synnefo.db.models import SynnefoUser |
5 | 4 |
|
6 | 5 |
class SynnefoAuthMiddleware(object): |
... | ... | |
15 | 14 |
#Retrieve user from DB or other caching mechanism |
16 | 15 |
user = SynnefoUser.objects.filter(auth_token = request.META[self.auth_token]) |
17 | 16 |
if user is None : |
18 |
return HttpResponseRedirect(content='Athentication Required')
|
|
17 |
return HttpResponseRedirect(settings.SIBBOLLETH_HOST)
|
|
19 | 18 |
request.user = user |
20 | 19 |
return |
21 | 20 |
|
... | ... | |
28 | 27 |
# mechanism |
29 | 28 |
user = SynnefoUser.objects.filter(username = request.META[self.auth_user]) |
30 | 29 |
|
31 |
return HttpResponseRedirect(content= settings.SIBBOLLETH_HOST)
|
|
30 |
return HttpResponseRedirect(settings.SIBBOLLETH_HOST) |
|
32 | 31 |
|
33 |
return HttpResponseRedirect(content='Athentication Required') |
|
32 |
return HttpResponseRedirect(settings.SIBBOLLETH_HOST) |
|
33 |
|
|
34 |
def process_response(self, request, response): |
|
35 |
response['Vary'] = self.auth_key |
|
36 |
return response |
|
34 | 37 |
|
35 | 38 |
#class HttpResponseAuthenticationRequired(HttpResponse): |
36 | 39 |
# status_code = 401 |
b/api/tests_auth.py | ||
---|---|---|
9 | 9 |
from django.test import TestCase |
10 | 10 |
from django.test.client import Client |
11 | 11 |
|
12 |
from synnefo.logic.shibboleth import Tokens |
|
13 |
from synnefo.db.models import SynnefoUser |
|
14 |
|
|
12 | 15 |
class AuthTestCase(TestCase): |
13 |
fixtures = ['auth_test_data']
|
|
14 |
apibase = '/api/v1.0'
|
|
16 |
fixtures = ['api_test_data']
|
|
17 |
apibase = '/api/v1.1'
|
|
15 | 18 |
|
16 | 19 |
def setUp(self): |
17 | 20 |
self.client = Client() |
18 | 21 |
|
19 |
def register_sibbolleth_user(self):
|
|
20 |
""" test registration of sibboleth user upon new incoming request
|
|
22 |
def test_auth_shibboleth(self):
|
|
23 |
""" test redirect to shibboleth page
|
|
21 | 24 |
""" |
22 |
response = self.client.get( self.apibase + '/servers', {}, |
|
23 |
**{'X-givenName':'notme', |
|
24 |
'X-sn':'0xdeadbabe'}) |
|
25 |
|
|
25 |
response = self.client.get(self.apibase + '/servers') |
|
26 |
self.assertEquals(response.status_code, 302) |
|
26 | 27 |
|
27 |
def test_auth_sibbolleth(self):
|
|
28 |
""" test whether the authentication mechanism sets the correct headers
|
|
28 |
def test_register_shibboleth_user(self):
|
|
29 |
""" test registration of sibboleth user upon new incoming request
|
|
29 | 30 |
""" |
31 |
response = self.client.get(self.apibase + '/servers', {}, |
|
32 |
**{Tokens.SIB_GIVEN_NAME: 'Jimmy', |
|
33 |
Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME: 'jh@gmail.com', |
|
34 |
Tokens.SIB_DISPLAY_NAME: 'Jimmy Hendrix'}) |
|
35 |
|
|
36 |
user = None |
|
37 |
try: |
|
38 |
user = SynnefoUser.objects.get(uniq = "jh@gmail.com") |
|
39 |
except SynnefoUser.DoesNotExist: |
|
40 |
self.assertNotEqual(user, None) |
|
41 |
self.assertNotEqual(user, None) |
|
30 | 42 |
|
31 | 43 |
def test_auth_headers(self): |
32 | 44 |
""" test whether the authentication mechanism sets the correct headers |
33 | 45 |
""" |
34 | 46 |
#Check with non-existing user |
35 |
response = self.client.get( self.apibase + '/servers', {},
|
|
36 |
**{'X-Auth-User':'notme', |
|
37 |
'X-Auth-Key':'0xdeadbabe'}) |
|
47 |
response = self.client.get(self.apibase + '/servers', {}, |
|
48 |
**{'X-Auth-User': 'notme',
|
|
49 |
'X-Auth-Key': '0xdeadbabe'})
|
|
38 | 50 |
self.assertEquals(response.status_code, 401) |
39 | 51 |
|
40 | 52 |
#Check with existing user |
41 |
response = self.client.get( self.apibase + '/', {},
|
|
42 |
**{'X-Auth-User':'testuser', |
|
43 |
'X-Auth-Key':'testuserpasswd'}) |
|
53 |
response = self.client.get(self.apibase + '/', {}, |
|
54 |
**{'X-Auth-User': 'testuser',
|
|
55 |
'X-Auth-Key': 'testuserpasswd'})
|
|
44 | 56 |
self.assertEquals(response.status_code, 204) |
45 | 57 |
self.assertNotEqual(response['X-Auth-Token'], None) |
46 | 58 |
self.assertEquals(response['X-Server-Management-Url'], '') |
... | ... | |
49 | 61 |
|
50 | 62 |
#Check access now that we do have an auth token |
51 | 63 |
token = response['X-Auth-Token'] |
52 |
response = self.client.get (self.apibase + '/servers/detail', {},
|
|
64 |
response = self.client.get(self.apibase + '/servers/detail', {}, |
|
53 | 65 |
**{'X-Auth-Token': token}) |
54 | 66 |
self.assertEquals(response.status_code, 200) |
b/db/fixtures/initial_data.json | ||
---|---|---|
1 | 1 |
[ |
2 |
{ |
|
3 |
"model": "db.SynnefoUser", |
|
4 |
"pk": 1, |
|
5 |
"fields": { |
|
6 |
"name": "testdbuser", |
|
7 |
"realname" :"test db user", |
|
8 |
"uniq" :"test@synnefo.gr", |
|
9 |
"credit": 10, |
|
10 |
"auth_token": "46e427d657b20defe352804f0eb6f8a2", |
|
11 |
"type": "STUDENT", |
|
12 |
"created": "2011-02-06" |
|
13 |
} |
|
14 |
} |
|
2 | 15 |
] |
b/db/models.py | ||
---|---|---|
2 | 2 |
|
3 | 3 |
from django.conf import settings |
4 | 4 |
from django.db import models |
5 |
from django.contrib.auth.models import User |
|
6 | 5 |
|
7 | 6 |
import datetime |
8 | 7 |
|
b/logic/shibboleth.py | ||
---|---|---|
1 |
# |
|
2 |
# Business Logic for working with sibbolleth users |
|
3 |
# |
|
4 |
# Copyright 2010 Greek Research and Technology Network |
|
5 |
# |
|
6 |
|
|
7 |
from synnefo.logic import users |
|
8 |
|
|
9 |
class Tokens: |
|
10 |
SIB_GIVEN_NAME = "givenName" |
|
11 |
SIB_SN = "sn" |
|
12 |
SIB_CN = "cn" |
|
13 |
SIB_DISPLAY_NAME = "displayName" |
|
14 |
SIB_EDU_PERSON_PRINCIPAL_NAME = "eduPersonPrincipalName" |
|
15 |
SIB_EDU_PERSON_AFFILIATION = "eduPersonAffiliation" |
|
16 |
SIB_SCHAC_HOME_ORGANISATION = "schacHomeOrganization" |
|
17 |
SIB_SCHAC_PERSONAL_UNIQUE_CODE = "schacPersonalUniqueCode" |
|
18 |
SIB_GR_EDU_PERSON_UNDERGRADUATE_BRANCH = "grEduPersonUndergraduateBranch" |
|
19 |
|
|
20 |
class NoUniqueToken(object): |
|
21 |
pass |
|
22 |
|
|
23 |
def register_shibboleth_user(tokens): |
|
24 |
"""Registers a sibbolleth user using the input hash as a source for data. |
|
25 |
The token requirements are described in this document |
|
26 |
http://aai.grnet.gr/policy |
|
27 |
""" |
|
28 |
|
|
29 |
realname = tokens[Tokens.SIB_GIVEN_NAME] | tokens[Tokens.SIB_GIVEN_NAME] |
|
30 |
is_student = tokens[Tokens.SIB_SCHAC_PERSONAL_UNIQUE_CODE] | \ |
|
31 |
tokens[Tokens.SIB_GR_EDU_PERSON_UNDERGRADUATE_BRANCH] |
|
32 |
|
|
33 |
unq = tokens[Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME] |
|
34 |
|
|
35 |
if unq is None: |
|
36 |
raise NoUniqueToken |
|
37 |
|
|
38 |
if is_student: |
|
39 |
users.register_student(realname, '' ,unq) |
|
40 |
else : |
|
41 |
users.register_professor(realname, '' ,unq) |
/dev/null | ||
---|---|---|
1 |
# |
|
2 |
# Business Logic for working with sibbolleth users |
|
3 |
# |
|
4 |
# Copyright 2010 Greek Research and Technology Network |
|
5 |
# |
|
6 |
|
|
7 |
from synnefo.logic import users |
|
8 |
|
|
9 |
class Tokens: |
|
10 |
SIB_GIVEN_NAME = "givenName" |
|
11 |
SIB_SN = "sn" |
|
12 |
SIB_CN = "cn" |
|
13 |
SIB_DISPLAY_NAME = "displayName" |
|
14 |
SIB_EDU_PERSON_PRINCIPAL_NAME = "eduPersonPrincipalName" |
|
15 |
SIB_EDU_PERSON_AFFILIATION = "eduPersonAffiliation" |
|
16 |
SIB_SCHAC_HOME_ORGANISATION = "schacHomeOrganization" |
|
17 |
SIB_SCHAC_PERSONAL_UNIQUE_CODE = "schacPersonalUniqueCode" |
|
18 |
SIB_GR_EDU_PERSON_UNDERGRADUATE_BRANCH = "grEduPersonUndergraduateBranch" |
|
19 |
|
|
20 |
class NoUniqueToken(object): |
|
21 |
pass |
|
22 |
|
|
23 |
|
|
24 |
def register_sibbolleth_user(tokens): |
|
25 |
"""Registers a sibbolleth user using the input hash as a source for data. |
|
26 |
The token requirements are described in this document |
|
27 |
http://aai.grnet.gr/policy |
|
28 |
""" |
|
29 |
|
|
30 |
realname = tokens[Tokens.SIB_GIVEN_NAME] | tokens[Tokens.SIB_GIVEN_NAME] |
|
31 |
is_student = tokens[Tokens.SIB_SCHAC_PERSONAL_UNIQUE_CODE] | \ |
|
32 |
tokens[Tokens.SIB_GR_EDU_PERSON_UNDERGRADUATE_BRANCH] |
|
33 |
|
|
34 |
unq = tokens[Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME] |
|
35 |
|
|
36 |
if unq is None: |
|
37 |
raise NoUniqueToken |
|
38 |
|
|
39 |
if is_student: |
|
40 |
users.register_student(realname, '' ,unq) |
|
41 |
else : |
|
42 |
users.register_professor(realname, '' ,unq) |
b/logic/tests.py | ||
---|---|---|
10 | 10 |
from synnefo.logic import credits |
11 | 11 |
from synnefo.logic import users |
12 | 12 |
from django.test import TestCase |
13 |
from django.core.exceptions import ObjectDoesNotExist |
|
14 | 13 |
|
15 | 14 |
import hashlib |
16 | 15 |
|
... | ... | |
116 | 115 |
""" |
117 | 116 |
user = self._register_user() |
118 | 117 |
self.assertNotEquals(user, None) |
119 |
|
|
118 |
|
|
120 | 119 |
#Check hash generation |
121 | 120 |
md5 = hashlib.md5() |
122 | 121 |
md5.update(user.uniq) |
... | ... | |
129 | 128 |
""" |
130 | 129 |
user = self._register_user() |
131 | 130 |
users.delete_user(user) |
132 |
user1 = None |
|
133 | 131 |
|
134 |
try: |
|
135 |
user1 = SynnefoUser.objects.get(name = "jpage") |
|
136 |
except ObjectDoesNotExist: |
|
137 |
self.assertEquals(user1, None) |
|
132 |
self.assertRaises(SynnefoUser.DoesNotExist, SynnefoUser.objects.get, name = "jpage") |
b/settings.py.dist | ||
---|---|---|
97 | 97 |
'django.middleware.locale.LocaleMiddleware', |
98 | 98 |
'django.middleware.common.CommonMiddleware', |
99 | 99 |
'synnefo.middleware.StripURLMiddleware', |
100 |
'django.contrib.auth.middleware.AuthenticationMiddleware', |
|
100 |
#'django.contrib.auth.middleware.AuthenticationMiddleware', |
|
101 |
#'synnefo.api.middleware.SynnefoAuthMiddleware', |
|
101 | 102 |
'django.contrib.messages.middleware.MessageMiddleware', |
102 | 103 |
) |
103 | 104 |
|
... | ... | |
153 | 154 |
API_ROOT_URL = 'http://127.0.0.1:8000/api/' |
154 | 155 |
|
155 | 156 |
SIBBOLLETH_HOST = "http://wayf.grnet.gr/" |
156 |
|
Also available in: Unified diff