Skip to content

feat: middleware guards — permission-based handler access control#35

Merged
jordanpartridge merged 1 commit into
mainfrom
feat/13-middleware-guards
Apr 27, 2026
Merged

feat: middleware guards — permission-based handler access control#35
jordanpartridge merged 1 commit into
mainfrom
feat/13-middleware-guards

Conversation

@jordanpartridge
Copy link
Copy Markdown
Contributor

@jordanpartridge jordanpartridge commented Apr 27, 2026

Summary

Adds permission-based middleware guards under src/Bot/Middleware/Guards/:

  • Guard interface — contract with authorize(userId, channelId): bool for custom guards
  • RequiresRole — short-circuits if user lacks a specific Mattermost role (e.g. system_admin)
  • RequiresPermission — maps permission names to roles (e.g. manage_teamteam_admin|system_admin)
  • ChannelMember — verifies user is a member of the post's channel via GET /channels/{id}/members/{userId}

All guards follow the existing cache-backed pattern from AdminOnly with configurable TTL via mattermost.bot.guard_cache_ttl (default 300s).

Closes #13

Test plan

  • RequiresRole — 7 tests: allows/blocks by role, caches lookups, handles API failures, passes non-PostCreated events, drops empty userId, implements Guard interface
  • RequiresPermission — 8 tests: allows/blocks by permission→role mapping, denies unknown permissions, caches, handles API failures, passes non-PostCreated, implements Guard
  • ChannelMember — 9 tests: allows members, blocks non-members, caches per user+channel, checks different channels separately, handles API failures, passes non-PostCreated, drops empty userId/channelId, implements Guard
  • pint --test — passed
  • pest — 292 passed, 0 failed
  • phpstan analyse (level 8) — 0 errors
  • rector --dry-run — no changes

Demo: pending — orchestrator will post

Add Guard interface and three guard middleware classes under
src/Bot/Middleware/Guards/:

- RequiresRole: checks user's Mattermost roles (e.g. system_admin)
- RequiresPermission: maps permissions to roles (e.g. manage_team)
- ChannelMember: verifies user is a member of the post's channel

All guards follow the existing cache-backed pattern from AdminOnly
with configurable TTL via mattermost.bot.guard_cache_ttl. Full Pest
BDD test coverage included.
@jordanpartridge jordanpartridge merged commit 07a6344 into main Apr 27, 2026
4 checks passed
@jordanpartridge jordanpartridge deleted the feat/13-middleware-guards branch April 27, 2026 01:33
Copy link
Copy Markdown

@lexi-chief-of-staff lexi-chief-of-staff Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it.

  • Clean abstraction on top of AdminOnly caching/API pattern.
  • Tests cover allows/blocks/caches/failures/empty IDs/non-posts systematically.
  • PERMISSION_ROLE_MAP reasonable starting set; easy to extend.
  • Keys TTL-checked and min 1s — avoids perf footguns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Middleware guards — permission-based handler access control

1 participant