Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / oa2 / models.py @ 698016f7

History | View | Annotate | Download (5.9 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 datetime
35 e28a4841 Sofia Papagiannaki
36 3fc7fd80 Kostas Papadimitriou
from django.db import models
37 3fc7fd80 Kostas Papadimitriou
from django.utils.translation import ugettext_lazy as _
38 e28a4841 Sofia Papagiannaki
from django.core.exceptions import ValidationError
39 3fc7fd80 Kostas Papadimitriou
40 3fc7fd80 Kostas Papadimitriou
CLIENT_TYPES = (
41 3fc7fd80 Kostas Papadimitriou
    ('confidential', _('Confidential')),
42 3fc7fd80 Kostas Papadimitriou
    ('public', _('Public'))
43 3fc7fd80 Kostas Papadimitriou
)
44 3fc7fd80 Kostas Papadimitriou
45 3fc7fd80 Kostas Papadimitriou
CONFIDENTIAL_TYPES = ['confidential']
46 3fc7fd80 Kostas Papadimitriou
47 e28a4841 Sofia Papagiannaki
TOKEN_TYPES = (('Basic', _('Basic')),
48 e28a4841 Sofia Papagiannaki
               ('Bearer', _('Bearer')))
49 e28a4841 Sofia Papagiannaki
50 e28a4841 Sofia Papagiannaki
GRANT_TYPES = (('authorization_code', _('Authorization code')),
51 e28a4841 Sofia Papagiannaki
               ('password', _('Password')),
52 e28a4841 Sofia Papagiannaki
               ('client_credentials', _('Client Credentials')))
53 e28a4841 Sofia Papagiannaki
54 d3bb95d3 Sofia Papagiannaki
ACCESS_TOKEN_TYPES = (('online', _('Online token')),
55 d3bb95d3 Sofia Papagiannaki
                      ('offline', _('Offline token')))
56 d3bb95d3 Sofia Papagiannaki
57 3fc7fd80 Kostas Papadimitriou
58 3fc7fd80 Kostas Papadimitriou
class RedirectUrl(models.Model):
59 e28a4841 Sofia Papagiannaki
    client = models.ForeignKey('oa2.Client', on_delete=models.PROTECT)
60 e28a4841 Sofia Papagiannaki
    is_default = models.BooleanField(default=True)
61 3fc7fd80 Kostas Papadimitriou
    url = models.URLField(unique=True)
62 3fc7fd80 Kostas Papadimitriou
63 3fc7fd80 Kostas Papadimitriou
    class Meta:
64 e28a4841 Sofia Papagiannaki
        ordering = ('is_default', )
65 e28a4841 Sofia Papagiannaki
        unique_together = ('client', 'url',)
66 3fc7fd80 Kostas Papadimitriou
67 3fc7fd80 Kostas Papadimitriou
68 3fc7fd80 Kostas Papadimitriou
class Client(models.Model):
69 3fc7fd80 Kostas Papadimitriou
    name = models.CharField(max_length=100)
70 3fc7fd80 Kostas Papadimitriou
    identifier = models.CharField(max_length=255, unique=True)
71 e28a4841 Sofia Papagiannaki
    secret = models.CharField(max_length=255, null=True, default=None)
72 3fc7fd80 Kostas Papadimitriou
    url = models.CharField(max_length=255)
73 3fc7fd80 Kostas Papadimitriou
    type = models.CharField(max_length=100, choices=CLIENT_TYPES,
74 3fc7fd80 Kostas Papadimitriou
                            default='confidential')
75 e28a4841 Sofia Papagiannaki
    is_trusted = models.BooleanField(default=False)
76 e28a4841 Sofia Papagiannaki
77 e28a4841 Sofia Papagiannaki
    def save(self, **kwargs):
78 e28a4841 Sofia Papagiannaki
        if self.secret is None and self.type == 'confidential':
79 e28a4841 Sofia Papagiannaki
            raise ValidationError("Confidential clients require a secret")
80 e28a4841 Sofia Papagiannaki
        super(Client, self).save(**kwargs)
81 3fc7fd80 Kostas Papadimitriou
82 3fc7fd80 Kostas Papadimitriou
    def requires_auth(self):
83 3fc7fd80 Kostas Papadimitriou
        return self.type in CONFIDENTIAL_TYPES
84 3fc7fd80 Kostas Papadimitriou
85 3fc7fd80 Kostas Papadimitriou
    def get_default_redirect_uri(self):
86 3fc7fd80 Kostas Papadimitriou
        return self.redirecturl_set.get().url
87 3fc7fd80 Kostas Papadimitriou
88 3fc7fd80 Kostas Papadimitriou
    def redirect_uri_is_valid(self, uri):
89 698016f7 Sofia Papagiannaki
        for redirect_uri in self.redirecturl_set.values_list('url', flat=True):
90 698016f7 Sofia Papagiannaki
            if uri == redirect_uri:
91 698016f7 Sofia Papagiannaki
                return True
92 698016f7 Sofia Papagiannaki
            elif uri.startswith(redirect_uri.rstrip('/') + '/'):
93 698016f7 Sofia Papagiannaki
                return True
94 698016f7 Sofia Papagiannaki
        return False
95 3fc7fd80 Kostas Papadimitriou
96 3fc7fd80 Kostas Papadimitriou
    def get_id(self):
97 3fc7fd80 Kostas Papadimitriou
        return self.identifier
98 3fc7fd80 Kostas Papadimitriou
99 3fc7fd80 Kostas Papadimitriou
100 3fc7fd80 Kostas Papadimitriou
class AuthorizationCode(models.Model):
101 e28a4841 Sofia Papagiannaki
    user = models.ForeignKey('im.AstakosUser', on_delete=models.PROTECT)
102 3fc7fd80 Kostas Papadimitriou
    code = models.TextField()
103 252eb705 Sofia Papagiannaki
    redirect_uri = models.CharField(max_length=255, null=True, default=None)
104 e28a4841 Sofia Papagiannaki
    client = models.ForeignKey('oa2.Client', on_delete=models.PROTECT)
105 e28a4841 Sofia Papagiannaki
    scope = models.TextField(null=True, default=None)
106 e28a4841 Sofia Papagiannaki
    created_at = models.DateTimeField(default=datetime.datetime.now())
107 3fc7fd80 Kostas Papadimitriou
108 d3bb95d3 Sofia Papagiannaki
    access_token = models.CharField(max_length=100, choices=ACCESS_TOKEN_TYPES,
109 d3bb95d3 Sofia Papagiannaki
                                    default='online')
110 d3bb95d3 Sofia Papagiannaki
111 3fc7fd80 Kostas Papadimitriou
    # not really useful
112 e28a4841 Sofia Papagiannaki
    state = models.TextField(null=True, default=None)
113 e28a4841 Sofia Papagiannaki
114 e28a4841 Sofia Papagiannaki
    def client_id_is_valid(self, client_id):
115 e28a4841 Sofia Papagiannaki
        return self.client_id == client_id
116 e28a4841 Sofia Papagiannaki
117 e28a4841 Sofia Papagiannaki
    def redirect_uri_is_valid(self, redirect_uri, client):
118 e28a4841 Sofia Papagiannaki
        return (self.redirect_uri == redirect_uri and
119 e28a4841 Sofia Papagiannaki
                client.redirect_uri_is_valid(redirect_uri))
120 e28a4841 Sofia Papagiannaki
121 e28a4841 Sofia Papagiannaki
    def __repr__(self):
122 e28a4841 Sofia Papagiannaki
        return ("Authorization code: %s "
123 ae73cdc0 Sofia Papagiannaki
                "(user: %r, client: %r, redirect_uri: %r, scope: %r)" % (
124 e28a4841 Sofia Papagiannaki
                    self.code,
125 e28a4841 Sofia Papagiannaki
                    self.user.log_display,
126 e28a4841 Sofia Papagiannaki
                    self.client.get_id(),
127 e28a4841 Sofia Papagiannaki
                    self.redirect_uri, self.scope))
128 3fc7fd80 Kostas Papadimitriou
129 3fc7fd80 Kostas Papadimitriou
130 3fc7fd80 Kostas Papadimitriou
class Token(models.Model):
131 3fc7fd80 Kostas Papadimitriou
    code = models.TextField()
132 e28a4841 Sofia Papagiannaki
    created_at = models.DateTimeField(default=datetime.datetime.now())
133 3fc7fd80 Kostas Papadimitriou
    expires_at = models.DateTimeField()
134 e28a4841 Sofia Papagiannaki
    token_type = models.CharField(max_length=100, choices=TOKEN_TYPES,
135 e28a4841 Sofia Papagiannaki
                                  default='Bearer')
136 e28a4841 Sofia Papagiannaki
    grant_type = models.CharField(max_length=100, choices=GRANT_TYPES,
137 e28a4841 Sofia Papagiannaki
                                  default='authorization_code')
138 e28a4841 Sofia Papagiannaki
139 e28a4841 Sofia Papagiannaki
    # authorization fields
140 e28a4841 Sofia Papagiannaki
    user = models.ForeignKey('im.AstakosUser', on_delete=models.PROTECT)
141 e28a4841 Sofia Papagiannaki
    redirect_uri = models.CharField(max_length=255)
142 e28a4841 Sofia Papagiannaki
    client = models.ForeignKey('oa2.Client', on_delete=models.PROTECT)
143 e28a4841 Sofia Papagiannaki
    scope = models.TextField(null=True, default=None)
144 d3bb95d3 Sofia Papagiannaki
    access_token = models.CharField(max_length=100, choices=ACCESS_TOKEN_TYPES,
145 d3bb95d3 Sofia Papagiannaki
                                    default='online')
146 e28a4841 Sofia Papagiannaki
147 e28a4841 Sofia Papagiannaki
    # not really useful
148 e28a4841 Sofia Papagiannaki
    state = models.TextField(null=True, default=None)
149 e28a4841 Sofia Papagiannaki
150 e28a4841 Sofia Papagiannaki
    def __repr__(self):
151 ae73cdc0 Sofia Papagiannaki
        return ("Token: %r (token_type: %r, grant_type: %r, "
152 ae73cdc0 Sofia Papagiannaki
                "user: %r, client: %r, scope: %r)" % (
153 e28a4841 Sofia Papagiannaki
                    self.code, self.token_type, self.grant_type,
154 e28a4841 Sofia Papagiannaki
                    self.user.log_display, self.client.get_id(), self.scope))