From 605db2b047798212670c85645a59cde87c821721 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Fri, 24 Nov 2023 11:07:38 +0100 Subject: [PATCH] Add Secret Json Schema Validation --- api/resource_types.go | 19 ++++++++++++------- helper/resources.go | 10 ++++++++++ helper/share.go | 16 ++++++++++++++++ helper/util.go | 30 ++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/api/resource_types.go b/api/resource_types.go index 5b3a753..0f091d0 100644 --- a/api/resource_types.go +++ b/api/resource_types.go @@ -6,14 +6,19 @@ import ( "fmt" ) -//ResourceType is the Type of a Resource +// ResourceType is the Type of a Resource type ResourceType struct { - ID string `json:"id,omitempty"` - Slug string `json:"slug,omitempty"` - Description string `json:"description,omitempty"` - Definition json.RawMessage `json:"definition,omitempty"` - Created *Time `json:"created,omitempty"` - Modified *Time `json:"modified,omitempty"` + ID string `json:"id,omitempty"` + Slug string `json:"slug,omitempty"` + Description string `json:"description,omitempty"` + Definition string `json:"definition,omitempty"` + Created *Time `json:"created,omitempty"` + Modified *Time `json:"modified,omitempty"` +} + +type ResourceTypeSchema struct { + Resource json.RawMessage `json:"resource"` + Secret json.RawMessage `json:"secret"` } // GetResourceTypesOptions is a placeholder for future options diff --git a/helper/resources.go b/helper/resources.go index 0d30014..72d9744 100644 --- a/helper/resources.go +++ b/helper/resources.go @@ -42,6 +42,11 @@ func CreateResource(ctx context.Context, c *api.Client, folderParentID, name, us return "", fmt.Errorf("Marshalling Secret Data: %w", err) } + err = validateSecretData(rType, string(secretData)) + if err != nil { + return "", fmt.Errorf("Validating Secret Data: %w", err) + } + encSecretData, err := c.EncryptMessage(string(secretData)) if err != nil { return "", fmt.Errorf("Encrypting Secret Data for User me: %w", err) @@ -223,6 +228,11 @@ func UpdateResource(ctx context.Context, c *api.Client, resourceID, name, userna return fmt.Errorf("Unknown ResourceType: %v", rType.Slug) } + err = validateSecretData(rType, secretData) + if err != nil { + return fmt.Errorf("Validating Secret Data: %w", err) + } + newResource.Secrets = []api.Secret{} for _, user := range users { var encSecretData string diff --git a/helper/share.go b/helper/share.go index f28dbbd..d9514b3 100644 --- a/helper/share.go +++ b/helper/share.go @@ -63,6 +63,22 @@ func ShareResource(ctx context.Context, c *api.Client, resourceID string, change return fmt.Errorf("Decrypting Resource Secret: %w", err) } + // Secret Validation + resource, err := c.GetResource(ctx, resourceID) + if err != nil { + return fmt.Errorf("Getting Resource: %w", err) + } + + rType, err := c.GetResourceType(ctx, resource.ResourceTypeID) + if err != nil { + return fmt.Errorf("Getting ResourceType: %w", err) + } + + err = validateSecretData(rType, secretData) + if err != nil { + return fmt.Errorf("Validating Secret Data: %w", err) + } + simulationResult, err := c.SimulateShareResource(ctx, resourceID, shareRequest) if err != nil { return fmt.Errorf("Simulate Share Resource: %w", err) diff --git a/helper/util.go b/helper/util.go index 78b1960..1692870 100644 --- a/helper/util.go +++ b/helper/util.go @@ -1,9 +1,13 @@ package helper import ( + "bytes" + "encoding/json" "fmt" + "strings" "github.com/passbolt/go-passbolt/api" + "github.com/santhosh-tekuri/jsonschema" ) func getPublicKeyByUserID(userID string, Users []api.User) (string, error) { @@ -32,3 +36,29 @@ func getSecretByResourceID(secrets []api.Secret, resourceID string) (*api.Secret } return nil, fmt.Errorf("Cannot Find Secret for id %v", resourceID) } + +func validateSecretData(rType *api.ResourceType, secretData string) error { + var schemaDefinition api.ResourceTypeSchema + err := json.Unmarshal([]byte(rType.Definition), &schemaDefinition) + if err != nil { + return fmt.Errorf("Unmarshal Json Schema: %w", err) + } + + comp := jsonschema.NewCompiler() + + err = comp.AddResource("secret.json", bytes.NewReader(schemaDefinition.Secret)) + if err != nil { + return fmt.Errorf("Adding Json Schema: %w", err) + } + + schema, err := comp.Compile("secret.json") + if err != nil { + return fmt.Errorf("Compiling Json Schema: %w", err) + } + + err = schema.Validate(strings.NewReader(secretData)) + if err != nil { + return fmt.Errorf("Validating Secret Data: %w", err) + } + return nil +}