def send_email_notification(self, template, result): ''' This function is called from ckanext-datarequest after a DataRequest is created, commented on or closed. The organization selected during the DataRequest creation is sent an email notification if an admin has added an email address for notification. ''' context = self._get_context() data_dict = { 'organization_id': result['organization'].get('name'), 'success': True, } channels = toolkit.get_action(constants.EMAIL_CHANNELS_SHOW)(context, data_dict) if channels: extra_vars = { 'site_url': config.get('ckan.site_url'), 'site_title': config.get('ckan.site_title'), 'datarequest_url': result['datarequest_url'], 'datarequest_title': result['title'], 'datarequest_description': result['description'], 'action_type': template, } email_subject = base.render_jinja2('notify/email/{}.txt'.format('subject'), extra_vars) email_body = base.render_jinja2('notify/email/{}.txt'.format(template), extra_vars) for channel in channels: channel = dotdict(channel) mailer.mail_user(channel, email_subject, email_body)
def request_validation(admin, admin_email, resource_url): ''' Send request to specific user for data resource validation :param admin: The admin username :type admin: string :param admin_email: The admin email :type admin_email: string :param resource_url: The full URL to the resource :type resource_url: string ''' if not admin: raise MailerException(_('Admin username not provided')) if not admin_email: raise MailerException(_('Admin email not provided')) if not resource_url: raise MailerException(_('Resource URL not provided')) site_title = config.get('ckan.site_title') body = render_jinja2('emails/request_access_body.txt', { 'resource_url': resource_url, 'site_title': site_title, 'user_name': admin }) subject = render_jinja2('emails/request_access_subject.txt', {'site_title': site_title}) subject = subject.split('\n')[0] mailer.mail_recipient(admin, admin_email, subject, body, headers={})
def notify_lockout(user): extra_vars = { 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, } subject = render_jinja2('security/emails/lockout_subject.txt', extra_vars) subject = subject.split('\n')[0] # Make sure we only use the first line body = render_jinja2('security/emails/lockout_mail.txt', extra_vars) mail_user(user, subject, body)
def news_subscription_create(context, data_dict): '''Create a subscription . :param notify_by_mail: Setting if user should be notified by mail for news. :type notify_by_mail: boolean, default False :returns: the newly created subscription object :rtype: dictionary ''' l.check_access('news_subscription', context, data_dict) news_subscription_schema = schema.news_subscription_schema() data, errors = df.validate(data_dict, news_subscription_schema, context) if errors: raise t.ValidationError(errors) model = context['model'] user = context['user'] user_obj = model.User.get(user) notify_by_mail = data_dict.get('notify_by_mail', False) is_subscribed = ckanextNewsSubscriptions.get_subscription(user_obj.id) if is_subscribed: raise t.ValidationError('Subscribtion for user %s already exists!' % user_obj.name) subscription = ckanextNewsSubscriptions(subscriber_id=user_obj.id, notify_by_mail=notify_by_mail) subscription.save() out = subscription.as_dict() send_email_condition = config.get('testing', False) if not send_email_condition: # Notify the user via email # TODO: E-mail notifications should be sent asynchronous using celery tasks # TODO: Setup email server for testing mode vars = { 'site_title_dk': config_option_show('ckan.site_title', 'da_DK'), 'site_title_en': config_option_show('ckan.site_title', 'en'), 'site_url': config.get('ckan.site_url'), 'user_name': user_obj.name } msg_body = render_jinja2('emails/news_subscriptions.txt', vars) msg_subject = render_jinja2('emails/news_subscriptions_subject.txt', vars) send_email(msg_body, user_obj.email, msg_subject) return out
def send_notification_emails(users, template, extra_vars): """ Sets the email body and sends an email notification to each user in the list provided :param users: list of user email addresses to receive the notification :param template: string indicating which email template to use :param extra_vars: dict :return: """ if users: subject = render_jinja2('emails/subjects/{0}.txt'.format(template), extra_vars) body = render_jinja2('emails/bodies/{0}.txt'.format(template), extra_vars) for user in users: toolkit.enqueue_job(send_email, [user, subject, body], title=u'Comment Email')
def prepare_error_mail(context, source_id, status, template): extra_vars = get_mail_extra_vars(context, source_id, status) body = render_jinja2(template, extra_vars) subject = '{} - Harvesting Job - Error Notification'\ .format(config.get('ckan.site_title')) return subject, body
def send_slack_notification(self, template, result): ''' This function is called from ckanext-datarequest after a DataRequest is created, commented on or closed. The organization selected during the DataRequest creation is sent a slack notification if an admin has added Slack as a notification channel. ''' context = self._get_context() organization = result.get('organization', None) data_dict = { 'organization_id': organization['name'] if organization else '', 'success': True, } channels = toolkit.get_action(constants.SLACK_CHANNELS_SHOW)(context, data_dict) if channels: extra_vars = { 'site_title': config.get('ckan.site_title'), 'datarequest_url': result['datarequest_url'], 'datarequest_title': result['title'], 'datarequest_description': result['description'], } slack_message = {'text': base.render_jinja2('notify/slack/{}.txt'.format(template), extra_vars)} for channel in channels: requests.post( channel['webhook_url'], data=json.dumps(slack_message), headers={'Content-type': 'application/json'} )
def prepare_summary_mail(context, source_id, status): extra_vars = get_mail_extra_vars(context, source_id, status) body = render_jinja2('emails/summary_email.txt', extra_vars) subject = '{} - Harvesting Job Successful - Summary Notification'\ .format(config.get('ckan.site_title')) return subject, body
def notify_lockout(user, lockout_timeout): extra_vars = { 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, 'password_reset_url': config.get('ckan.site_url').rstrip('/') + '/user/login', 'lockout_mins': lockout_timeout // 60, } subject = render_jinja2('security/emails/lockout_subject.txt', extra_vars) subject = subject.split('\n')[0] # Make sure we only use the first line body = render_jinja2('security/emails/lockout_mail.txt', extra_vars) + _build_footer_content(extra_vars) mail_user(user, subject, body)
def _compose_email_body(org_dict, user, event='request'): org_link = toolkit.url_for('data-container_read', id=org_dict['name'], qualified=True) return render_jinja2('emails/data_container_{0}.txt'.format(event), { 'user_name': user.fullname or user.name, 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'org_title': org_dict['title'], 'org_link': org_link, })
def get_reset_link_body(user): extra_vars = { 'reset_link': get_reset_link(user), 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, } # NOTE: This template is translated return render_jinja2('emails/reset_password.txt', extra_vars)
def _get_reset_link_body(user): extra_vars = { 'reset_link': get_reset_link(user), 'site_title_dk': config_option_show('ckan.site_title', 'da_DK'), 'site_title_en': config_option_show('ckan.site_title', 'en'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, } return render_jinja2('emails/reset_password.txt', extra_vars)
def get_reg_link_body(user): extra_vars = { 'reg_link': get_reset_link(user), 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url') + '/' + h.lang(), 'user_name': user.name, 'tou_version': get_latest_legal_version('tou'), 'privacy_version': get_latest_legal_version('privacy') } return render_jinja2('emails/user_registration.txt', extra_vars)
def send_reset_link(user): create_reset_key(user) body = get_reset_link_body(user) extra_vars = {'site_title': config.get('ckan.site_title')} subject = render_jinja2('emails/reset_password_subject.txt', extra_vars) # Make sure we only use the first line subject = subject.split('\n')[0] mail_user(user, subject, body)
def compose_container_email_body(container, user, event): context = {} context['recipient'] = user.fullname or user.name context['site_title'] = config.get('ckan.site_title') context['site_url'] = config.get('ckan.site_url') context['container'] = container context['container_url'] = toolkit.url_for('data-container_read', id=container['name'], qualified=True) return render_jinja2('emails/container/%s.html' % event, context)
def _send_mail(user_ids, action_type, datarequest): for user_id in user_ids: try: user_data = model.User.get(user_id) extra_vars = { 'datarequest': datarequest, 'user': user_data, 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url') } subject = base.render_jinja2('emails/subjects/{0}.txt'.format(action_type), extra_vars) body = base.render_jinja2('emails/bodies/{0}.txt'.format(action_type), extra_vars) mailer.mail_user(user_data, subject, body) except Exception: logging.exception("Error sending notification to {0}".format(user_id))
def get_registration_body(user): """set up text for user registration email""" extra_vars = { 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.get('name'), 'display_name': user.get('display_name', user['name']) } # NOTE: This template is translated return render_jinja2('emails/registration.txt', extra_vars)
def _send_reset_link(user): create_reset_key(user) body = _get_reset_link_body(user) extra_vars = { 'site_title_dk': config_option_show('ckan.site_title', 'da_DK'), 'site_title_en': config_option_show('ckan.site_title', 'en') } subject = render_jinja2('emails/reset_password_subject.txt', extra_vars) subject = subject.split('\n')[0] mail_user(user, subject, body)
def _send_mail(user_ids, action_type, datarequest, job_title): for user_id in user_ids: try: user_data = model.User.get(user_id) extra_vars = { 'datarequest': datarequest, 'user': user_data, 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url') } subject = base.render_jinja2( 'emails/subjects/{0}.txt'.format(action_type), extra_vars) body = base.render_jinja2( 'emails/bodies/{0}.txt'.format(action_type), extra_vars) tk.enqueue_job(mailer.mail_user, [user_data, subject, body], title=job_title) except Exception: logging.exception( "Error sending notification to {0}".format(user_id))
def send_invite(user, group_dict=None, role=None): create_reset_key(user) body = get_invite_body(user, group_dict, role) extra_vars = {'site_title': config.get('ckan.site_title')} subject = render_jinja2('emails/invite_user_subject.txt', extra_vars) # Make sure we only use the first line subject = subject.split('\n')[0] mail_user(user, subject, body)
def _compose_email_body(user, dataset, role, event): dataset_link = toolkit.url_for('dataset_read', id=dataset.id, qualified=True) return render_jinja2('collaborators/emails/{0}_collaborator.html'.format(event), { 'user_name': user.fullname or user.name, 'role': role, 'site_title': toolkit.config.get('ckan.site_title'), 'site_url': toolkit.config.get('ckan.site_url'), 'dataset_title': dataset.title, 'dataset_link': dataset_link })
def _send_mail(user_ids, action_type, datarequest): for user_id in user_ids: try: user_data = model.User.get(user_id) extra_vars = { "datarequest": datarequest, "user": user_data, "site_title": config.get("ckan.site_title"), "site_url": config.get("ckan.site_url"), } subject = base.render_jinja2(f"emails/subjects/{action_type}.txt", extra_vars) body = base.render_jinja2(f"emails/bodies/{action_type}.txt", extra_vars) mailer.mail_user(user_data, subject, body) except Exception: logging.exception(f"Error sending notification to {user_id}")
def request_resource(context, data_dict): '''Sent Email with a resource request to the owner of a dataset.''' contact_email = data_dict.get('contact_email') owner_id = data_dict.get('creator_id') resource_id = data_dict.get('resource_id') resource_link = toolkit.url_for( action='resource_read', controller='package', id=data_dict.get('package_name'), resource_id=resource_id) package = package_show(context, {'id':data_dict.get('package_name')}) dashboard_restricted = config.get( 'ckan.site_url') + '/dashboard/restricted' # create request e-mail extra_vars = { 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_email': data_dict.get('email'), 'resource_name': data_dict.get('resource_name'), 'resource_link': config.get('ckan.site_url') + resource_link, 'package_name': data_dict.get('pkg_title'), 'message': data_dict.get('message', ''), 'dashboard_restricted': dashboard_restricted, 'admin_email_to': config.get('email_to', 'email_to_undefined')} body = render_jinja2( 'restricted/emails/restricted_access_unauth_request.txt', extra_vars) subject = \ _('Αίτημα πρόσβασης στο {0} από τον χρήστη {1}').format( data_dict.get('resource_name'), data_dict.get('email')) # send e-mail try: ckan.lib.mailer.mail_recipient(data_dict.get('email'), contact_email, subject, body) except ckan.lib.mailer.MailerException: success = False # return 'Error sending e-mail' request_dict = {'resource_id': resource_id, 'message': data_dict.get('message'), 'owner_id': owner_id, 'request_email': data_dict.get('email') } logic.save_restricted_request(request_dict) # return _('Mail sent!') data = {'resource_id': resource_id, 'maintainer_email': contact_email, 'user_email': data_dict.get('email'), 'package_title':data_dict.get('pkg_title'), 'message': data_dict.get('message')} return render( 'restricted/restricted_request_access_result.html', extra_vars={'data': data, 'pkg_dict': package, 'success': True})
def send_registration_email(user): """send new users an email at the time of registartion""" body = get_registration_body(user) extra_vars = {'site_title': config.get('ckan.site_title')} subject = render_jinja2('emails/registration_subject.txt', extra_vars) # Make sure we only use the first line subject = subject.split('\n')[0] recipient_name = user.get('display_name', user['name']) recipient_email = user.get('email') mailer.mail_recipient(recipient_name, recipient_email, subject, body)
def send_reset_link(user): create_reset_key(user) body = get_reset_link_body(user) extra_vars = { 'site_title': config.get('ckan.site_title') } subject = render_jinja2('emails/reset_password_subject.txt', extra_vars) # Make sure we only use the first line subject = subject.split('\n')[0] mail_user(user, subject, body)
def send_invite(user, group_dict=None, role=None): create_reset_key(user) body = get_invite_body(user, group_dict, role) extra_vars = { 'site_title': config.get('ckan.site_title') } subject = render_jinja2('emails/invite_user_subject.txt', extra_vars) # Make sure we only use the first line subject = subject.split('\n')[0] mail_user(user, subject, body)
def prepare_summary_mail(context, source_id, status, template): extra_vars = get_mail_extra_vars(context, source_id, status) body = render_jinja2(template, extra_vars) if str(status['last_job']['stats'].get('errored', 0)) == '0': subject = '{} - Harvesting Job Successful - Summary Notification'\ .format(config.get('ckan.site_title')) else: subject = '{} - Harvesting Job with Errors - Summary Notification'\ .format(config.get('ckan.site_title')) return subject, body
def request_activation(user): """ Request activation for user :param user: the user for whom an activation link should be requested :type user: dict """ create_activation_key(user) site_title = config.get('ckan.site_title') site_url = config.get('ckan.site_url') body = render_jinja2( 'emails/confirm_user_email.txt', { 'activation_link': get_activation_link(user), 'site_url': site_url, 'site_title': site_title, 'user_name': user.name }) subject = render_jinja2('emails/confirm_user_subject.txt', {'site_title': site_title}) subject = subject.split('\n')[0] mailer.mail_recipient(user.name, user.email, subject, body, headers={})
def send_email_dataset_notification(datasets_by_contacts, action_type): for contact in datasets_by_contacts: try: log.info("Preparing email data for {0} notification to {1}".format( action_type, contact.get('email'))) datasets = [] for contact_dataset in contact.get('datasets', {}): date = datetime.strptime( contact_dataset.get('next_update_due'), '%Y-%m-%d') datasets.append({ 'url': h.url_for('dataset_read', id=contact_dataset.get('name'), _external=True), 'next_due_date': date.strftime('%d/%m/%Y') }) extra_vars = {'datasets': datasets} subject = render_jinja2( 'emails/subjects/{0}.txt'.format(action_type), extra_vars) body = render_jinja2('emails/bodies/{0}.txt'.format(action_type), extra_vars) site_title = 'Data | Queensland Government' site_url = config.get('ckan.site_url') enqueue_job(mailer._mail_recipient, [ contact.get('email'), contact.get('email'), site_title, site_url, subject, body ], title=action_type) log.info( "Added email to job worker default queue for {0} notification to {1}" .format(action_type, contact.get('email'))) except Exception as e: log.error("Error sending {0} notification to {1}".format( action_type, contact.get('email'))) log.error(str(e))
def send_notification_email(template, to=None, extra_vars=[]): """ Compile an alert email notification to be sent via the job worker queue :param template: string :param to: string :param extra_vars: list :return: """ from ckan.lib.base import render_jinja2 from ckan.plugins import toolkit if not to: to = config.get('ckanext.harvest_tools.email_to', config.get('email_to')) subject = config.get('ckan.site_title') + ' - ' + render_jinja2( 'emails/subject/{0}.txt'.format(template), extra_vars) body = render_jinja2('emails/body/{0}.txt'.format(template), extra_vars) toolkit.enqueue_job(send_email, [to, subject, body], title=u'Harvest tools email alert')
def _build_footer_content(extra_vars): custom_path = config.get('ckanext.security.brute_force_footer_path') if (custom_path and os.path.exists(custom_path)): log.warning( 'Overriding brute force lockout email footer with {}'.format( custom_path)) with open(custom_path, 'r') as footer_file: footer_content = footer_file.read() env = config['pylons.app_globals'].jinja_env template = env.from_string(footer_content) return '\n\n' + template.render(**extra_vars) else: footer_path = 'security/emails/lockout_footer.txt' return '\n\n' + render_jinja2(footer_path, extra_vars)
def test_reset_password_custom_body(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = {'reset_link': mailer.get_reset_link(user_obj)} expected = render_jinja2('emails/reset_password.txt', extra_vars) body = self.get_email_body(msg[3]) assert_equal(expected, body) assert_in('**test**', body)
def _compose_email_body(data_dict, user, event='request', feedback=None): ''' Formats an email body ''' pkg_link = toolkit.url_for('dataset_read', id=data_dict['name'], qualified=True) return render_jinja2('emails/package_publish_{0}.html'.format(event), { 'admin_name': user.fullname or user.name, 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'package_title': data_dict.get('title'), 'package_description': data_dict.get('notes', ''), 'package_url': pkg_link, 'publisher_name': data_dict.get('contact_name'), 'feedback': feedback })
def test_reset_password_custom_body(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = { 'reset_link': mailer.get_reset_link(user_obj) } expected = render_jinja2('emails/reset_password.txt', extra_vars) body = self.get_email_body(msg[3]) assert_equal(expected, body) assert_in('**test**', body)
def get_invite_body(user, group_dict=None, role=None): if group_dict: group_type = (_('organization') if group_dict['is_organization'] else _('group')) extra_vars = { 'reset_link': get_reset_link(user), 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, } if role: extra_vars['role_name'] = h.roles_translated().get(role, _(role)) if group_dict: extra_vars['group_type'] = group_type extra_vars['group_title'] = group_dict.get('title') # NOTE: This template is translated return render_jinja2('emails/invite_user.txt', extra_vars)
def test_invite_user_custom_body(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_invite(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = { 'reset_link': mailer.get_reset_link(user_obj), 'user_name': user['name'], 'site_title': config.get('ckan.site_title'), } expected = render_jinja2('emails/invite_user.txt', extra_vars) body = self.get_email_body(msg[3]) assert_equal(expected, body) assert_in('**test**', body)
def test_invite_user_custom_subject(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_invite(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = { 'site_title': config.get('ckan.site_title'), } expected = render_jinja2('emails/invite_user_subject.txt', extra_vars) expected = expected.split('\n')[0] subject = self.get_email_subject(msg[3]) assert_equal(expected, subject) assert_in('**test**', subject)
def send_feedback(context): ''' Sends a feedback message to the recipients in the feedback.recipients config list. :param dict context: A dictionary containing the name, email and feedback from a user. ''' body = render_jinja2('emails/feedback.txt', context) subject = 'IOOS Catalog Feedback' recipients = config.get('feedback.recipients') if not recipients: log.info("No recipients specified, feedback email not sent") return recipients = recipients.split(' ') mail = Mail() msg = Message(subject, sender=config.get('smtp.mail_from'), recipients=recipients) msg.extra_headers = {"referring_site": context['referrer']} msg.body = body mail.send(msg)
def _get_issue_email_body(issue, issue_subject, user_obj): extra_vars = _get_issue_vars(issue, issue_subject, user_obj) # Would use p.toolkit.render, but it mucks with response and other things, # which is unnecessary, and p.toolkit.render_text uses genshi... return render_jinja2('issues/email/new_issue.html', extra_vars=extra_vars)
def _get_comment_email_body(comment, issue_subject, user_obj, recipient): extra_vars = _get_issue_vars(comment.issue, issue_subject, user_obj, recipient) extra_vars['comment'] = comment return render_jinja2('issues/email/new_comment.html', extra_vars=extra_vars)
def user_invite(context, data_dict): '''Invite a new user. You must be authorized to create group members. :param email: the email of the user to be invited to the group :type email: string :param group_id: the id or name of the group :type group_id: string :param role: role of the user in the group. One of ``member``, ``editor``, or ``admin`` :type role: string :returns: the newly created yser :rtype: dictionary ''' toolkit.check_access('user_invite', context, data_dict) schema = context.get('schema', logic.schema.default_user_invite_schema()) data, errors = toolkit.navl_validate(data_dict, schema, context) if errors: raise toolkit.ValidationError(errors) model = context['model'] group = model.Group.get(data['group_id']) if not group: raise toolkit.ObjectNotFound() name = logic.action.create._get_random_username_from_email(data['email']) password = str(random.SystemRandom().random()) data['name'] = name data['password'] = password data['state'] = model.State.PENDING user_dict = toolkit.get_action('user_create')(context, data) user = model.User.get(user_dict['id']) member_dict = { 'username': user.id, 'id': data['group_id'], 'role': data['role'] } toolkit.get_action('group_member_create')(context, member_dict) if group.is_organization: group_dict = toolkit.get_action('organization_show')(context, {'id': data['group_id']}) else: group_dict = toolkit.get_action('group_show')(context, {'id': data['group_id']}) mailer.create_reset_key(user) # Email body group_type = (toolkit._('organization') if group_dict['is_organization'] else toolkit._('group')) role = data['role'] extra_vars = { 'reset_link': mailer.get_reset_link(user), 'site_title': config.get('ckan.site_title'), 'site_url': config.get('ckan.site_url'), 'user_name': user.name, 'role_name': authz.roles_trans().get(role, toolkit._(role)), 'group_type': group_type, 'group_title': group_dict.get('title'), } # NOTE: This template is translated body = render_jinja2('emails/invite_user.txt', extra_vars) subject = toolkit._('Invite for {site_title}').format( site_title=config.get('ckan.site_title')) mailer.mail_user(user, subject, body) return model_dictize.user_dictize(user, context)