root / snf-astakos-app / astakos / oa2 / backends / djangobackend.py @ 35cbac33
History | View | Annotate | Download (6 kB)
1 |
# Copyright 2013 GRNET S.A. All rights reserved.
|
---|---|
2 |
#
|
3 |
# Redistribution and use in source and binary forms, with or
|
4 |
# without modification, are permitted provided that the following
|
5 |
# conditions are met:
|
6 |
#
|
7 |
# 1. Redistributions of source code must retain the above
|
8 |
# copyright notice, this list of conditions and the following
|
9 |
# disclaimer.
|
10 |
#
|
11 |
# 2. Redistributions in binary form must reproduce the above
|
12 |
# copyright notice, this list of conditions and the following
|
13 |
# disclaimer in the documentation and/or other materials
|
14 |
# provided with the distribution.
|
15 |
#
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 |
# POSSIBILITY OF SUCH DAMAGE.
|
28 |
#
|
29 |
# The views and conclusions contained in the software and
|
30 |
# documentation are those of the authors and should not be
|
31 |
# interpreted as representing official policies, either expressed
|
32 |
# or implied, of GRNET S.A.
|
33 |
|
34 |
import astakos.oa2.models as oa2_models |
35 |
|
36 |
from astakos.oa2.backends import base as oa2base |
37 |
from astakos.oa2.backends import base as errors |
38 |
|
39 |
from django import http |
40 |
from django.conf import settings |
41 |
from django.core.exceptions import ValidationError |
42 |
from django.core.validators import URLValidator |
43 |
from django.core.urlresolvers import reverse |
44 |
from django.conf.urls.defaults import patterns, url |
45 |
from django.http import HttpResponseNotAllowed |
46 |
from django.views.decorators.csrf import csrf_exempt |
47 |
|
48 |
from synnefo.lib import join_urls |
49 |
|
50 |
import logging |
51 |
logger = logging.getLogger(__name__) |
52 |
|
53 |
|
54 |
class DjangoViewsMixin(object): |
55 |
|
56 |
def auth_view(self, request): |
57 |
oa2request = self.build_request(request)
|
58 |
oa2response = self.authorize(oa2request, accept=False) |
59 |
return self._build_response(oa2response) |
60 |
|
61 |
@csrf_exempt
|
62 |
def token_view(self, request): |
63 |
if request.method != 'POST': |
64 |
return HttpResponseNotAllowed(['POST']) |
65 |
|
66 |
oa2request = self.build_request(request)
|
67 |
oa2response = self.grant_token(oa2request)
|
68 |
return self._build_response(oa2response) |
69 |
|
70 |
|
71 |
class DjangoBackendORMMixin(object): |
72 |
|
73 |
def get_client_by_credentials(self, username, password): |
74 |
try:
|
75 |
return oa2_models.Client.objects.get(identifier=username,
|
76 |
secret=password) |
77 |
except oa2_models.Client.DoesNotExist:
|
78 |
raise errors.InvalidClientID("No such client found") |
79 |
|
80 |
def get_client_by_id(self, clientid): |
81 |
try:
|
82 |
return oa2_models.Client.objects.get(identifier=clientid)
|
83 |
except oa2_models.Client.DoesNotExist:
|
84 |
raise errors.InvalidClientID("No such client found") |
85 |
|
86 |
def get_authorization_code(self, code): |
87 |
try:
|
88 |
return oa2_models.AuthorizationCode.objects.get(code=code)
|
89 |
except oa2_models.AuthorizationCode.DoesNotExist:
|
90 |
raise errors.OA2Error("No such authorization code") |
91 |
|
92 |
def get_token(self, token): |
93 |
try:
|
94 |
return oa2_models.Token.objects.get(code=token)
|
95 |
except oa2_models.Token.DoesNotExist:
|
96 |
raise errors.OA2Error("No such token") |
97 |
|
98 |
def delete_authorization_code(self, code): |
99 |
code.delete() |
100 |
logger.info(u'%r deleted' % code)
|
101 |
|
102 |
def delete_token(self, token): |
103 |
token.delete() |
104 |
logger.info(u'%r deleted' % token)
|
105 |
|
106 |
def check_credentials(self, client, username, secret): |
107 |
if not (username == client.get_id() and secret == client.secret): |
108 |
raise errors.InvalidAuthorizationRequest("Invalid credentials") |
109 |
|
110 |
|
111 |
class DjangoBackend(DjangoBackendORMMixin, oa2base.SimpleBackend, |
112 |
DjangoViewsMixin): |
113 |
|
114 |
code_model = oa2_models.AuthorizationCode.objects |
115 |
token_model = oa2_models.Token.objects |
116 |
client_model = oa2_models.Client.objects |
117 |
|
118 |
def _build_response(self, oa2response): |
119 |
response = http.HttpResponse() |
120 |
response.status_code = oa2response.status |
121 |
response.content = oa2response.body |
122 |
for key, value in oa2response.headers.iteritems(): |
123 |
response[key] = value |
124 |
return response
|
125 |
|
126 |
def build_request(self, django_request): |
127 |
params = { |
128 |
'method': django_request.method,
|
129 |
'path': django_request.path,
|
130 |
'GET': django_request.GET,
|
131 |
'POST': django_request.POST,
|
132 |
'META': django_request.META,
|
133 |
'secure': settings.DEBUG or django_request.is_secure(), |
134 |
#'secure': django_request.is_secure(),
|
135 |
} |
136 |
# TODO: check for valid astakos user
|
137 |
if django_request.user.is_authenticated():
|
138 |
params['user'] = django_request.user
|
139 |
return oa2base.Request(**params)
|
140 |
|
141 |
def get_url_patterns(self): |
142 |
_patterns = patterns( |
143 |
'',
|
144 |
url(r'^%s/?$' % join_urls(self.endpoints_prefix, |
145 |
self.authorization_endpoint.rstrip('/')), |
146 |
self.auth_view,
|
147 |
name='%s_authenticate' % self.id), |
148 |
url(r'^%s/?$' % join_urls(self.endpoints_prefix, |
149 |
self.token_endpoint.rstrip('/')), |
150 |
self.token_view,
|
151 |
name='%s_token' % self.id), |
152 |
) |
153 |
return _patterns
|
154 |
|
155 |
def is_uri(self, string): |
156 |
validator = URLValidator() |
157 |
try:
|
158 |
validator(string) |
159 |
except ValidationError:
|
160 |
return False |
161 |
else:
|
162 |
return True |
163 |
|
164 |
def get_login_uri(self): |
165 |
return reverse('login') |
166 |
|
167 |
|
168 |
class AstakosBackend(DjangoBackend): |
169 |
pass
|