91bd0fc63778ae137acf6dd06f7aa068d2c8fd39
[mediagoblin.git] / mediagoblin / plugins / oauth / models.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 import uuid
18 import bcrypt
19
20 from datetime import datetime, timedelta
21
22 from mediagoblin.db.sql.base import Base
23 from mediagoblin.db.sql.models import User
24
25 from sqlalchemy import (
26 Column, Unicode, Integer, DateTime, ForeignKey, Enum)
27 from sqlalchemy.orm import relationship
28
29 # Don't remove this, I *think* it applies sqlalchemy-migrate functionality onto
30 # the models.
31 from migrate import changeset
32
33
34 class OAuthClient(Base):
35 __tablename__ = 'oauth__client'
36
37 id = Column(Integer, primary_key=True)
38 created = Column(DateTime, nullable=False,
39 default=datetime.now)
40
41 name = Column(Unicode)
42 description = Column(Unicode)
43
44 identifier = Column(Unicode, unique=True, index=True)
45 secret = Column(Unicode, index=True)
46
47 owner_id = Column(Integer, ForeignKey(User.id))
48 owner = relationship(User, backref='registered_clients')
49
50 redirect_uri = Column(Unicode)
51
52 type = Column(Enum(
53 u'confidential',
54 u'public'))
55
56 def generate_identifier(self):
57 self.identifier = unicode(uuid.uuid4())
58
59 def generate_secret(self):
60 self.secret = unicode(
61 bcrypt.hashpw(
62 unicode(uuid.uuid4()),
63 bcrypt.gensalt()))
64
65 def __repr__(self):
66 return '<{0} {1}:{2} ({3})>'.format(
67 self.__class__.__name__,
68 self.id,
69 self.name.encode('ascii', 'replace'),
70 self.owner.username.encode('ascii', 'replace'))
71
72
73 class OAuthUserClient(Base):
74 __tablename__ = 'oauth__user_client'
75 id = Column(Integer, primary_key=True)
76
77 user_id = Column(Integer, ForeignKey(User.id))
78 user = relationship(User, backref='oauth_clients')
79
80 client_id = Column(Integer, ForeignKey(OAuthClient.id))
81 client = relationship(OAuthClient, backref='users')
82
83 state = Column(Enum(
84 u'approved',
85 u'rejected'))
86
87 def __repr__(self):
88 return '<{0} #{1} {2} [{3}, {4}]>'.format(
89 self.__class__.__name__,
90 self.id,
91 self.state.encode('ascii', 'replace'),
92 self.user,
93 self.client)
94
95
96 class OAuthToken(Base):
97 __tablename__ = 'oauth__tokens'
98
99 id = Column(Integer, primary_key=True)
100 created = Column(DateTime, nullable=False,
101 default=datetime.now)
102 expires = Column(DateTime, nullable=False,
103 default=lambda: datetime.now() + timedelta(days=30))
104 token = Column(Unicode, index=True)
105 refresh_token = Column(Unicode, index=True)
106
107 user_id = Column(Integer, ForeignKey(User.id), nullable=False,
108 index=True)
109 user = relationship(User)
110
111 client_id = Column(Integer, ForeignKey(OAuthClient.id), nullable=False)
112 client = relationship(OAuthClient)
113
114 def __repr__(self):
115 return '<{0} #{1} expires {2} [{3}, {4}]>'.format(
116 self.__class__.__name__,
117 self.id,
118 self.expires.isoformat(),
119 self.user,
120 self.client)
121
122
123 class OAuthCode(Base):
124 __tablename__ = 'oauth__codes'
125
126 id = Column(Integer, primary_key=True)
127 created = Column(DateTime, nullable=False,
128 default=datetime.now)
129 expires = Column(DateTime, nullable=False,
130 default=lambda: datetime.now() + timedelta(minutes=5))
131 code = Column(Unicode, index=True)
132
133 user_id = Column(Integer, ForeignKey(User.id), nullable=False,
134 index=True)
135 user = relationship(User)
136
137 client_id = Column(Integer, ForeignKey(OAuthClient.id), nullable=False)
138 client = relationship(OAuthClient)
139
140 def __repr__(self):
141 return '<{0} #{1} expires {2} [{3}, {4}]>'.format(
142 self.__class__.__name__,
143 self.id,
144 self.expires.isoformat(),
145 self.user,
146 self.client)
147
148
149 MODELS = [
150 OAuthToken,
151 OAuthCode,
152 OAuthClient,
153 OAuthUserClient]