From 65807e93724f85a743ad14a4a6c8a22fb7f10f51 Mon Sep 17 00:00:00 2001 From: Craig Jellick Date: Wed, 31 Jan 2018 19:14:35 -0700 Subject: [PATCH] Distinguish between listing and getting We now have resources (subtypes of authConfig) that can be retrieved by ID but their collections are not viewable. This change is needed to suppport that. --- api/server.go | 16 +++++++++++----- authorization/all.go | 4 ++++ store/schema/schema_store.go | 2 +- types/schema_funcs.go | 7 +++++++ types/server_types.go | 1 + 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/api/server.go b/api/server.go index 5a2296d2..d473920c 100644 --- a/api/server.go +++ b/api/server.go @@ -186,26 +186,32 @@ func (s *Server) handle(rw http.ResponseWriter, req *http.Request) (*types.APICo if apiRequest.Link == "" { switch apiRequest.Method { case http.MethodGet: - if !apiRequest.AccessControl.CanList(apiRequest, apiRequest.Schema) { - return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not list "+apiRequest.Schema.Type) + if apiRequest.ID == "" { + if !apiRequest.AccessControl.CanList(apiRequest, apiRequest.Schema) { + return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not list "+apiRequest.Schema.ID) + } + } else { + if !apiRequest.AccessControl.CanGet(apiRequest, apiRequest.Schema) { + return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not get "+apiRequest.Schema.ID) + } } handler = apiRequest.Schema.ListHandler nextHandler = s.Defaults.ListHandler case http.MethodPost: if !apiRequest.AccessControl.CanCreate(apiRequest, apiRequest.Schema) { - return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not create "+apiRequest.Schema.Type) + return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not create "+apiRequest.Schema.ID) } handler = apiRequest.Schema.CreateHandler nextHandler = s.Defaults.CreateHandler case http.MethodPut: if !apiRequest.AccessControl.CanUpdate(apiRequest, nil, apiRequest.Schema) { - return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not update "+apiRequest.Schema.Type) + return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not update "+apiRequest.Schema.ID) } handler = apiRequest.Schema.UpdateHandler nextHandler = s.Defaults.UpdateHandler case http.MethodDelete: if !apiRequest.AccessControl.CanDelete(apiRequest, nil, apiRequest.Schema) { - return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not delete "+apiRequest.Schema.Type) + return apiRequest, httperror.NewAPIError(httperror.PermissionDenied, "Can not delete "+apiRequest.Schema.ID) } handler = apiRequest.Schema.DeleteHandler nextHandler = s.Defaults.DeleteHandler diff --git a/authorization/all.go b/authorization/all.go index 2e6e4d48..fc7821c4 100644 --- a/authorization/all.go +++ b/authorization/all.go @@ -14,6 +14,10 @@ func (*AllAccess) CanCreate(apiContext *types.APIContext, schema *types.Schema) return slice.ContainsString(schema.CollectionMethods, http.MethodPost) } +func (*AllAccess) CanGet(apiContext *types.APIContext, schema *types.Schema) bool { + return slice.ContainsString(schema.ResourceMethods, http.MethodGet) +} + func (*AllAccess) CanList(apiContext *types.APIContext, schema *types.Schema) bool { return slice.ContainsString(schema.CollectionMethods, http.MethodGet) } diff --git a/store/schema/schema_store.go b/store/schema/schema_store.go index b557510d..6ba91c5f 100644 --- a/store/schema/schema_store.go +++ b/store/schema/schema_store.go @@ -74,7 +74,7 @@ func (s *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *ty continue } - if schema.CanList(apiContext) { + if schema.CanList(apiContext) || schema.CanGet(apiContext) { schemas = s.addSchema(apiContext, schema, schemaMap, schemas, included) } } diff --git a/types/schema_funcs.go b/types/schema_funcs.go index 130f0e98..a6f26b9d 100644 --- a/types/schema_funcs.go +++ b/types/schema_funcs.go @@ -28,6 +28,13 @@ func (s *Schema) CanList(context *APIContext) bool { return context.AccessControl.CanList(context, s) } +func (s *Schema) CanGet(context *APIContext) bool { + if context == nil { + return slice.ContainsString(s.ResourceMethods, http.MethodGet) + } + return context.AccessControl.CanGet(context, s) +} + func (s *Schema) CanCreate(context *APIContext) bool { if context == nil { return slice.ContainsString(s.CollectionMethods, http.MethodPost) diff --git a/types/server_types.go b/types/server_types.go index f38d7fda..14752d14 100644 --- a/types/server_types.go +++ b/types/server_types.go @@ -71,6 +71,7 @@ type ResponseWriter interface { type AccessControl interface { CanCreate(apiContext *APIContext, schema *Schema) bool CanList(apiContext *APIContext, schema *Schema) bool + CanGet(apiContext *APIContext, schema *Schema) bool CanUpdate(apiContext *APIContext, obj map[string]interface{}, schema *Schema) bool CanDelete(apiContext *APIContext, obj map[string]interface{}, schema *Schema) bool