diff --git a/common/common.go b/common/common.go index 4a53e1f..98dde9f 100644 --- a/common/common.go +++ b/common/common.go @@ -170,6 +170,25 @@ type Policy struct { Timestamp int64 `json:"timestamp" bson:"timestamp"` } +// Return true if the services of 2 policy objects are identical +func ComparePolicyServices(existingPolicy *Policy, newPolicy *Policy) bool { + for _, existingService := range existingPolicy.Services { + found := false + for _, newService := range newPolicy.Services { + if newService.OrgID == existingService.OrgID && + newService.ServiceName == existingService.ServiceName && + newService.Version == existingService.Version { + found = true + break + } + } + if !found { + return false + } + } + return true +} + // MetaData is the metadata that identifies and defines the sync service object. // Every object includes metadata (mandatory) and data (optional). The metadata and data can be updated independently. // Each sync service node (ESS) has an address that is composed of the node's ID, Type, and Organization. diff --git a/core/storage/boltStorage.go b/core/storage/boltStorage.go index 84218b3..5d5a8b2 100644 --- a/core/storage/boltStorage.go +++ b/core/storage/boltStorage.go @@ -243,6 +243,12 @@ func (store *BoltStorage) StoreObject(metaData common.MetaData, data []byte, sta (object.Meta.DestinationPolicy != nil && metaData.DestinationPolicy == nil) { return object, &common.InvalidRequest{"Can't update the existence of Destination Policy"} } + // Don't allow updates to the service reference of an existing object. + if object.Meta.DestinationPolicy != nil && metaData.DestinationPolicy != nil { + if same := common.ComparePolicyServices(object.Meta.DestinationPolicy, metaData.DestinationPolicy); !same { + return object, &common.InvalidRequest{Message: "Can't update the service name, org or version in Destination Policy"} + } + } metaData.DataID = object.Meta.DataID // Keep the previous data id object.Meta = metaData object.Status = status @@ -281,6 +287,12 @@ func (store *BoltStorage) StoreObject(metaData common.MetaData, data []byte, sta (object.Meta.DestinationPolicy != nil && metaData.DestinationPolicy == nil) { return object, &common.InvalidRequest{Message: "Can't update the existence of Destination Policy"} } + // Don't allow updates to the service reference of an existing object. + if object.Meta.DestinationPolicy != nil && metaData.DestinationPolicy != nil { + if same := common.ComparePolicyServices(object.Meta.DestinationPolicy, metaData.DestinationPolicy); !same { + return object, &common.InvalidRequest{Message: "Can't update the service name, org or version in Destination Policy"} + } + } if metaData.DestinationPolicy != nil { newObject.Destinations = object.Destinations } diff --git a/core/storage/mongoStorage.go b/core/storage/mongoStorage.go index 7454553..b429f4b 100644 --- a/core/storage/mongoStorage.go +++ b/core/storage/mongoStorage.go @@ -339,6 +339,14 @@ func (store *MongoStorage) StoreObject(metaData common.MetaData, data []byte, st (metaData.DestinationPolicy == nil && existingObject.MetaData.DestinationPolicy != nil) { return nil, &common.InvalidRequest{Message: "Can't update the existence of Destination Policy"} } + + // Don't allow updates to the service reference of an existing object. + if existingObject.MetaData.DestinationPolicy != nil && metaData.DestinationPolicy != nil { + if same := common.ComparePolicyServices(existingObject.MetaData.DestinationPolicy, metaData.DestinationPolicy); !same { + return nil, &common.InvalidRequest{Message: "Can't update the service name, org or version in Destination Policy"} + } + } + if metaData.MetaOnly { metaData.DataID = existingObject.MetaData.DataID metaData.ObjectSize = existingObject.MetaData.ObjectSize