Files
mcpctl/src/mcpd/src/routes/users.ts
Michal dcda93d179
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / typecheck (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / package (pull_request) Has been cancelled
feat: granular RBAC with resource/operation bindings, users, groups
- Replace admin role with granular roles: view, create, delete, edit, run
- Two binding types: resource bindings (role+resource+optional name) and
  operation bindings (role:run + action like backup, logs, impersonate)
- Name-scoped resource bindings for per-instance access control
- Remove role from project members (all permissions via RBAC)
- Add users, groups, RBAC CRUD endpoints and CLI commands
- describe user/group shows all RBAC access (direct + inherited)
- create rbac supports --subject, --binding, --operation flags
- Backup/restore handles users, groups, RBAC definitions
- mcplocal project-based MCP endpoint discovery
- Full test coverage for all new functionality

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:05:19 +00:00

32 lines
907 B
TypeScript

import type { FastifyInstance } from 'fastify';
import type { UserService } from '../services/user.service.js';
export function registerUserRoutes(
app: FastifyInstance,
service: UserService,
): void {
app.get('/api/v1/users', async () => {
return service.list();
});
app.get<{ Params: { id: string } }>('/api/v1/users/:id', async (request) => {
// Support lookup by email (contains @) or by id
const idOrEmail = request.params.id;
if (idOrEmail.includes('@')) {
return service.getByEmail(idOrEmail);
}
return service.getById(idOrEmail);
});
app.post('/api/v1/users', async (request, reply) => {
const user = await service.create(request.body);
reply.code(201);
return user;
});
app.delete<{ Params: { id: string } }>('/api/v1/users/:id', async (_request, reply) => {
await service.delete(_request.params.id);
reply.code(204);
});
}