Software /
code /
prosody-modules
File
mod_pubsub_alertmanager/mod_pubsub_alertmanager.lua @ 5418:f2c7bb3af600
mod_http_oauth2: Add role selector to consent page
List includes all roles available to the user, if more than one.
Defaults to either the first role in the scope string or the users
primary role.
Earlier draft listed all roles, but having options that can't be
selected is bad UX and the entire list of all roles on the server could
be long, and perhaps even sensitive.
Allows e.g. picking a role with fewer permissions than what might
otherwise have been selected.
UX wise, doing this with more checkboxes or possibly radio buttons would
have been confusion and/or looked messier.
Fixes the previous situation where unselecting a role would default to
the primary role, which could be more permissions than requested.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 05 May 2023 01:23:13 +0200 |
parent | 4627:adda872fa9e1 |
child | 5485:67190744b1eb |
line wrap: on
line source
local st = require "util.stanza"; local json = require "util.json"; local filters = { --[[ TODO what's useful? ]] }; local render = require "util.interpolation".new("%b{}", tostring, filters); local uuid_generate = require "util.uuid".generate; -- TODO alertmanager supports inclusion of HTTP auth and OAuth, worth looking -- into for using instead of request IP module:depends("http"); local pubsub_service = module:depends("pubsub").service; local error_mapping = { ["forbidden"] = 403; ["item-not-found"] = 404; ["internal-server-error"] = 500; ["conflict"] = 409; }; local function publish_payload(node, actor, item_id, payload) local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, }) :add_child(payload); local ok, err = pubsub_service:publish(node, actor, item_id, post_item); module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or ""); if not ok then return error_mapping[err] or 500; end return 202; end local node_template = module:get_option_string("alertmanager_node_template", "{path?alerts}"); function handle_POST(event, path) local request = event.request; local payload = json.decode(event.request.body); if type(payload) ~= "table" then return 400; end if payload.version ~= "4" then return 501; end for _, alert in ipairs(payload.alerts) do local item = st.stanza("alerts", {xmlns = "urn:uuid:e3bec775-c607-4e9b-9a3f-94de1316d861:v4", status=alert.status}); for k, v in pairs(alert.annotations) do item:text_tag("annotation", v, { name=k }); end for k, v in pairs(alert.labels) do item:text_tag("label", v, { name=k }); end item:tag("starts", { at = alert.startsAt}):up(); if alert.endsAt and alert.status == "resolved" then item:tag("ends", { at = alert.endsAt }):up(); end if alert.generatorURL then item:tag("link", { href=alert.generatorURL }):up(); end local node = render(node_template, {alert = alert, path = path, payload = payload, request = request}); local ret = publish_payload(node, request.ip, uuid_generate(), item); if ret ~= 202 then return ret end end return 202; end local template = module:get_option_string("alertmanager_body_template", [[ *ALARM!* Status: {status} Starts at: {startsAt}{endsAt& Ends at: {endsAt}} Labels: {labels% {idx}: {item}} Annotations: {annotations% {idx}: {item}} ]]); module:hook("pubsub-summary/urn:uuid:e3bec775-c607-4e9b-9a3f-94de1316d861:v4", function(event) local payload = event.payload; local data = { status = payload.attr.status, firing = "firing" == payload.attr.status, resolved = "resolved" == payload.attr.status, annotations = {}, labels = {}, endsAt = payload:find("ends/@at"), startsAt = payload:find("starts/@at"), }; for label in payload:childtags("label") do data.labels[tostring(label.attr.name)] = label:get_text(); end for annotation in payload:childtags("annotation") do data.annotations[tostring(annotation.attr.name)] = annotation:get_text(); end return render(template, data); end); module:provides("http", { route = { ["POST /*"] = handle_POST; ["POST"] = handle_POST; }; });