92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
import logging
|
|
import re
|
|
from typing import Any, List, Optional, Tuple
|
|
|
|
import attr
|
|
from fastapi import Request
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBasicCredentials
|
|
from jinja2 import TemplateNotFound
|
|
from mautrix.types import Format, MessageType, TextMessageEventContent
|
|
from mautrix.util.formatter import parse_html
|
|
|
|
from ..config import RoutingKey
|
|
from ..util.template import TemplateManager, TemplateUtil
|
|
from .types import OTHER_ENUMS, Action, EventParse # type: ignore
|
|
|
|
spaces = re.compile(" +")
|
|
space = " "
|
|
|
|
|
|
messages = TemplateManager("gitlab", "messages")
|
|
templates = TemplateManager("gitlab", "mixins")
|
|
|
|
|
|
async def authorize(
|
|
route: RoutingKey,
|
|
request: Request,
|
|
basic_credentials: Optional[HTTPBasicCredentials],
|
|
bearer_credentials: Optional[HTTPAuthorizationCredentials],
|
|
) -> bool:
|
|
provided: Optional[str] = request.headers.get("x-gitlab-token")
|
|
return provided == route.secret_token
|
|
|
|
|
|
async def handle_event(x_gitlab_event: str, payload: Any) -> List[Tuple[str, str]]:
|
|
evt = EventParse[x_gitlab_event].deserialize(payload)
|
|
try:
|
|
tpl = messages[evt.template_name]
|
|
except TemplateNotFound:
|
|
msg = f"Received unhandled gitlab event type {x_gitlab_event}"
|
|
logging.error(msg)
|
|
logging.debug(payload)
|
|
return []
|
|
|
|
aborted = False
|
|
|
|
def abort() -> None:
|
|
nonlocal aborted
|
|
aborted = True
|
|
|
|
base_args = {
|
|
**{field.key: field for field in Action if field.key.isupper()},
|
|
**OTHER_ENUMS,
|
|
"util": TemplateUtil,
|
|
}
|
|
|
|
msgs = []
|
|
for subevt in evt.preprocess():
|
|
args = {
|
|
**attr.asdict(subevt, recurse=False),
|
|
**{key: getattr(subevt, key) for key in subevt.event_properties},
|
|
"abort": abort,
|
|
**base_args,
|
|
}
|
|
args["templates"] = templates.proxy(args)
|
|
|
|
html = tpl.render(**args)
|
|
if not html or aborted:
|
|
aborted = False
|
|
continue
|
|
html = spaces.sub(space, html.strip())
|
|
|
|
content = TextMessageEventContent(
|
|
msgtype=MessageType.TEXT,
|
|
format=Format.HTML,
|
|
formatted_body=html,
|
|
body=await parse_html(html),
|
|
)
|
|
content["xyz.maubot.gitlab.webhook"] = {
|
|
"event_type": x_gitlab_event,
|
|
**subevt.meta,
|
|
}
|
|
msgs.append((content.body, content.formatted_body))
|
|
return msgs
|
|
|
|
|
|
async def parse_event(
|
|
route: RoutingKey, payload: Any, request: Request
|
|
) -> List[Tuple[str, str]]:
|
|
x_gitlab_event = request.headers.get("x-gitlab-event")
|
|
if x_gitlab_event:
|
|
return await handle_event(x_gitlab_event, payload)
|
|
return []
|