def request_password_reset(user, profile, request): profile.password_reset_key = sha1(str(random.random())).hexdigest() profile.password_reset_time = datetime.datetime.now() context = find_site(profile) reset_url = resource_url(context, request, "reset_confirm.html", query=dict(key=profile.password_reset_key)) # send email mail = Message() system_name = get_setting(context, 'system_name', 'KARL') admin_email = get_setting(context, 'admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "%s Password Reset Request" % system_name body = render( "templates/email_reset_password.pt", dict(login=user['login'], reset_url=reset_url, system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail)
def bounce_message_throttled(self, message): mailer = getUtility(IMailDelivery) from_email = get_setting(self.root, 'postoffice.bounce_from_email') if from_email is None: from_email = get_setting(self.root, 'admin_email') bounce_message = Message() bounce_message['From'] = from_email bounce_message['To'] = message['From'] bounce_message['Subject'] = 'Your submission to Karl has bounced.' bounce_message.set_type('text/html') bounce_message.set_payload( render( 'templates/bounce_email_throttled.pt', dict( subject=message.get('Subject'), system_name=get_setting(self.root, 'system_name', 'KARL'), admin_email=get_setting(self.root, 'admin_email'), ), ).encode('UTF-8'), 'UTF-8') self.queue.bounce(message, wrap_send(mailer.bounce), from_email, bounce_message=bounce_message)
def request_password_reset(user, profile, request): profile.password_reset_key = sha1( str(random.random())).hexdigest() profile.password_reset_time = datetime.datetime.now() context = find_site(profile) reset_url = resource_url( context, request, "reset_confirm.html", query=dict(key=profile.password_reset_key)) # send email mail = Message() system_name = get_setting(context, 'system_name', 'KARL') admin_email = get_setting(context, 'admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "%s Password Reset Request" % system_name body = render( "templates/email_reset_password.pt", dict(login=user['login'], reset_url=reset_url, system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail)
def test_bounce_custom_message(self): import base64 from repoze.postoffice.message import Message class DummySend(object): def __init__(self): self.sent = [] def __call__(self, fromaddr, toaddrs, message): self.sent.append((fromaddr, toaddrs, message)) bounced = Message() bounced['To'] = 'Submissions <*****@*****.**>' bounced['From'] = 'Chris Rossi <*****@*****.**>' queue = self._make_one() send = DummySend() bounce_message = Message() bounce_message.set_payload('TEST') queue.bounce(bounced, send, 'Bouncer <*****@*****.**>', bounce_message=bounce_message) self.assertEqual(len(send.sent), 1) fromaddr, toaddrs, message = send.sent[0] self.assertEqual(fromaddr, 'Bouncer <*****@*****.**>') self.assertEqual(toaddrs, ['Chris Rossi <*****@*****.**>']) self.assertEqual(message.get_payload(), 'TEST') self.assertEqual(message['X-Postoffice'], 'Bounced')
def __init__(self, context, profile, request): from repoze.postoffice.message import Message message = Message() message["From"] = "Karl <*****@*****.**>" message["To"] = "Andy Ex <*****@*****.**>" message["Subject"] = "Testing" message.set_payload("Test email", "UTF-8") self.message = message
def __call__(self): context, request = self.context, self.request api = AdminTemplateAPI(context, request, "Admin UI: Send Email") admin_email = get_setting(context, "admin_email") system_name = get_setting(context, "system_name") profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ("self", "%s <%s>" % (admin.title, admin.email)), ("admin", "%s Administrator <%s>" % (system_name, admin_email)), ] if "send_email" in request.params: mailer = getUtility(IMailDelivery) group = request.params["to_group"] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, "security_state", None) == "inactive": continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params["from_email"] == "self": message["From"] = from_emails[0][1] message_from = admin.email else: message["From"] = from_emails[1][1] message_from = admin_email message["To"] = "%s <%s>" % (profile.title, profile.email) message["Subject"] = request.params["subject"] body = u"<html><body>%s</body></html>" % (request.params["text"]) message.set_payload(body.encode("UTF-8"), "UTF-8") message.set_type("text/html") mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = model_url(context, request, "admin.html", query=dict(status_message=status_message)) else: redirect_to = model_url( find_communities(context), request, "all_communities.html", query=dict(status_message=status_message), ) return HTTPFound(location=redirect_to) return dict(api=api, menu=_menu_macro(), to_groups=self.to_groups, from_emails=from_emails)
def login_user(request, profile, login, userid): site = request.root admin_only = asbool(request.registry.settings.get('admin_only', '')) admins = aslist(request.registry.settings.get('admin_userids', '')) if admin_only and userid not in admins: return site_down_view(site, request) settings = request.registry.settings device_cookie_name = settings.get('device_cookie', 'CxR61DzG3P0Ae1') max_age = settings.get('login_cookie_max_age', '36000') max_age = int(max_age) response = remember_login(site, request, userid, max_age) # have we logged in from this computer & browser before? active_device = request.cookies.get(device_cookie_name, None) if active_device is None and profile is not None: # if not, send email reset_url = request.resource_url(profile, 'change_password.html') mail = Message() system_name = settings.get('system_name', 'KARL') admin_email = settings.get('admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "New %s Login Notification" % system_name user_agent = user_agents.parse(request.user_agent) body = render( "templates/email_suspicious_login.pt", dict(login=login, reset_url=reset_url, device_info=user_agent), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) # set cookie to avoid further notifications for this device active_device = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(16)) response.set_cookie(device_cookie_name, active_device, max_age=315360000) if profile is not None: profile.active_device = active_device request.session['logout_reason'] = None return response
def bounce(self, message, send, bounce_from_addr, bounce_reason=None, bounce_message=None): """ Sends a bounce message to the sender of 'message'. The mechanism for mail delivery is passed in via the 'send' argument. 'bounce_from_addr' specifices the email address the bounce message should be from. If 'bounce_reason' is specified, a bounce message will be generated using the given bounce reason, a string. If 'bounce_message' is specified, the given bounce message is sent, rather than generating a new one. 'bounce_message' should be an instance of `email.message.Message`. If neither 'bounce_reason' or 'bounce_message' is specified, a generic bounce message will be sent. Specifying both is an error. The 'send' argument is a callable with the following signature:: def send(fromaddr, toaddrs, message): "Send an email message." Implementations can be found in `repoze.sendmail`. See `repoze.sendmail.delivery.QueuedMailDelivery.send` or `repoze.sendmail.delivery.DirectMailDelivery.send`. """ if bounce_reason is not None and bounce_message is not None: raise ValueError( "May only specify one of either 'bounce_reason' or " "'bounce_message'." ) toaddrs = [message['From'],] if bounce_message is None: if bounce_reason is None: bounce_reason = u'Email message is invalid.' if 'Date' in message: date = message['Date'] else: date = datetime.datetime.now().ctime() bounce_to = message['To'] subject = 'Your message to %s has bounced.' % bounce_to bounce_message = Message() bounce_message['Subject'] = subject bounce_message['From'] = bounce_from_addr bounce_message['To'] = message['From'] body = _default_bounce_body % (date, bounce_to, bounce_reason) bounce_message.set_payload(body.encode('UTF-8'), 'UTF-8') bounce_message['X-Postoffice'] = 'Bounced' send(bounce_from_addr, toaddrs, bounce_message)
def quarantine(self, message, error, send=None, notice_from=None): """ Adds a message and corresponding exception info to the 'quarantine'. If an application attempts to process a message and encounters an exception it may choose to place the message in quarantine such that the message and corresponding exception info can be examined by developers and/or site administrators. Once the problem causing the exception has been addressed, the messages can be requeued and tried again. The 'send' argument is optional. If specified it will be used to notify the sender of the message that their message has been quarantined. The 'send' argument is a callable with the following signature:: def send(fromaddr, toaddrs, message): "Send an email message." Implementations can be found in `repoze.sendmail`. See `repoze.sendmail.delivery.QueuedMailDelivery.send` or `repoze.sendmail.delivery.DirectMailDelivery.send`. If 'send' is specificed, 'notice_from' must also be specified, where 'notice_from' is the apparent from email address of the notice sent to the sender. """ if send is not None and notice_from is None: raise ValueError("Must specify 'notice_from' in order to send " "notice.") quarantine = self._quarantine id = _new_id(quarantine) message['X-Postoffice-Id'] = str(id) quarantine[id] = (_QueuedMessage(message), error) if send is not None: notice = Message() notice['Subject'] = ('An error has occurred while processing your ' 'email to %s' % message['To']) notice['From'] = notice_from notice['To'] = message['From'] if 'Date' in message: date = message['Date'] else: date = datetime.datetime.now().ctime() notice['X-Postoffice'] = 'Bounced' body = _quarantine_notice_body % (date, message['To']) notice.set_payload(body.encode('UTF-8'), 'UTF-8') send(notice_from, [message['From'],], notice)
def send_reminders(env, start, end): print print "Sending reminders for passwords expiring between %s and %s" % ( start.strftime('%Y-%m-%d %H:%M'), end.strftime('%Y-%m-%d %H:%M')) print root = env['root'] registry = env['registry'] request = env['request'] system_name = get_setting(root, 'system_name', 'KARL') admin_email = get_setting(root, 'admin_email') site_url = get_setting(root, 'script_app_url') reset_url = "%s/reset_request.html" % site_url profiles = find_profiles(root) for profile in profiles.values(): auth_method = profile.auth_method.lower() if auth_method != 'password': continue expiration = profile.password_expiration_date if expiration > start and expiration < end: mail = Message() mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "%s Password Expiration Reminder" % system_name body = render( "templates/password_expiration_reminder.pt", dict(login=profile.__name__, reset_url=reset_url, expiration_date=start.strftime('%Y-%m-%d'), system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) print "Sent reminder to user '%s'" % profile.title.encode("UTF-8") print
def send_reminders(env, start, end): print print "Sending reminders for passwords expiring between %s and %s" % ( start.strftime('%Y-%m-%d %H:%M'), end.strftime('%Y-%m-%d %H:%M')) print root = env['root'] registry = env['registry'] request = env['request'] system_name = get_setting(root, 'system_name', 'KARL') admin_email = get_setting(root, 'admin_email') site_url = get_setting(root, 'script_app_url') reset_url = "%s/reset_request.html" % site_url profiles = find_profiles(root) for profile in profiles.values(): expiration = profile.password_expiration_date if expiration > start and expiration < end: mail = Message() mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "%s Password Expiration Reminder" % system_name body = render( "templates/password_expiration_reminder.pt", dict(login=profile.__name__, reset_url=reset_url, expiration_date=start.strftime('%Y-%m-%d'), system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) print "Sent reminder to user '%s'" % profile.title print
def bounce_message_throttled(self, message): mailer = getUtility(IMailDelivery) from_email = get_setting(self.root, 'postoffice.bounce_from_email') if from_email is None: from_email = get_setting(self.root, 'admin_email') bounce_message = Message() bounce_message['From'] = from_email bounce_message['To'] = message['From'] bounce_message['Subject'] = 'Your submission to Karl has bounced.' bounce_message.set_type('text/html') bounce_message.set_payload(render_template( 'templates/bounce_email_throttled.pt', subject=message.get('Subject'), system_name=get_setting(self.root, 'system_name', 'KARL'), admin_email=get_setting(self.root, 'admin_email'), ).encode('UTF-8'), 'UTF-8') self.queue.bounce( message, wrap_send(mailer.send), from_email, bounce_message=bounce_message )
def login_view(context, request): settings = request.registry.settings came_from = request.session.get('came_from', request.url) if 'login.html' in came_from or 'logout.html' in came_from: came_from = request.application_url request.session['came_from'] = came_from submitted = request.params.get('form.submitted', None) if submitted: # identify login = request.POST.get('login') password = request.POST.get('password') if login is None or password is None: return HTTPFound(location='%s/login.html' % request.application_url) max_retries = request.registry.settings.get('max_login_retries', 8) left = context.login_tries.get(login, max_retries) left = left - 1 users = find_users(context) user = users.get_by_login(login) profiles = find_profiles(context) profile = profiles.get(user['id']) if user else None # max tries almost reached, send email warning if left == 2 and profile is not None: reset_url = request.resource_url(profile, 'change_password.html') mail = Message() system_name = settings.get('system_name', 'KARL') admin_email = settings.get('admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "Too many failed logins to %s" % system_name body = render( "templates/email_locked_warning.pt", dict(login=login, reset_url=reset_url, system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) # if max tries reached, send password reset and lock if left < 1: log_failed_login(request, login) # only send email the first time if profile is not None and left == 0: context.login_tries[login] = -1 request_password_reset(user, profile, request) page_title = 'Access to %s is locked' % settings.get( 'system_name', 'KARL') api = TemplateAPI(context, request, page_title) response = render_to_response('templates/locked.pt', dict( api=api, app_url=request.application_url), request=request) return response # authenticate reason = 'Bad username or password.' try: userid = _authenticate(context, login, password) except TypeError: userid = None # if not successful, try again if not userid: log_failed_login(request, login) reason = "%s You have %d attempts left." % (reason, left) context.login_tries[login] = left redirect = request.resource_url(request.root, 'login.html', query={'reason': reason}) return HTTPFound(location=redirect) # all ok, remember context.login_tries[login] = max_retries return login_user(request, profile, login, userid) page_title = 'Login to %s' % settings.get( 'system_name', 'KARL') # Per #366377, don't say what screen api = TemplateAPI(context, request, page_title) status_message = request.params.get('reason', None) if status_message != '@@@one-session-only@@@': api.status_message = status_message status_message = None response = render_to_response('templates/login.pt', dict(api=api, status_message=status_message, app_url=request.application_url), request=request) forget_headers = forget(request) response.headers.extend(forget_headers) return response
def make_non_staff(profile, inform_moderators=True): """ When a user is removed from the KarlStaff role, their community memberships are removed. Moderators of their communities are optionally informed via email. """ id = profile.__name__ moderators = {} users = find_users(profile) profile.categories = {} for group in list(users.get_by_id(id)['groups']): if group.startswith('group.community'): # Remove user from group users.remove_user_from_group(id, group) if not inform_moderators: continue # Keep track of moderators we need to email making sure # each moderator is emailed only once and each community is # only mentioned once in any given email. community_name = group.split(':')[1] moderators_group = ('group.community:%s:moderators' % community_name) for moderator in users.users_in_group(moderators_group): if moderator == id: continue # Really should only come up in unittests if moderator not in moderators: moderators[moderator] = set() moderators[moderator].add(community_name) if not inform_moderators: return communities = find_communities(profile) profiles = profile.__parent__ mailer = getUtility(IMailDelivery) for moderator_id in moderators: moderator = profiles[moderator_id] msg = Message() msg['From'] = get_setting(profile, 'admin_email') msg['To'] = '%s <%s>' % (moderator.title, moderator.email) msg['Subject'] = 'Notice that %s is now former staff' % profile.title former_communities = sorted( [communities[c] for c in moderators[moderator_id]], key=lambda x: x.title) app_url = get_setting(profile, 'offline_app_url') communities_info = [ dict(title=c.title, unremove_url='%s%s?user_id=%s' % (app_url, model_path(c, 'members', 'add_existing.html'), id)) for c in former_communities ] body = render( 'templates/email_notify_former_staff.pt', dict(name=profile.title, communities=communities_info), ) if isinstance(body, unicode): body = body.encode('UTF-8') msg.set_payload(body, 'UTF-8') msg.set_type('text/html') mailer.send([msg['To']], msg)
def __call__(self): context, request = self.context, self.request api = AdminTemplateAPI(context, request, 'Admin UI: Send Email') admin_email = get_setting(context, 'admin_email') system_name = get_setting(context, 'system_name') profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ('self', '%s <%s>' % (admin.title, admin.email)), ('admin', '%s Administrator <%s>' % (system_name, admin_email)), ] if 'send_email' in request.params: mailer = getUtility(IMailDelivery) group = request.params['to_group'] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, 'security_state', None) == 'inactive': continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params['from_email'] == 'self': message['From'] = from_emails[0][1] message_from = admin.email else: message['From'] = from_emails[1][1] message_from = admin_email message['To'] = '%s <%s>' % (profile.title, profile.email) message['Subject'] = request.params['subject'] body = u'<html><body>%s</body></html>' % ( request.params['text']) message.set_payload(body.encode('UTF-8'), 'UTF-8') message.set_type('text/html') mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = resource_url( context, request, 'admin.html', query=dict(status_message=status_message)) else: redirect_to = resource_url( find_communities(context), request, 'all_communities.html', query=dict(status_message=status_message)) return HTTPFound(location=redirect_to) return dict( api=api, menu=_menu_macro(), to_groups=self.to_groups, from_emails=from_emails, )
def join_community_view(context, request): """ User sends an email to community moderator(s) asking to join the community. Email contains a link to "add_existing" view, in members, that a moderator can use to add member to the community. """ assert ICommunity.providedBy(context) # Get logged in user profiles = find_profiles(context) user = authenticated_userid(request) profile = profiles[user] # Handle form submission if "form.submitted" in request.POST: message = request.POST.get("message", "") moderators = [profiles[id] for id in context.moderator_names] mail = Message() mail["From"] = "%s <%s>" % (profile.title, profile.email) mail["To"] = ",".join( ["%s <%s>" % (p.title, p.email) for p in moderators]) mail["Subject"] = "Request to join %s community" % context.title body_template = get_renderer( "templates/email_join_community.pt").implementation() profile_url = resource_url(profile, request) accept_url = resource_url(context, request, "members", "add_existing.html", query={"user_id": user}) body = body_template(message=message, community_title=context.title, person_name=profile.title, profile_url=profile_url, accept_url=accept_url) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [p.email for p in moderators] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) status_message = "Your request has been sent to the moderators." location = resource_url(context, request, query={"status_message": status_message}) return HTTPFound(location=location) # Show form page_title = "Join " + context.title api = TemplateAPI(context, request, page_title) return dict(api=api, profile=profile, community=context, post_url=resource_url(context, request, "join.html"), formfields=api.formfields)
def login_view(context, request): settings = request.registry.settings came_from = request.session.get('came_from', request.url) came_from = _fixup_came_from(request, came_from) request.session['came_from'] = came_from submitted = request.params.get('form.submitted', None) if submitted: # identify login = request.POST.get('login') password = request.POST.get('password') if login is None or password is None: return HTTPFound(location='%s/login.html' % request.application_url) max_age = request.registry.settings.get('login_cookie_max_age', '36000') max_age = int(max_age) max_retries = request.registry.settings.get('max_login_retries', 8) left = context.login_tries.get(login, max_retries) left = left - 1 profiles = find_profiles(context) profile = profiles.get(login) # max tries almost reached, send email warning if left == 2 and profile is not None: reset_url = request.resource_url(profile, 'change_password.html') mail = Message() system_name = settings.get('system_name', 'KARL') admin_email = settings.get('admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "Too many failed logins to %s" % system_name body = render( "templates/email_locked_warning.pt", dict(login=login, reset_url=reset_url, system_name=system_name), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) # if max tries reached, send password reset and lock if left < 1: # only send email the first time if profile is not None and left == 0: context.login_tries[login] = -1 users = find_users(context) user = users.get_by_id(login) request_password_reset(user, profile, request) page_title = 'Access to %s is locked' % settings.get('system_name', 'KARL') api = TemplateAPI(context, request, page_title) response = render_to_response( 'templates/locked.pt', dict( api=api, app_url=request.application_url), request=request) return response # authenticate reason = 'Bad username or password.' userid = _authenticate(context, login, password) # if not successful, try again if not userid: reason = "%s You have %d attempts left." % (reason, left) context.login_tries[login] = left redirect = request.resource_url( request.root, 'login.html', query={'reason': reason}) return HTTPFound(location=redirect) device_cookie_name = request.registry.settings.get('device_cookie', 'CxR61DzG3P0Ae1') # all ok, remember admin_only = asbool(request.registry.settings.get('admin_only', '')) admins = aslist(request.registry.settings.get('admin_userids', '')) if not admin_only or userid in admins: context.login_tries[login] = max_retries response = remember_login(context, request, userid, max_age) # have we logged in from this computer & browser before? active_device = request.cookies.get(device_cookie_name, None) if active_device is None: # if not, send email reset_url = request.resource_url(profile, 'change_password.html') mail = Message() system_name = settings.get('system_name', 'KARL') admin_email = settings.get('admin_email') mail["From"] = "%s Administrator <%s>" % (system_name, admin_email) mail["To"] = "%s <%s>" % (profile.title, profile.email) mail["Subject"] = "New %s Login Notification" % system_name # TODO Carlos needs to come back and get this working # https://bugs.launchpad.net/karl4/+bug/1648569/comments/10 # user_agent = user_agents.parse(request.user_agent) body = render( "templates/email_suspicious_login.pt", dict(login=login, reset_url=reset_url, device_info=request.user_agent), request=request, ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [profile.email] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) # set cookie to avoid further notifications for this device active_device = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(16)) response.set_cookie(device_cookie_name, active_device, max_age=315360000) profile.active_device = active_device request.session['logout_reason'] = None return response else: return site_down_view(context, request) page_title = 'Login to %s' % settings.get('system_name', 'KARL') # Per #366377, don't say what screen api = TemplateAPI(context, request, page_title) status_message = request.params.get('reason', None) if status_message != '@@@one-session-only@@@': api.status_message = status_message status_message = None response = render_to_response( 'templates/login.pt', dict( api=api, status_message = status_message, app_url=request.application_url), request=request) forget_headers = forget(request) response.headers.extend(forget_headers) return response
def __call__(self): context, request = self.context, self.request request.layout_manager.use_layout('admin') api = AdminTemplateAPI(context, request, 'Admin UI: Send Email') admin_email = get_setting(context, 'admin_email') system_name = get_setting(context, 'system_name') profiles = find_profiles(context) admin = profiles[authenticated_userid(request)] from_emails = [ ('self', '%s <%s>' % (admin.title, admin.email)), ('admin', '%s Administrator <%s>' % (system_name, admin_email)), ] if 'send_email' in request.params or 'submit' in request.params: mailer = getUtility(IMailDelivery) group = request.params['to_group'] users = find_users(context) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile]) n = 0 for docid in docids: profile = resolver(docid) if getattr(profile, 'security_state', None) == 'inactive': continue userid = profile.__name__ if group and not users.member_of_group(userid, group): continue message = Message() if request.params['from_email'] == 'self': message['From'] = from_emails[0][1] message_from = admin.email else: message['From'] = from_emails[1][1] message_from = admin_email message['To'] = '%s <%s>' % (profile.title, profile.email) message['Subject'] = request.params['subject'] body = u'<html><body>%s</body></html>' % ( request.params['text'] ) message.set_payload(body.encode('UTF-8'), 'UTF-8') message.set_type('text/html') mailer.send([profile.email], message) n += 1 status_message = "Sent message to %d users." % n if has_permission(ADMINISTER, context, request): redirect_to = resource_url( context, request, 'admin.html', query=dict(status_message=status_message)) else: redirect_to = resource_url( find_communities(context), request, 'all_communities.html', query=dict(status_message=status_message)) return HTTPFound(location=redirect_to) return dict( api=api, menu=_menu_macro(), to_groups = self.to_groups, from_emails=from_emails, )
def join_community_view(context, request): """ User sends an email to community moderator(s) asking to join the community. Email contains a link to "add_existing" view, in members, that a moderator can use to add member to the community. """ assert ICommunity.providedBy(context) # Get logged in user profiles = find_profiles(context) user = authenticated_userid(request) profile = profiles[user] # Handle form submission if "form.submitted" in request.POST: message = request.POST.get("message", "") moderators = [profiles[id] for id in context.moderator_names] mail = Message() mail["From"] = "%s <%s>" % (profile.title, profile.email) mail["To"] = ",".join( ["%s <%s>" % (p.title, p.email) for p in moderators] ) mail["Subject"] = "Request to join %s community" % context.title body_template = get_renderer( "templates/email_join_community.pt").implementation() profile_url = resource_url(profile, request) accept_url=resource_url(context, request, "members", "add_existing.html", query={"user_id": user}) body = body_template( message=message, community_title=context.title, person_name=profile.title, profile_url=profile_url, accept_url=accept_url ) if isinstance(body, unicode): body = body.encode("UTF-8") mail.set_payload(body, "UTF-8") mail.set_type("text/html") recipients = [p.email for p in moderators] mailer = getUtility(IMailDelivery) mailer.send(recipients, mail) status_message = "Your request has been sent to the moderators." location = resource_url(context, request, query={"status_message": status_message}) return HTTPFound(location=location) # Show form page_title = "Join " + context.title api = TemplateAPI(context, request, page_title) return dict(api=api, profile=profile, community=context, post_url=resource_url(context, request, "join.html"), formfields=api.formfields)