Do not send an oauth token expiry time
[cds-indico.git] / indico / modules / oauth / models / tokens.py
blob296200d42d13930121eb75b70654985a67957f5d
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from __future__ import unicode_literals
19 from datetime import datetime, timedelta
21 from sqlalchemy.dialects.postgresql import ARRAY
23 from indico.core.db import db
24 from indico.core.db.sqlalchemy import UTCDateTime
25 from indico.util.string import return_ascii
26 from indico.util.date_time import now_utc
27 from MaKaC.common.cache import GenericCache
30 class OAuthToken(db.Model):
31 """OAuth tokens"""
33 __tablename__ = 'tokens'
34 __table_args__ = (db.UniqueConstraint('application_id', 'user_id'),
35 {'schema': 'oauth'})
37 #: the unique identifier of the token
38 id = db.Column(
39 db.Integer,
40 primary_key=True
42 #: the identifier of the linked application
43 application_id = db.Column(
44 db.Integer,
45 db.ForeignKey('oauth.applications.id'),
46 nullable=False
48 #: the identifier of the linked user
49 user_id = db.Column(
50 db.Integer,
51 db.ForeignKey('users.users.id'),
52 nullable=False,
53 index=True
55 #: an unguessable unique string of characters
56 access_token = db.Column(
57 db.String,
58 unique=True,
59 nullable=False
61 #: the list of scopes the linked application may request access to
62 scopes = db.Column(
63 ARRAY(db.String)
65 #: the last time the token was used by the application
66 last_used_dt = db.Column(
67 UTCDateTime,
68 nullable=True,
69 default=now_utc
72 #: application authorized by this token
73 application = db.relationship(
74 'OAuthApplication',
75 lazy=True,
76 backref=db.backref(
77 'tokens',
78 lazy='dynamic',
79 cascade='all, delete-orphan'
82 #: the user who owns this token
83 user = db.relationship(
84 'User',
85 lazy=False,
86 backref=db.backref(
87 'oauth_tokens',
88 lazy='dynamic',
89 cascade='all, delete-orphan'
93 @property
94 def locator(self):
95 return {'id': self.id}
97 @property
98 def expires(self):
99 # work around to have a non-expiring token
100 return datetime.utcnow() + timedelta(days=3650)
102 @property
103 def type(self):
104 return 'bearer'
106 @return_ascii
107 def __repr__(self):
108 return '<OAuthToken({}, {}, {})>'.format(self.id, self.application, self.user)
111 class OAuthGrant(object):
112 """OAuth grant token"""
114 #: cache entry to store grant tokens
115 _cache = GenericCache('oauth-grant-tokens')
117 def __init__(self, client_id, code, redirect_uri, user, scopes, expires):
118 self.client_id = client_id
119 self.code = code
120 self.redirect_uri = redirect_uri
121 self.user = user
122 self.scopes = scopes
123 self.expires = expires
125 @property
126 def key(self):
127 return self.make_key(self.client_id, self.code)
129 @property
130 def ttl(self):
131 return self.expires - datetime.utcnow()
133 @classmethod
134 def get(cls, client_id, code):
135 key = cls.make_key(client_id, code)
136 return cls._cache.get(key)
138 @classmethod
139 def make_key(cls, client_id, code):
140 return '{}:{}'.format(client_id, code)
142 def delete(self):
143 self._cache.delete(self.key)
145 def save(self):
146 self._cache.set(key=self.key, val=self, time=self.ttl)