mirror of
https://github.com/zulip/zulip.git
synced 2025-11-16 03:41:58 +00:00
Move getting client to api_key_only_webhook_view.
This decreases the amount of convention developers need to understand in order to write a new webhook integration.
This commit is contained in:
@@ -125,8 +125,9 @@ def get_client_name(request, is_json_view):
|
|||||||
else:
|
else:
|
||||||
return "Unspecified"
|
return "Unspecified"
|
||||||
|
|
||||||
def process_client(request, user_profile, is_json_view=False):
|
def process_client(request, user_profile, is_json_view=False, client_name=None):
|
||||||
client_name = get_client_name(request, is_json_view)
|
if client_name is None:
|
||||||
|
client_name = get_client_name(request, is_json_view)
|
||||||
|
|
||||||
# Transitional hack for early 2014. Eventually the ios clients
|
# Transitional hack for early 2014. Eventually the ios clients
|
||||||
# will all report ZulipiOS, and we can remove the next couple lines.
|
# will all report ZulipiOS, and we can remove the next couple lines.
|
||||||
@@ -164,28 +165,31 @@ def validate_api_key(role, api_key):
|
|||||||
return profile
|
return profile
|
||||||
|
|
||||||
# Use this for webhook views that don't get an email passed in.
|
# Use this for webhook views that don't get an email passed in.
|
||||||
def api_key_only_webhook_view(view_func):
|
def api_key_only_webhook_view(client_name):
|
||||||
@csrf_exempt
|
def _wrapped_view_func(view_func):
|
||||||
@has_request_variables
|
@csrf_exempt
|
||||||
@wraps(view_func)
|
@has_request_variables
|
||||||
def _wrapped_view_func(request, api_key=REQ,
|
@wraps(view_func)
|
||||||
*args, **kwargs):
|
def _wrapped_func_arguments(request, api_key=REQ,
|
||||||
|
*args, **kwargs):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_profile = UserProfile.objects.get(api_key=api_key)
|
user_profile = UserProfile.objects.get(api_key=api_key)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
raise JsonableError("Invalid API key")
|
raise JsonableError("Invalid API key")
|
||||||
if not user_profile.is_active:
|
if not user_profile.is_active:
|
||||||
raise JsonableError("Account not active")
|
raise JsonableError("Account not active")
|
||||||
if user_profile.realm.deactivated:
|
if user_profile.realm.deactivated:
|
||||||
raise JsonableError("Realm for account has been deactivated")
|
raise JsonableError("Realm for account has been deactivated")
|
||||||
|
|
||||||
request.user = user_profile
|
request.user = user_profile
|
||||||
request._email = user_profile.email
|
request._email = user_profile.email
|
||||||
process_client(request, user_profile)
|
webhook_client_name = "Zulip{}Webhook".format(client_name)
|
||||||
if settings.RATE_LIMITING:
|
process_client(request, user_profile, client_name=webhook_client_name)
|
||||||
rate_limit_user(request, user_profile, domain='all')
|
if settings.RATE_LIMITING:
|
||||||
return view_func(request, user_profile, *args, **kwargs)
|
rate_limit_user(request, user_profile, domain='all')
|
||||||
|
return view_func(request, user_profile, request.client, *args, **kwargs)
|
||||||
|
return _wrapped_func_arguments
|
||||||
return _wrapped_view_func
|
return _wrapped_view_func
|
||||||
|
|
||||||
# From Django 1.8, modified to leave off ?next=/
|
# From Django 1.8, modified to leave off ?next=/
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ CIRCLECI_MESSAGE_TEMPLATE = '[Build]({build_url}) triggered by {username} on {br
|
|||||||
|
|
||||||
FAILED_STATUS = 'failed'
|
FAILED_STATUS = 'failed'
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('CircleCI')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_circleci_webhook(request, user_profile, payload=REQ(argument_type='body'), stream=REQ(default='circleci')):
|
def api_circleci_webhook(request, user_profile, client, payload=REQ(argument_type='body'), stream=REQ(default='circleci')):
|
||||||
payload = payload['payload']
|
payload = payload['payload']
|
||||||
subject = get_subject(payload)
|
subject = get_subject(payload)
|
||||||
body = get_body(payload)
|
body = get_body(payload)
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipCircleCIWebhook'), 'stream', [stream], subject, body)
|
check_send_message(user_profile, client, 'stream', [stream], subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
def get_subject(payload):
|
def get_subject(payload):
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ CODESHIP_STATUS_MAPPER = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Codeship')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_codeship_webhook(request, user_profile, payload=REQ(argument_type='body'),
|
def api_codeship_webhook(request, user_profile, client, payload=REQ(argument_type='body'),
|
||||||
stream=REQ(default='codeship')):
|
stream=REQ(default='codeship')):
|
||||||
try:
|
try:
|
||||||
payload = payload['build']
|
payload = payload['build']
|
||||||
@@ -30,7 +30,7 @@ def api_codeship_webhook(request, user_profile, payload=REQ(argument_type='body'
|
|||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
return json_error("Missing key {} in JSON".format(e.message))
|
return json_error("Missing key {} in JSON".format(e.message))
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipCodeshipWebhook'), 'stream', [stream], subject, body)
|
check_send_message(user_profile, client, 'stream', [stream], subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,9 +79,10 @@ def convert_jira_markup(content, realm):
|
|||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view("JIRA")
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_jira_webhook(request, user_profile, payload=REQ(argument_type='body'),
|
def api_jira_webhook(request, user_profile, client,
|
||||||
|
payload=REQ(argument_type='body'),
|
||||||
stream=REQ(default='jira')):
|
stream=REQ(default='jira')):
|
||||||
def get_in(payload, keys, default=''):
|
def get_in(payload, keys, default=''):
|
||||||
try:
|
try:
|
||||||
@@ -168,6 +169,6 @@ def api_jira_webhook(request, user_profile, payload=REQ(argument_type='body'),
|
|||||||
logging.warning("Got JIRA event type we don't understand: %s" % (event,))
|
logging.warning("Got JIRA event type we don't understand: %s" % (event,))
|
||||||
return json_error("Unknown JIRA event type")
|
return json_error("Unknown JIRA event type")
|
||||||
|
|
||||||
check_send_message(user_profile, get_client("ZulipJIRAWebhook"), "stream",
|
check_send_message(user_profile, client, "stream",
|
||||||
[stream], subject, content)
|
[stream], subject, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ from zerver.lib.validator import check_dict
|
|||||||
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view("NewRelic")
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_newrelic_webhook(request, user_profile, stream=REQ(),
|
def api_newrelic_webhook(request, user_profile, client, stream=REQ(),
|
||||||
alert=REQ(validator=check_dict([]), default=None),
|
alert=REQ(validator=check_dict([]), default=None),
|
||||||
deployment=REQ(validator=check_dict([]), default=None)):
|
deployment=REQ(validator=check_dict([]), default=None)):
|
||||||
if alert:
|
if alert:
|
||||||
@@ -27,6 +27,6 @@ def api_newrelic_webhook(request, user_profile, stream=REQ(),
|
|||||||
else:
|
else:
|
||||||
return json_error("Unknown webhook request")
|
return json_error("Unknown webhook request")
|
||||||
|
|
||||||
check_send_message(user_profile, get_client("ZulipNewRelicWebhook"), "stream",
|
check_send_message(user_profile, client, "stream",
|
||||||
[stream], subject, content)
|
[stream], subject, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -65,18 +65,18 @@ def build_pagerduty_formatdict(message):
|
|||||||
return format_dict
|
return format_dict
|
||||||
|
|
||||||
|
|
||||||
def send_raw_pagerduty_json(user_profile, stream, message, topic):
|
def send_raw_pagerduty_json(user_profile, client, stream, message, topic):
|
||||||
subject = topic or 'pagerduty'
|
subject = topic or 'pagerduty'
|
||||||
body = (
|
body = (
|
||||||
u'Unknown pagerduty message\n'
|
u'Unknown pagerduty message\n'
|
||||||
u'``` py\n'
|
u'``` py\n'
|
||||||
u'%s\n'
|
u'%s\n'
|
||||||
u'```') % (pprint.pformat(message),)
|
u'```') % (pprint.pformat(message),)
|
||||||
check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream',
|
check_send_message(user_profile, client, 'stream',
|
||||||
[stream], subject, body)
|
[stream], subject, body)
|
||||||
|
|
||||||
|
|
||||||
def send_formated_pagerduty(user_profile, stream, message_type, format_dict, topic):
|
def send_formated_pagerduty(user_profile, client, stream, message_type, format_dict, topic):
|
||||||
if message_type in ('incident.trigger', 'incident.unacknowledge'):
|
if message_type in ('incident.trigger', 'incident.unacknowledge'):
|
||||||
template = (u':imp: Incident '
|
template = (u':imp: Incident '
|
||||||
u'[{incident_num}]({incident_url}) {action} by '
|
u'[{incident_num}]({incident_url}) {action} by '
|
||||||
@@ -97,25 +97,25 @@ def send_formated_pagerduty(user_profile, stream, message_type, format_dict, top
|
|||||||
subject = topic or u'incident {incident_num}'.format(**format_dict)
|
subject = topic or u'incident {incident_num}'.format(**format_dict)
|
||||||
body = template.format(**format_dict)
|
body = template.format(**format_dict)
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream',
|
check_send_message(user_profile, client, 'stream',
|
||||||
[stream], subject, body)
|
[stream], subject, body)
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('PagerDuty')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_pagerduty_webhook(request, user_profile, payload=REQ(argument_type='body'),
|
def api_pagerduty_webhook(request, user_profile, client, payload=REQ(argument_type='body'),
|
||||||
stream=REQ(default='pagerduty'), topic=REQ(default=None)):
|
stream=REQ(default='pagerduty'), topic=REQ(default=None)):
|
||||||
for message in payload['messages']:
|
for message in payload['messages']:
|
||||||
message_type = message['type']
|
message_type = message['type']
|
||||||
|
|
||||||
if message_type not in PAGER_DUTY_EVENT_NAMES:
|
if message_type not in PAGER_DUTY_EVENT_NAMES:
|
||||||
send_raw_pagerduty_json(user_profile, stream, message, topic)
|
send_raw_pagerduty_json(user_profile, client, stream, message, topic)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
format_dict = build_pagerduty_formatdict(message)
|
format_dict = build_pagerduty_formatdict(message)
|
||||||
except:
|
except:
|
||||||
send_raw_pagerduty_json(user_profile, stream, message, topic)
|
send_raw_pagerduty_json(user_profile, client, stream, message, topic)
|
||||||
else:
|
else:
|
||||||
send_formated_pagerduty(user_profile, stream, message_type, format_dict, topic)
|
send_formated_pagerduty(user_profile, client, stream, message_type, format_dict, topic)
|
||||||
|
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ SUPPORTED_CHECK_TYPES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Pingdom')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_pingdom_webhook(request, user_profile, payload=REQ(argument_type='body'), stream=REQ(default='pingdom')):
|
def api_pingdom_webhook(request, user_profile, client, payload=REQ(argument_type='body'), stream=REQ(default='pingdom')):
|
||||||
check_type = get_check_type(payload)
|
check_type = get_check_type(payload)
|
||||||
|
|
||||||
if check_type in SUPPORTED_CHECK_TYPES:
|
if check_type in SUPPORTED_CHECK_TYPES:
|
||||||
@@ -38,7 +38,7 @@ def api_pingdom_webhook(request, user_profile, payload=REQ(argument_type='body')
|
|||||||
else:
|
else:
|
||||||
return json_error('Unsupported check_type: {check_type}'.format(check_type=check_type))
|
return json_error('Unsupported check_type: {check_type}'.format(check_type=check_type))
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipPingdomWebhook'), 'stream', [stream], subject, body)
|
check_send_message(user_profile, client, 'stream', [stream], subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,9 +147,9 @@ def api_pivotal_webhook_v5(request, user_profile, stream):
|
|||||||
|
|
||||||
return subject, content
|
return subject, content
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view("Pivotal")
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_pivotal_webhook(request, user_profile, stream=REQ()):
|
def api_pivotal_webhook(request, user_profile, client, stream=REQ()):
|
||||||
subject = content = None
|
subject = content = None
|
||||||
try:
|
try:
|
||||||
subject, content = api_pivotal_webhook_v3(request, user_profile, stream)
|
subject, content = api_pivotal_webhook_v3(request, user_profile, stream)
|
||||||
@@ -165,6 +165,6 @@ def api_pivotal_webhook(request, user_profile, stream=REQ()):
|
|||||||
if subject is None or content is None:
|
if subject is None or content is None:
|
||||||
return json_error("Unable to handle Pivotal payload")
|
return json_error("Unable to handle Pivotal payload")
|
||||||
|
|
||||||
check_send_message(user_profile, get_client("ZulipPivotalWebhook"), "stream",
|
check_send_message(user_profile, client, "stream",
|
||||||
[stream], subject, content)
|
[stream], subject, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import ujson
|
|||||||
from six.moves import range
|
from six.moves import range
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Taiga')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_taiga_webhook(request, user_profile, message=REQ(argument_type='body'),
|
def api_taiga_webhook(request, user_profile, client, message=REQ(argument_type='body'),
|
||||||
stream=REQ(default='taiga'), topic=REQ(default='General')):
|
stream=REQ(default='taiga'), topic=REQ(default='General')):
|
||||||
parsed_events = parse_message(message)
|
parsed_events = parse_message(message)
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ def api_taiga_webhook(request, user_profile, message=REQ(argument_type='body'),
|
|||||||
for event in parsed_events:
|
for event in parsed_events:
|
||||||
content += generate_content(event) + '\n'
|
content += generate_content(event) + '\n'
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipTaigaWebhook'), 'stream', [stream], topic, content)
|
check_send_message(user_profile, client, 'stream', [stream], topic, content)
|
||||||
|
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ def get_teamcity_property_value(property_list, name):
|
|||||||
return property['value']
|
return property['value']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Teamcity')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_teamcity_webhook(request, user_profile, payload=REQ(argument_type='body'),
|
def api_teamcity_webhook(request, user_profile, client, payload=REQ(argument_type='body'),
|
||||||
stream=REQ(default='teamcity')):
|
stream=REQ(default='teamcity')):
|
||||||
message = payload['build']
|
message = payload['build']
|
||||||
|
|
||||||
@@ -85,8 +85,8 @@ def api_teamcity_webhook(request, user_profile, payload=REQ(argument_type='body'
|
|||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
body = "Your personal build of " + body
|
body = "Your personal build of " + body
|
||||||
check_send_message(user_profile, get_client('ZulipTeamcityWebhook'), 'private', [teamcity_user.email], topic, body)
|
check_send_message(user_profile, client, 'private', [teamcity_user.email], topic, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipTeamcityWebhook'), 'stream', [stream], topic, body)
|
check_send_message(user_profile, client, 'stream', [stream], topic, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ from zerver.lib.validator import check_dict, check_string
|
|||||||
import ujson
|
import ujson
|
||||||
|
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Travis')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_travis_webhook(request, user_profile, stream=REQ(default='travis'),
|
def api_travis_webhook(request, user_profile, client,
|
||||||
|
stream=REQ(default='travis'),
|
||||||
topic=REQ(default=None),
|
topic=REQ(default=None),
|
||||||
message=REQ('payload', validator=check_dict([
|
message=REQ('payload', validator=check_dict([
|
||||||
['author_name', check_string],
|
['author_name', check_string],
|
||||||
@@ -40,5 +41,5 @@ def api_travis_webhook(request, user_profile, stream=REQ(default='travis'),
|
|||||||
|
|
||||||
body = template % (author, message_type, emoji, changes, build_url)
|
body = template % (author, message_type, emoji, changes, build_url)
|
||||||
|
|
||||||
check_send_message(user_profile, get_client('ZulipTravisWebhook'), 'stream', [stream], topic, body)
|
check_send_message(user_profile, client, 'stream', [stream], topic, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_vi
|
|||||||
|
|
||||||
import ujson
|
import ujson
|
||||||
|
|
||||||
@api_key_only_webhook_view
|
@api_key_only_webhook_view('Yo')
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_yo_app_webhook(request, user_profile, email=REQ(default=None),
|
def api_yo_app_webhook(request, user_profile, client, email=REQ(default=None),
|
||||||
username=REQ(default='Yo Bot'), topic=REQ(default='None'),
|
username=REQ(default='Yo Bot'), topic=REQ(default='None'),
|
||||||
user_ip=REQ(default='None')):
|
user_ip=REQ(default='None')):
|
||||||
|
|
||||||
body = ('Yo from %s') % (username,)
|
body = ('Yo from %s') % (username,)
|
||||||
check_send_message(user_profile, get_client('ZulipYoWebhook'), 'private', [email], topic, body)
|
check_send_message(user_profile, client, 'private', [email], topic, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|||||||
Reference in New Issue
Block a user