mirror of
https://github.com/zulip/zulip.git
synced 2026-07-12 21:04:41 +08:00
An earlier commit today made it so that we don't create tickets for feedback if the Python process had seen a message from that user in the last few minutes. This doesn't help much when you have multiple processes, so now we track the times in redis. (imported from commit 62ff8ceb55d815d03566f407c1c85037334e4d6d)
143 lines
5.3 KiB
Python
143 lines
5.3 KiB
Python
from django.http import HttpResponse
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.contrib.auth.views import login as django_login_page
|
|
from django.http import HttpResponseRedirect
|
|
from django.shortcuts import render_to_response, redirect
|
|
from django.template import RequestContext, loader
|
|
|
|
from zerver.decorator import has_request_variables, REQ, json_to_dict
|
|
from zerver.lib.actions import internal_send_message
|
|
from zerver.lib.response import json_success, json_error, json_response, json_method_not_allowed
|
|
from zerver.lib.rest import rest_dispatch as _rest_dispatch
|
|
from zerver.models import get_realm, get_user_profile_by_email, resolve_email_to_domain, \
|
|
UserProfile
|
|
from zilencer.forms import EnterpriseToSForm
|
|
from error_notify import notify_server_error, notify_browser_error
|
|
from django.core.mail import send_mail
|
|
from django.conf import settings
|
|
import time
|
|
import redis
|
|
|
|
rest_dispatch = csrf_exempt((lambda request, *args, **kwargs: _rest_dispatch(request, globals(), *args, **kwargs)))
|
|
|
|
client = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=0)
|
|
|
|
def has_enough_time_expired_since_last_message(sender_email, min_delay):
|
|
# This function returns a boolean, but it also has the side effect
|
|
# of noting that a new message was received.
|
|
key = 'zilencer:feedback:%s' % (sender_email,)
|
|
t = int(time.time())
|
|
last_time = client.getset(key, t)
|
|
if last_time is None:
|
|
return True
|
|
delay = t - int(last_time)
|
|
return delay > min_delay
|
|
|
|
def get_ticket_number():
|
|
fn = '/var/tmp/.feedback-bot-ticket-number'
|
|
try:
|
|
ticket_number = int(open(fn).read()) + 1
|
|
except:
|
|
ticket_number = 1
|
|
open(fn, 'w').write('%d' % ticket_number)
|
|
return ticket_number
|
|
|
|
@has_request_variables
|
|
def submit_feedback(request, deployment, message=REQ(converter=json_to_dict)):
|
|
domainish = message["sender_domain"]
|
|
if get_realm("zulip.com") not in deployment.realms.all():
|
|
domainish += " via " + deployment.name
|
|
subject = "%s" % (message["sender_email"],)
|
|
|
|
if len(subject) > 60:
|
|
subject = subject[:57].rstrip() + "..."
|
|
|
|
content = ''
|
|
sender_email = message['sender_email']
|
|
|
|
# We generate ticket numbers if it's been more than a few minutes
|
|
# since their last message. This avoids some noise when people use
|
|
# enter-send.
|
|
need_ticket = has_enough_time_expired_since_last_message(sender_email, 180)
|
|
|
|
if need_ticket:
|
|
ticket_number = get_ticket_number()
|
|
content += '\n~~~'
|
|
content += '\nticket Z%03d (@support please ack)' % (ticket_number,)
|
|
content += '\nsender: %s' % (message['sender_full_name'],)
|
|
content += '\nemail: %s' % (sender_email,)
|
|
if 'sender_domain' in message:
|
|
content += '\nrealm: %s' % (message['sender_domain'],)
|
|
content += '\n~~~'
|
|
content += '\n\n'
|
|
|
|
content += message['content']
|
|
|
|
internal_send_message("feedback@zulip.com", "stream", "support", subject, content)
|
|
|
|
return HttpResponse(message['sender_email'])
|
|
|
|
@has_request_variables
|
|
def report_error(request, deployment, type=REQ, report=REQ(converter=json_to_dict)):
|
|
report['deployment'] = deployment.name
|
|
if type == 'browser':
|
|
notify_browser_error(report)
|
|
elif type == 'server':
|
|
notify_server_error(report)
|
|
else:
|
|
return json_error("Invalid type parameter")
|
|
return json_response({})
|
|
|
|
def realm_for_email(email):
|
|
try:
|
|
user = get_user_profile_by_email(email)
|
|
return user.realm
|
|
except UserProfile.DoesNotExist:
|
|
pass
|
|
|
|
return get_realm(resolve_email_to_domain(email))
|
|
|
|
# Requests made to this endpoint are UNAUTHENTICATED
|
|
@csrf_exempt
|
|
@has_request_variables
|
|
def lookup_endpoints_for_user(request, email=REQ()):
|
|
try:
|
|
return json_response(realm_for_email(email).deployment.endpoints)
|
|
except AttributeError:
|
|
return json_error("Cannot determine endpoint for user.", status=404)
|
|
|
|
def account_deployment_dispatch(request, **kwargs):
|
|
sso_unknown_email = False
|
|
if request.method == 'POST':
|
|
email = request.POST['username']
|
|
realm = realm_for_email(email)
|
|
try:
|
|
return HttpResponseRedirect(realm.deployment.base_site_url)
|
|
except AttributeError:
|
|
# No deployment found for this user/email
|
|
sso_unknown_email = True
|
|
|
|
template_response = django_login_page(request, **kwargs)
|
|
template_response.context_data['desktop_sso_dispatch'] = True
|
|
template_response.context_data['desktop_sso_unknown_email'] = sso_unknown_email
|
|
return template_response
|
|
|
|
def enterprise_registration(request):
|
|
if request.method == "POST":
|
|
form = EnterpriseToSForm(request.POST)
|
|
if form.is_valid():
|
|
company = form.cleaned_data["company"]
|
|
name = form.cleaned_data["full_name"]
|
|
subject = "Enterprise terms acceptance for " + company
|
|
body = loader.render_to_string(
|
|
"zilencer/enterprise_tos_accept_body.txt",
|
|
{"name": name, "company": company})
|
|
send_mail(subject, body, settings.EMAIL_HOST_USER,
|
|
["support@zulip.com"])
|
|
return redirect("https://zulip.com/enterprise/download")
|
|
else:
|
|
form = EnterpriseToSForm()
|
|
return render_to_response(
|
|
"zilencer/enterprise-registration.html", {"form": form},
|
|
context_instance=RequestContext(request))
|