##// END OF EJS Templates
added fault tolerant case when celeryconfig is not present in the directory....
marcink -
r555:03676d39 default
parent child Browse files
Show More
@@ -1,316 +1,323 b''
1 from celery.decorators import task
1 from celery.decorators import task
2 from celery.task.sets import subtask
2
3 from celeryconfig import PYLONS_CONFIG as config
4 from operator import itemgetter
3 from operator import itemgetter
5 from pylons.i18n.translation import _
4 from pylons.i18n.translation import _
6 from rhodecode.lib.celerylib import run_task, locked_task
5 from rhodecode.lib.celerylib import run_task, locked_task
7 from rhodecode.lib.helpers import person
6 from rhodecode.lib.helpers import person
8 from rhodecode.lib.smtp_mailer import SmtpMailer
7 from rhodecode.lib.smtp_mailer import SmtpMailer
9 from rhodecode.lib.utils import OrderedDict
8 from rhodecode.lib.utils import OrderedDict
10 from time import mktime
9 from time import mktime
11 from vcs.backends.hg import MercurialRepository
10 from vcs.backends.hg import MercurialRepository
12 import json
11 import json
13 import traceback
12 import traceback
14
13
14 try:
15 from celeryconfig import PYLONS_CONFIG as config
16 except ImportError:
17 #if celeryconfig is not present let's just load our pylons
18 #config instead
19 from pylons import config
20
21
15 __all__ = ['whoosh_index', 'get_commits_stats',
22 __all__ = ['whoosh_index', 'get_commits_stats',
16 'reset_user_password', 'send_email']
23 'reset_user_password', 'send_email']
17
24
18 def get_session():
25 def get_session():
19 from sqlalchemy import engine_from_config
26 from sqlalchemy import engine_from_config
20 from sqlalchemy.orm import sessionmaker, scoped_session
27 from sqlalchemy.orm import sessionmaker, scoped_session
21 engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
28 engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
22 sa = scoped_session(sessionmaker(bind=engine))
29 sa = scoped_session(sessionmaker(bind=engine))
23 return sa
30 return sa
24
31
25 def get_hg_settings():
32 def get_hg_settings():
26 from rhodecode.model.db import RhodeCodeSettings
33 from rhodecode.model.db import RhodeCodeSettings
27 try:
34 try:
28 sa = get_session()
35 sa = get_session()
29 ret = sa.query(RhodeCodeSettings).all()
36 ret = sa.query(RhodeCodeSettings).all()
30 finally:
37 finally:
31 sa.remove()
38 sa.remove()
32
39
33 if not ret:
40 if not ret:
34 raise Exception('Could not get application settings !')
41 raise Exception('Could not get application settings !')
35 settings = {}
42 settings = {}
36 for each in ret:
43 for each in ret:
37 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
44 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
38
45
39 return settings
46 return settings
40
47
41 def get_hg_ui_settings():
48 def get_hg_ui_settings():
42 from rhodecode.model.db import RhodeCodeUi
49 from rhodecode.model.db import RhodeCodeUi
43 try:
50 try:
44 sa = get_session()
51 sa = get_session()
45 ret = sa.query(RhodeCodeUi).all()
52 ret = sa.query(RhodeCodeUi).all()
46 finally:
53 finally:
47 sa.remove()
54 sa.remove()
48
55
49 if not ret:
56 if not ret:
50 raise Exception('Could not get application ui settings !')
57 raise Exception('Could not get application ui settings !')
51 settings = {}
58 settings = {}
52 for each in ret:
59 for each in ret:
53 k = each.ui_key
60 k = each.ui_key
54 v = each.ui_value
61 v = each.ui_value
55 if k == '/':
62 if k == '/':
56 k = 'root_path'
63 k = 'root_path'
57
64
58 if k.find('.') != -1:
65 if k.find('.') != -1:
59 k = k.replace('.', '_')
66 k = k.replace('.', '_')
60
67
61 if each.ui_section == 'hooks':
68 if each.ui_section == 'hooks':
62 v = each.ui_active
69 v = each.ui_active
63
70
64 settings[each.ui_section + '_' + k] = v
71 settings[each.ui_section + '_' + k] = v
65
72
66 return settings
73 return settings
67
74
68 @task
75 @task
69 @locked_task
76 @locked_task
70 def whoosh_index(repo_location, full_index):
77 def whoosh_index(repo_location, full_index):
71 log = whoosh_index.get_logger()
78 log = whoosh_index.get_logger()
72 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
79 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
73 WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
80 WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
74
81
75 @task
82 @task
76 @locked_task
83 @locked_task
77 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
84 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
78 from rhodecode.model.db import Statistics, Repository
85 from rhodecode.model.db import Statistics, Repository
79 log = get_commits_stats.get_logger()
86 log = get_commits_stats.get_logger()
80 author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
87 author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
81
88
82 commits_by_day_author_aggregate = {}
89 commits_by_day_author_aggregate = {}
83 commits_by_day_aggregate = {}
90 commits_by_day_aggregate = {}
84 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
91 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
85 repo = MercurialRepository(repos_path + repo_name)
92 repo = MercurialRepository(repos_path + repo_name)
86
93
87 skip_date_limit = True
94 skip_date_limit = True
88 parse_limit = 350 #limit for single task changeset parsing optimal for
95 parse_limit = 350 #limit for single task changeset parsing optimal for
89 last_rev = 0
96 last_rev = 0
90 last_cs = None
97 last_cs = None
91 timegetter = itemgetter('time')
98 timegetter = itemgetter('time')
92
99
93 sa = get_session()
100 sa = get_session()
94
101
95 dbrepo = sa.query(Repository)\
102 dbrepo = sa.query(Repository)\
96 .filter(Repository.repo_name == repo_name).scalar()
103 .filter(Repository.repo_name == repo_name).scalar()
97 cur_stats = sa.query(Statistics)\
104 cur_stats = sa.query(Statistics)\
98 .filter(Statistics.repository == dbrepo).scalar()
105 .filter(Statistics.repository == dbrepo).scalar()
99 if cur_stats:
106 if cur_stats:
100 last_rev = cur_stats.stat_on_revision
107 last_rev = cur_stats.stat_on_revision
101 if not repo.revisions:
108 if not repo.revisions:
102 return True
109 return True
103
110
104 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
111 if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
105 #pass silently without any work if we're not on first revision or current
112 #pass silently without any work if we're not on first revision or current
106 #state of parsing revision(from db marker) is the last revision
113 #state of parsing revision(from db marker) is the last revision
107 return True
114 return True
108
115
109 if cur_stats:
116 if cur_stats:
110 commits_by_day_aggregate = OrderedDict(
117 commits_by_day_aggregate = OrderedDict(
111 json.loads(
118 json.loads(
112 cur_stats.commit_activity_combined))
119 cur_stats.commit_activity_combined))
113 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
120 commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
114
121
115 log.debug('starting parsing %s', parse_limit)
122 log.debug('starting parsing %s', parse_limit)
116 for cnt, rev in enumerate(repo.revisions[last_rev:]):
123 for cnt, rev in enumerate(repo.revisions[last_rev:]):
117 last_cs = cs = repo.get_changeset(rev)
124 last_cs = cs = repo.get_changeset(rev)
118 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
125 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
119 cs.date.timetuple()[2])
126 cs.date.timetuple()[2])
120 timetupple = [int(x) for x in k.split('-')]
127 timetupple = [int(x) for x in k.split('-')]
121 timetupple.extend([0 for _ in xrange(6)])
128 timetupple.extend([0 for _ in xrange(6)])
122 k = mktime(timetupple)
129 k = mktime(timetupple)
123 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
130 if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
124 try:
131 try:
125 l = [timegetter(x) for x in commits_by_day_author_aggregate\
132 l = [timegetter(x) for x in commits_by_day_author_aggregate\
126 [author_key_cleaner(cs.author)]['data']]
133 [author_key_cleaner(cs.author)]['data']]
127 time_pos = l.index(k)
134 time_pos = l.index(k)
128 except ValueError:
135 except ValueError:
129 time_pos = False
136 time_pos = False
130
137
131 if time_pos >= 0 and time_pos is not False:
138 if time_pos >= 0 and time_pos is not False:
132
139
133 datadict = commits_by_day_author_aggregate\
140 datadict = commits_by_day_author_aggregate\
134 [author_key_cleaner(cs.author)]['data'][time_pos]
141 [author_key_cleaner(cs.author)]['data'][time_pos]
135
142
136 datadict["commits"] += 1
143 datadict["commits"] += 1
137 datadict["added"] += len(cs.added)
144 datadict["added"] += len(cs.added)
138 datadict["changed"] += len(cs.changed)
145 datadict["changed"] += len(cs.changed)
139 datadict["removed"] += len(cs.removed)
146 datadict["removed"] += len(cs.removed)
140 #print datadict
147 #print datadict
141
148
142 else:
149 else:
143 #print 'ELSE !!!!'
150 #print 'ELSE !!!!'
144 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
151 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
145
152
146 datadict = {"time":k,
153 datadict = {"time":k,
147 "commits":1,
154 "commits":1,
148 "added":len(cs.added),
155 "added":len(cs.added),
149 "changed":len(cs.changed),
156 "changed":len(cs.changed),
150 "removed":len(cs.removed),
157 "removed":len(cs.removed),
151 }
158 }
152 commits_by_day_author_aggregate\
159 commits_by_day_author_aggregate\
153 [author_key_cleaner(cs.author)]['data'].append(datadict)
160 [author_key_cleaner(cs.author)]['data'].append(datadict)
154
161
155 else:
162 else:
156 #print k, 'nokey ADDING'
163 #print k, 'nokey ADDING'
157 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
164 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
158 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
165 commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
159 "label":author_key_cleaner(cs.author),
166 "label":author_key_cleaner(cs.author),
160 "data":[{"time":k,
167 "data":[{"time":k,
161 "commits":1,
168 "commits":1,
162 "added":len(cs.added),
169 "added":len(cs.added),
163 "changed":len(cs.changed),
170 "changed":len(cs.changed),
164 "removed":len(cs.removed),
171 "removed":len(cs.removed),
165 }],
172 }],
166 "schema":["commits"],
173 "schema":["commits"],
167 }
174 }
168
175
169 # #gather all data by day
176 # #gather all data by day
170 if commits_by_day_aggregate.has_key(k):
177 if commits_by_day_aggregate.has_key(k):
171 commits_by_day_aggregate[k] += 1
178 commits_by_day_aggregate[k] += 1
172 else:
179 else:
173 commits_by_day_aggregate[k] = 1
180 commits_by_day_aggregate[k] = 1
174
181
175 if cnt >= parse_limit:
182 if cnt >= parse_limit:
176 #don't fetch to much data since we can freeze application
183 #don't fetch to much data since we can freeze application
177 break
184 break
178
185
179 overview_data = []
186 overview_data = []
180 for k, v in commits_by_day_aggregate.items():
187 for k, v in commits_by_day_aggregate.items():
181 overview_data.append([k, v])
188 overview_data.append([k, v])
182 overview_data = sorted(overview_data, key=itemgetter(0))
189 overview_data = sorted(overview_data, key=itemgetter(0))
183
190
184 if not commits_by_day_author_aggregate:
191 if not commits_by_day_author_aggregate:
185 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
192 commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
186 "label":author_key_cleaner(repo.contact),
193 "label":author_key_cleaner(repo.contact),
187 "data":[0, 1],
194 "data":[0, 1],
188 "schema":["commits"],
195 "schema":["commits"],
189 }
196 }
190
197
191 stats = cur_stats if cur_stats else Statistics()
198 stats = cur_stats if cur_stats else Statistics()
192 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
199 stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
193 stats.commit_activity_combined = json.dumps(overview_data)
200 stats.commit_activity_combined = json.dumps(overview_data)
194
201
195 log.debug('last revison %s', last_rev)
202 log.debug('last revison %s', last_rev)
196 leftovers = len(repo.revisions[last_rev:])
203 leftovers = len(repo.revisions[last_rev:])
197 log.debug('revisions to parse %s', leftovers)
204 log.debug('revisions to parse %s', leftovers)
198
205
199 if last_rev == 0 or leftovers < parse_limit:
206 if last_rev == 0 or leftovers < parse_limit:
200 stats.languages = json.dumps(__get_codes_stats(repo_name))
207 stats.languages = json.dumps(__get_codes_stats(repo_name))
201
208
202 stats.repository = dbrepo
209 stats.repository = dbrepo
203 stats.stat_on_revision = last_cs.revision
210 stats.stat_on_revision = last_cs.revision
204
211
205 try:
212 try:
206 sa.add(stats)
213 sa.add(stats)
207 sa.commit()
214 sa.commit()
208 except:
215 except:
209 log.error(traceback.format_exc())
216 log.error(traceback.format_exc())
210 sa.rollback()
217 sa.rollback()
211 return False
218 return False
212 if len(repo.revisions) > 1:
219 if len(repo.revisions) > 1:
213 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
220 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
214
221
215 return True
222 return True
216
223
217 @task
224 @task
218 def reset_user_password(user_email):
225 def reset_user_password(user_email):
219 log = reset_user_password.get_logger()
226 log = reset_user_password.get_logger()
220 from rhodecode.lib import auth
227 from rhodecode.lib import auth
221 from rhodecode.model.db import User
228 from rhodecode.model.db import User
222
229
223 try:
230 try:
224 try:
231 try:
225 sa = get_session()
232 sa = get_session()
226 user = sa.query(User).filter(User.email == user_email).scalar()
233 user = sa.query(User).filter(User.email == user_email).scalar()
227 new_passwd = auth.PasswordGenerator().gen_password(8,
234 new_passwd = auth.PasswordGenerator().gen_password(8,
228 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
235 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
229 if user:
236 if user:
230 user.password = auth.get_crypt_password(new_passwd)
237 user.password = auth.get_crypt_password(new_passwd)
231 sa.add(user)
238 sa.add(user)
232 sa.commit()
239 sa.commit()
233 log.info('change password for %s', user_email)
240 log.info('change password for %s', user_email)
234 if new_passwd is None:
241 if new_passwd is None:
235 raise Exception('unable to generate new password')
242 raise Exception('unable to generate new password')
236
243
237 except:
244 except:
238 log.error(traceback.format_exc())
245 log.error(traceback.format_exc())
239 sa.rollback()
246 sa.rollback()
240
247
241 run_task(send_email, user_email,
248 run_task(send_email, user_email,
242 "Your new rhodecode password",
249 "Your new rhodecode password",
243 'Your new rhodecode password:%s' % (new_passwd))
250 'Your new rhodecode password:%s' % (new_passwd))
244 log.info('send new password mail to %s', user_email)
251 log.info('send new password mail to %s', user_email)
245
252
246
253
247 except:
254 except:
248 log.error('Failed to update user password')
255 log.error('Failed to update user password')
249 log.error(traceback.format_exc())
256 log.error(traceback.format_exc())
250 return True
257 return True
251
258
252 @task
259 @task
253 def send_email(recipients, subject, body):
260 def send_email(recipients, subject, body):
254 log = send_email.get_logger()
261 log = send_email.get_logger()
255 email_config = dict(config.items('DEFAULT'))
262 email_config = dict(config.items('DEFAULT'))
256 mail_from = email_config.get('app_email_from')
263 mail_from = email_config.get('app_email_from')
257 user = email_config.get('smtp_username')
264 user = email_config.get('smtp_username')
258 passwd = email_config.get('smtp_password')
265 passwd = email_config.get('smtp_password')
259 mail_server = email_config.get('smtp_server')
266 mail_server = email_config.get('smtp_server')
260 mail_port = email_config.get('smtp_port')
267 mail_port = email_config.get('smtp_port')
261 tls = email_config.get('smtp_use_tls')
268 tls = email_config.get('smtp_use_tls')
262 ssl = False
269 ssl = False
263
270
264 try:
271 try:
265 m = SmtpMailer(mail_from, user, passwd, mail_server,
272 m = SmtpMailer(mail_from, user, passwd, mail_server,
266 mail_port, ssl, tls)
273 mail_port, ssl, tls)
267 m.send(recipients, subject, body)
274 m.send(recipients, subject, body)
268 except:
275 except:
269 log.error('Mail sending failed')
276 log.error('Mail sending failed')
270 log.error(traceback.format_exc())
277 log.error(traceback.format_exc())
271 return False
278 return False
272 return True
279 return True
273
280
274 @task
281 @task
275 def create_repo_fork(form_data, cur_user):
282 def create_repo_fork(form_data, cur_user):
276 import os
283 import os
277 from rhodecode.model.repo_model import RepoModel
284 from rhodecode.model.repo_model import RepoModel
278 sa = get_session()
285 sa = get_session()
279 rm = RepoModel(sa)
286 rm = RepoModel(sa)
280
287
281 rm.create(form_data, cur_user, just_db=True, fork=True)
288 rm.create(form_data, cur_user, just_db=True, fork=True)
282
289
283 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
290 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
284 repo_path = os.path.join(repos_path, form_data['repo_name'])
291 repo_path = os.path.join(repos_path, form_data['repo_name'])
285 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
292 repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
286
293
287 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
294 MercurialRepository(str(repo_fork_path), True, clone_url=str(repo_path))
288
295
289
296
290 def __get_codes_stats(repo_name):
297 def __get_codes_stats(repo_name):
291 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
298 LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
292 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
299 'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
293 'h', 'java', 'js', 'jsp', 'jspx', 'lisp',
300 'h', 'java', 'js', 'jsp', 'jspx', 'lisp',
294 'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
301 'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
295 'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh',
302 'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh',
296 'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
303 'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
297 'yaws']
304 'yaws']
298 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
305 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
299 repo = MercurialRepository(repos_path + repo_name)
306 repo = MercurialRepository(repos_path + repo_name)
300
307
301 code_stats = {}
308 code_stats = {}
302 for topnode, dirs, files in repo.walk('/', 'tip'):
309 for topnode, dirs, files in repo.walk('/', 'tip'):
303 for f in files:
310 for f in files:
304 k = f.mimetype
311 k = f.mimetype
305 if f.extension in LANGUAGES_EXTENSIONS:
312 if f.extension in LANGUAGES_EXTENSIONS:
306 if code_stats.has_key(k):
313 if code_stats.has_key(k):
307 code_stats[k] += 1
314 code_stats[k] += 1
308 else:
315 else:
309 code_stats[k] = 1
316 code_stats[k] = 1
310
317
311 return code_stats or {}
318 return code_stats or {}
312
319
313
320
314
321
315
322
316
323
@@ -1,269 +1,269 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # database managment for hg app
3 # database managment for hg app
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20
20
21 """
21 """
22 Created on April 10, 2010
22 Created on April 10, 2010
23 database managment and creation for hg app
23 database managment and creation for hg app
24 @author: marcink
24 @author: marcink
25 """
25 """
26
26
27 from os.path import dirname as dn, join as jn
27 from os.path import dirname as dn, join as jn
28 import os
28 import os
29 import sys
29 import sys
30 import uuid
30 import uuid
31
31
32 from rhodecode.lib.auth import get_crypt_password
32 from rhodecode.lib.auth import get_crypt_password
33 from rhodecode.lib.utils import ask_ok
33 from rhodecode.lib.utils import ask_ok
34 from rhodecode.model import init_model
34 from rhodecode.model import init_model
35 from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
35 from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
36 UserToPerm
36 UserToPerm
37 from rhodecode.model import meta
37 from rhodecode.model import meta
38 from sqlalchemy.engine import create_engine
38 from sqlalchemy.engine import create_engine
39 import logging
39 import logging
40
40
41 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
42
42
43 class DbManage(object):
43 class DbManage(object):
44 def __init__(self, log_sql, dbname, root, tests=False):
44 def __init__(self, log_sql, dbname, root, tests=False):
45 self.dbname = dbname
45 self.dbname = dbname
46 self.tests = tests
46 self.tests = tests
47 self.root = root
47 self.root = root
48 dburi = 'sqlite:////%s' % jn(self.root, self.dbname)
48 dburi = 'sqlite:////%s' % jn(self.root, self.dbname)
49 engine = create_engine(dburi, echo=log_sql)
49 engine = create_engine(dburi, echo=log_sql)
50 init_model(engine)
50 init_model(engine)
51 self.sa = meta.Session
51 self.sa = meta.Session
52 self.db_exists = False
52 self.db_exists = False
53
53
54 def check_for_db(self, override):
54 def check_for_db(self, override):
55 db_path = jn(self.root, self.dbname)
55 db_path = jn(self.root, self.dbname)
56 log.info('checking for existing db in %s', db_path)
56 log.info('checking for existing db in %s', db_path)
57 if os.path.isfile(db_path):
57 if os.path.isfile(db_path):
58 self.db_exists = True
58 self.db_exists = True
59 log.info('database exist')
59 log.info('database exist')
60 if not override:
60 if not override:
61 raise Exception('database already exists')
61 raise Exception('database already exists')
62
62
63 def create_tables(self, override=False):
63 def create_tables(self, override=False):
64 """
64 """
65 Create a auth database
65 Create a auth database
66 """
66 """
67 self.check_for_db(override)
67 self.check_for_db(override)
68 if override:
68 if override:
69 log.info("database exist and it's going to be destroyed")
69 log.info("database exist and it's going to be destroyed")
70 if self.tests:
70 if self.tests:
71 destroy = True
71 destroy = True
72 else:
72 else:
73 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
73 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
74 if not destroy:
74 if not destroy:
75 sys.exit()
75 sys.exit()
76 if self.db_exists and destroy:
76 if self.db_exists and destroy:
77 os.remove(jn(self.root, self.dbname))
77 os.remove(jn(self.root, self.dbname))
78 checkfirst = not override
78 checkfirst = not override
79 meta.Base.metadata.create_all(checkfirst=checkfirst)
79 meta.Base.metadata.create_all(checkfirst=checkfirst)
80 log.info('Created tables for %s', self.dbname)
80 log.info('Created tables for %s', self.dbname)
81
81
82 def admin_prompt(self):
82 def admin_prompt(self):
83 if not self.tests:
83 if not self.tests:
84 import getpass
84 import getpass
85 username = raw_input('Specify admin username:')
85 username = raw_input('Specify admin username:')
86 password = getpass.getpass('Specify admin password:')
86 password = getpass.getpass('Specify admin password:')
87 confirm = getpass.getpass('Confirm password:')
87 confirm = getpass.getpass('Confirm password:')
88 if password != confirm:
88 if password != confirm:
89 log.error('passwords mismatch')
89 log.error('passwords mismatch')
90 sys.exit()
90 sys.exit()
91 email = raw_input('Specify admin email:')
91 email = raw_input('Specify admin email:')
92 self.create_user(username, password, email, True)
92 self.create_user(username, password, email, True)
93 else:
93 else:
94 log.info('creating admin and regular test users')
94 log.info('creating admin and regular test users')
95 self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
95 self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
96 self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
96 self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
97 self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
97 self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
98
98
99
99
100
100
101 def config_prompt(self, test_repo_path=''):
101 def config_prompt(self, test_repo_path=''):
102 log.info('Setting up repositories config')
102 log.info('Setting up repositories config')
103
103
104 if not self.tests and not test_repo_path:
104 if not self.tests and not test_repo_path:
105 path = raw_input('Specify valid full path to your repositories'
105 path = raw_input('Specify valid full path to your repositories'
106 ' you can change this later in application settings:')
106 ' you can change this later in application settings:')
107 else:
107 else:
108 path = test_repo_path
108 path = test_repo_path
109
109
110 if not os.path.isdir(path):
110 if not os.path.isdir(path):
111 log.error('You entered wrong path: %s', path)
111 log.error('You entered wrong path: %s', path)
112 sys.exit()
112 sys.exit()
113
113
114 hooks1 = RhodeCodeUi()
114 hooks1 = RhodeCodeUi()
115 hooks1.ui_section = 'hooks'
115 hooks1.ui_section = 'hooks'
116 hooks1.ui_key = 'changegroup.update'
116 hooks1.ui_key = 'changegroup.update'
117 hooks1.ui_value = 'hg update >&2'
117 hooks1.ui_value = 'hg update >&2'
118
118
119 hooks2 = RhodeCodeUi()
119 hooks2 = RhodeCodeUi()
120 hooks2.ui_section = 'hooks'
120 hooks2.ui_section = 'hooks'
121 hooks2.ui_key = 'changegroup.repo_size'
121 hooks2.ui_key = 'changegroup.repo_size'
122 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
122 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
123
123
124 web1 = RhodeCodeUi()
124 web1 = RhodeCodeUi()
125 web1.ui_section = 'web'
125 web1.ui_section = 'web'
126 web1.ui_key = 'push_ssl'
126 web1.ui_key = 'push_ssl'
127 web1.ui_value = 'false'
127 web1.ui_value = 'false'
128
128
129 web2 = RhodeCodeUi()
129 web2 = RhodeCodeUi()
130 web2.ui_section = 'web'
130 web2.ui_section = 'web'
131 web2.ui_key = 'allow_archive'
131 web2.ui_key = 'allow_archive'
132 web2.ui_value = 'gz zip bz2'
132 web2.ui_value = 'gz zip bz2'
133
133
134 web3 = RhodeCodeUi()
134 web3 = RhodeCodeUi()
135 web3.ui_section = 'web'
135 web3.ui_section = 'web'
136 web3.ui_key = 'allow_push'
136 web3.ui_key = 'allow_push'
137 web3.ui_value = '*'
137 web3.ui_value = '*'
138
138
139 web4 = RhodeCodeUi()
139 web4 = RhodeCodeUi()
140 web4.ui_section = 'web'
140 web4.ui_section = 'web'
141 web4.ui_key = 'baseurl'
141 web4.ui_key = 'baseurl'
142 web4.ui_value = '/'
142 web4.ui_value = '/'
143
143
144 paths = RhodeCodeUi()
144 paths = RhodeCodeUi()
145 paths.ui_section = 'paths'
145 paths.ui_section = 'paths'
146 paths.ui_key = '/'
146 paths.ui_key = '/'
147 paths.ui_value = os.path.join(path, '*')
147 paths.ui_value = os.path.join(path, '*')
148
148
149
149
150 hgsettings1 = RhodeCodeSettings()
150 hgsettings1 = RhodeCodeSettings()
151
151
152 hgsettings1.app_settings_name = 'realm'
152 hgsettings1.app_settings_name = 'realm'
153 hgsettings1.app_settings_value = 'rhodecode authentication'
153 hgsettings1.app_settings_value = 'RhodeCode authentication'
154
154
155 hgsettings2 = RhodeCodeSettings()
155 hgsettings2 = RhodeCodeSettings()
156 hgsettings2.app_settings_name = 'title'
156 hgsettings2.app_settings_name = 'title'
157 hgsettings2.app_settings_value = 'rhodecode'
157 hgsettings2.app_settings_value = 'RhodeCode'
158
158
159 try:
159 try:
160 self.sa.add(hooks1)
160 self.sa.add(hooks1)
161 self.sa.add(hooks2)
161 self.sa.add(hooks2)
162 self.sa.add(web1)
162 self.sa.add(web1)
163 self.sa.add(web2)
163 self.sa.add(web2)
164 self.sa.add(web3)
164 self.sa.add(web3)
165 self.sa.add(web4)
165 self.sa.add(web4)
166 self.sa.add(paths)
166 self.sa.add(paths)
167 self.sa.add(hgsettings1)
167 self.sa.add(hgsettings1)
168 self.sa.add(hgsettings2)
168 self.sa.add(hgsettings2)
169 self.sa.commit()
169 self.sa.commit()
170 except:
170 except:
171 self.sa.rollback()
171 self.sa.rollback()
172 raise
172 raise
173 log.info('created ui config')
173 log.info('created ui config')
174
174
175 def create_user(self, username, password, email='', admin=False):
175 def create_user(self, username, password, email='', admin=False):
176 log.info('creating administrator user %s', username)
176 log.info('creating administrator user %s', username)
177 new_user = User()
177 new_user = User()
178 new_user.username = username
178 new_user.username = username
179 new_user.password = get_crypt_password(password)
179 new_user.password = get_crypt_password(password)
180 new_user.name = 'Hg'
180 new_user.name = 'RhodeCode'
181 new_user.lastname = 'Admin'
181 new_user.lastname = 'Admin'
182 new_user.email = email
182 new_user.email = email
183 new_user.admin = admin
183 new_user.admin = admin
184 new_user.active = True
184 new_user.active = True
185
185
186 try:
186 try:
187 self.sa.add(new_user)
187 self.sa.add(new_user)
188 self.sa.commit()
188 self.sa.commit()
189 except:
189 except:
190 self.sa.rollback()
190 self.sa.rollback()
191 raise
191 raise
192
192
193 def create_default_user(self):
193 def create_default_user(self):
194 log.info('creating default user')
194 log.info('creating default user')
195 #create default user for handling default permissions.
195 #create default user for handling default permissions.
196 def_user = User()
196 def_user = User()
197 def_user.username = 'default'
197 def_user.username = 'default'
198 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
198 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
199 def_user.name = 'default'
199 def_user.name = 'default'
200 def_user.lastname = 'default'
200 def_user.lastname = 'default'
201 def_user.email = 'default@default.com'
201 def_user.email = 'default@default.com'
202 def_user.admin = False
202 def_user.admin = False
203 def_user.active = False
203 def_user.active = False
204 try:
204 try:
205 self.sa.add(def_user)
205 self.sa.add(def_user)
206 self.sa.commit()
206 self.sa.commit()
207 except:
207 except:
208 self.sa.rollback()
208 self.sa.rollback()
209 raise
209 raise
210
210
211 def create_permissions(self):
211 def create_permissions(self):
212 #module.(access|create|change|delete)_[name]
212 #module.(access|create|change|delete)_[name]
213 #module.(read|write|owner)
213 #module.(read|write|owner)
214 perms = [('repository.none', 'Repository no access'),
214 perms = [('repository.none', 'Repository no access'),
215 ('repository.read', 'Repository read access'),
215 ('repository.read', 'Repository read access'),
216 ('repository.write', 'Repository write access'),
216 ('repository.write', 'Repository write access'),
217 ('repository.admin', 'Repository admin access'),
217 ('repository.admin', 'Repository admin access'),
218 ('hg.admin', 'Hg Administrator'),
218 ('hg.admin', 'Hg Administrator'),
219 ('hg.create.repository', 'Repository create'),
219 ('hg.create.repository', 'Repository create'),
220 ('hg.create.none', 'Repository creation disabled'),
220 ('hg.create.none', 'Repository creation disabled'),
221 ('hg.register.none', 'Register disabled'),
221 ('hg.register.none', 'Register disabled'),
222 ('hg.register.manual_activate', 'Register new user with rhodecode without manual activation'),
222 ('hg.register.manual_activate', 'Register new user with rhodecode without manual activation'),
223 ('hg.register.auto_activate', 'Register new user with rhodecode without auto activation'),
223 ('hg.register.auto_activate', 'Register new user with rhodecode without auto activation'),
224 ]
224 ]
225
225
226 for p in perms:
226 for p in perms:
227 new_perm = Permission()
227 new_perm = Permission()
228 new_perm.permission_name = p[0]
228 new_perm.permission_name = p[0]
229 new_perm.permission_longname = p[1]
229 new_perm.permission_longname = p[1]
230 try:
230 try:
231 self.sa.add(new_perm)
231 self.sa.add(new_perm)
232 self.sa.commit()
232 self.sa.commit()
233 except:
233 except:
234 self.sa.rollback()
234 self.sa.rollback()
235 raise
235 raise
236
236
237 def populate_default_permissions(self):
237 def populate_default_permissions(self):
238 log.info('creating default user permissions')
238 log.info('creating default user permissions')
239
239
240 default_user = self.sa.query(User)\
240 default_user = self.sa.query(User)\
241 .filter(User.username == 'default').scalar()
241 .filter(User.username == 'default').scalar()
242
242
243 reg_perm = UserToPerm()
243 reg_perm = UserToPerm()
244 reg_perm.user = default_user
244 reg_perm.user = default_user
245 reg_perm.permission = self.sa.query(Permission)\
245 reg_perm.permission = self.sa.query(Permission)\
246 .filter(Permission.permission_name == 'hg.register.manual_activate')\
246 .filter(Permission.permission_name == 'hg.register.manual_activate')\
247 .scalar()
247 .scalar()
248
248
249 create_repo_perm = UserToPerm()
249 create_repo_perm = UserToPerm()
250 create_repo_perm.user = default_user
250 create_repo_perm.user = default_user
251 create_repo_perm.permission = self.sa.query(Permission)\
251 create_repo_perm.permission = self.sa.query(Permission)\
252 .filter(Permission.permission_name == 'hg.create.repository')\
252 .filter(Permission.permission_name == 'hg.create.repository')\
253 .scalar()
253 .scalar()
254
254
255 default_repo_perm = UserToPerm()
255 default_repo_perm = UserToPerm()
256 default_repo_perm.user = default_user
256 default_repo_perm.user = default_user
257 default_repo_perm.permission = self.sa.query(Permission)\
257 default_repo_perm.permission = self.sa.query(Permission)\
258 .filter(Permission.permission_name == 'repository.read')\
258 .filter(Permission.permission_name == 'repository.read')\
259 .scalar()
259 .scalar()
260
260
261 try:
261 try:
262 self.sa.add(reg_perm)
262 self.sa.add(reg_perm)
263 self.sa.add(create_repo_perm)
263 self.sa.add(create_repo_perm)
264 self.sa.add(default_repo_perm)
264 self.sa.add(default_repo_perm)
265 self.sa.commit()
265 self.sa.commit()
266 except:
266 except:
267 self.sa.rollback()
267 self.sa.rollback()
268 raise
268 raise
269
269
@@ -1,361 +1,361 b''
1 """ this is forms validation classes
1 """ this is forms validation classes
2 http://formencode.org/module-formencode.validators.html
2 http://formencode.org/module-formencode.validators.html
3 for list off all availible validators
3 for list off all availible validators
4
4
5 we can create our own validators
5 we can create our own validators
6
6
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
8 pre_validators [] These validators will be applied before the schema
8 pre_validators [] These validators will be applied before the schema
9 chained_validators [] These validators will be applied after the schema
9 chained_validators [] These validators will be applied after the schema
10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
12 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
12 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
13 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
13 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
14
14
15
15
16 <name> = formencode.validators.<name of validator>
16 <name> = formencode.validators.<name of validator>
17 <name> must equal form name
17 <name> must equal form name
18 list=[1,2,3,4,5]
18 list=[1,2,3,4,5]
19 for SELECT use formencode.All(OneOf(list), Int())
19 for SELECT use formencode.All(OneOf(list), Int())
20
20
21 """
21 """
22 from formencode import All
22 from formencode import All
23 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
23 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
24 Email, Bool, StringBoolean
24 Email, Bool, StringBoolean
25 from pylons import session
25 from pylons import session
26 from pylons.i18n.translation import _
26 from pylons.i18n.translation import _
27 from rhodecode.lib.auth import check_password, get_crypt_password
27 from rhodecode.lib.auth import check_password, get_crypt_password
28 from rhodecode.model import meta
28 from rhodecode.model import meta
29 from rhodecode.model.user_model import UserModel
29 from rhodecode.model.user_model import UserModel
30 from rhodecode.model.db import User, Repository
30 from rhodecode.model.db import User, Repository
31 from sqlalchemy.exc import OperationalError
31 from sqlalchemy.exc import OperationalError
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 from webhelpers.pylonslib.secure_form import authentication_token
33 from webhelpers.pylonslib.secure_form import authentication_token
34 import formencode
34 import formencode
35 import logging
35 import logging
36 import os
36 import os
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 #this is needed to translate the messages using _() in validators
41 #this is needed to translate the messages using _() in validators
42 class State_obj(object):
42 class State_obj(object):
43 _ = staticmethod(_)
43 _ = staticmethod(_)
44
44
45 #===============================================================================
45 #===============================================================================
46 # VALIDATORS
46 # VALIDATORS
47 #===============================================================================
47 #===============================================================================
48 class ValidAuthToken(formencode.validators.FancyValidator):
48 class ValidAuthToken(formencode.validators.FancyValidator):
49 messages = {'invalid_token':_('Token mismatch')}
49 messages = {'invalid_token':_('Token mismatch')}
50
50
51 def validate_python(self, value, state):
51 def validate_python(self, value, state):
52
52
53 if value != authentication_token():
53 if value != authentication_token():
54 raise formencode.Invalid(self.message('invalid_token', state,
54 raise formencode.Invalid(self.message('invalid_token', state,
55 search_number=value), value, state)
55 search_number=value), value, state)
56
56
57 def ValidUsername(edit, old_data):
57 def ValidUsername(edit, old_data):
58 class _ValidUsername(formencode.validators.FancyValidator):
58 class _ValidUsername(formencode.validators.FancyValidator):
59
59
60 def validate_python(self, value, state):
60 def validate_python(self, value, state):
61 if value in ['default', 'new_user']:
61 if value in ['default', 'new_user']:
62 raise formencode.Invalid(_('Invalid username'), value, state)
62 raise formencode.Invalid(_('Invalid username'), value, state)
63 #check if user is uniq
63 #check if user is uniq
64 sa = meta.Session
64 sa = meta.Session
65 old_un = None
65 old_un = None
66 if edit:
66 if edit:
67 old_un = sa.query(User).get(old_data.get('user_id')).username
67 old_un = sa.query(User).get(old_data.get('user_id')).username
68
68
69 if old_un != value or not edit:
69 if old_un != value or not edit:
70 if sa.query(User).filter(User.username == value).scalar():
70 if sa.query(User).filter(User.username == value).scalar():
71 raise formencode.Invalid(_('This username already exists') ,
71 raise formencode.Invalid(_('This username already exists') ,
72 value, state)
72 value, state)
73 meta.Session.remove()
73 meta.Session.remove()
74
74
75 return _ValidUsername
75 return _ValidUsername
76
76
77 class ValidPassword(formencode.validators.FancyValidator):
77 class ValidPassword(formencode.validators.FancyValidator):
78
78
79 def to_python(self, value, state):
79 def to_python(self, value, state):
80 if value:
80 if value:
81 return get_crypt_password(value)
81 return get_crypt_password(value)
82
82
83 class ValidAuth(formencode.validators.FancyValidator):
83 class ValidAuth(formencode.validators.FancyValidator):
84 messages = {
84 messages = {
85 'invalid_password':_('invalid password'),
85 'invalid_password':_('invalid password'),
86 'invalid_login':_('invalid user name'),
86 'invalid_login':_('invalid user name'),
87 'disabled_account':_('Your acccount is disabled')
87 'disabled_account':_('Your acccount is disabled')
88
88
89 }
89 }
90 #error mapping
90 #error mapping
91 e_dict = {'username':messages['invalid_login'],
91 e_dict = {'username':messages['invalid_login'],
92 'password':messages['invalid_password']}
92 'password':messages['invalid_password']}
93 e_dict_disable = {'username':messages['disabled_account']}
93 e_dict_disable = {'username':messages['disabled_account']}
94
94
95 def validate_python(self, value, state):
95 def validate_python(self, value, state):
96 password = value['password']
96 password = value['password']
97 username = value['username']
97 username = value['username']
98 user = UserModel().get_user_by_name(username)
98 user = UserModel().get_user_by_name(username)
99 if user is None:
99 if user is None:
100 raise formencode.Invalid(self.message('invalid_password',
100 raise formencode.Invalid(self.message('invalid_password',
101 state=State_obj), value, state,
101 state=State_obj), value, state,
102 error_dict=self.e_dict)
102 error_dict=self.e_dict)
103 if user:
103 if user:
104 if user.active:
104 if user.active:
105 if user.username == username and check_password(password,
105 if user.username == username and check_password(password,
106 user.password):
106 user.password):
107 return value
107 return value
108 else:
108 else:
109 log.warning('user %s not authenticated', username)
109 log.warning('user %s not authenticated', username)
110 raise formencode.Invalid(self.message('invalid_password',
110 raise formencode.Invalid(self.message('invalid_password',
111 state=State_obj), value, state,
111 state=State_obj), value, state,
112 error_dict=self.e_dict)
112 error_dict=self.e_dict)
113 else:
113 else:
114 log.warning('user %s is disabled', username)
114 log.warning('user %s is disabled', username)
115 raise formencode.Invalid(self.message('disabled_account',
115 raise formencode.Invalid(self.message('disabled_account',
116 state=State_obj),
116 state=State_obj),
117 value, state,
117 value, state,
118 error_dict=self.e_dict_disable)
118 error_dict=self.e_dict_disable)
119
119
120 class ValidRepoUser(formencode.validators.FancyValidator):
120 class ValidRepoUser(formencode.validators.FancyValidator):
121
121
122 def to_python(self, value, state):
122 def to_python(self, value, state):
123 try:
123 try:
124 self.user_db = meta.Session.query(User)\
124 self.user_db = meta.Session.query(User)\
125 .filter(User.active == True)\
125 .filter(User.active == True)\
126 .filter(User.username == value).one()
126 .filter(User.username == value).one()
127 except Exception:
127 except Exception:
128 raise formencode.Invalid(_('This username is not valid'),
128 raise formencode.Invalid(_('This username is not valid'),
129 value, state)
129 value, state)
130 finally:
130 finally:
131 meta.Session.remove()
131 meta.Session.remove()
132
132
133 return self.user_db.user_id
133 return self.user_db.user_id
134
134
135 def ValidRepoName(edit, old_data):
135 def ValidRepoName(edit, old_data):
136 class _ValidRepoName(formencode.validators.FancyValidator):
136 class _ValidRepoName(formencode.validators.FancyValidator):
137
137
138 def to_python(self, value, state):
138 def to_python(self, value, state):
139 slug = h.repo_name_slug(value)
139 slug = h.repo_name_slug(value)
140 if slug in ['_admin']:
140 if slug in ['_admin']:
141 raise formencode.Invalid(_('This repository name is disallowed'),
141 raise formencode.Invalid(_('This repository name is disallowed'),
142 value, state)
142 value, state)
143 if old_data.get('repo_name') != value or not edit:
143 if old_data.get('repo_name') != value or not edit:
144 sa = meta.Session
144 sa = meta.Session
145 if sa.query(Repository).filter(Repository.repo_name == slug).scalar():
145 if sa.query(Repository).filter(Repository.repo_name == slug).scalar():
146 raise formencode.Invalid(_('This repository already exists') ,
146 raise formencode.Invalid(_('This repository already exists') ,
147 value, state)
147 value, state)
148 meta.Session.remove()
148 meta.Session.remove()
149 return slug
149 return slug
150
150
151
151
152 return _ValidRepoName
152 return _ValidRepoName
153
153
154 class ValidPerms(formencode.validators.FancyValidator):
154 class ValidPerms(formencode.validators.FancyValidator):
155 messages = {'perm_new_user_name':_('This username is not valid')}
155 messages = {'perm_new_user_name':_('This username is not valid')}
156
156
157 def to_python(self, value, state):
157 def to_python(self, value, state):
158 perms_update = []
158 perms_update = []
159 perms_new = []
159 perms_new = []
160 #build a list of permission to update and new permission to create
160 #build a list of permission to update and new permission to create
161 for k, v in value.items():
161 for k, v in value.items():
162 if k.startswith('perm_'):
162 if k.startswith('perm_'):
163 if k.startswith('perm_new_user'):
163 if k.startswith('perm_new_user'):
164 new_perm = value.get('perm_new_user', False)
164 new_perm = value.get('perm_new_user', False)
165 new_user = value.get('perm_new_user_name', False)
165 new_user = value.get('perm_new_user_name', False)
166 if new_user and new_perm:
166 if new_user and new_perm:
167 if (new_user, new_perm) not in perms_new:
167 if (new_user, new_perm) not in perms_new:
168 perms_new.append((new_user, new_perm))
168 perms_new.append((new_user, new_perm))
169 else:
169 else:
170 usr = k[5:]
170 usr = k[5:]
171 if usr == 'default':
171 if usr == 'default':
172 if value['private']:
172 if value['private']:
173 #set none for default when updating to private repo
173 #set none for default when updating to private repo
174 v = 'repository.none'
174 v = 'repository.none'
175 perms_update.append((usr, v))
175 perms_update.append((usr, v))
176 value['perms_updates'] = perms_update
176 value['perms_updates'] = perms_update
177 value['perms_new'] = perms_new
177 value['perms_new'] = perms_new
178 sa = meta.Session
178 sa = meta.Session
179 for k, v in perms_new:
179 for k, v in perms_new:
180 try:
180 try:
181 self.user_db = sa.query(User)\
181 self.user_db = sa.query(User)\
182 .filter(User.active == True)\
182 .filter(User.active == True)\
183 .filter(User.username == k).one()
183 .filter(User.username == k).one()
184 except Exception:
184 except Exception:
185 msg = self.message('perm_new_user_name',
185 msg = self.message('perm_new_user_name',
186 state=State_obj)
186 state=State_obj)
187 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
187 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
188 return value
188 return value
189
189
190 class ValidSettings(formencode.validators.FancyValidator):
190 class ValidSettings(formencode.validators.FancyValidator):
191
191
192 def to_python(self, value, state):
192 def to_python(self, value, state):
193 #settings form can't edit user
193 #settings form can't edit user
194 if value.has_key('user'):
194 if value.has_key('user'):
195 del['value']['user']
195 del['value']['user']
196
196
197 return value
197 return value
198
198
199 class ValidPath(formencode.validators.FancyValidator):
199 class ValidPath(formencode.validators.FancyValidator):
200 def to_python(self, value, state):
200 def to_python(self, value, state):
201 isdir = os.path.isdir(value.replace('*', ''))
201 isdir = os.path.isdir(value.replace('*', ''))
202 if (value.endswith('/*') or value.endswith('/**')) and isdir:
202 if (value.endswith('/*') or value.endswith('/**')) and isdir:
203 return value
203 return value
204 elif not isdir:
204 elif not isdir:
205 msg = _('This is not a valid path')
205 msg = _('This is not a valid path')
206 else:
206 else:
207 msg = _('You need to specify * or ** at the end of path (ie. /tmp/*)')
207 msg = _('You need to specify * or ** at the end of path (ie. /tmp/*)')
208
208
209 raise formencode.Invalid(msg, value, state,
209 raise formencode.Invalid(msg, value, state,
210 error_dict={'paths_root_path':msg})
210 error_dict={'paths_root_path':msg})
211
211
212 def UniqSystemEmail(old_data):
212 def UniqSystemEmail(old_data):
213 class _UniqSystemEmail(formencode.validators.FancyValidator):
213 class _UniqSystemEmail(formencode.validators.FancyValidator):
214 def to_python(self, value, state):
214 def to_python(self, value, state):
215 if old_data.get('email') != value:
215 if old_data.get('email') != value:
216 sa = meta.Session
216 sa = meta.Session
217 try:
217 try:
218 user = sa.query(User).filter(User.email == value).scalar()
218 user = sa.query(User).filter(User.email == value).scalar()
219 if user:
219 if user:
220 raise formencode.Invalid(_("That e-mail address is already taken") ,
220 raise formencode.Invalid(_("That e-mail address is already taken") ,
221 value, state)
221 value, state)
222 finally:
222 finally:
223 meta.Session.remove()
223 meta.Session.remove()
224
224
225 return value
225 return value
226
226
227 return _UniqSystemEmail
227 return _UniqSystemEmail
228
228
229 class ValidSystemEmail(formencode.validators.FancyValidator):
229 class ValidSystemEmail(formencode.validators.FancyValidator):
230 def to_python(self, value, state):
230 def to_python(self, value, state):
231 sa = meta.Session
231 sa = meta.Session
232 try:
232 try:
233 user = sa.query(User).filter(User.email == value).scalar()
233 user = sa.query(User).filter(User.email == value).scalar()
234 if user is None:
234 if user is None:
235 raise formencode.Invalid(_("That e-mail address doesn't exist.") ,
235 raise formencode.Invalid(_("That e-mail address doesn't exist.") ,
236 value, state)
236 value, state)
237 finally:
237 finally:
238 meta.Session.remove()
238 meta.Session.remove()
239
239
240 return value
240 return value
241
241
242 #===============================================================================
242 #===============================================================================
243 # FORMS
243 # FORMS
244 #===============================================================================
244 #===============================================================================
245 class LoginForm(formencode.Schema):
245 class LoginForm(formencode.Schema):
246 allow_extra_fields = True
246 allow_extra_fields = True
247 filter_extra_fields = True
247 filter_extra_fields = True
248 username = UnicodeString(
248 username = UnicodeString(
249 strip=True,
249 strip=True,
250 min=1,
250 min=1,
251 not_empty=True,
251 not_empty=True,
252 messages={
252 messages={
253 'empty':_('Please enter a login'),
253 'empty':_('Please enter a login'),
254 'tooShort':_('Enter a value %(min)i characters long or more')}
254 'tooShort':_('Enter a value %(min)i characters long or more')}
255 )
255 )
256
256
257 password = UnicodeString(
257 password = UnicodeString(
258 strip=True,
258 strip=True,
259 min=6,
259 min=6,
260 not_empty=True,
260 not_empty=True,
261 messages={
261 messages={
262 'empty':_('Please enter a password'),
262 'empty':_('Please enter a password'),
263 'tooShort':_('Enter a value %(min)i characters long or more')}
263 'tooShort':_('Enter %(min)i characters or more')}
264 )
264 )
265
265
266
266
267 #chained validators have access to all data
267 #chained validators have access to all data
268 chained_validators = [ValidAuth]
268 chained_validators = [ValidAuth]
269
269
270 def UserForm(edit=False, old_data={}):
270 def UserForm(edit=False, old_data={}):
271 class _UserForm(formencode.Schema):
271 class _UserForm(formencode.Schema):
272 allow_extra_fields = True
272 allow_extra_fields = True
273 filter_extra_fields = True
273 filter_extra_fields = True
274 username = All(UnicodeString(strip=True, min=1, not_empty=True), ValidUsername(edit, old_data))
274 username = All(UnicodeString(strip=True, min=1, not_empty=True), ValidUsername(edit, old_data))
275 if edit:
275 if edit:
276 new_password = All(UnicodeString(strip=True, min=6, not_empty=False), ValidPassword)
276 new_password = All(UnicodeString(strip=True, min=6, not_empty=False), ValidPassword)
277 admin = StringBoolean(if_missing=False)
277 admin = StringBoolean(if_missing=False)
278 else:
278 else:
279 password = All(UnicodeString(strip=True, min=6, not_empty=True), ValidPassword)
279 password = All(UnicodeString(strip=True, min=6, not_empty=True), ValidPassword)
280 active = StringBoolean(if_missing=False)
280 active = StringBoolean(if_missing=False)
281 name = UnicodeString(strip=True, min=1, not_empty=True)
281 name = UnicodeString(strip=True, min=1, not_empty=True)
282 lastname = UnicodeString(strip=True, min=1, not_empty=True)
282 lastname = UnicodeString(strip=True, min=1, not_empty=True)
283 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
283 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
284
284
285 return _UserForm
285 return _UserForm
286
286
287 RegisterForm = UserForm
287 RegisterForm = UserForm
288
288
289 def PasswordResetForm():
289 def PasswordResetForm():
290 class _PasswordResetForm(formencode.Schema):
290 class _PasswordResetForm(formencode.Schema):
291 allow_extra_fields = True
291 allow_extra_fields = True
292 filter_extra_fields = True
292 filter_extra_fields = True
293 email = All(ValidSystemEmail(), Email(not_empty=True))
293 email = All(ValidSystemEmail(), Email(not_empty=True))
294 return _PasswordResetForm
294 return _PasswordResetForm
295
295
296 def RepoForm(edit=False, old_data={}):
296 def RepoForm(edit=False, old_data={}):
297 class _RepoForm(formencode.Schema):
297 class _RepoForm(formencode.Schema):
298 allow_extra_fields = True
298 allow_extra_fields = True
299 filter_extra_fields = False
299 filter_extra_fields = False
300 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
300 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
301 description = UnicodeString(strip=True, min=1, not_empty=True)
301 description = UnicodeString(strip=True, min=1, not_empty=True)
302 private = StringBoolean(if_missing=False)
302 private = StringBoolean(if_missing=False)
303
303
304 if edit:
304 if edit:
305 user = All(Int(not_empty=True), ValidRepoUser)
305 user = All(Int(not_empty=True), ValidRepoUser)
306
306
307 chained_validators = [ValidPerms]
307 chained_validators = [ValidPerms]
308 return _RepoForm
308 return _RepoForm
309
309
310 def RepoForkForm(edit=False, old_data={}):
310 def RepoForkForm(edit=False, old_data={}):
311 class _RepoForkForm(formencode.Schema):
311 class _RepoForkForm(formencode.Schema):
312 allow_extra_fields = True
312 allow_extra_fields = True
313 filter_extra_fields = False
313 filter_extra_fields = False
314 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
314 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
315 description = UnicodeString(strip=True, min=1, not_empty=True)
315 description = UnicodeString(strip=True, min=1, not_empty=True)
316 private = StringBoolean(if_missing=False)
316 private = StringBoolean(if_missing=False)
317
317
318 return _RepoForkForm
318 return _RepoForkForm
319
319
320 def RepoSettingsForm(edit=False, old_data={}):
320 def RepoSettingsForm(edit=False, old_data={}):
321 class _RepoForm(formencode.Schema):
321 class _RepoForm(formencode.Schema):
322 allow_extra_fields = True
322 allow_extra_fields = True
323 filter_extra_fields = False
323 filter_extra_fields = False
324 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
324 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
325 description = UnicodeString(strip=True, min=1, not_empty=True)
325 description = UnicodeString(strip=True, min=1, not_empty=True)
326 private = StringBoolean(if_missing=False)
326 private = StringBoolean(if_missing=False)
327
327
328 chained_validators = [ValidPerms, ValidSettings]
328 chained_validators = [ValidPerms, ValidSettings]
329 return _RepoForm
329 return _RepoForm
330
330
331
331
332 def ApplicationSettingsForm():
332 def ApplicationSettingsForm():
333 class _ApplicationSettingsForm(formencode.Schema):
333 class _ApplicationSettingsForm(formencode.Schema):
334 allow_extra_fields = True
334 allow_extra_fields = True
335 filter_extra_fields = False
335 filter_extra_fields = False
336 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
336 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
337 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
337 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
338
338
339 return _ApplicationSettingsForm
339 return _ApplicationSettingsForm
340
340
341 def ApplicationUiSettingsForm():
341 def ApplicationUiSettingsForm():
342 class _ApplicationUiSettingsForm(formencode.Schema):
342 class _ApplicationUiSettingsForm(formencode.Schema):
343 allow_extra_fields = True
343 allow_extra_fields = True
344 filter_extra_fields = False
344 filter_extra_fields = False
345 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
345 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
346 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
346 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
347 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
347 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
348 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
348 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
349
349
350 return _ApplicationUiSettingsForm
350 return _ApplicationUiSettingsForm
351
351
352 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
352 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
353 class _DefaultPermissionsForm(formencode.Schema):
353 class _DefaultPermissionsForm(formencode.Schema):
354 allow_extra_fields = True
354 allow_extra_fields = True
355 filter_extra_fields = True
355 filter_extra_fields = True
356 overwrite_default = OneOf(['true', 'false'], if_missing='false')
356 overwrite_default = OneOf(['true', 'false'], if_missing='false')
357 default_perm = OneOf(perms_choices)
357 default_perm = OneOf(perms_choices)
358 default_register = OneOf(register_choices)
358 default_register = OneOf(register_choices)
359 default_create = OneOf(create_choices)
359 default_create = OneOf(create_choices)
360
360
361 return _DefaultPermissionsForm
361 return _DefaultPermissionsForm
@@ -1,44 +1,26 b''
1 """Setup the rhodecode application"""
1 """Setup the rhodecode application"""
2 from os.path import dirname as dn, join as jn
3 from rhodecode.config.environment import load_environment
2 from rhodecode.config.environment import load_environment
4 from rhodecode.lib.db_manage import DbManage
3 from rhodecode.lib.db_manage import DbManage
5 import logging
4 import logging
6 import os
5 import os
7 import shutil
8
6
9 log = logging.getLogger(__name__)
7 log = logging.getLogger(__name__)
10 ROOT = dn(os.path.realpath(__file__))
11
8
12 def setup_app(command, conf, vars):
9 def setup_app(command, conf, vars):
13 """Place any commands to setup rhodecode here"""
10 """Place any commands to setup rhodecode here"""
14 print dn(os.path.realpath(__file__))
15 print(ROOT)
16 dbname = os.path.split(conf['sqlalchemy.db1.url'])[-1]
11 dbname = os.path.split(conf['sqlalchemy.db1.url'])[-1]
17 dbmanage = DbManage(log_sql=True, dbname=dbname, root=conf['here'],
12 dbmanage = DbManage(log_sql=True, dbname=dbname, root=conf['here'],
18 tests=False)
13 tests=False)
19 dbmanage.create_tables(override=True)
14 dbmanage.create_tables(override=True)
20 dbmanage.config_prompt(None)
15 dbmanage.config_prompt(None)
21 dbmanage.create_default_user()
16 dbmanage.create_default_user()
22 dbmanage.admin_prompt()
17 dbmanage.admin_prompt()
23 dbmanage.create_permissions()
18 dbmanage.create_permissions()
24 dbmanage.populate_default_permissions()
19 dbmanage.populate_default_permissions()
25
20
26 celeryconfig_file = 'celeryconfig.py'
21 load_environment(conf.global_conf, conf.local_conf, initial=True)
27
28 celeryconfig_path = jn(ROOT, celeryconfig_file)
29
30
31 if not os.path.isfile(jn(conf['here'], celeryconfig_file)):
32 try:
33 shutil.copy(celeryconfig_path, conf['here'])
34 except IOError:
35 log.error('failed to copy celeryconfig.py from source %s '
36 ' to this directory please copy it manually ',
37 celeryconfig_path)
38 else:
39 load_environment(conf.global_conf, conf.local_conf, initial=True)
40
22
41
23
42
24
43
25
44
26
General Comments 0
You need to be logged in to leave comments. Login now