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