def send_system_message(user, subject, body, system_user=None, distinguished='admin', repliable=False, add_to_sent=True, author=None, signed=False): from v1.lib.db import queries if system_user is None: system_user = Account.system_user() if not system_user: g.log.warning("Can't send system message " "- invalid system_user or g.system_user setting") return if not author: author = system_user item, inbox_rel = Message._new(author, user, subject, body, ip='0.0.0.0') item.distinguished = distinguished item.repliable = repliable item.display_author = system_user._id item.signed = signed item._commit() try: queries.new_message(item, inbox_rel, add_to_sent=add_to_sent) except MemcachedError: raise MessageError('verbify_inbox')
def POST_zendeskreply(self): request_body = request.POST recipient = request_body["recipient"] sender_email = request_body["sender"] from_ = request_body["from"] subject = request_body["subject"] body_plain = request_body["body-plain"] stripped_text = request_body["stripped-text"] timestamp = request_body["timestamp"] token = request_body["token"] signature = request_body["signature"] email_id = request_body["Message-Id"] if not validate_mailgun_webhook(timestamp, token, signature): # per Mailgun docs send a 406 so the message won't be retried abort(406, "invalid signature") message_id36 = parse_and_validate_reply_to_address(recipient) if not message_id36: # per Mailgun docs send a 406 so the message won't be retried abort(406, "invalid message") parent = Message._byID36(message_id36, data=True) to = Account._byID(parent.author_id, data=True) sr = Subverbify._byID(parent.sr_id, data=True) if stripped_text.startswith(ZENDESK_PREFIX): stripped_text = stripped_text[len(ZENDESK_PREFIX):].lstrip() if len(stripped_text) > 10000: body = stripped_text[:10000] + "\n\n--snipped--" else: body = stripped_text try: markdown_souptest(body) except SoupError: g.log.warning("bad markdown in modmail email: %s", body) abort(406, "invalid body") if parent.get_muted_user_in_conversation(): queue_blocked_muted_email(sr, parent, sender_email, email_id) return # keep the subject consistent message_subject = parent.subject if not message_subject.startswith("re: "): message_subject = "re: " + message_subject # from_ is like '"NAME (GROUP)" <*****@*****.**>' match = re.search("\"(?P<name>\w+) [\w ()]*\"", from_) from_sr = True author = Account.system_user() if match and match.group( "name") in g.live_config['modmail_account_map']: zendesk_name = match.group("name") moderator_name = g.live_config['modmail_account_map'][zendesk_name] moderator = Account._by_name(moderator_name) if sr.is_moderator_with_perms(moderator, "mail"): author = moderator from_sr = False message, inbox_rel = Message._new( author=author, to=to, subject=message_subject, body=body, ip='0.0.0.0', parent=parent, sr=sr, from_sr=from_sr, can_send_email=False, sent_via_email=True, email_id=email_id, ) message._commit() queries.new_message(message, inbox_rel) g.stats.simple_event("mailgun.incoming.success") g.stats.simple_event("modmail_email.incoming_email")
def POST_authorize(self, authorize, client, redirect_uri, scope, state, duration, response_type): """Endpoint for OAuth2 authorization.""" self._check_employee_grants(client, scope) self._check_redirect_uri(client, redirect_uri) self._check_response_type_and_scope(response_type, scope) self._check_client_type_and_duration(response_type, client, duration) if c.errors: return self._error_response(state, redirect_uri, as_fragment=(response_type == "token")) if response_type == "code": code = OAuth2AuthorizationCode._new(client._id, redirect_uri, c.user._id36, scope, duration == "permanent") resp = {"code": code._id, "state": state} final_redirect = _update_redirect_uri(redirect_uri, resp) g.stats.simple_event( 'oauth2.POST_authorize.authorization_code_create') elif response_type == "token": device_id = get_device_id(client) token = OAuth2AccessToken._new( client_id=client._id, user_id=c.user._id36, scope=scope, device_id=device_id, ) resp = OAuth2AccessController._make_new_token_response(token) resp["state"] = state final_redirect = _update_redirect_uri(redirect_uri, resp, as_fragment=True) g.stats.simple_event('oauth2.POST_authorize.access_token_create') # If this is the first time the user is logging in with an official # mobile app, sild them if (g.live_config.get('mobile_sild_first_login') and not c.user.has_used_mobile_app and client._id in g.mobile_auth_sild_clients): buyer = Account.system_user() admintools.adjust_sodium_expiration(c.user, days=g.mobile_auth_sild_time) create_gift_sodium(buyer._id, c.user._id, g.mobile_auth_sild_time, datetime.now(g.tz), signed=True, note='first_mobile_auth') subject = 'Let there be sodium! Verbify just sent you Verbify sodium!' message = ( "Thank you for using the Verbify mobile app! As a thank you " "for logging in during launch week, you've been gifted %s of " "Verbify Sodium.\n\n" "Verbify Sodium is Verbify's premium membership program, which " "grants you: \n" "An ads-free experience in Verbify's mobile apps, and\n" "Extra site features on desktop\n\n" "Discuss and get help on the features and perks at " "r/sodiumbenefits.") % g.mobile_auth_sild_message message += '\n\n' + strings.sodium_benefits_msg send_system_message(c.user, subject, message, add_to_sent=False) c.user.has_used_mobile_app = True c.user._commit() return self.redirect(final_redirect, code=302)
def message_event(self, message, event_type="ss.send_message", request=None, context=None): """Create a 'message' event for event-collector. message: An v1.models.Message object request: pylons.request of the request that created the message context: pylons.tmpl_context of the request that created the message """ from v1.models import Account, Message sender = message.author_slow if message.first_message: first_message = Message._byID(message.first_message, data=True) else: first_message = message event = Event( topic="message_events", event_type=event_type, time=message._date, request=request, context=context, data={ # set these manually rather than allowing them to be set from # the request context because the loggedin user might not # be the message sender "user_id": sender._id, "user_name": sender.name, }, ) if sender == Account.system_user(): sender_type = "automated" else: sender_type = "user" event.add("sender_type", sender_type) event.add("message_kind", "message") event.add("message_id", message._id) event.add("message_fullname", message._fullname) event.add_text("message_body", message.body) event.add_text("message_subject", message.subject) event.add("first_message_id", first_message._id) event.add("first_message_fullname", first_message._fullname) if request and request.POST.get("source", None): source = request.POST["source"] if source in {"compose", "permalink", "usermail"}: event.add("page", source) if message.sent_via_email: event.add("is_third_party", True) event.add("third_party_metadata", "mailgun") target = Account._byID(message.to_id, data=True) event.add_target_fields(target) self.save_event(event)