@@ -32,9 +32,22 @@ func RegisterInternalRoutes(e *echo.Echo, deps Dependencies) {
3232 userRepo = repositories .NewUserRepositoryFromQueryStore (deps .QueryStore )
3333 }
3434
35- // Create internal group with webhook auth (with orgRepo for existence check)
35+ // Create internal group with webhook auth
3636 internal := e .Group ("/internal/api" )
37- internal .Use (middleware .WebhookAuth (orgRepo ))
37+ internal .Use (middleware .WebhookAuth ())
38+
39+ // Add org resolution middleware - resolves org name to UUID and adds to domain context
40+ if deps .QueryStore != nil {
41+ if db := repositories .GetDBFromQueryStore (deps .QueryStore ); db != nil {
42+ // Create identifier resolver (infrastructure layer)
43+ identifierResolver := repositories .NewIdentifierResolver (db )
44+ // Pass interface to middleware (clean architecture!)
45+ internal .Use (middleware .ResolveOrgContextMiddleware (identifierResolver ))
46+ log .Println ("Org context resolution middleware enabled for internal routes" )
47+ } else {
48+ log .Println ("WARNING: QueryStore does not implement GetDB() *gorm.DB - org resolution disabled" )
49+ }
50+ }
3851
3952 // Organization and User management endpoints
4053 if orgRepo != nil && userRepo != nil {
@@ -70,50 +83,44 @@ func RegisterInternalRoutes(e *echo.Echo, deps Dependencies) {
7083 log .Println ("RBAC management endpoints registered at /internal/api/rbac" )
7184 }
7285
73- orgService := domain .NewOrgService ()
74- orgScopedRepo := repositories .NewOrgScopedRepository (deps .Repository , orgService )
86+ // For internal routes, use RBAC-wrapped repository
87+ // Architecture:
88+ // - Webhook secret authenticates the SYSTEM (backend orchestrator)
89+ // - X-User-ID header identifies the END USER making the request
90+ // - RBAC enforces what that USER can do (via repository layer)
91+ // - Org scoping handled by middleware (ResolveOrgContextMiddleware) + database foreign keys
92+
93+ // Create identifier resolver for unit name→UUID resolution
94+ var identifierResolver domain.IdentifierResolver
95+ if deps .QueryStore != nil {
96+ if db := repositories .GetDBFromQueryStore (deps .QueryStore ); db != nil {
97+ identifierResolver = repositories .NewIdentifierResolver (db )
98+ }
99+ }
75100
76- // Create handler with org-scoped repository
77- // The repository will automatically:
78- // - Filter List() to org namespace
79- // - Validate all operations belong to user's org
101+ // Create handler with org-scoped + RBAC-wrapped repository
80102 unitHandler := unithandlers .NewHandler (
81- domain .UnitManagement (orgScopedRepo ),
103+ domain .UnitManagement (deps .Repository ), // Use RBAC-wrapped repository directly
104+ deps .BlobStore ,
82105 deps .RBACManager ,
83106 deps .Signer ,
84107 deps .QueryStore ,
108+ identifierResolver ,
85109 )
86110
87-
88-
89-
90- if deps .RBACManager != nil {
91- // With RBAC - apply RBAC permission checks
92- // Org scoping is automatic via orgScopedRepository
93- internal .POST ("/units" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitWrite , "*" )(unitHandler .CreateUnit ))
94- internal .GET ("/units" , unitHandler .ListUnits ) // Automatically filters by org
95- internal .GET ("/units/:id" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitRead , "{id}" )(unitHandler .GetUnit ))
96- internal .DELETE ("/units/:id" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitDelete , "{id}" )(unitHandler .DeleteUnit ))
97- internal .GET ("/units/:id/download" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitRead , "{id}" )(unitHandler .DownloadUnit ))
98- internal .POST ("/units/:id/upload" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitWrite , "{id}" )(unitHandler .UploadUnit ))
99- internal .POST ("/units/:id/lock" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitLock , "{id}" )(unitHandler .LockUnit ))
100- internal .DELETE ("/units/:id/unlock" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitLock , "{id}" )(unitHandler .UnlockUnit ))
101- internal .GET ("/units/:id/status" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitRead , "{id}" )(unitHandler .GetUnitStatus ))
102- internal .GET ("/units/:id/versions" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitRead , "{id}" )(unitHandler .ListVersions ))
103- internal .POST ("/units/:id/restore" , wrapWithWebhookRBAC (deps .RBACManager , rbac .ActionUnitWrite , "{id}" )(unitHandler .RestoreVersion ))
104- } else {
105- internal .POST ("/units" , unitHandler .CreateUnit )
106- internal .GET ("/units" , unitHandler .ListUnits )
107- internal .GET ("/units/:id" , unitHandler .GetUnit )
108- internal .DELETE ("/units/:id" , unitHandler .DeleteUnit )
109- internal .GET ("/units/:id/download" , unitHandler .DownloadUnit )
110- internal .POST ("/units/:id/upload" , unitHandler .UploadUnit )
111- internal .POST ("/units/:id/lock" , unitHandler .LockUnit )
112- internal .DELETE ("/units/:id/unlock" , unitHandler .UnlockUnit )
113- internal .GET ("/units/:id/status" , unitHandler .GetUnitStatus )
114- internal .GET ("/units/:id/versions" , unitHandler .ListVersions )
115- internal .POST ("/units/:id/restore" , unitHandler .RestoreVersion )
116- }
111+ // Internal routes with RBAC enforcement
112+ // Note: Users must have permissions assigned via /internal/api/rbac endpoints
113+ internal .POST ("/units" , unitHandler .CreateUnit )
114+ internal .GET ("/units" , unitHandler .ListUnits )
115+ internal .GET ("/units/:id" , unitHandler .GetUnit )
116+ internal .DELETE ("/units/:id" , unitHandler .DeleteUnit )
117+ internal .GET ("/units/:id/download" , unitHandler .DownloadUnit )
118+ internal .POST ("/units/:id/upload" , unitHandler .UploadUnit )
119+ internal .POST ("/units/:id/lock" , unitHandler .LockUnit )
120+ internal .DELETE ("/units/:id/unlock" , unitHandler .UnlockUnit )
121+ internal .GET ("/units/:id/status" , unitHandler .GetUnitStatus )
122+ internal .GET ("/units/:id/versions" , unitHandler .ListVersions )
123+ internal .POST ("/units/:id/restore" , unitHandler .RestoreVersion )
117124
118125 // Health check for internal routes
119126 internal .GET ("/health" , func (c echo.Context ) error {
@@ -153,7 +160,6 @@ func RegisterInternalRoutes(e *echo.Echo, deps Dependencies) {
153160
154161 log .Printf ("Internal routes registered at /internal/api/* with webhook authentication" )
155162}
156-
157163// wrapWithWebhookRBAC wraps a handler with RBAC permission checking
158164func wrapWithWebhookRBAC (manager * rbac.RBACManager , action rbac.Action , resource string ) func (echo.HandlerFunc ) echo.HandlerFunc {
159165 return func (next echo.HandlerFunc ) echo.HandlerFunc {
@@ -208,3 +214,4 @@ func wrapWithWebhookRBAC(manager *rbac.RBACManager, action rbac.Action, resource
208214 }
209215 }
210216}
217+
0 commit comments