check / check (push) Waiting to run
Each entrypoint on the webhook page has an Edit button that shows its
description as a form, with Save and Cancel, in place. Edit hides while
the form is open, so the form always opens on the saved description.
Saving posts to /hook/{id}/entrypoints/{entrypointID}/edit, behind the
same login, CSRF and ownership checks as activate, deactivate and
delete, and writes only the description column, so the URL never
changes. An empty description shows as "Entrypoint". Activate and
deactivate now write only the active column, so they cannot write back
an older description over an edit.
Model: opus-5-5
112 lines
3.8 KiB
Go
112 lines
3.8 KiB
Go
package handlers
|
|
|
|
import "net/http"
|
|
|
|
// noticeParam is the query parameter an action's redirect carries its
|
|
// notice code in.
|
|
const noticeParam = "notice"
|
|
|
|
// noticeCode names one of the fixed lines noticeFor knows. An action
|
|
// redirects with the code rather than the line, so nothing a client
|
|
// puts in the URL reaches the page: a code noticeFor does not know
|
|
// shows nothing.
|
|
type noticeCode string
|
|
|
|
// The codes of the actions on the webhook pages and of signing out.
|
|
// Replay's codes, with the reasons a replay can be refused, and
|
|
// resubmit's codes are defined beside those actions.
|
|
const (
|
|
webhookCreated noticeCode = "webhook-created"
|
|
webhookSaved noticeCode = "webhook-saved"
|
|
webhookDeleted noticeCode = "webhook-deleted"
|
|
entrypointAdded noticeCode = "entrypoint-added"
|
|
entrypointSaved noticeCode = "entrypoint-saved"
|
|
entrypointDeleted noticeCode = "entrypoint-deleted"
|
|
entrypointActivated noticeCode = "entrypoint-activated"
|
|
entrypointDeactivated noticeCode = "entrypoint-deactivated"
|
|
targetAdded noticeCode = "target-added"
|
|
targetSaved noticeCode = "target-saved"
|
|
targetDeleted noticeCode = "target-deleted"
|
|
targetActivated noticeCode = "target-activated"
|
|
targetDeactivated noticeCode = "target-deactivated"
|
|
signedOut noticeCode = "signed-out"
|
|
)
|
|
|
|
// notice is the line templates/notice.html shows above a page to say
|
|
// what an action did.
|
|
type notice struct {
|
|
Text string
|
|
|
|
// Failed shows the line as an error: the action was refused.
|
|
Failed bool
|
|
}
|
|
|
|
// noticeFor returns the notice the request's URL names, or nil when it
|
|
// names none or an unknown code.
|
|
func noticeFor(r *http.Request) *notice {
|
|
n, ok := map[noticeCode]notice{
|
|
webhookCreated: {Text: "Webhook created."},
|
|
webhookSaved: {Text: "Webhook saved."},
|
|
webhookDeleted: {Text: "Webhook deleted."},
|
|
entrypointAdded: {Text: "Entrypoint added."},
|
|
entrypointSaved: {Text: "Entrypoint description saved."},
|
|
entrypointDeleted: {Text: "Entrypoint deleted."},
|
|
entrypointActivated: {Text: "Entrypoint activated."},
|
|
entrypointDeactivated: {Text: "Entrypoint deactivated."},
|
|
targetAdded: {Text: "Target added."},
|
|
targetSaved: {Text: "Target saved."},
|
|
targetDeleted: {Text: "Target deleted."},
|
|
targetActivated: {Text: "Target activated."},
|
|
targetDeactivated: {Text: "Target deactivated."},
|
|
signedOut: {Text: "Signed out."},
|
|
|
|
replayQueued: {
|
|
Text: "Replay queued: a new delivery was created " +
|
|
"against the target's current configuration.",
|
|
},
|
|
replayTargetDeleted: {
|
|
Text: "Not replayed: the target this delivery was for " +
|
|
"has been deleted. Recreate the target, then replay.",
|
|
Failed: true,
|
|
},
|
|
replayTargetMissing: {
|
|
Text: "Not replayed: the target this delivery was for " +
|
|
"no longer exists.",
|
|
Failed: true,
|
|
},
|
|
replayTargetInactive: {
|
|
Text: "Not replayed: the target this delivery was for " +
|
|
"is deactivated. Activate it, then replay.",
|
|
Failed: true,
|
|
},
|
|
replayNotTerminal: {
|
|
Text: "Not replayed: this delivery has not finished yet.",
|
|
Failed: true,
|
|
},
|
|
replayInFlight: {
|
|
Text: "Not replayed: a delivery of this event to this " +
|
|
"target is already in flight.",
|
|
Failed: true,
|
|
},
|
|
|
|
resubmitQueued: {
|
|
Text: "Resubmitted: a new event was created from the " +
|
|
"stored one and queued to every active target.",
|
|
},
|
|
resubmitNoTargets: {
|
|
Text: "Resubmitted: a new event was created, but this " +
|
|
"source has no active targets, so nothing was queued.",
|
|
},
|
|
}[noticeCode(r.URL.Query().Get(noticeParam))]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
return &n
|
|
}
|
|
|
|
// withNotice returns path with code added as its notice.
|
|
func withNotice(path string, code noticeCode) string {
|
|
return path + "?" + noticeParam + "=" + string(code)
|
|
}
|