From 1b07eda70b719a5fe8a184c67b6e0ab199765542 Mon Sep 17 00:00:00 2001 From: Albin Antony Date: Mon, 30 Oct 2023 16:53:51 +0530 Subject: [PATCH] Add #347 Draft data agreements shouldn't require any mandatory fields --- go.mod | 4 + go.sum | 9 ++ .../config_create_dataagreement.go | 89 +++++++++++++++---- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index aa794a8..8957f7a 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,9 @@ require ( github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator v9.31.0+incompatible // indirect github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -45,6 +48,7 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.13.6 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 29d8db4..97b78e8 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,12 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= +github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -126,6 +132,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= @@ -159,6 +167,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/surullabs/lint v0.0.0-20171003141706-f90256a82312 h1:0VtpevdoVHcdR3zI+SSS8N4shp+sg5Jtu7KR2/NSiN0= github.com/surullabs/lint v0.0.0-20171003141706-f90256a82312/go.mod h1:e68ddoKX7GR9ME1d1EsK19L0U/RqSEjZPmSOI9mrAWY= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= diff --git a/src/v2/handler/dataagreement/config_create_dataagreement.go b/src/v2/handler/dataagreement/config_create_dataagreement.go index bf55a83..9246abd 100644 --- a/src/v2/handler/dataagreement/config_create_dataagreement.go +++ b/src/v2/handler/dataagreement/config_create_dataagreement.go @@ -7,13 +7,14 @@ import ( "io" "net/http" - "github.com/asaskevich/govalidator" "github.com/bb-consent/api/src/common" "github.com/bb-consent/api/src/config" "github.com/bb-consent/api/src/org" + "github.com/bb-consent/api/src/policy" "github.com/bb-consent/api/src/v2/dataagreement" "github.com/bb-consent/api/src/v2/revision" "github.com/bb-consent/api/src/v2/token" + "github.com/go-playground/validator" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -63,8 +64,37 @@ var MethodOfUseMappings = []MethodOfUseMapping{ }, } +type policyForDataAgreement struct { + policy.Policy + Id string `json:"id"` + Name string `json:"name" validate:"requiredWhenActive"` + Url string `json:"url" validate:"requiredWhenActive"` +} + +type dataAgreement struct { + Id primitive.ObjectID `json:"id" bson:"_id,omitempty"` + Version string `json:"version"` + ControllerId string `json:"controllerId"` + ControllerUrl string `json:"controllerUrl" validate:"requiredWhenActive"` + ControllerName string `json:"controllerName" validate:"requiredWhenActive"` + Policy policyForDataAgreement `json:"policy" validate:"requiredWhenActive"` + Purpose string `json:"purpose" validate:"requiredWhenActive"` + PurposeDescription string `json:"purposeDescription" validate:"requiredWhenActive,max=500"` + LawfulBasis string `json:"lawfulBasis" validate:"requiredWhenActive"` + MethodOfUse string `json:"methodOfUse" validate:"requiredWhenActive"` + DpiaDate string `json:"dpiaDate"` + DpiaSummaryUrl string `json:"dpiaSummaryUrl"` + Signature dataagreement.Signature `json:"signature" validate:"requiredWhenActive"` + Active bool `json:"active"` + Forgettable bool `json:"forgettable"` + CompatibleWithVersionId string `json:"compatibleWithVersionId"` + Lifecycle string `json:"lifecycle" validate:"requiredWhenActive"` + OrganisationId string `json:"-"` + IsDeleted bool `json:"-"` +} + type addDataAgreementReq struct { - DataAgreement dataagreement.DataAgreement `json:"dataAgreement" valid:"required"` + DataAgreement dataAgreement `json:"dataAgreement"` } type addDataAgreementResp struct { @@ -98,21 +128,39 @@ func isValidMethodOfUse(methodOfUse string) bool { return isFound } +func registerCustomValidation(validate *validator.Validate) { + if err := validate.RegisterValidation("requiredWhenActive", func(fl validator.FieldLevel) bool { + dataAgreement := fl.Top().Interface().(dataAgreement) + + // If "active" is true, require the field + if dataAgreement.Active { + return fl.Field().String() != "" + } + + return true + + }); err != nil { + panic(err) + } +} + func validateAddDataAgreementRequestBody(dataAgreementReq addDataAgreementReq) error { - // validating request payload - valid, err := govalidator.ValidateStruct(dataAgreementReq) - if !valid { + var validate = validator.New() + registerCustomValidation(validate) + if err := validate.Struct(dataAgreementReq.DataAgreement); err != nil { return err } - // Proceed if lawful basis provided is valid - if !isValidLawfulBasisOfProcessing(dataAgreementReq.DataAgreement.LawfulBasis) { - return errors.New("invalid lawful basis provided") - } + if dataAgreementReq.DataAgreement.Active { + // Proceed if lawful basis provided is valid + if !isValidLawfulBasisOfProcessing(dataAgreementReq.DataAgreement.LawfulBasis) { + return errors.New("invalid lawful basis provided") + } - // Proceed if method of use is valid - if !isValidMethodOfUse(dataAgreementReq.DataAgreement.MethodOfUse) { - return errors.New("invalid method of use provided") + // Proceed if method of use is valid + if !isValidMethodOfUse(dataAgreementReq.DataAgreement.MethodOfUse) { + return errors.New("invalid method of use provided") + } } return nil @@ -120,7 +168,7 @@ func validateAddDataAgreementRequestBody(dataAgreementReq addDataAgreementReq) e func setDataAgreementLifecycle(active bool) string { var lifecycle string - if active == true { + if active { lifecycle = "complete" } else { lifecycle = "draft" @@ -130,7 +178,16 @@ func setDataAgreementLifecycle(active bool) string { func updateDataAgreementFromAddDataAgreementRequestBody(requestBody addDataAgreementReq, newDataAgreement dataagreement.DataAgreement) dataagreement.DataAgreement { - newDataAgreement.Policy = requestBody.DataAgreement.Policy + newDataAgreement.Policy.Id = requestBody.DataAgreement.Policy.Id + newDataAgreement.Policy.Name = requestBody.DataAgreement.Policy.Name + newDataAgreement.Policy.Version = requestBody.DataAgreement.Policy.Version + newDataAgreement.Policy.Url = requestBody.DataAgreement.Policy.Url + newDataAgreement.Policy.Jurisdiction = requestBody.DataAgreement.Policy.Jurisdiction + newDataAgreement.Policy.IndustrySector = requestBody.DataAgreement.Policy.IndustrySector + newDataAgreement.Policy.DataRetentionPeriodDays = requestBody.DataAgreement.Policy.DataRetentionPeriodDays + newDataAgreement.Policy.GeographicRestriction = requestBody.DataAgreement.Policy.GeographicRestriction + newDataAgreement.Policy.StorageLocation = requestBody.DataAgreement.Policy.StorageLocation + newDataAgreement.Policy.ThirdPartyDataSharing = requestBody.DataAgreement.Policy.ThirdPartyDataSharing newDataAgreement.Purpose = requestBody.DataAgreement.Purpose newDataAgreement.PurposeDescription = requestBody.DataAgreement.PurposeDescription newDataAgreement.LawfulBasis = requestBody.DataAgreement.LawfulBasis @@ -188,7 +245,9 @@ func ConfigCreateDataAgreement(w http.ResponseWriter, r *http.Request) { newDataAgreement.ControllerName = o.Name newDataAgreement.ControllerUrl = o.EulaURL newDataAgreement.IsDeleted = false - newDataAgreement.Version = version + if lifecycle == config.Complete { + newDataAgreement.Version = version + } newDataAgreement.Lifecycle = lifecycle // Create new revision