##// END OF EJS Templates
emails: ensure none empty emails are fetched from admin accounts in recipinets aren't specified....
marcink -
r2896:5e035500 default
parent child Browse files
Show More
@@ -1,301 +1,307 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2018 RhodeCode GmbH
3 # Copyright (C) 2012-2018 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 """
21 """
22 RhodeCode task modules, containing all task that suppose to be run
22 RhodeCode task modules, containing all task that suppose to be run
23 by celery daemon
23 by celery daemon
24 """
24 """
25
25
26 import os
26 import os
27 import time
27 import time
28
28
29 import rhodecode
29 import rhodecode
30 from rhodecode.lib import audit_logger
30 from rhodecode.lib import audit_logger
31 from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask
31 from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask
32 from rhodecode.lib.hooks_base import log_create_repository
32 from rhodecode.lib.hooks_base import log_create_repository
33 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
33 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
34 from rhodecode.lib.utils2 import safe_int, str2bool
34 from rhodecode.lib.utils2 import safe_int, str2bool
35 from rhodecode.model.db import Session, IntegrityError, Repository, User
35 from rhodecode.model.db import Session, IntegrityError, Repository, User, true
36
36
37
37
38 @async_task(ignore_result=True, base=RequestContextTask)
38 @async_task(ignore_result=True, base=RequestContextTask)
39 def send_email(recipients, subject, body='', html_body='', email_config=None):
39 def send_email(recipients, subject, body='', html_body='', email_config=None):
40 """
40 """
41 Sends an email with defined parameters from the .ini files.
41 Sends an email with defined parameters from the .ini files.
42
42
43 :param recipients: list of recipients, it this is empty the defined email
43 :param recipients: list of recipients, it this is empty the defined email
44 address from field 'email_to' is used instead
44 address from field 'email_to' is used instead
45 :param subject: subject of the mail
45 :param subject: subject of the mail
46 :param body: body of the mail
46 :param body: body of the mail
47 :param html_body: html version of body
47 :param html_body: html version of body
48 """
48 """
49 log = get_logger(send_email)
49 log = get_logger(send_email)
50
50
51 email_config = email_config or rhodecode.CONFIG
51 email_config = email_config or rhodecode.CONFIG
52 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
52 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
53 if not recipients:
53 if not recipients:
54 # if recipients are not defined we send to email_config + all admins
54 # if recipients are not defined we send to email_config + all admins
55 admins = [
55 admins = []
56 u.email for u in User.query().filter(User.admin == True).all()]
56 for u in User.query().filter(User.admin == true()).all():
57 recipients = [email_config.get('email_to')] + admins
57 if u.email:
58 admins.append(u.email)
59 recipients = []
60 config_email = email_config.get('email_to')
61 if config_email:
62 recipients += [config_email]
63 recipients += admins
58
64
59 mail_server = email_config.get('smtp_server') or None
65 mail_server = email_config.get('smtp_server') or None
60 if mail_server is None:
66 if mail_server is None:
61 log.error("SMTP server information missing. Sending email failed. "
67 log.error("SMTP server information missing. Sending email failed. "
62 "Make sure that `smtp_server` variable is configured "
68 "Make sure that `smtp_server` variable is configured "
63 "inside the .ini file")
69 "inside the .ini file")
64 return False
70 return False
65
71
66 mail_from = email_config.get('app_email_from', 'RhodeCode')
72 mail_from = email_config.get('app_email_from', 'RhodeCode')
67 user = email_config.get('smtp_username')
73 user = email_config.get('smtp_username')
68 passwd = email_config.get('smtp_password')
74 passwd = email_config.get('smtp_password')
69 mail_port = email_config.get('smtp_port')
75 mail_port = email_config.get('smtp_port')
70 tls = str2bool(email_config.get('smtp_use_tls'))
76 tls = str2bool(email_config.get('smtp_use_tls'))
71 ssl = str2bool(email_config.get('smtp_use_ssl'))
77 ssl = str2bool(email_config.get('smtp_use_ssl'))
72 debug = str2bool(email_config.get('debug'))
78 debug = str2bool(email_config.get('debug'))
73 smtp_auth = email_config.get('smtp_auth')
79 smtp_auth = email_config.get('smtp_auth')
74
80
75 try:
81 try:
76 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
82 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
77 mail_port, ssl, tls, debug=debug)
83 mail_port, ssl, tls, debug=debug)
78 m.send(recipients, subject, body, html_body)
84 m.send(recipients, subject, body, html_body)
79 except Exception:
85 except Exception:
80 log.exception('Mail sending failed')
86 log.exception('Mail sending failed')
81 return False
87 return False
82 return True
88 return True
83
89
84
90
85 @async_task(ignore_result=True, base=RequestContextTask)
91 @async_task(ignore_result=True, base=RequestContextTask)
86 def create_repo(form_data, cur_user):
92 def create_repo(form_data, cur_user):
87 from rhodecode.model.repo import RepoModel
93 from rhodecode.model.repo import RepoModel
88 from rhodecode.model.user import UserModel
94 from rhodecode.model.user import UserModel
89 from rhodecode.model.settings import SettingsModel
95 from rhodecode.model.settings import SettingsModel
90
96
91 log = get_logger(create_repo)
97 log = get_logger(create_repo)
92
98
93 cur_user = UserModel()._get_user(cur_user)
99 cur_user = UserModel()._get_user(cur_user)
94 owner = cur_user
100 owner = cur_user
95
101
96 repo_name = form_data['repo_name']
102 repo_name = form_data['repo_name']
97 repo_name_full = form_data['repo_name_full']
103 repo_name_full = form_data['repo_name_full']
98 repo_type = form_data['repo_type']
104 repo_type = form_data['repo_type']
99 description = form_data['repo_description']
105 description = form_data['repo_description']
100 private = form_data['repo_private']
106 private = form_data['repo_private']
101 clone_uri = form_data.get('clone_uri')
107 clone_uri = form_data.get('clone_uri')
102 repo_group = safe_int(form_data['repo_group'])
108 repo_group = safe_int(form_data['repo_group'])
103 landing_rev = form_data['repo_landing_rev']
109 landing_rev = form_data['repo_landing_rev']
104 copy_fork_permissions = form_data.get('copy_permissions')
110 copy_fork_permissions = form_data.get('copy_permissions')
105 copy_group_permissions = form_data.get('repo_copy_permissions')
111 copy_group_permissions = form_data.get('repo_copy_permissions')
106 fork_of = form_data.get('fork_parent_id')
112 fork_of = form_data.get('fork_parent_id')
107 state = form_data.get('repo_state', Repository.STATE_PENDING)
113 state = form_data.get('repo_state', Repository.STATE_PENDING)
108
114
109 # repo creation defaults, private and repo_type are filled in form
115 # repo creation defaults, private and repo_type are filled in form
110 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
116 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
111 enable_statistics = form_data.get(
117 enable_statistics = form_data.get(
112 'enable_statistics', defs.get('repo_enable_statistics'))
118 'enable_statistics', defs.get('repo_enable_statistics'))
113 enable_locking = form_data.get(
119 enable_locking = form_data.get(
114 'enable_locking', defs.get('repo_enable_locking'))
120 'enable_locking', defs.get('repo_enable_locking'))
115 enable_downloads = form_data.get(
121 enable_downloads = form_data.get(
116 'enable_downloads', defs.get('repo_enable_downloads'))
122 'enable_downloads', defs.get('repo_enable_downloads'))
117
123
118 try:
124 try:
119 repo = RepoModel()._create_repo(
125 repo = RepoModel()._create_repo(
120 repo_name=repo_name_full,
126 repo_name=repo_name_full,
121 repo_type=repo_type,
127 repo_type=repo_type,
122 description=description,
128 description=description,
123 owner=owner,
129 owner=owner,
124 private=private,
130 private=private,
125 clone_uri=clone_uri,
131 clone_uri=clone_uri,
126 repo_group=repo_group,
132 repo_group=repo_group,
127 landing_rev=landing_rev,
133 landing_rev=landing_rev,
128 fork_of=fork_of,
134 fork_of=fork_of,
129 copy_fork_permissions=copy_fork_permissions,
135 copy_fork_permissions=copy_fork_permissions,
130 copy_group_permissions=copy_group_permissions,
136 copy_group_permissions=copy_group_permissions,
131 enable_statistics=enable_statistics,
137 enable_statistics=enable_statistics,
132 enable_locking=enable_locking,
138 enable_locking=enable_locking,
133 enable_downloads=enable_downloads,
139 enable_downloads=enable_downloads,
134 state=state
140 state=state
135 )
141 )
136 Session().commit()
142 Session().commit()
137
143
138 # now create this repo on Filesystem
144 # now create this repo on Filesystem
139 RepoModel()._create_filesystem_repo(
145 RepoModel()._create_filesystem_repo(
140 repo_name=repo_name,
146 repo_name=repo_name,
141 repo_type=repo_type,
147 repo_type=repo_type,
142 repo_group=RepoModel()._get_repo_group(repo_group),
148 repo_group=RepoModel()._get_repo_group(repo_group),
143 clone_uri=clone_uri,
149 clone_uri=clone_uri,
144 )
150 )
145 repo = Repository.get_by_repo_name(repo_name_full)
151 repo = Repository.get_by_repo_name(repo_name_full)
146 log_create_repository(created_by=owner.username, **repo.get_dict())
152 log_create_repository(created_by=owner.username, **repo.get_dict())
147
153
148 # update repo commit caches initially
154 # update repo commit caches initially
149 repo.update_commit_cache()
155 repo.update_commit_cache()
150
156
151 # set new created state
157 # set new created state
152 repo.set_state(Repository.STATE_CREATED)
158 repo.set_state(Repository.STATE_CREATED)
153 repo_id = repo.repo_id
159 repo_id = repo.repo_id
154 repo_data = repo.get_api_data()
160 repo_data = repo.get_api_data()
155
161
156 audit_logger.store(
162 audit_logger.store(
157 'repo.create', action_data={'data': repo_data},
163 'repo.create', action_data={'data': repo_data},
158 user=cur_user,
164 user=cur_user,
159 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
165 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
160
166
161 Session().commit()
167 Session().commit()
162 except Exception as e:
168 except Exception as e:
163 log.warning('Exception occurred when creating repository, '
169 log.warning('Exception occurred when creating repository, '
164 'doing cleanup...', exc_info=True)
170 'doing cleanup...', exc_info=True)
165 if isinstance(e, IntegrityError):
171 if isinstance(e, IntegrityError):
166 Session().rollback()
172 Session().rollback()
167
173
168 # rollback things manually !
174 # rollback things manually !
169 repo = Repository.get_by_repo_name(repo_name_full)
175 repo = Repository.get_by_repo_name(repo_name_full)
170 if repo:
176 if repo:
171 Repository.delete(repo.repo_id)
177 Repository.delete(repo.repo_id)
172 Session().commit()
178 Session().commit()
173 RepoModel()._delete_filesystem_repo(repo)
179 RepoModel()._delete_filesystem_repo(repo)
174 log.info('Cleanup of repo %s finished', repo_name_full)
180 log.info('Cleanup of repo %s finished', repo_name_full)
175 raise
181 raise
176
182
177 return True
183 return True
178
184
179
185
180 @async_task(ignore_result=True, base=RequestContextTask)
186 @async_task(ignore_result=True, base=RequestContextTask)
181 def create_repo_fork(form_data, cur_user):
187 def create_repo_fork(form_data, cur_user):
182 """
188 """
183 Creates a fork of repository using internal VCS methods
189 Creates a fork of repository using internal VCS methods
184 """
190 """
185 from rhodecode.model.repo import RepoModel
191 from rhodecode.model.repo import RepoModel
186 from rhodecode.model.user import UserModel
192 from rhodecode.model.user import UserModel
187
193
188 log = get_logger(create_repo_fork)
194 log = get_logger(create_repo_fork)
189
195
190 cur_user = UserModel()._get_user(cur_user)
196 cur_user = UserModel()._get_user(cur_user)
191 owner = cur_user
197 owner = cur_user
192
198
193 repo_name = form_data['repo_name'] # fork in this case
199 repo_name = form_data['repo_name'] # fork in this case
194 repo_name_full = form_data['repo_name_full']
200 repo_name_full = form_data['repo_name_full']
195 repo_type = form_data['repo_type']
201 repo_type = form_data['repo_type']
196 description = form_data['description']
202 description = form_data['description']
197 private = form_data['private']
203 private = form_data['private']
198 clone_uri = form_data.get('clone_uri')
204 clone_uri = form_data.get('clone_uri')
199 repo_group = safe_int(form_data['repo_group'])
205 repo_group = safe_int(form_data['repo_group'])
200 landing_rev = form_data['landing_rev']
206 landing_rev = form_data['landing_rev']
201 copy_fork_permissions = form_data.get('copy_permissions')
207 copy_fork_permissions = form_data.get('copy_permissions')
202 fork_id = safe_int(form_data.get('fork_parent_id'))
208 fork_id = safe_int(form_data.get('fork_parent_id'))
203
209
204 try:
210 try:
205 fork_of = RepoModel()._get_repo(fork_id)
211 fork_of = RepoModel()._get_repo(fork_id)
206 RepoModel()._create_repo(
212 RepoModel()._create_repo(
207 repo_name=repo_name_full,
213 repo_name=repo_name_full,
208 repo_type=repo_type,
214 repo_type=repo_type,
209 description=description,
215 description=description,
210 owner=owner,
216 owner=owner,
211 private=private,
217 private=private,
212 clone_uri=clone_uri,
218 clone_uri=clone_uri,
213 repo_group=repo_group,
219 repo_group=repo_group,
214 landing_rev=landing_rev,
220 landing_rev=landing_rev,
215 fork_of=fork_of,
221 fork_of=fork_of,
216 copy_fork_permissions=copy_fork_permissions
222 copy_fork_permissions=copy_fork_permissions
217 )
223 )
218
224
219 Session().commit()
225 Session().commit()
220
226
221 base_path = Repository.base_path()
227 base_path = Repository.base_path()
222 source_repo_path = os.path.join(base_path, fork_of.repo_name)
228 source_repo_path = os.path.join(base_path, fork_of.repo_name)
223
229
224 # now create this repo on Filesystem
230 # now create this repo on Filesystem
225 RepoModel()._create_filesystem_repo(
231 RepoModel()._create_filesystem_repo(
226 repo_name=repo_name,
232 repo_name=repo_name,
227 repo_type=repo_type,
233 repo_type=repo_type,
228 repo_group=RepoModel()._get_repo_group(repo_group),
234 repo_group=RepoModel()._get_repo_group(repo_group),
229 clone_uri=source_repo_path,
235 clone_uri=source_repo_path,
230 )
236 )
231 repo = Repository.get_by_repo_name(repo_name_full)
237 repo = Repository.get_by_repo_name(repo_name_full)
232 log_create_repository(created_by=owner.username, **repo.get_dict())
238 log_create_repository(created_by=owner.username, **repo.get_dict())
233
239
234 # update repo commit caches initially
240 # update repo commit caches initially
235 config = repo._config
241 config = repo._config
236 config.set('extensions', 'largefiles', '')
242 config.set('extensions', 'largefiles', '')
237 repo.update_commit_cache(config=config)
243 repo.update_commit_cache(config=config)
238
244
239 # set new created state
245 # set new created state
240 repo.set_state(Repository.STATE_CREATED)
246 repo.set_state(Repository.STATE_CREATED)
241
247
242 repo_id = repo.repo_id
248 repo_id = repo.repo_id
243 repo_data = repo.get_api_data()
249 repo_data = repo.get_api_data()
244 audit_logger.store(
250 audit_logger.store(
245 'repo.fork', action_data={'data': repo_data},
251 'repo.fork', action_data={'data': repo_data},
246 user=cur_user,
252 user=cur_user,
247 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
253 repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id))
248
254
249 Session().commit()
255 Session().commit()
250 except Exception as e:
256 except Exception as e:
251 log.warning('Exception occurred when forking repository, '
257 log.warning('Exception occurred when forking repository, '
252 'doing cleanup...', exc_info=True)
258 'doing cleanup...', exc_info=True)
253 if isinstance(e, IntegrityError):
259 if isinstance(e, IntegrityError):
254 Session().rollback()
260 Session().rollback()
255
261
256 # rollback things manually !
262 # rollback things manually !
257 repo = Repository.get_by_repo_name(repo_name_full)
263 repo = Repository.get_by_repo_name(repo_name_full)
258 if repo:
264 if repo:
259 Repository.delete(repo.repo_id)
265 Repository.delete(repo.repo_id)
260 Session().commit()
266 Session().commit()
261 RepoModel()._delete_filesystem_repo(repo)
267 RepoModel()._delete_filesystem_repo(repo)
262 log.info('Cleanup of repo %s finished', repo_name_full)
268 log.info('Cleanup of repo %s finished', repo_name_full)
263 raise
269 raise
264
270
265 return True
271 return True
266
272
267
273
268 @async_task(ignore_result=True)
274 @async_task(ignore_result=True)
269 def repo_maintenance(repoid):
275 def repo_maintenance(repoid):
270 from rhodecode.lib import repo_maintenance as repo_maintenance_lib
276 from rhodecode.lib import repo_maintenance as repo_maintenance_lib
271 log = get_logger(repo_maintenance)
277 log = get_logger(repo_maintenance)
272 repo = Repository.get_by_id_or_repo_name(repoid)
278 repo = Repository.get_by_id_or_repo_name(repoid)
273 if repo:
279 if repo:
274 maintenance = repo_maintenance_lib.RepoMaintenance()
280 maintenance = repo_maintenance_lib.RepoMaintenance()
275 tasks = maintenance.get_tasks_for_repo(repo)
281 tasks = maintenance.get_tasks_for_repo(repo)
276 log.debug('Executing %s tasks on repo `%s`', tasks, repoid)
282 log.debug('Executing %s tasks on repo `%s`', tasks, repoid)
277 executed_types = maintenance.execute(repo)
283 executed_types = maintenance.execute(repo)
278 log.debug('Got execution results %s', executed_types)
284 log.debug('Got execution results %s', executed_types)
279 else:
285 else:
280 log.debug('Repo `%s` not found or without a clone_url', repoid)
286 log.debug('Repo `%s` not found or without a clone_url', repoid)
281
287
282
288
283 @async_task(ignore_result=True)
289 @async_task(ignore_result=True)
284 def check_for_update():
290 def check_for_update():
285 from rhodecode.model.update import UpdateModel
291 from rhodecode.model.update import UpdateModel
286 update_url = UpdateModel().get_update_url()
292 update_url = UpdateModel().get_update_url()
287 cur_ver = rhodecode.__version__
293 cur_ver = rhodecode.__version__
288
294
289 try:
295 try:
290 data = UpdateModel().get_update_data(update_url)
296 data = UpdateModel().get_update_data(update_url)
291 latest = data['versions'][0]
297 latest = data['versions'][0]
292 UpdateModel().store_version(latest['version'])
298 UpdateModel().store_version(latest['version'])
293 except Exception:
299 except Exception:
294 pass
300 pass
295
301
296
302
297 @async_task(ignore_result=False)
303 @async_task(ignore_result=False)
298 def beat_check(*args, **kwargs):
304 def beat_check(*args, **kwargs):
299 log = get_logger(beat_check)
305 log = get_logger(beat_check)
300 log.info('Got args: %r and kwargs %r', args, kwargs)
306 log.info('Got args: %r and kwargs %r', args, kwargs)
301 return time.time()
307 return time.time()
General Comments 0
You need to be logged in to leave comments. Login now