mirror of https://github.com/zulip/zulip.git
webhooks/teamcity: Ignore third-party specific payload formats.
The TeamCity webhook plugin supports multiple payload formats that are customized to be used by different services such as Slack, Flowdock, etc. We don't support such payloads, so we should ignore them and stick to parsing only the generic ones. We should also notify that bot owner about the error.
This commit is contained in:
parent
97995b4779
commit
404439e98c
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"username":"TeamCity",
|
||||||
|
"icon_url":"https://raw.githubusercontent.com/tcplugins/tcWebHooks/master/docs/icons/teamcity-logo-48x48.png",
|
||||||
|
"attachments":[
|
||||||
|
{
|
||||||
|
"title":"Failed (broken) : ${buildName} <${buildStatusUrl}|build #${buildNumber}>",
|
||||||
|
"fallback":"Failed (broken) : ${buildName} build #${buildNumber}",
|
||||||
|
"color":"danger",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"title":"Status",
|
||||||
|
"value":"${buildStatus}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"Project Name",
|
||||||
|
"value":"<${rootUrl}/project.html?projectId=${projectExternalId}|${projectName}>",
|
||||||
|
"short":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"Build Name",
|
||||||
|
"value":"<${rootUrl}/viewType.html?buildTypeId=${buildExternalTypeId}|${buildName}>",
|
||||||
|
"short":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"Commit",
|
||||||
|
"value":"<${buildStatusUrl}&tab=buildChangesDiv|${substr(build.vcs.number,0,7,32)}>",
|
||||||
|
"short":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"Triggered By",
|
||||||
|
"value":"${triggeredBy}",
|
||||||
|
"short":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"Agent",
|
||||||
|
"value":"${agentName}",
|
||||||
|
"short":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -2,7 +2,9 @@
|
||||||
import ujson
|
import ujson
|
||||||
|
|
||||||
from zerver.lib.test_classes import WebhookTestCase
|
from zerver.lib.test_classes import WebhookTestCase
|
||||||
from zerver.models import Recipient
|
from zerver.lib.send_email import FromAddress
|
||||||
|
from zerver.models import Recipient, get_user, get_realm
|
||||||
|
from zerver.webhooks.teamcity.view import MISCONFIGURED_PAYLOAD_TYPE_ERROR_MESSAGE
|
||||||
|
|
||||||
class TeamcityHookTests(WebhookTestCase):
|
class TeamcityHookTests(WebhookTestCase):
|
||||||
STREAM_NAME = 'teamcity'
|
STREAM_NAME = 'teamcity'
|
||||||
|
@ -39,3 +41,15 @@ class TeamcityHookTests(WebhookTestCase):
|
||||||
|
|
||||||
self.assertEqual(msg.content, expected_message)
|
self.assertEqual(msg.content, expected_message)
|
||||||
self.assertEqual(msg.recipient.type, Recipient.PERSONAL)
|
self.assertEqual(msg.recipient.type, Recipient.PERSONAL)
|
||||||
|
|
||||||
|
def test_non_generic_payload_ignore_pm_notification(self) -> None:
|
||||||
|
expected_message = MISCONFIGURED_PAYLOAD_TYPE_ERROR_MESSAGE.format(
|
||||||
|
bot_name=get_user('webhook-bot@zulip.com', get_realm('zulip')).full_name,
|
||||||
|
support_email=FromAddress.SUPPORT
|
||||||
|
).strip()
|
||||||
|
payload = self.get_body('slack_non_generic_payload')
|
||||||
|
self.client_post(self.url, payload, content_type="application/json")
|
||||||
|
msg = self.get_last_message()
|
||||||
|
|
||||||
|
self.assertEqual(msg.content, expected_message)
|
||||||
|
self.assertEqual(msg.recipient.type, Recipient.PERSONAL)
|
||||||
|
|
|
@ -8,12 +8,23 @@ from django.db.models import Q
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
|
||||||
from zerver.decorator import api_key_only_webhook_view
|
from zerver.decorator import api_key_only_webhook_view
|
||||||
from zerver.lib.actions import check_send_private_message
|
from zerver.lib.actions import check_send_private_message, \
|
||||||
|
send_rate_limited_pm_notification_to_bot_owner
|
||||||
|
from zerver.lib.send_email import FromAddress
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_error, json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import Realm, UserProfile
|
from zerver.models import Realm, UserProfile
|
||||||
|
|
||||||
|
MISCONFIGURED_PAYLOAD_TYPE_ERROR_MESSAGE = """
|
||||||
|
Hi there! Your bot {bot_name} just received a TeamCity payload in a
|
||||||
|
format that Zulip doesn't recognize. This usually indicates a
|
||||||
|
configuration issue in your TeamCity webhook settings. Please make sure
|
||||||
|
that you set the **Payload Format** option to **Legacy Webhook (JSON)**
|
||||||
|
in your TeamCity webhook configuration. Contact {support_email} if you
|
||||||
|
need further help!
|
||||||
|
"""
|
||||||
|
|
||||||
def guess_zulip_user_from_teamcity(teamcity_username: str, realm: Realm) -> Optional[UserProfile]:
|
def guess_zulip_user_from_teamcity(teamcity_username: str, realm: Realm) -> Optional[UserProfile]:
|
||||||
try:
|
try:
|
||||||
# Try to find a matching user in Zulip
|
# Try to find a matching user in Zulip
|
||||||
|
@ -39,7 +50,18 @@ def get_teamcity_property_value(property_list: List[Dict[str, str]], name: str)
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def api_teamcity_webhook(request: HttpRequest, user_profile: UserProfile,
|
def api_teamcity_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||||
payload: Dict[str, Any]=REQ(argument_type='body')) -> HttpResponse:
|
payload: Dict[str, Any]=REQ(argument_type='body')) -> HttpResponse:
|
||||||
message = payload['build']
|
message = payload.get('build')
|
||||||
|
if message is None:
|
||||||
|
# Ignore third-party specific (e.g. Slack/HipChat) payload formats
|
||||||
|
# and notify the bot owner
|
||||||
|
message = MISCONFIGURED_PAYLOAD_TYPE_ERROR_MESSAGE.format(
|
||||||
|
bot_name=user_profile.full_name,
|
||||||
|
support_email=FromAddress.SUPPORT,
|
||||||
|
).strip()
|
||||||
|
send_rate_limited_pm_notification_to_bot_owner(
|
||||||
|
user_profile, user_profile.realm, message)
|
||||||
|
|
||||||
|
return json_success()
|
||||||
|
|
||||||
build_name = message['buildFullName']
|
build_name = message['buildFullName']
|
||||||
build_url = message['buildStatusUrl']
|
build_url = message['buildStatusUrl']
|
||||||
|
|
Loading…
Reference in New Issue