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:
Tomasz Kolek
2016-05-12 22:49:36 +02:00
committed by Tim Abbott
parent d55c3bd142
commit db7ea8b484
12 changed files with 68 additions and 62 deletions

View File

@@ -125,8 +125,9 @@ def get_client_name(request, is_json_view):
else:
return "Unspecified"
def process_client(request, user_profile, is_json_view=False):
client_name = get_client_name(request, is_json_view)
def process_client(request, user_profile, is_json_view=False, client_name=None):
if client_name is None:
client_name = get_client_name(request, is_json_view)
# Transitional hack for early 2014. Eventually the ios clients
# 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
# Use this for webhook views that don't get an email passed in.
def api_key_only_webhook_view(view_func):
@csrf_exempt
@has_request_variables
@wraps(view_func)
def _wrapped_view_func(request, api_key=REQ,
*args, **kwargs):
def api_key_only_webhook_view(client_name):
def _wrapped_view_func(view_func):
@csrf_exempt
@has_request_variables
@wraps(view_func)
def _wrapped_func_arguments(request, api_key=REQ,
*args, **kwargs):
try:
user_profile = UserProfile.objects.get(api_key=api_key)
except UserProfile.DoesNotExist:
raise JsonableError("Invalid API key")
if not user_profile.is_active:
raise JsonableError("Account not active")
if user_profile.realm.deactivated:
raise JsonableError("Realm for account has been deactivated")
try:
user_profile = UserProfile.objects.get(api_key=api_key)
except UserProfile.DoesNotExist:
raise JsonableError("Invalid API key")
if not user_profile.is_active:
raise JsonableError("Account not active")
if user_profile.realm.deactivated:
raise JsonableError("Realm for account has been deactivated")
request.user = user_profile
request._email = user_profile.email
process_client(request, user_profile)
if settings.RATE_LIMITING:
rate_limit_user(request, user_profile, domain='all')
return view_func(request, user_profile, *args, **kwargs)
request.user = user_profile
request._email = user_profile.email
webhook_client_name = "Zulip{}Webhook".format(client_name)
process_client(request, user_profile, client_name=webhook_client_name)
if settings.RATE_LIMITING:
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
# From Django 1.8, modified to leave off ?next=/

View File

@@ -13,14 +13,14 @@ CIRCLECI_MESSAGE_TEMPLATE = '[Build]({build_url}) triggered by {username} on {br
FAILED_STATUS = 'failed'
@api_key_only_webhook_view
@api_key_only_webhook_view('CircleCI')
@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']
subject = get_subject(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()
def get_subject(payload):

View File

@@ -19,9 +19,9 @@ CODESHIP_STATUS_MAPPER = {
}
@api_key_only_webhook_view
@api_key_only_webhook_view('Codeship')
@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')):
try:
payload = payload['build']
@@ -30,7 +30,7 @@ def api_codeship_webhook(request, user_profile, payload=REQ(argument_type='body'
except KeyError as e:
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()

View File

@@ -79,9 +79,10 @@ def convert_jira_markup(content, realm):
return content
@api_key_only_webhook_view
@api_key_only_webhook_view("JIRA")
@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')):
def get_in(payload, keys, default=''):
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,))
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)
return json_success()

View File

@@ -7,9 +7,9 @@ from zerver.lib.validator import check_dict
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
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),
deployment=REQ(validator=check_dict([]), default=None)):
if alert:
@@ -27,6 +27,6 @@ def api_newrelic_webhook(request, user_profile, stream=REQ(),
else:
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)
return json_success()

View File

@@ -65,18 +65,18 @@ def build_pagerduty_formatdict(message):
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'
body = (
u'Unknown pagerduty message\n'
u'``` py\n'
u'%s\n'
u'```') % (pprint.pformat(message),)
check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream',
check_send_message(user_profile, client, 'stream',
[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'):
template = (u':imp: Incident '
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)
body = template.format(**format_dict)
check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream',
check_send_message(user_profile, client, 'stream',
[stream], subject, body)
@api_key_only_webhook_view
@api_key_only_webhook_view('PagerDuty')
@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)):
for message in payload['messages']:
message_type = message['type']
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:
format_dict = build_pagerduty_formatdict(message)
except:
send_raw_pagerduty_json(user_profile, stream, message, topic)
send_raw_pagerduty_json(user_profile, client, stream, message, topic)
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()

View File

@@ -27,9 +27,9 @@ SUPPORTED_CHECK_TYPES = (
)
@api_key_only_webhook_view
@api_key_only_webhook_view('Pingdom')
@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)
if check_type in SUPPORTED_CHECK_TYPES:
@@ -38,7 +38,7 @@ def api_pingdom_webhook(request, user_profile, payload=REQ(argument_type='body')
else:
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()

View File

@@ -147,9 +147,9 @@ def api_pivotal_webhook_v5(request, user_profile, stream):
return subject, content
@api_key_only_webhook_view
@api_key_only_webhook_view("Pivotal")
@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
try:
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:
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)
return json_success()

View File

@@ -28,9 +28,9 @@ import ujson
from six.moves import range
@api_key_only_webhook_view
@api_key_only_webhook_view('Taiga')
@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')):
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:
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()

View File

@@ -31,9 +31,9 @@ def get_teamcity_property_value(property_list, name):
return property['value']
return None
@api_key_only_webhook_view
@api_key_only_webhook_view('Teamcity')
@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')):
message = payload['build']
@@ -85,8 +85,8 @@ def api_teamcity_webhook(request, user_profile, payload=REQ(argument_type='body'
return json_success()
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()
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()

View File

@@ -8,9 +8,10 @@ from zerver.lib.validator import check_dict, check_string
import ujson
@api_key_only_webhook_view
@api_key_only_webhook_view('Travis')
@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),
message=REQ('payload', validator=check_dict([
['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)
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()

View File

@@ -7,12 +7,12 @@ from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_vi
import ujson
@api_key_only_webhook_view
@api_key_only_webhook_view('Yo')
@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'),
user_ip=REQ(default='None')):
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()