Statistics
| Branch: | Tag: | Revision:

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