Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / oa2 / backends / djangobackend.py @ 6c966fb7

History | View | Annotate | Download (6 kB)

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