From a46895081ee9a7528560763be7175fdb0d3249d4 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Mon, 29 May 2023 22:13:25 +0200 Subject: [PATCH] chore: actually validate API key privileges and refs --- graph/resolver.go | 21 +++++++++++++++++++++ graph/schema.resolvers.go | 9 ++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/graph/resolver.go b/graph/resolver.go index 5c6c003..98bc974 100644 --- a/graph/resolver.go +++ b/graph/resolver.go @@ -8,6 +8,7 @@ import ( "gitlab.com/unboundsoftware/eventsourced/eventsourced" "gitlab.com/unboundsoftware/schemas/cache" + "gitlab.com/unboundsoftware/schemas/middleware" ) //go:generate go run github.com/99designs/gqlgen @@ -27,6 +28,26 @@ type Resolver struct { Cache *cache.Cache } +func (r *Resolver) apiKeyCanAccessRef(ctx context.Context, ref string, publish bool) (string, error) { + key, err := middleware.ApiKeyFromContext(ctx) + if err != nil { + return "", err + } + apiKey := r.Cache.ApiKeyByKey(key) + if publish && !apiKey.Publish { + return "", fmt.Errorf("provided API-key doesn't have publish privilege") + } + if !publish && !apiKey.Read { + return "", fmt.Errorf("provided API-key doesn't have read privilege") + } + for _, rr := range apiKey.Refs { + if rr == ref { + return apiKey.Name, nil + } + } + return "", fmt.Errorf("provided API-key doesn't have the required privilege on the requested Schema Ref") +} + func (r *Resolver) handler(ctx context.Context, aggregate eventsourced.Aggregate) (eventsourced.CommandHandler, error) { return eventsourced.NewHandler(ctx, aggregate, r.EventStore, eventsourced.WithEventPublisher(r.Publisher)) } diff --git a/graph/schema.resolvers.go b/graph/schema.resolvers.go index fa6fca9..d3c9684 100644 --- a/graph/schema.resolvers.go +++ b/graph/schema.resolvers.go @@ -74,11 +74,10 @@ func (r *mutationResolver) AddAPIKey(ctx context.Context, input *model.InputAPIK // UpdateSubGraph is the resolver for the updateSubGraph field. func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.InputSubGraph) (*model.SubGraph, error) { orgId := middleware.OrganizationFromContext(ctx) - key, err := middleware.ApiKeyFromContext(ctx) + name, err := r.apiKeyCanAccessRef(ctx, input.Ref, true) if err != nil { return nil, err } - apiKey := r.Cache.ApiKeyByKey(key) subGraphId := r.Cache.SubGraphId(orgId, input.Ref, input.Service) subGraph := &domain.SubGraph{} if subGraphId != "" { @@ -115,7 +114,7 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input Url: input.URL, WSUrl: input.WsURL, Sdl: input.Sdl, - Initiator: apiKey.Name, + Initiator: name, }) if err != nil { return nil, err @@ -133,6 +132,10 @@ func (r *queryResolver) Organizations(ctx context.Context) ([]*model.Organizatio // Supergraph is the resolver for the supergraph field. func (r *queryResolver) Supergraph(ctx context.Context, ref string, isAfter *string) (model.Supergraph, error) { orgId := middleware.OrganizationFromContext(ctx) + _, err := r.apiKeyCanAccessRef(ctx, ref, false) + if err != nil { + return nil, err + } after := "" if isAfter != nil { after = *isAfter