Feature #44337
openAdd an administration page listing all webhooks
Description
Webhooks introduced in #29664 are owned by a user and managed from a single page reachable from My account. A webhook is only visible and editable by the user who created it, administrators cannot see or edit the webhooks. There is no entry in the administration menu.
This may be a problem:
Any member with the use_webhooks permission can register a hook posting project data to an external endpoint, and no administrator can see that it exists.
Once webhooks are enabled, an administrator has no way to know which external endpoints are receiving project data, how many hooks exist, or which projects and events they cover. Admins cannot respond to the question "where is our issue data being sent?".
Proposal: Add a separate administration page
A new page listing all webhooks:- a new entry in the administration menu
- the list shows the same columns as the personal page plus an Author column
- administrators can view, edit, deactivate and delete any webhook from that page
I am willing to provide a patch if the approach is agreed upon.
Files
Related issues
Updated by Vincent Robert 23 days ago
- Related to Feature #29664: Webhook triggers in Redmine added
Updated by Marius BĂLTEANU 22 days ago
I'm adding also Jens and Holger from Plan.io who contributed with this feature.
Updated by Vincent Robert 22 days ago
Here is the proposed patch.
It adds the administration page at /admin/webhooks, listing all webhooks. Administrators can edit, deactivate and delete any webhook.
The existing /webhooks page is unchanged: it still lists only the hooks of the current user.
The field secret of another user is never displayed; submitting the field empty keeps the stored value.
The admin page stays reachable when webhooks_enabled is off, with a notice, so that existing webhooks can still be reviewed and removed at the moment an administrator needs it.
The patch also resolves a performance issue by changing one line in Webhook#setable_projects (N+1 queries when filtering lots of projects)
Updated by Marius BĂLTEANU 15 days ago
- Target version set to 7.0.1
I would like to include this in 7.0.1 being an important improvement of the Webhook feature.
Updated by Marius BĂLTEANU 9 days ago
- Target version changed from 7.0.1 to Candidate for next minor release
Updated by Jens Krämer 8 days ago
I just had a look at this and I generally like it. However the patch is malformed (patch: **** malformed patch at line 393: @ -87,8 +97,127 @ class WebhooksControllerTest < Redmine::ControllerTest), I made it work with git apply --recount --3way. Also conflicts in fr.yml due to recent upstream changes. Might also split out non-en i18n into a separate commit.
Things I think need adressing:
- The performance fix (
Webhook#setable_projects) should be in a separate commit, it is unrelated to the admin page feature. secret_hidden?should be namedforeign_webhookor something like that since it's also used to decide whether to render the owner or not in the form.- a new secret an admin tries to set on a webhook they do not own is lost if the form is redisplayed due to validation errors.
Nice to have: pagination seems reasonable at this point, since an admin will see the aggregation of all webhooks systemwide.
Updated by Jens Krämer 8 days ago
Also, for an admin it might be of interest when a webhook was created, so maybe show that in the list as well?
Updated by Holger Just 7 days ago
- The performance fix (
Webhook#setable_projects) should be in a separate commit, it is unrelated to the admin page feature.
I concur. It should be a separate commit.
Also, with the proposed change, we would now check for the implicit view_project permission (via Project.visible) and the use_webhooks permission. I think, it is sufficient to only check the latter, i.e. to just run Project.allowed_to(user, :use_webhooks).
We should also drop the to_a there. Instead, in the before_validation hook we could just pluck the IDs and compare it to the ids of the hook's proposed projects.
secret_hidden?should be namedforeign_webhookor something like that since it's also used to decide whether to render the owner or not in the form.
Maybe we could reverse the meaning of this method and implement it as an instance method on the actual webhook model as Webhook#own? instead to check if the webhook's user is User.current. That would get rid if the rather awkward controller/view helper method.
However, thinking a bit more about it, I'm not sure if we should use such a helper method at all since it conflates various meanings into a sub-optimally named method. It may be clearer to just check this condition "manually" wherever required.
Finally, I'd like to propose some further changes:
- The check whether to allow setting the secret (now proposed in
WebhooksController#webhook_params) should instead be implemented usingsafe_attributeson the model, similar to most other models in Redmine (as we don't generally use Rails' params filtering framework). Instead of using the plainbuildorupdatemethods with a "raw" parameters, we would instead call e.g.@webhook.safe_attributes = webhook_params - Instead of checking which webhooks can be edited in
WebhooksController#editable_webhooks, we should instead introduce a newWebhook.editablescope and an accompanyingWebhook#editable?method (each receiving an optionaluserargument which defaults toUser.current). The newWebhook.editablescope should then be called inWebhookController#find_webhook. This would follow the approach for all other models. - I'm not a fan of the
ADMIN_CUSTODY_ACTIONSand the accompanying check incheck_enabled. Instead, I think we should have separate methods forcheck_enabledandcheck_enabled_or_adminwich are then installed as before_filters for the respective actions, e.g.before_action :check_enabled_or_admin, only: [:edit, :update, :destroy] before_action :check_enabled, except: [:edit, :update, :destroy] def check_enabled render_403 unless Webhook.enabled? end def check_enabled_or_admin render_403 unless Webhook.enabled? || User.current.admin? end
Updated by Marius BĂLTEANU 7 days ago
Vincent Robert wrote:
The patch also resolves a performance issue by changing one line in
Webhook#setable_projects(N+1 queries when filtering lots of projects)
I've created #44386.
Updated by Marius BĂLTEANU 6 days ago
- Related to Patch #44386: Avoid N+1 queries generated by Webhook#setable_projects added