##// END OF EJS Templates
cleanup: removed pycrypto code from db schema, it's unused anyway
marcink -
r3519:66982ec6 default
parent child Browse files
Show More
@@ -1,1339 +1,1337 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import time
22 import time
23 import base64
23 import base64
24 import hashlib
24 import hashlib
25 import logging
25 import logging
26 import datetime
26 import datetime
27 import warnings
27 import warnings
28 import ipaddress
28 import ipaddress
29 import functools
29 import functools
30 import traceback
30 import traceback
31 import itertools
31 import itertools
32 import collections
32 import collections
33
33
34
34
35 from sqlalchemy import *
35 from sqlalchemy import *
36 from sqlalchemy.ext.hybrid import hybrid_property
36 from sqlalchemy.ext.hybrid import hybrid_property
37 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
37 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
38 from sqlalchemy.exc import OperationalError
38 from sqlalchemy.exc import OperationalError
39 from beaker.cache import cache_region, region_invalidate
39 from beaker.cache import cache_region, region_invalidate
40 from webob.exc import HTTPNotFound
40 from webob.exc import HTTPNotFound
41 from Crypto.Cipher import AES
42 from Crypto import Random
43 from zope.cachedescriptors.property import Lazy as LazyProperty
41 from zope.cachedescriptors.property import Lazy as LazyProperty
44
42
45 from rhodecode.translation import _
43 from rhodecode.translation import _
46
44
47 from rhodecode.lib.vcs import get_backend
45 from rhodecode.lib.vcs import get_backend
48 from rhodecode.lib.vcs.utils.helpers import get_scm
46 from rhodecode.lib.vcs.utils.helpers import get_scm
49 from rhodecode.lib.vcs.exceptions import VCSError
47 from rhodecode.lib.vcs.exceptions import VCSError
50 from rhodecode.lib.vcs.backends.base import (
48 from rhodecode.lib.vcs.backends.base import (
51 EmptyCommit, Reference, MergeFailureReason)
49 EmptyCommit, Reference, MergeFailureReason)
52 from rhodecode.lib.utils2 import (
50 from rhodecode.lib.utils2 import (
53 str2bool, safe_str, get_commit_safe, safe_unicode, remove_prefix, md5_safe,
51 str2bool, safe_str, get_commit_safe, safe_unicode, remove_prefix, md5_safe,
54 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict)
52 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict)
55 from rhodecode.lib.ext_json import json
53 from rhodecode.lib.ext_json import json
56 from rhodecode.lib.caching_query import FromCache
54 from rhodecode.lib.caching_query import FromCache
57 from rhodecode.lib.encrypt import AESCipher
55 from rhodecode.lib.encrypt import AESCipher
58
56
59 from rhodecode.model.meta import Base, Session
57 from rhodecode.model.meta import Base, Session
60
58
61 URL_SEP = '/'
59 URL_SEP = '/'
62 log = logging.getLogger(__name__)
60 log = logging.getLogger(__name__)
63
61
64 #==============================================================================
62 #==============================================================================
65 # BASE CLASSES
63 # BASE CLASSES
66 #==============================================================================
64 #==============================================================================
67
65
68 _hash_key = lambda k: md5_safe(k)
66 _hash_key = lambda k: md5_safe(k)
69
67
70
68
71 # this is propagated from .ini file beaker.session.secret
69 # this is propagated from .ini file beaker.session.secret
72 # and initialized at environment.py
70 # and initialized at environment.py
73 ENCRYPTION_KEY = None
71 ENCRYPTION_KEY = None
74
72
75
73
76 class EncryptedValue(TypeDecorator):
74 class EncryptedValue(TypeDecorator):
77 """
75 """
78 Special column for encrypted data, use like::
76 Special column for encrypted data, use like::
79
77
80 value = Column("encrypted_value", EncryptedValue(40), nullable=False)
78 value = Column("encrypted_value", EncryptedValue(40), nullable=False)
81
79
82 This column is intelligent so if value is in unencrypted form it return
80 This column is intelligent so if value is in unencrypted form it return
83 unencrypted form, but on save it always encrypts
81 unencrypted form, but on save it always encrypts
84 """
82 """
85 impl = String
83 impl = String
86
84
87 def process_bind_param(self, value, dialect):
85 def process_bind_param(self, value, dialect):
88 if not value:
86 if not value:
89 return value
87 return value
90 if value.startswith('enc$aes$'):
88 if value.startswith('enc$aes$'):
91 # protect against double encrypting if someone manually starts doing
89 # protect against double encrypting if someone manually starts doing
92 raise ValueError('value needs to be in unencrypted format, ie. '
90 raise ValueError('value needs to be in unencrypted format, ie. '
93 'not starting with enc$aes$')
91 'not starting with enc$aes$')
94 return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value)
92 return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value)
95
93
96 def process_result_value(self, value, dialect):
94 def process_result_value(self, value, dialect):
97 if not value:
95 if not value:
98 return value
96 return value
99
97
100 parts = value.split('$', 3)
98 parts = value.split('$', 3)
101 if not len(parts) == 3:
99 if not len(parts) == 3:
102 # probably not encrypted values
100 # probably not encrypted values
103 return value
101 return value
104 else:
102 else:
105 if parts[0] != 'enc':
103 if parts[0] != 'enc':
106 # parts ok but without our header ?
104 # parts ok but without our header ?
107 return value
105 return value
108
106
109 # at that stage we know it's our encryption
107 # at that stage we know it's our encryption
110 decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2])
108 decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2])
111 return decrypted_data
109 return decrypted_data
112
110
113
111
114 class BaseModel(object):
112 class BaseModel(object):
115 """
113 """
116 Base Model for all classes
114 Base Model for all classes
117 """
115 """
118
116
119 @classmethod
117 @classmethod
120 def _get_keys(cls):
118 def _get_keys(cls):
121 """return column names for this model """
119 """return column names for this model """
122 return class_mapper(cls).c.keys()
120 return class_mapper(cls).c.keys()
123
121
124 def get_dict(self):
122 def get_dict(self):
125 """
123 """
126 return dict with keys and values corresponding
124 return dict with keys and values corresponding
127 to this model data """
125 to this model data """
128
126
129 d = {}
127 d = {}
130 for k in self._get_keys():
128 for k in self._get_keys():
131 d[k] = getattr(self, k)
129 d[k] = getattr(self, k)
132
130
133 # also use __json__() if present to get additional fields
131 # also use __json__() if present to get additional fields
134 _json_attr = getattr(self, '__json__', None)
132 _json_attr = getattr(self, '__json__', None)
135 if _json_attr:
133 if _json_attr:
136 # update with attributes from __json__
134 # update with attributes from __json__
137 if callable(_json_attr):
135 if callable(_json_attr):
138 _json_attr = _json_attr()
136 _json_attr = _json_attr()
139 for k, val in _json_attr.iteritems():
137 for k, val in _json_attr.iteritems():
140 d[k] = val
138 d[k] = val
141 return d
139 return d
142
140
143 def get_appstruct(self):
141 def get_appstruct(self):
144 """return list with keys and values tupples corresponding
142 """return list with keys and values tupples corresponding
145 to this model data """
143 to this model data """
146
144
147 l = []
145 l = []
148 for k in self._get_keys():
146 for k in self._get_keys():
149 l.append((k, getattr(self, k),))
147 l.append((k, getattr(self, k),))
150 return l
148 return l
151
149
152 def populate_obj(self, populate_dict):
150 def populate_obj(self, populate_dict):
153 """populate model with data from given populate_dict"""
151 """populate model with data from given populate_dict"""
154
152
155 for k in self._get_keys():
153 for k in self._get_keys():
156 if k in populate_dict:
154 if k in populate_dict:
157 setattr(self, k, populate_dict[k])
155 setattr(self, k, populate_dict[k])
158
156
159 @classmethod
157 @classmethod
160 def query(cls):
158 def query(cls):
161 return Session().query(cls)
159 return Session().query(cls)
162
160
163 @classmethod
161 @classmethod
164 def get(cls, id_):
162 def get(cls, id_):
165 if id_:
163 if id_:
166 return cls.query().get(id_)
164 return cls.query().get(id_)
167
165
168 @classmethod
166 @classmethod
169 def get_or_404(cls, id_):
167 def get_or_404(cls, id_):
170 try:
168 try:
171 id_ = int(id_)
169 id_ = int(id_)
172 except (TypeError, ValueError):
170 except (TypeError, ValueError):
173 raise HTTPNotFound
171 raise HTTPNotFound
174
172
175 res = cls.query().get(id_)
173 res = cls.query().get(id_)
176 if not res:
174 if not res:
177 raise HTTPNotFound
175 raise HTTPNotFound
178 return res
176 return res
179
177
180 @classmethod
178 @classmethod
181 def getAll(cls):
179 def getAll(cls):
182 # deprecated and left for backward compatibility
180 # deprecated and left for backward compatibility
183 return cls.get_all()
181 return cls.get_all()
184
182
185 @classmethod
183 @classmethod
186 def get_all(cls):
184 def get_all(cls):
187 return cls.query().all()
185 return cls.query().all()
188
186
189 @classmethod
187 @classmethod
190 def delete(cls, id_):
188 def delete(cls, id_):
191 obj = cls.query().get(id_)
189 obj = cls.query().get(id_)
192 Session().delete(obj)
190 Session().delete(obj)
193
191
194 def __repr__(self):
192 def __repr__(self):
195 if hasattr(self, '__unicode__'):
193 if hasattr(self, '__unicode__'):
196 # python repr needs to return str
194 # python repr needs to return str
197 try:
195 try:
198 return safe_str(self.__unicode__())
196 return safe_str(self.__unicode__())
199 except UnicodeDecodeError:
197 except UnicodeDecodeError:
200 pass
198 pass
201 return '<DB:%s>' % (self.__class__.__name__)
199 return '<DB:%s>' % (self.__class__.__name__)
202
200
203
201
204 class RhodeCodeSetting(Base, BaseModel):
202 class RhodeCodeSetting(Base, BaseModel):
205 __tablename__ = 'rhodecode_settings'
203 __tablename__ = 'rhodecode_settings'
206 __table_args__ = (
204 __table_args__ = (
207 UniqueConstraint('app_settings_name'),
205 UniqueConstraint('app_settings_name'),
208 {'extend_existing': True, 'mysql_engine': 'InnoDB',
206 {'extend_existing': True, 'mysql_engine': 'InnoDB',
209 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
207 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
210 )
208 )
211
209
212 SETTINGS_TYPES = {
210 SETTINGS_TYPES = {
213 'str': safe_str,
211 'str': safe_str,
214 'int': safe_int,
212 'int': safe_int,
215 'unicode': safe_unicode,
213 'unicode': safe_unicode,
216 'bool': str2bool,
214 'bool': str2bool,
217 'list': functools.partial(aslist, sep=',')
215 'list': functools.partial(aslist, sep=',')
218 }
216 }
219 DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions'
217 DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions'
220 GLOBAL_CONF_KEY = 'app_settings'
218 GLOBAL_CONF_KEY = 'app_settings'
221
219
222 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
220 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
223 app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None)
221 app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None)
224 _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None)
222 _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None)
225 _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None)
223 _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None)
226
224
227 def __init__(self, key='', val='', type='unicode'):
225 def __init__(self, key='', val='', type='unicode'):
228 self.app_settings_name = key
226 self.app_settings_name = key
229 self.app_settings_value = val
227 self.app_settings_value = val
230 self.app_settings_type = type
228 self.app_settings_type = type
231
229
232 @validates('_app_settings_value')
230 @validates('_app_settings_value')
233 def validate_settings_value(self, key, val):
231 def validate_settings_value(self, key, val):
234 assert type(val) == unicode
232 assert type(val) == unicode
235 return val
233 return val
236
234
237 @hybrid_property
235 @hybrid_property
238 def app_settings_value(self):
236 def app_settings_value(self):
239 v = self._app_settings_value
237 v = self._app_settings_value
240 _type = self.app_settings_type
238 _type = self.app_settings_type
241 converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode']
239 converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode']
242 return converter(v)
240 return converter(v)
243
241
244 @app_settings_value.setter
242 @app_settings_value.setter
245 def app_settings_value(self, val):
243 def app_settings_value(self, val):
246 """
244 """
247 Setter that will always make sure we use unicode in app_settings_value
245 Setter that will always make sure we use unicode in app_settings_value
248
246
249 :param val:
247 :param val:
250 """
248 """
251 self._app_settings_value = safe_unicode(val)
249 self._app_settings_value = safe_unicode(val)
252
250
253 @hybrid_property
251 @hybrid_property
254 def app_settings_type(self):
252 def app_settings_type(self):
255 return self._app_settings_type
253 return self._app_settings_type
256
254
257 @app_settings_type.setter
255 @app_settings_type.setter
258 def app_settings_type(self, val):
256 def app_settings_type(self, val):
259 if val not in self.SETTINGS_TYPES:
257 if val not in self.SETTINGS_TYPES:
260 raise Exception('type must be one of %s got %s'
258 raise Exception('type must be one of %s got %s'
261 % (self.SETTINGS_TYPES.keys(), val))
259 % (self.SETTINGS_TYPES.keys(), val))
262 self._app_settings_type = val
260 self._app_settings_type = val
263
261
264 def __unicode__(self):
262 def __unicode__(self):
265 return u"<%s('%s:%s[%s]')>" % (
263 return u"<%s('%s:%s[%s]')>" % (
266 self.__class__.__name__,
264 self.__class__.__name__,
267 self.app_settings_name, self.app_settings_value, self.app_settings_type
265 self.app_settings_name, self.app_settings_value, self.app_settings_type
268 )
266 )
269
267
270
268
271 class RhodeCodeUi(Base, BaseModel):
269 class RhodeCodeUi(Base, BaseModel):
272 __tablename__ = 'rhodecode_ui'
270 __tablename__ = 'rhodecode_ui'
273 __table_args__ = (
271 __table_args__ = (
274 UniqueConstraint('ui_key'),
272 UniqueConstraint('ui_key'),
275 {'extend_existing': True, 'mysql_engine': 'InnoDB',
273 {'extend_existing': True, 'mysql_engine': 'InnoDB',
276 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
274 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
277 )
275 )
278
276
279 HOOK_REPO_SIZE = 'changegroup.repo_size'
277 HOOK_REPO_SIZE = 'changegroup.repo_size'
280 # HG
278 # HG
281 HOOK_PRE_PULL = 'preoutgoing.pre_pull'
279 HOOK_PRE_PULL = 'preoutgoing.pre_pull'
282 HOOK_PULL = 'outgoing.pull_logger'
280 HOOK_PULL = 'outgoing.pull_logger'
283 HOOK_PRE_PUSH = 'prechangegroup.pre_push'
281 HOOK_PRE_PUSH = 'prechangegroup.pre_push'
284 HOOK_PUSH = 'changegroup.push_logger'
282 HOOK_PUSH = 'changegroup.push_logger'
285
283
286 # TODO: johbo: Unify way how hooks are configured for git and hg,
284 # TODO: johbo: Unify way how hooks are configured for git and hg,
287 # git part is currently hardcoded.
285 # git part is currently hardcoded.
288
286
289 # SVN PATTERNS
287 # SVN PATTERNS
290 SVN_BRANCH_ID = 'vcs_svn_branch'
288 SVN_BRANCH_ID = 'vcs_svn_branch'
291 SVN_TAG_ID = 'vcs_svn_tag'
289 SVN_TAG_ID = 'vcs_svn_tag'
292
290
293 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
291 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
294 ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None)
292 ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None)
295 ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None)
293 ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None)
296 ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None)
294 ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None)
297 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
295 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
298
296
299 def __repr__(self):
297 def __repr__(self):
300 return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section,
298 return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section,
301 self.ui_key, self.ui_value)
299 self.ui_key, self.ui_value)
302
300
303
301
304 class User(Base, BaseModel):
302 class User(Base, BaseModel):
305 __tablename__ = 'users'
303 __tablename__ = 'users'
306 __table_args__ = (
304 __table_args__ = (
307 UniqueConstraint('username'), UniqueConstraint('email'),
305 UniqueConstraint('username'), UniqueConstraint('email'),
308 Index('u_username_idx', 'username'),
306 Index('u_username_idx', 'username'),
309 Index('u_email_idx', 'email'),
307 Index('u_email_idx', 'email'),
310 {'extend_existing': True, 'mysql_engine': 'InnoDB',
308 {'extend_existing': True, 'mysql_engine': 'InnoDB',
311 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
309 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
312 )
310 )
313 DEFAULT_USER = 'default'
311 DEFAULT_USER = 'default'
314 DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}'
312 DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}'
315
313
316 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
314 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
317 username = Column("username", String(255), nullable=True, unique=None, default=None)
315 username = Column("username", String(255), nullable=True, unique=None, default=None)
318 password = Column("password", String(255), nullable=True, unique=None, default=None)
316 password = Column("password", String(255), nullable=True, unique=None, default=None)
319 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
317 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
320 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
318 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
321 name = Column("firstname", String(255), nullable=True, unique=None, default=None)
319 name = Column("firstname", String(255), nullable=True, unique=None, default=None)
322 lastname = Column("lastname", String(255), nullable=True, unique=None, default=None)
320 lastname = Column("lastname", String(255), nullable=True, unique=None, default=None)
323 _email = Column("email", String(255), nullable=True, unique=None, default=None)
321 _email = Column("email", String(255), nullable=True, unique=None, default=None)
324 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
322 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
325 extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None)
323 extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None)
326 extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None)
324 extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None)
327 api_key = Column("api_key", String(255), nullable=True, unique=None, default=None)
325 api_key = Column("api_key", String(255), nullable=True, unique=None, default=None)
328 inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
326 inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
329 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
327 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
330 _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data
328 _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data
331
329
332 user_log = relationship('UserLog')
330 user_log = relationship('UserLog')
333 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
331 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
334
332
335 repositories = relationship('Repository')
333 repositories = relationship('Repository')
336 repository_groups = relationship('RepoGroup')
334 repository_groups = relationship('RepoGroup')
337 user_groups = relationship('UserGroup')
335 user_groups = relationship('UserGroup')
338
336
339 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
337 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
340 followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all')
338 followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all')
341
339
342 repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all')
340 repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all')
343 repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all')
341 repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all')
344
342
345 group_member = relationship('UserGroupMember', cascade='all')
343 group_member = relationship('UserGroupMember', cascade='all')
346
344
347 notifications = relationship('UserNotification', cascade='all')
345 notifications = relationship('UserNotification', cascade='all')
348 # notifications assigned to this user
346 # notifications assigned to this user
349 user_created_notifications = relationship('Notification', cascade='all')
347 user_created_notifications = relationship('Notification', cascade='all')
350 # comments created by this user
348 # comments created by this user
351 user_comments = relationship('ChangesetComment', cascade='all')
349 user_comments = relationship('ChangesetComment', cascade='all')
352 user_emails = relationship('UserEmailMap', cascade='all')
350 user_emails = relationship('UserEmailMap', cascade='all')
353 user_auth_tokens = relationship('UserApiKeys', cascade='all')
351 user_auth_tokens = relationship('UserApiKeys', cascade='all')
354 # gists
352 # gists
355 user_gists = relationship('Gist', cascade='all')
353 user_gists = relationship('Gist', cascade='all')
356 # user pull requests
354 # user pull requests
357 user_pull_requests = relationship('PullRequest', cascade='all')
355 user_pull_requests = relationship('PullRequest', cascade='all')
358
356
359 def __unicode__(self):
357 def __unicode__(self):
360 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
358 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
361 self.user_id, self.username)
359 self.user_id, self.username)
362
360
363 @hybrid_property
361 @hybrid_property
364 def email(self):
362 def email(self):
365 return self._email
363 return self._email
366
364
367 @email.setter
365 @email.setter
368 def email(self, val):
366 def email(self, val):
369 self._email = val.lower() if val else None
367 self._email = val.lower() if val else None
370
368
371 @property
369 @property
372 def firstname(self):
370 def firstname(self):
373 # alias for future
371 # alias for future
374 return self.name
372 return self.name
375
373
376 @property
374 @property
377 def username_and_name(self):
375 def username_and_name(self):
378 return '%s (%s %s)' % (self.username, self.firstname, self.lastname)
376 return '%s (%s %s)' % (self.username, self.firstname, self.lastname)
379
377
380 @property
378 @property
381 def full_name(self):
379 def full_name(self):
382 return '%s %s' % (self.firstname, self.lastname)
380 return '%s %s' % (self.firstname, self.lastname)
383
381
384 @property
382 @property
385 def full_contact(self):
383 def full_contact(self):
386 return '%s %s <%s>' % (self.firstname, self.lastname, self.email)
384 return '%s %s <%s>' % (self.firstname, self.lastname, self.email)
387
385
388 @property
386 @property
389 def short_contact(self):
387 def short_contact(self):
390 return '%s %s' % (self.firstname, self.lastname)
388 return '%s %s' % (self.firstname, self.lastname)
391
389
392 @property
390 @property
393 def is_admin(self):
391 def is_admin(self):
394 return self.admin
392 return self.admin
395
393
396 @classmethod
394 @classmethod
397 def get_by_username(cls, username, case_insensitive=False, cache=False):
395 def get_by_username(cls, username, case_insensitive=False, cache=False):
398 if case_insensitive:
396 if case_insensitive:
399 q = cls.query().filter(func.lower(cls.username) == func.lower(username))
397 q = cls.query().filter(func.lower(cls.username) == func.lower(username))
400 else:
398 else:
401 q = cls.query().filter(cls.username == username)
399 q = cls.query().filter(cls.username == username)
402
400
403 if cache:
401 if cache:
404 q = q.options(FromCache(
402 q = q.options(FromCache(
405 "sql_cache_short",
403 "sql_cache_short",
406 "get_user_%s" % _hash_key(username)))
404 "get_user_%s" % _hash_key(username)))
407 return q.scalar()
405 return q.scalar()
408
406
409 @classmethod
407 @classmethod
410 def get_by_auth_token(cls, auth_token, cache=False, fallback=True):
408 def get_by_auth_token(cls, auth_token, cache=False, fallback=True):
411 q = cls.query().filter(cls.api_key == auth_token)
409 q = cls.query().filter(cls.api_key == auth_token)
412
410
413 if cache:
411 if cache:
414 q = q.options(FromCache("sql_cache_short",
412 q = q.options(FromCache("sql_cache_short",
415 "get_auth_token_%s" % auth_token))
413 "get_auth_token_%s" % auth_token))
416 res = q.scalar()
414 res = q.scalar()
417
415
418 if fallback and not res:
416 if fallback and not res:
419 #fallback to additional keys
417 #fallback to additional keys
420 _res = UserApiKeys.query()\
418 _res = UserApiKeys.query()\
421 .filter(UserApiKeys.api_key == auth_token)\
419 .filter(UserApiKeys.api_key == auth_token)\
422 .filter(or_(UserApiKeys.expires == -1,
420 .filter(or_(UserApiKeys.expires == -1,
423 UserApiKeys.expires >= time.time()))\
421 UserApiKeys.expires >= time.time()))\
424 .first()
422 .first()
425 if _res:
423 if _res:
426 res = _res.user
424 res = _res.user
427 return res
425 return res
428
426
429 @classmethod
427 @classmethod
430 def get_by_email(cls, email, case_insensitive=False, cache=False):
428 def get_by_email(cls, email, case_insensitive=False, cache=False):
431
429
432 if case_insensitive:
430 if case_insensitive:
433 q = cls.query().filter(func.lower(cls.email) == func.lower(email))
431 q = cls.query().filter(func.lower(cls.email) == func.lower(email))
434
432
435 else:
433 else:
436 q = cls.query().filter(cls.email == email)
434 q = cls.query().filter(cls.email == email)
437
435
438 if cache:
436 if cache:
439 q = q.options(FromCache("sql_cache_short",
437 q = q.options(FromCache("sql_cache_short",
440 "get_email_key_%s" % email))
438 "get_email_key_%s" % email))
441
439
442 ret = q.scalar()
440 ret = q.scalar()
443 if ret is None:
441 if ret is None:
444 q = UserEmailMap.query()
442 q = UserEmailMap.query()
445 # try fetching in alternate email map
443 # try fetching in alternate email map
446 if case_insensitive:
444 if case_insensitive:
447 q = q.filter(func.lower(UserEmailMap.email) == func.lower(email))
445 q = q.filter(func.lower(UserEmailMap.email) == func.lower(email))
448 else:
446 else:
449 q = q.filter(UserEmailMap.email == email)
447 q = q.filter(UserEmailMap.email == email)
450 q = q.options(joinedload(UserEmailMap.user))
448 q = q.options(joinedload(UserEmailMap.user))
451 if cache:
449 if cache:
452 q = q.options(FromCache("sql_cache_short",
450 q = q.options(FromCache("sql_cache_short",
453 "get_email_map_key_%s" % email))
451 "get_email_map_key_%s" % email))
454 ret = getattr(q.scalar(), 'user', None)
452 ret = getattr(q.scalar(), 'user', None)
455
453
456 return ret
454 return ret
457
455
458 @classmethod
456 @classmethod
459 def get_first_admin(cls):
457 def get_first_admin(cls):
460 user = User.query().filter(User.admin == True).first()
458 user = User.query().filter(User.admin == True).first()
461 if user is None:
459 if user is None:
462 raise Exception('Missing administrative account!')
460 raise Exception('Missing administrative account!')
463 return user
461 return user
464
462
465 @classmethod
463 @classmethod
466 def get_default_user(cls, cache=False):
464 def get_default_user(cls, cache=False):
467 user = User.get_by_username(User.DEFAULT_USER, cache=cache)
465 user = User.get_by_username(User.DEFAULT_USER, cache=cache)
468 if user is None:
466 if user is None:
469 raise Exception('Missing default account!')
467 raise Exception('Missing default account!')
470 return user
468 return user
471
469
472
470
473 class UserApiKeys(Base, BaseModel):
471 class UserApiKeys(Base, BaseModel):
474 __tablename__ = 'user_api_keys'
472 __tablename__ = 'user_api_keys'
475 __table_args__ = (
473 __table_args__ = (
476 Index('uak_api_key_idx', 'api_key'),
474 Index('uak_api_key_idx', 'api_key'),
477 Index('uak_api_key_expires_idx', 'api_key', 'expires'),
475 Index('uak_api_key_expires_idx', 'api_key', 'expires'),
478 UniqueConstraint('api_key'),
476 UniqueConstraint('api_key'),
479 {'extend_existing': True, 'mysql_engine': 'InnoDB',
477 {'extend_existing': True, 'mysql_engine': 'InnoDB',
480 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
478 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
481 )
479 )
482 __mapper_args__ = {}
480 __mapper_args__ = {}
483
481
484 # ApiKey role
482 # ApiKey role
485 ROLE_ALL = 'token_role_all'
483 ROLE_ALL = 'token_role_all'
486 ROLE_HTTP = 'token_role_http'
484 ROLE_HTTP = 'token_role_http'
487 ROLE_VCS = 'token_role_vcs'
485 ROLE_VCS = 'token_role_vcs'
488 ROLE_API = 'token_role_api'
486 ROLE_API = 'token_role_api'
489 ROLE_FEED = 'token_role_feed'
487 ROLE_FEED = 'token_role_feed'
490 ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED]
488 ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED]
491
489
492 user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
490 user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
493 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
491 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
494 api_key = Column("api_key", String(255), nullable=False, unique=True)
492 api_key = Column("api_key", String(255), nullable=False, unique=True)
495 description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql'))
493 description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql'))
496 expires = Column('expires', Float(53), nullable=False)
494 expires = Column('expires', Float(53), nullable=False)
497 role = Column('role', String(255), nullable=True)
495 role = Column('role', String(255), nullable=True)
498 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
496 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
499
497
500 user = relationship('User', lazy='joined')
498 user = relationship('User', lazy='joined')
501
499
502
500
503 class UserEmailMap(Base, BaseModel):
501 class UserEmailMap(Base, BaseModel):
504 __tablename__ = 'user_email_map'
502 __tablename__ = 'user_email_map'
505 __table_args__ = (
503 __table_args__ = (
506 Index('uem_email_idx', 'email'),
504 Index('uem_email_idx', 'email'),
507 UniqueConstraint('email'),
505 UniqueConstraint('email'),
508 {'extend_existing': True, 'mysql_engine': 'InnoDB',
506 {'extend_existing': True, 'mysql_engine': 'InnoDB',
509 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
507 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
510 )
508 )
511 __mapper_args__ = {}
509 __mapper_args__ = {}
512
510
513 email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
511 email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
514 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
512 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
515 _email = Column("email", String(255), nullable=True, unique=False, default=None)
513 _email = Column("email", String(255), nullable=True, unique=False, default=None)
516 user = relationship('User', lazy='joined')
514 user = relationship('User', lazy='joined')
517
515
518 @validates('_email')
516 @validates('_email')
519 def validate_email(self, key, email):
517 def validate_email(self, key, email):
520 # check if this email is not main one
518 # check if this email is not main one
521 main_email = Session().query(User).filter(User.email == email).scalar()
519 main_email = Session().query(User).filter(User.email == email).scalar()
522 if main_email is not None:
520 if main_email is not None:
523 raise AttributeError('email %s is present is user table' % email)
521 raise AttributeError('email %s is present is user table' % email)
524 return email
522 return email
525
523
526 @hybrid_property
524 @hybrid_property
527 def email(self):
525 def email(self):
528 return self._email
526 return self._email
529
527
530 @email.setter
528 @email.setter
531 def email(self, val):
529 def email(self, val):
532 self._email = val.lower() if val else None
530 self._email = val.lower() if val else None
533
531
534
532
535 class UserIpMap(Base, BaseModel):
533 class UserIpMap(Base, BaseModel):
536 __tablename__ = 'user_ip_map'
534 __tablename__ = 'user_ip_map'
537 __table_args__ = (
535 __table_args__ = (
538 UniqueConstraint('user_id', 'ip_addr'),
536 UniqueConstraint('user_id', 'ip_addr'),
539 {'extend_existing': True, 'mysql_engine': 'InnoDB',
537 {'extend_existing': True, 'mysql_engine': 'InnoDB',
540 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
538 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
541 )
539 )
542 __mapper_args__ = {}
540 __mapper_args__ = {}
543
541
544 ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
542 ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
545 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
543 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
546 ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None)
544 ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None)
547 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
545 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
548 description = Column("description", String(10000), nullable=True, unique=None, default=None)
546 description = Column("description", String(10000), nullable=True, unique=None, default=None)
549 user = relationship('User', lazy='joined')
547 user = relationship('User', lazy='joined')
550
548
551 def __unicode__(self):
549 def __unicode__(self):
552 return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__,
550 return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__,
553 self.user_id, self.ip_addr)
551 self.user_id, self.ip_addr)
554
552
555
553
556 class UserLog(Base, BaseModel):
554 class UserLog(Base, BaseModel):
557 __tablename__ = 'user_logs'
555 __tablename__ = 'user_logs'
558 __table_args__ = (
556 __table_args__ = (
559 {'extend_existing': True, 'mysql_engine': 'InnoDB',
557 {'extend_existing': True, 'mysql_engine': 'InnoDB',
560 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
558 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
561 )
559 )
562 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
560 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
563 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
561 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
564 username = Column("username", String(255), nullable=True, unique=None, default=None)
562 username = Column("username", String(255), nullable=True, unique=None, default=None)
565 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True)
563 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True)
566 repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None)
564 repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None)
567 user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None)
565 user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None)
568 action = Column("action", String(1200000), nullable=True, unique=None, default=None)
566 action = Column("action", String(1200000), nullable=True, unique=None, default=None)
569 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
567 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
570
568
571 def __unicode__(self):
569 def __unicode__(self):
572 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
570 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
573 self.repository_name,
571 self.repository_name,
574 self.action)
572 self.action)
575
573
576 user = relationship('User')
574 user = relationship('User')
577 repository = relationship('Repository', cascade='')
575 repository = relationship('Repository', cascade='')
578
576
579
577
580 class UserGroup(Base, BaseModel):
578 class UserGroup(Base, BaseModel):
581 __tablename__ = 'users_groups'
579 __tablename__ = 'users_groups'
582 __table_args__ = (
580 __table_args__ = (
583 {'extend_existing': True, 'mysql_engine': 'InnoDB',
581 {'extend_existing': True, 'mysql_engine': 'InnoDB',
584 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
582 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
585 )
583 )
586
584
587 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
585 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
588 users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None)
586 users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None)
589 user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None)
587 user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None)
590 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
588 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
591 inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
589 inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
592 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
590 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
593 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
591 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
594 _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data
592 _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data
595
593
596 members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
594 members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
597 users_group_to_perm = relationship('UserGroupToPerm', cascade='all')
595 users_group_to_perm = relationship('UserGroupToPerm', cascade='all')
598 users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
596 users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
599 users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
597 users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
600 user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all')
598 user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all')
601 user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm ', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all')
599 user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm ', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all')
602
600
603 user = relationship('User')
601 user = relationship('User')
604
602
605 def __unicode__(self):
603 def __unicode__(self):
606 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
604 return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
607 self.users_group_id,
605 self.users_group_id,
608 self.users_group_name)
606 self.users_group_name)
609
607
610 @classmethod
608 @classmethod
611 def get_by_group_name(cls, group_name, cache=False,
609 def get_by_group_name(cls, group_name, cache=False,
612 case_insensitive=False):
610 case_insensitive=False):
613 if case_insensitive:
611 if case_insensitive:
614 q = cls.query().filter(func.lower(cls.users_group_name) ==
612 q = cls.query().filter(func.lower(cls.users_group_name) ==
615 func.lower(group_name))
613 func.lower(group_name))
616
614
617 else:
615 else:
618 q = cls.query().filter(cls.users_group_name == group_name)
616 q = cls.query().filter(cls.users_group_name == group_name)
619 if cache:
617 if cache:
620 q = q.options(FromCache(
618 q = q.options(FromCache(
621 "sql_cache_short",
619 "sql_cache_short",
622 "get_user_%s" % _hash_key(group_name)))
620 "get_user_%s" % _hash_key(group_name)))
623 return q.scalar()
621 return q.scalar()
624
622
625 @classmethod
623 @classmethod
626 def get(cls, user_group_id, cache=False):
624 def get(cls, user_group_id, cache=False):
627 user_group = cls.query()
625 user_group = cls.query()
628 if cache:
626 if cache:
629 user_group = user_group.options(FromCache("sql_cache_short",
627 user_group = user_group.options(FromCache("sql_cache_short",
630 "get_users_group_%s" % user_group_id))
628 "get_users_group_%s" % user_group_id))
631 return user_group.get(user_group_id)
629 return user_group.get(user_group_id)
632
630
633
631
634 class UserGroupMember(Base, BaseModel):
632 class UserGroupMember(Base, BaseModel):
635 __tablename__ = 'users_groups_members'
633 __tablename__ = 'users_groups_members'
636 __table_args__ = (
634 __table_args__ = (
637 {'extend_existing': True, 'mysql_engine': 'InnoDB',
635 {'extend_existing': True, 'mysql_engine': 'InnoDB',
638 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
636 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
639 )
637 )
640
638
641 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
639 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
642 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
640 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
643 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
641 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
644
642
645 user = relationship('User', lazy='joined')
643 user = relationship('User', lazy='joined')
646 users_group = relationship('UserGroup')
644 users_group = relationship('UserGroup')
647
645
648 def __init__(self, gr_id='', u_id=''):
646 def __init__(self, gr_id='', u_id=''):
649 self.users_group_id = gr_id
647 self.users_group_id = gr_id
650 self.user_id = u_id
648 self.user_id = u_id
651
649
652
650
653 class RepositoryField(Base, BaseModel):
651 class RepositoryField(Base, BaseModel):
654 __tablename__ = 'repositories_fields'
652 __tablename__ = 'repositories_fields'
655 __table_args__ = (
653 __table_args__ = (
656 UniqueConstraint('repository_id', 'field_key'), # no-multi field
654 UniqueConstraint('repository_id', 'field_key'), # no-multi field
657 {'extend_existing': True, 'mysql_engine': 'InnoDB',
655 {'extend_existing': True, 'mysql_engine': 'InnoDB',
658 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
656 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
659 )
657 )
660 PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields
658 PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields
661
659
662 repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
660 repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
663 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
661 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
664 field_key = Column("field_key", String(250))
662 field_key = Column("field_key", String(250))
665 field_label = Column("field_label", String(1024), nullable=False)
663 field_label = Column("field_label", String(1024), nullable=False)
666 field_value = Column("field_value", String(10000), nullable=False)
664 field_value = Column("field_value", String(10000), nullable=False)
667 field_desc = Column("field_desc", String(1024), nullable=False)
665 field_desc = Column("field_desc", String(1024), nullable=False)
668 field_type = Column("field_type", String(255), nullable=False, unique=None)
666 field_type = Column("field_type", String(255), nullable=False, unique=None)
669 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
667 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
670
668
671 repository = relationship('Repository')
669 repository = relationship('Repository')
672
670
673 @classmethod
671 @classmethod
674 def get_by_key_name(cls, key, repo):
672 def get_by_key_name(cls, key, repo):
675 row = cls.query()\
673 row = cls.query()\
676 .filter(cls.repository == repo)\
674 .filter(cls.repository == repo)\
677 .filter(cls.field_key == key).scalar()
675 .filter(cls.field_key == key).scalar()
678 return row
676 return row
679
677
680
678
681 class Repository(Base, BaseModel):
679 class Repository(Base, BaseModel):
682 __tablename__ = 'repositories'
680 __tablename__ = 'repositories'
683 __table_args__ = (
681 __table_args__ = (
684 UniqueConstraint('repo_name'),
682 UniqueConstraint('repo_name'),
685 Index('r_repo_name_idx', 'repo_name'),
683 Index('r_repo_name_idx', 'repo_name'),
686 {'extend_existing': True, 'mysql_engine': 'InnoDB',
684 {'extend_existing': True, 'mysql_engine': 'InnoDB',
687 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
685 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
688 )
686 )
689 DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}'
687 DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}'
690 DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}'
688 DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}'
691
689
692 STATE_CREATED = 'repo_state_created'
690 STATE_CREATED = 'repo_state_created'
693 STATE_PENDING = 'repo_state_pending'
691 STATE_PENDING = 'repo_state_pending'
694 STATE_ERROR = 'repo_state_error'
692 STATE_ERROR = 'repo_state_error'
695
693
696 LOCK_AUTOMATIC = 'lock_auto'
694 LOCK_AUTOMATIC = 'lock_auto'
697 LOCK_API = 'lock_api'
695 LOCK_API = 'lock_api'
698 LOCK_WEB = 'lock_web'
696 LOCK_WEB = 'lock_web'
699 LOCK_PULL = 'lock_pull'
697 LOCK_PULL = 'lock_pull'
700
698
701 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
699 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
702 repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None)
700 repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None)
703 repo_state = Column("repo_state", String(255), nullable=True)
701 repo_state = Column("repo_state", String(255), nullable=True)
704
702
705 clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None)
703 clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None)
706 repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None)
704 repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None)
707 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
705 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
708 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
706 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
709 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
707 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
710 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
708 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
711 description = Column("description", String(10000), nullable=True, unique=None, default=None)
709 description = Column("description", String(10000), nullable=True, unique=None, default=None)
712 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
710 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
713 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
711 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
714 _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None)
712 _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None)
715 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
713 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
716 _locked = Column("locked", String(255), nullable=True, unique=False, default=None)
714 _locked = Column("locked", String(255), nullable=True, unique=False, default=None)
717 _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data
715 _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data
718
716
719 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
717 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
720 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
718 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
721
719
722 user = relationship('User')
720 user = relationship('User')
723 fork = relationship('Repository', remote_side=repo_id)
721 fork = relationship('Repository', remote_side=repo_id)
724 group = relationship('RepoGroup')
722 group = relationship('RepoGroup')
725 repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id')
723 repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id')
726 users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
724 users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
727 stats = relationship('Statistics', cascade='all', uselist=False)
725 stats = relationship('Statistics', cascade='all', uselist=False)
728
726
729 followers = relationship('UserFollowing',
727 followers = relationship('UserFollowing',
730 primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id',
728 primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id',
731 cascade='all')
729 cascade='all')
732 extra_fields = relationship('RepositoryField',
730 extra_fields = relationship('RepositoryField',
733 cascade="all, delete, delete-orphan")
731 cascade="all, delete, delete-orphan")
734
732
735 logs = relationship('UserLog')
733 logs = relationship('UserLog')
736 comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan")
734 comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan")
737
735
738 pull_requests_org = relationship('PullRequest',
736 pull_requests_org = relationship('PullRequest',
739 primaryjoin='PullRequest.org_repo_id==Repository.repo_id',
737 primaryjoin='PullRequest.org_repo_id==Repository.repo_id',
740 cascade="all, delete, delete-orphan")
738 cascade="all, delete, delete-orphan")
741
739
742 pull_requests_other = relationship('PullRequest',
740 pull_requests_other = relationship('PullRequest',
743 primaryjoin='PullRequest.other_repo_id==Repository.repo_id',
741 primaryjoin='PullRequest.other_repo_id==Repository.repo_id',
744 cascade="all, delete, delete-orphan")
742 cascade="all, delete, delete-orphan")
745
743
746 def __unicode__(self):
744 def __unicode__(self):
747 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
745 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
748 safe_unicode(self.repo_name))
746 safe_unicode(self.repo_name))
749
747
750 @classmethod
748 @classmethod
751 def get_by_repo_name(cls, repo_name):
749 def get_by_repo_name(cls, repo_name):
752 q = Session().query(cls).filter(cls.repo_name == repo_name)
750 q = Session().query(cls).filter(cls.repo_name == repo_name)
753 q = q.options(joinedload(Repository.fork))\
751 q = q.options(joinedload(Repository.fork))\
754 .options(joinedload(Repository.user))\
752 .options(joinedload(Repository.user))\
755 .options(joinedload(Repository.group))
753 .options(joinedload(Repository.group))
756 return q.scalar()
754 return q.scalar()
757
755
758
756
759 class RepoGroup(Base, BaseModel):
757 class RepoGroup(Base, BaseModel):
760 __tablename__ = 'groups'
758 __tablename__ = 'groups'
761 __table_args__ = (
759 __table_args__ = (
762 UniqueConstraint('group_name', 'group_parent_id'),
760 UniqueConstraint('group_name', 'group_parent_id'),
763 {'extend_existing': True, 'mysql_engine': 'InnoDB',
761 {'extend_existing': True, 'mysql_engine': 'InnoDB',
764 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
762 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
765 )
763 )
766 __mapper_args__ = {'order_by': 'group_name'}
764 __mapper_args__ = {'order_by': 'group_name'}
767
765
768 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
766 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
769 group_name = Column("group_name", String(255), nullable=False, unique=True, default=None)
767 group_name = Column("group_name", String(255), nullable=False, unique=True, default=None)
770 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
768 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
771 group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None)
769 group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None)
772 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
770 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
773 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
771 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
774 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
772 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
775
773
776 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
774 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
777 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
775 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
778 parent_group = relationship('RepoGroup', remote_side=group_id)
776 parent_group = relationship('RepoGroup', remote_side=group_id)
779 user = relationship('User')
777 user = relationship('User')
780
778
781 def __init__(self, group_name='', parent_group=None):
779 def __init__(self, group_name='', parent_group=None):
782 self.group_name = group_name
780 self.group_name = group_name
783 self.parent_group = parent_group
781 self.parent_group = parent_group
784
782
785 def __unicode__(self):
783 def __unicode__(self):
786 return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id,
784 return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id,
787 self.group_name)
785 self.group_name)
788
786
789 @classmethod
787 @classmethod
790 def url_sep(cls):
788 def url_sep(cls):
791 return URL_SEP
789 return URL_SEP
792
790
793 @classmethod
791 @classmethod
794 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
792 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
795 if case_insensitive:
793 if case_insensitive:
796 gr = cls.query().filter(func.lower(cls.group_name)
794 gr = cls.query().filter(func.lower(cls.group_name)
797 == func.lower(group_name))
795 == func.lower(group_name))
798 else:
796 else:
799 gr = cls.query().filter(cls.group_name == group_name)
797 gr = cls.query().filter(cls.group_name == group_name)
800 if cache:
798 if cache:
801 gr = gr.options(FromCache(
799 gr = gr.options(FromCache(
802 "sql_cache_short",
800 "sql_cache_short",
803 "get_group_%s" % _hash_key(group_name)))
801 "get_group_%s" % _hash_key(group_name)))
804 return gr.scalar()
802 return gr.scalar()
805
803
806
804
807 class Permission(Base, BaseModel):
805 class Permission(Base, BaseModel):
808 __tablename__ = 'permissions'
806 __tablename__ = 'permissions'
809 __table_args__ = (
807 __table_args__ = (
810 Index('p_perm_name_idx', 'permission_name'),
808 Index('p_perm_name_idx', 'permission_name'),
811 {'extend_existing': True, 'mysql_engine': 'InnoDB',
809 {'extend_existing': True, 'mysql_engine': 'InnoDB',
812 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
810 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
813 )
811 )
814 PERMS = [
812 PERMS = [
815 ('hg.admin', _('RhodeCode Super Administrator')),
813 ('hg.admin', _('RhodeCode Super Administrator')),
816
814
817 ('repository.none', _('Repository no access')),
815 ('repository.none', _('Repository no access')),
818 ('repository.read', _('Repository read access')),
816 ('repository.read', _('Repository read access')),
819 ('repository.write', _('Repository write access')),
817 ('repository.write', _('Repository write access')),
820 ('repository.admin', _('Repository admin access')),
818 ('repository.admin', _('Repository admin access')),
821
819
822 ('group.none', _('Repository group no access')),
820 ('group.none', _('Repository group no access')),
823 ('group.read', _('Repository group read access')),
821 ('group.read', _('Repository group read access')),
824 ('group.write', _('Repository group write access')),
822 ('group.write', _('Repository group write access')),
825 ('group.admin', _('Repository group admin access')),
823 ('group.admin', _('Repository group admin access')),
826
824
827 ('usergroup.none', _('User group no access')),
825 ('usergroup.none', _('User group no access')),
828 ('usergroup.read', _('User group read access')),
826 ('usergroup.read', _('User group read access')),
829 ('usergroup.write', _('User group write access')),
827 ('usergroup.write', _('User group write access')),
830 ('usergroup.admin', _('User group admin access')),
828 ('usergroup.admin', _('User group admin access')),
831
829
832 ('hg.repogroup.create.false', _('Repository Group creation disabled')),
830 ('hg.repogroup.create.false', _('Repository Group creation disabled')),
833 ('hg.repogroup.create.true', _('Repository Group creation enabled')),
831 ('hg.repogroup.create.true', _('Repository Group creation enabled')),
834
832
835 ('hg.usergroup.create.false', _('User Group creation disabled')),
833 ('hg.usergroup.create.false', _('User Group creation disabled')),
836 ('hg.usergroup.create.true', _('User Group creation enabled')),
834 ('hg.usergroup.create.true', _('User Group creation enabled')),
837
835
838 ('hg.create.none', _('Repository creation disabled')),
836 ('hg.create.none', _('Repository creation disabled')),
839 ('hg.create.repository', _('Repository creation enabled')),
837 ('hg.create.repository', _('Repository creation enabled')),
840 ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')),
838 ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')),
841 ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')),
839 ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')),
842
840
843 ('hg.fork.none', _('Repository forking disabled')),
841 ('hg.fork.none', _('Repository forking disabled')),
844 ('hg.fork.repository', _('Repository forking enabled')),
842 ('hg.fork.repository', _('Repository forking enabled')),
845
843
846 ('hg.register.none', _('Registration disabled')),
844 ('hg.register.none', _('Registration disabled')),
847 ('hg.register.manual_activate', _('User Registration with manual account activation')),
845 ('hg.register.manual_activate', _('User Registration with manual account activation')),
848 ('hg.register.auto_activate', _('User Registration with automatic account activation')),
846 ('hg.register.auto_activate', _('User Registration with automatic account activation')),
849
847
850 ('hg.extern_activate.manual', _('Manual activation of external account')),
848 ('hg.extern_activate.manual', _('Manual activation of external account')),
851 ('hg.extern_activate.auto', _('Automatic activation of external account')),
849 ('hg.extern_activate.auto', _('Automatic activation of external account')),
852
850
853 ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')),
851 ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')),
854 ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')),
852 ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')),
855 ]
853 ]
856
854
857 # definition of system default permissions for DEFAULT user
855 # definition of system default permissions for DEFAULT user
858 DEFAULT_USER_PERMISSIONS = [
856 DEFAULT_USER_PERMISSIONS = [
859 'repository.read',
857 'repository.read',
860 'group.read',
858 'group.read',
861 'usergroup.read',
859 'usergroup.read',
862 'hg.create.repository',
860 'hg.create.repository',
863 'hg.repogroup.create.false',
861 'hg.repogroup.create.false',
864 'hg.usergroup.create.false',
862 'hg.usergroup.create.false',
865 'hg.create.write_on_repogroup.true',
863 'hg.create.write_on_repogroup.true',
866 'hg.fork.repository',
864 'hg.fork.repository',
867 'hg.register.manual_activate',
865 'hg.register.manual_activate',
868 'hg.extern_activate.auto',
866 'hg.extern_activate.auto',
869 'hg.inherit_default_perms.true',
867 'hg.inherit_default_perms.true',
870 ]
868 ]
871
869
872 # defines which permissions are more important higher the more important
870 # defines which permissions are more important higher the more important
873 # Weight defines which permissions are more important.
871 # Weight defines which permissions are more important.
874 # The higher number the more important.
872 # The higher number the more important.
875 PERM_WEIGHTS = {
873 PERM_WEIGHTS = {
876 'repository.none': 0,
874 'repository.none': 0,
877 'repository.read': 1,
875 'repository.read': 1,
878 'repository.write': 3,
876 'repository.write': 3,
879 'repository.admin': 4,
877 'repository.admin': 4,
880
878
881 'group.none': 0,
879 'group.none': 0,
882 'group.read': 1,
880 'group.read': 1,
883 'group.write': 3,
881 'group.write': 3,
884 'group.admin': 4,
882 'group.admin': 4,
885
883
886 'usergroup.none': 0,
884 'usergroup.none': 0,
887 'usergroup.read': 1,
885 'usergroup.read': 1,
888 'usergroup.write': 3,
886 'usergroup.write': 3,
889 'usergroup.admin': 4,
887 'usergroup.admin': 4,
890
888
891 'hg.repogroup.create.false': 0,
889 'hg.repogroup.create.false': 0,
892 'hg.repogroup.create.true': 1,
890 'hg.repogroup.create.true': 1,
893
891
894 'hg.usergroup.create.false': 0,
892 'hg.usergroup.create.false': 0,
895 'hg.usergroup.create.true': 1,
893 'hg.usergroup.create.true': 1,
896
894
897 'hg.fork.none': 0,
895 'hg.fork.none': 0,
898 'hg.fork.repository': 1,
896 'hg.fork.repository': 1,
899 'hg.create.none': 0,
897 'hg.create.none': 0,
900 'hg.create.repository': 1
898 'hg.create.repository': 1
901 }
899 }
902
900
903 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
901 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
904 permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None)
902 permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None)
905 permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None)
903 permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None)
906
904
907 def __unicode__(self):
905 def __unicode__(self):
908 return u"<%s('%s:%s')>" % (
906 return u"<%s('%s:%s')>" % (
909 self.__class__.__name__, self.permission_id, self.permission_name
907 self.__class__.__name__, self.permission_id, self.permission_name
910 )
908 )
911
909
912 @classmethod
910 @classmethod
913 def get_by_key(cls, key):
911 def get_by_key(cls, key):
914 return cls.query().filter(cls.permission_name == key).scalar()
912 return cls.query().filter(cls.permission_name == key).scalar()
915
913
916
914
917 class UserRepoToPerm(Base, BaseModel):
915 class UserRepoToPerm(Base, BaseModel):
918 __tablename__ = 'repo_to_perm'
916 __tablename__ = 'repo_to_perm'
919 __table_args__ = (
917 __table_args__ = (
920 UniqueConstraint('user_id', 'repository_id', 'permission_id'),
918 UniqueConstraint('user_id', 'repository_id', 'permission_id'),
921 {'extend_existing': True, 'mysql_engine': 'InnoDB',
919 {'extend_existing': True, 'mysql_engine': 'InnoDB',
922 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
920 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
923 )
921 )
924 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
922 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
925 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
923 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
926 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
924 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
927 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
925 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
928
926
929 user = relationship('User')
927 user = relationship('User')
930 repository = relationship('Repository')
928 repository = relationship('Repository')
931 permission = relationship('Permission')
929 permission = relationship('Permission')
932
930
933 def __unicode__(self):
931 def __unicode__(self):
934 return u'<%s => %s >' % (self.user, self.repository)
932 return u'<%s => %s >' % (self.user, self.repository)
935
933
936
934
937 class UserUserGroupToPerm(Base, BaseModel):
935 class UserUserGroupToPerm(Base, BaseModel):
938 __tablename__ = 'user_user_group_to_perm'
936 __tablename__ = 'user_user_group_to_perm'
939 __table_args__ = (
937 __table_args__ = (
940 UniqueConstraint('user_id', 'user_group_id', 'permission_id'),
938 UniqueConstraint('user_id', 'user_group_id', 'permission_id'),
941 {'extend_existing': True, 'mysql_engine': 'InnoDB',
939 {'extend_existing': True, 'mysql_engine': 'InnoDB',
942 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
940 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
943 )
941 )
944 user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
942 user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
945 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
943 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
946 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
944 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
947 user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
945 user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
948
946
949 user = relationship('User')
947 user = relationship('User')
950 user_group = relationship('UserGroup')
948 user_group = relationship('UserGroup')
951 permission = relationship('Permission')
949 permission = relationship('Permission')
952
950
953 def __unicode__(self):
951 def __unicode__(self):
954 return u'<%s => %s >' % (self.user, self.user_group)
952 return u'<%s => %s >' % (self.user, self.user_group)
955
953
956
954
957 class UserToPerm(Base, BaseModel):
955 class UserToPerm(Base, BaseModel):
958 __tablename__ = 'user_to_perm'
956 __tablename__ = 'user_to_perm'
959 __table_args__ = (
957 __table_args__ = (
960 UniqueConstraint('user_id', 'permission_id'),
958 UniqueConstraint('user_id', 'permission_id'),
961 {'extend_existing': True, 'mysql_engine': 'InnoDB',
959 {'extend_existing': True, 'mysql_engine': 'InnoDB',
962 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
960 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
963 )
961 )
964 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
962 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
965 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
963 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
966 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
964 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
967
965
968 user = relationship('User')
966 user = relationship('User')
969 permission = relationship('Permission', lazy='joined')
967 permission = relationship('Permission', lazy='joined')
970
968
971 def __unicode__(self):
969 def __unicode__(self):
972 return u'<%s => %s >' % (self.user, self.permission)
970 return u'<%s => %s >' % (self.user, self.permission)
973
971
974
972
975 class UserGroupRepoToPerm(Base, BaseModel):
973 class UserGroupRepoToPerm(Base, BaseModel):
976 __tablename__ = 'users_group_repo_to_perm'
974 __tablename__ = 'users_group_repo_to_perm'
977 __table_args__ = (
975 __table_args__ = (
978 UniqueConstraint('repository_id', 'users_group_id', 'permission_id'),
976 UniqueConstraint('repository_id', 'users_group_id', 'permission_id'),
979 {'extend_existing': True, 'mysql_engine': 'InnoDB',
977 {'extend_existing': True, 'mysql_engine': 'InnoDB',
980 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
978 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
981 )
979 )
982 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
980 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
983 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
981 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
984 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
982 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
985 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
983 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
986
984
987 users_group = relationship('UserGroup')
985 users_group = relationship('UserGroup')
988 permission = relationship('Permission')
986 permission = relationship('Permission')
989 repository = relationship('Repository')
987 repository = relationship('Repository')
990
988
991 def __unicode__(self):
989 def __unicode__(self):
992 return u'<UserGroupRepoToPerm:%s => %s >' % (self.users_group, self.repository)
990 return u'<UserGroupRepoToPerm:%s => %s >' % (self.users_group, self.repository)
993
991
994
992
995 class UserGroupUserGroupToPerm(Base, BaseModel):
993 class UserGroupUserGroupToPerm(Base, BaseModel):
996 __tablename__ = 'user_group_user_group_to_perm'
994 __tablename__ = 'user_group_user_group_to_perm'
997 __table_args__ = (
995 __table_args__ = (
998 UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'),
996 UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'),
999 CheckConstraint('target_user_group_id != user_group_id'),
997 CheckConstraint('target_user_group_id != user_group_id'),
1000 {'extend_existing': True, 'mysql_engine': 'InnoDB',
998 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1001 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
999 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1002 )
1000 )
1003 user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1001 user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1004 target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1002 target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1005 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1003 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1006 user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1004 user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1007
1005
1008 target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id')
1006 target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id')
1009 user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id')
1007 user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id')
1010 permission = relationship('Permission')
1008 permission = relationship('Permission')
1011
1009
1012 def __unicode__(self):
1010 def __unicode__(self):
1013 return u'<UserGroupUserGroup:%s => %s >' % (self.target_user_group, self.user_group)
1011 return u'<UserGroupUserGroup:%s => %s >' % (self.target_user_group, self.user_group)
1014
1012
1015
1013
1016 class UserGroupToPerm(Base, BaseModel):
1014 class UserGroupToPerm(Base, BaseModel):
1017 __tablename__ = 'users_group_to_perm'
1015 __tablename__ = 'users_group_to_perm'
1018 __table_args__ = (
1016 __table_args__ = (
1019 UniqueConstraint('users_group_id', 'permission_id',),
1017 UniqueConstraint('users_group_id', 'permission_id',),
1020 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1018 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1021 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1019 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1022 )
1020 )
1023 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1021 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1024 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1022 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1025 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1023 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1026
1024
1027 users_group = relationship('UserGroup')
1025 users_group = relationship('UserGroup')
1028 permission = relationship('Permission')
1026 permission = relationship('Permission')
1029
1027
1030
1028
1031 class UserRepoGroupToPerm(Base, BaseModel):
1029 class UserRepoGroupToPerm(Base, BaseModel):
1032 __tablename__ = 'user_repo_group_to_perm'
1030 __tablename__ = 'user_repo_group_to_perm'
1033 __table_args__ = (
1031 __table_args__ = (
1034 UniqueConstraint('user_id', 'group_id', 'permission_id'),
1032 UniqueConstraint('user_id', 'group_id', 'permission_id'),
1035 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1033 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1036 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1034 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1037 )
1035 )
1038
1036
1039 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1037 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1040 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
1038 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
1041 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
1039 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
1042 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1040 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1043
1041
1044 user = relationship('User')
1042 user = relationship('User')
1045 group = relationship('RepoGroup')
1043 group = relationship('RepoGroup')
1046 permission = relationship('Permission')
1044 permission = relationship('Permission')
1047
1045
1048
1046
1049 class UserGroupRepoGroupToPerm(Base, BaseModel):
1047 class UserGroupRepoGroupToPerm(Base, BaseModel):
1050 __tablename__ = 'users_group_repo_group_to_perm'
1048 __tablename__ = 'users_group_repo_group_to_perm'
1051 __table_args__ = (
1049 __table_args__ = (
1052 UniqueConstraint('users_group_id', 'group_id'),
1050 UniqueConstraint('users_group_id', 'group_id'),
1053 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1051 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1054 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1052 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1055 )
1053 )
1056
1054
1057 users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1055 users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1058 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1056 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
1059 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
1057 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
1060 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1058 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
1061
1059
1062 users_group = relationship('UserGroup')
1060 users_group = relationship('UserGroup')
1063 permission = relationship('Permission')
1061 permission = relationship('Permission')
1064 group = relationship('RepoGroup')
1062 group = relationship('RepoGroup')
1065
1063
1066 @classmethod
1064 @classmethod
1067 def create(cls, user_group, repository_group, permission):
1065 def create(cls, user_group, repository_group, permission):
1068 n = cls()
1066 n = cls()
1069 n.users_group = user_group
1067 n.users_group = user_group
1070 n.group = repository_group
1068 n.group = repository_group
1071 n.permission = permission
1069 n.permission = permission
1072 Session().add(n)
1070 Session().add(n)
1073 return n
1071 return n
1074
1072
1075 def __unicode__(self):
1073 def __unicode__(self):
1076 return u'<UserGroupRepoGroupToPerm:%s => %s >' % (self.users_group, self.group)
1074 return u'<UserGroupRepoGroupToPerm:%s => %s >' % (self.users_group, self.group)
1077
1075
1078
1076
1079 class Statistics(Base, BaseModel):
1077 class Statistics(Base, BaseModel):
1080 __tablename__ = 'statistics'
1078 __tablename__ = 'statistics'
1081 __table_args__ = (
1079 __table_args__ = (
1082 UniqueConstraint('repository_id'),
1080 UniqueConstraint('repository_id'),
1083 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1081 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1084 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1082 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1085 )
1083 )
1086 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1084 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1087 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
1085 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
1088 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
1086 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
1089 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
1087 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
1090 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
1088 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
1091 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
1089 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
1092
1090
1093 repository = relationship('Repository', single_parent=True)
1091 repository = relationship('Repository', single_parent=True)
1094
1092
1095
1093
1096 class UserFollowing(Base, BaseModel):
1094 class UserFollowing(Base, BaseModel):
1097 __tablename__ = 'user_followings'
1095 __tablename__ = 'user_followings'
1098 __table_args__ = (
1096 __table_args__ = (
1099 UniqueConstraint('user_id', 'follows_repository_id'),
1097 UniqueConstraint('user_id', 'follows_repository_id'),
1100 UniqueConstraint('user_id', 'follows_user_id'),
1098 UniqueConstraint('user_id', 'follows_user_id'),
1101 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1099 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1102 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1100 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1103 )
1101 )
1104
1102
1105 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1103 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1106 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
1104 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
1107 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
1105 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
1108 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
1106 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
1109 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
1107 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
1110
1108
1111 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
1109 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
1112
1110
1113 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
1111 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
1114 follows_repository = relationship('Repository', order_by='Repository.repo_name')
1112 follows_repository = relationship('Repository', order_by='Repository.repo_name')
1115
1113
1116
1114
1117 class CacheKey(Base, BaseModel):
1115 class CacheKey(Base, BaseModel):
1118 __tablename__ = 'cache_invalidation'
1116 __tablename__ = 'cache_invalidation'
1119 __table_args__ = (
1117 __table_args__ = (
1120 UniqueConstraint('cache_key'),
1118 UniqueConstraint('cache_key'),
1121 Index('key_idx', 'cache_key'),
1119 Index('key_idx', 'cache_key'),
1122 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1120 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1123 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1121 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1124 )
1122 )
1125 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1123 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1126 cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None)
1124 cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None)
1127 cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None)
1125 cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None)
1128 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
1126 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
1129
1127
1130 def __init__(self, cache_key, cache_args=''):
1128 def __init__(self, cache_key, cache_args=''):
1131 self.cache_key = cache_key
1129 self.cache_key = cache_key
1132 self.cache_args = cache_args
1130 self.cache_args = cache_args
1133 self.cache_active = False
1131 self.cache_active = False
1134
1132
1135
1133
1136 class ChangesetComment(Base, BaseModel):
1134 class ChangesetComment(Base, BaseModel):
1137 __tablename__ = 'changeset_comments'
1135 __tablename__ = 'changeset_comments'
1138 __table_args__ = (
1136 __table_args__ = (
1139 Index('cc_revision_idx', 'revision'),
1137 Index('cc_revision_idx', 'revision'),
1140 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1138 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1141 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1139 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1142 )
1140 )
1143 comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
1141 comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
1144 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1142 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1145 revision = Column('revision', String(40), nullable=True)
1143 revision = Column('revision', String(40), nullable=True)
1146 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
1144 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
1147 line_no = Column('line_no', Unicode(10), nullable=True)
1145 line_no = Column('line_no', Unicode(10), nullable=True)
1148 hl_lines = Column('hl_lines', Unicode(512), nullable=True)
1146 hl_lines = Column('hl_lines', Unicode(512), nullable=True)
1149 f_path = Column('f_path', Unicode(1000), nullable=True)
1147 f_path = Column('f_path', Unicode(1000), nullable=True)
1150 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
1148 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
1151 text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False)
1149 text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False)
1152 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1150 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1153 modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1151 modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1154 renderer = Column('renderer', Unicode(64), nullable=True)
1152 renderer = Column('renderer', Unicode(64), nullable=True)
1155
1153
1156 author = relationship('User', lazy='joined')
1154 author = relationship('User', lazy='joined')
1157 repo = relationship('Repository')
1155 repo = relationship('Repository')
1158 status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
1156 status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
1159 pull_request = relationship('PullRequest', lazy='joined')
1157 pull_request = relationship('PullRequest', lazy='joined')
1160
1158
1161
1159
1162 class ChangesetStatus(Base, BaseModel):
1160 class ChangesetStatus(Base, BaseModel):
1163 __tablename__ = 'changeset_statuses'
1161 __tablename__ = 'changeset_statuses'
1164 __table_args__ = (
1162 __table_args__ = (
1165 Index('cs_revision_idx', 'revision'),
1163 Index('cs_revision_idx', 'revision'),
1166 Index('cs_version_idx', 'version'),
1164 Index('cs_version_idx', 'version'),
1167 UniqueConstraint('repo_id', 'revision', 'version'),
1165 UniqueConstraint('repo_id', 'revision', 'version'),
1168 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1166 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1169 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1167 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1170 )
1168 )
1171 STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed'
1169 STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed'
1172 STATUS_APPROVED = 'approved'
1170 STATUS_APPROVED = 'approved'
1173 STATUS_REJECTED = 'rejected'
1171 STATUS_REJECTED = 'rejected'
1174 STATUS_UNDER_REVIEW = 'under_review'
1172 STATUS_UNDER_REVIEW = 'under_review'
1175
1173
1176 STATUSES = [
1174 STATUSES = [
1177 (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default
1175 (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default
1178 (STATUS_APPROVED, _("Approved")),
1176 (STATUS_APPROVED, _("Approved")),
1179 (STATUS_REJECTED, _("Rejected")),
1177 (STATUS_REJECTED, _("Rejected")),
1180 (STATUS_UNDER_REVIEW, _("Under Review")),
1178 (STATUS_UNDER_REVIEW, _("Under Review")),
1181 ]
1179 ]
1182
1180
1183 changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True)
1181 changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True)
1184 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1182 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1185 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
1183 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
1186 revision = Column('revision', String(40), nullable=False)
1184 revision = Column('revision', String(40), nullable=False)
1187 status = Column('status', String(128), nullable=False, default=DEFAULT)
1185 status = Column('status', String(128), nullable=False, default=DEFAULT)
1188 changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
1186 changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
1189 modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
1187 modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
1190 version = Column('version', Integer(), nullable=False, default=0)
1188 version = Column('version', Integer(), nullable=False, default=0)
1191 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
1189 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
1192
1190
1193 author = relationship('User', lazy='joined')
1191 author = relationship('User', lazy='joined')
1194 repo = relationship('Repository')
1192 repo = relationship('Repository')
1195 comment = relationship('ChangesetComment', lazy='joined')
1193 comment = relationship('ChangesetComment', lazy='joined')
1196 pull_request = relationship('PullRequest', lazy='joined')
1194 pull_request = relationship('PullRequest', lazy='joined')
1197
1195
1198
1196
1199
1197
1200 class PullRequest(Base, BaseModel):
1198 class PullRequest(Base, BaseModel):
1201 __tablename__ = 'pull_requests'
1199 __tablename__ = 'pull_requests'
1202 __table_args__ = (
1200 __table_args__ = (
1203 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1201 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1204 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1202 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1205 )
1203 )
1206
1204
1207 STATUS_NEW = u'new'
1205 STATUS_NEW = u'new'
1208 STATUS_OPEN = u'open'
1206 STATUS_OPEN = u'open'
1209 STATUS_CLOSED = u'closed'
1207 STATUS_CLOSED = u'closed'
1210
1208
1211 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
1209 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
1212 title = Column('title', Unicode(255), nullable=True)
1210 title = Column('title', Unicode(255), nullable=True)
1213 description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True)
1211 description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True)
1214 status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW)
1212 status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW)
1215 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1213 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1216 updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1214 updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1217 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
1215 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
1218 _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql'))
1216 _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql'))
1219 org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1217 org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1220 org_ref = Column('org_ref', Unicode(255), nullable=False)
1218 org_ref = Column('org_ref', Unicode(255), nullable=False)
1221 other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1219 other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1222 other_ref = Column('other_ref', Unicode(255), nullable=False)
1220 other_ref = Column('other_ref', Unicode(255), nullable=False)
1223 _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True)
1221 _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True)
1224 _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True)
1222 _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True)
1225 _last_merge_status = Column('merge_status', Integer(), nullable=True)
1223 _last_merge_status = Column('merge_status', Integer(), nullable=True)
1226 merge_rev = Column('merge_rev', String(40), nullable=True)
1224 merge_rev = Column('merge_rev', String(40), nullable=True)
1227
1225
1228 def __repr__(self):
1226 def __repr__(self):
1229 return '<PullRequest #%s>' % (self.pull_request_id,)
1227 return '<PullRequest #%s>' % (self.pull_request_id,)
1230
1228
1231 author = relationship('User', lazy='joined')
1229 author = relationship('User', lazy='joined')
1232 reviewers = relationship('PullRequestReviewers',
1230 reviewers = relationship('PullRequestReviewers',
1233 cascade="all, delete, delete-orphan")
1231 cascade="all, delete, delete-orphan")
1234 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1232 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1235 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
1233 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
1236 statuses = relationship('ChangesetStatus')
1234 statuses = relationship('ChangesetStatus')
1237 comments = relationship('ChangesetComment',
1235 comments = relationship('ChangesetComment',
1238 cascade="all, delete, delete-orphan")
1236 cascade="all, delete, delete-orphan")
1239
1237
1240
1238
1241 class PullRequestReviewers(Base, BaseModel):
1239 class PullRequestReviewers(Base, BaseModel):
1242 __tablename__ = 'pull_request_reviewers'
1240 __tablename__ = 'pull_request_reviewers'
1243 __table_args__ = (
1241 __table_args__ = (
1244 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1242 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1245 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1243 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1246 )
1244 )
1247
1245
1248 def __init__(self, user=None, pull_request=None):
1246 def __init__(self, user=None, pull_request=None):
1249 self.user = user
1247 self.user = user
1250 self.pull_request = pull_request
1248 self.pull_request = pull_request
1251
1249
1252 pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True)
1250 pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True)
1253 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
1251 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
1254 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True)
1252 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True)
1255
1253
1256 user = relationship('User')
1254 user = relationship('User')
1257 pull_request = relationship('PullRequest')
1255 pull_request = relationship('PullRequest')
1258
1256
1259
1257
1260 class Notification(Base, BaseModel):
1258 class Notification(Base, BaseModel):
1261 __tablename__ = 'notifications'
1259 __tablename__ = 'notifications'
1262 __table_args__ = (
1260 __table_args__ = (
1263 Index('notification_type_idx', 'type'),
1261 Index('notification_type_idx', 'type'),
1264 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1262 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1265 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1263 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1266 )
1264 )
1267
1265
1268 TYPE_CHANGESET_COMMENT = u'cs_comment'
1266 TYPE_CHANGESET_COMMENT = u'cs_comment'
1269 TYPE_MESSAGE = u'message'
1267 TYPE_MESSAGE = u'message'
1270 TYPE_MENTION = u'mention'
1268 TYPE_MENTION = u'mention'
1271 TYPE_REGISTRATION = u'registration'
1269 TYPE_REGISTRATION = u'registration'
1272 TYPE_PULL_REQUEST = u'pull_request'
1270 TYPE_PULL_REQUEST = u'pull_request'
1273 TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
1271 TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
1274
1272
1275 notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
1273 notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
1276 subject = Column('subject', Unicode(512), nullable=True)
1274 subject = Column('subject', Unicode(512), nullable=True)
1277 body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True)
1275 body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True)
1278 created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
1276 created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
1279 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1277 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1280 type_ = Column('type', Unicode(255))
1278 type_ = Column('type', Unicode(255))
1281
1279
1282 created_by_user = relationship('User')
1280 created_by_user = relationship('User')
1283 notifications_to_users = relationship('UserNotification', lazy='joined',
1281 notifications_to_users = relationship('UserNotification', lazy='joined',
1284 cascade="all, delete, delete-orphan")
1282 cascade="all, delete, delete-orphan")
1285
1283
1286
1284
1287 class UserNotification(Base, BaseModel):
1285 class UserNotification(Base, BaseModel):
1288 __tablename__ = 'user_to_notification'
1286 __tablename__ = 'user_to_notification'
1289 __table_args__ = (
1287 __table_args__ = (
1290 UniqueConstraint('user_id', 'notification_id'),
1288 UniqueConstraint('user_id', 'notification_id'),
1291 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1289 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1292 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1290 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1293 )
1291 )
1294 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True)
1292 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True)
1295 notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
1293 notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
1296 read = Column('read', Boolean, default=False)
1294 read = Column('read', Boolean, default=False)
1297 sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
1295 sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
1298
1296
1299 user = relationship('User', lazy="joined")
1297 user = relationship('User', lazy="joined")
1300 notification = relationship('Notification', lazy="joined",
1298 notification = relationship('Notification', lazy="joined",
1301 order_by=lambda: Notification.created_on.desc(),)
1299 order_by=lambda: Notification.created_on.desc(),)
1302
1300
1303
1301
1304 class Gist(Base, BaseModel):
1302 class Gist(Base, BaseModel):
1305 __tablename__ = 'gists'
1303 __tablename__ = 'gists'
1306 __table_args__ = (
1304 __table_args__ = (
1307 Index('g_gist_access_id_idx', 'gist_access_id'),
1305 Index('g_gist_access_id_idx', 'gist_access_id'),
1308 Index('g_created_on_idx', 'created_on'),
1306 Index('g_created_on_idx', 'created_on'),
1309 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1307 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1310 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1308 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
1311 )
1309 )
1312 GIST_PUBLIC = u'public'
1310 GIST_PUBLIC = u'public'
1313 GIST_PRIVATE = u'private'
1311 GIST_PRIVATE = u'private'
1314 DEFAULT_FILENAME = u'gistfile1.txt'
1312 DEFAULT_FILENAME = u'gistfile1.txt'
1315
1313
1316 gist_id = Column('gist_id', Integer(), primary_key=True)
1314 gist_id = Column('gist_id', Integer(), primary_key=True)
1317 gist_access_id = Column('gist_access_id', Unicode(250))
1315 gist_access_id = Column('gist_access_id', Unicode(250))
1318 gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql'))
1316 gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql'))
1319 gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True)
1317 gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True)
1320 gist_expires = Column('gist_expires', Float(53), nullable=False)
1318 gist_expires = Column('gist_expires', Float(53), nullable=False)
1321 gist_type = Column('gist_type', Unicode(128), nullable=False)
1319 gist_type = Column('gist_type', Unicode(128), nullable=False)
1322 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1320 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1323 modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1321 modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
1324
1322
1325 owner = relationship('User')
1323 owner = relationship('User')
1326
1324
1327 def __repr__(self):
1325 def __repr__(self):
1328 return '<Gist:[%s]%s>' % (self.gist_type, self.gist_access_id)
1326 return '<Gist:[%s]%s>' % (self.gist_type, self.gist_access_id)
1329
1327
1330
1328
1331 class DbMigrateVersion(Base, BaseModel):
1329 class DbMigrateVersion(Base, BaseModel):
1332 __tablename__ = 'db_migrate_version'
1330 __tablename__ = 'db_migrate_version'
1333 __table_args__ = (
1331 __table_args__ = (
1334 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1332 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1335 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1333 'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
1336 )
1334 )
1337 repository_id = Column('repository_id', String(250), primary_key=True)
1335 repository_id = Column('repository_id', String(250), primary_key=True)
1338 repository_path = Column('repository_path', Text)
1336 repository_path = Column('repository_path', Text)
1339 version = Column('version', Integer)
1337 version = Column('version', Integer)
General Comments 0
You need to be logged in to leave comments. Login now