/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(EntitySet); if (read == null || (read.ReadByKeyRestrictions == null && read.IsReadable) || (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable)) { // If we don't have Read by key read restriction, we should check the set read restrction. AddOperation(item, OperationType.Get); } UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet); if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Patch); } DeleteRestrictionsType delete = Context.Model.GetRecord <DeleteRestrictionsType>(EntitySet); if (delete == null || delete.IsDeletable) { AddOperation(item, OperationType.Delete); } }
private void AddUpdateOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction) { UpdateRestrictionsType update = restriction?.UpdateRestrictions; if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Put); } }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmVocabularyAnnotatable target = entitySet; if (target == null) { target = NavigationSource as IEdmSingleton; } NavigationRestrictionsType navSourceRestrictionType = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions); NavigationRestrictionsType navPropRestrictionType = Context.Model.GetRecord <NavigationRestrictionsType>(NavigationProperty, CapabilitiesConstants.NavigationRestrictions); NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? .FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath()) ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); // Check whether the navigation property should be part of the path if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) { return; } // containment: Get / (Post - Collection | Patch - Single) // non-containment: Get AddGetOperation(item, restriction); if (NavigationProperty.ContainsTarget) { if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { if (LastSegmentIsKeySegment) { UpdateRestrictionsType updateEntity = Context.Model.GetRecord <UpdateRestrictionsType>(_entityType); if (updateEntity?.IsUpdatable ?? true) { AddUpdateOperation(item, restriction); } } else { InsertRestrictionsType insert = restriction?.InsertRestrictions; if (insert?.IsInsertable ?? true) { AddOperation(item, OperationType.Post); } } } else { AddUpdateOperation(item, restriction); } } AddDeleteOperation(item, restriction); }
protected override void SetSecurity(OpenApiOperation operation) { UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet, CapabilitiesConstants.UpdateRestrictions); if (update == null || update.Permissions == null) { return; } operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList(); }
public void UnknownAnnotatableTargetReturnsDefaultUpdateRestrictionsValues() { // Arrange EdmEntityType entityType = new EdmEntityType("NS", "Entity"); // Act UpdateRestrictionsType update = EdmCoreModel.Instance.GetRecord <UpdateRestrictionsType>(entityType); // Assert Assert.Null(update); }
/// <inheritdoc/> protected override void SetSecurity(OpenApiOperation operation) { IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)NavigationSourceSegment.NavigationSource; UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(annotatableNavigationSource, CapabilitiesConstants.UpdateRestrictions); if (update == null || update.Permissions == null) { return; } operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList(); }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { // Retrieve a singleton. ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(Singleton); if (read == null || read.IsReadable) { AddOperation(item, OperationType.Get); } // Update a singleton UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(Singleton); if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Patch); } }
protected override void AppendCustomParameters(OpenApiOperation operation) { UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet, CapabilitiesConstants.UpdateRestrictions); if (update == null) { return; } if (update.CustomHeaders != null) { AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header); } if (update.CustomQueryOptions != null) { AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query); } }
public void TargetOnEntitySetReturnsCorrectUpdateRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location) { // Arrange const string template = @" <Annotations Target=""NS.Default/Calendars""> {0} </Annotations>"; IEdmModel model = GetEdmModel(template, location); Assert.NotNull(model); // guard IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars"); Assert.NotNull(calendars); // guard // Act UpdateRestrictionsType update = model.GetRecord <UpdateRestrictionsType>(calendars); // Assert VerifyUpdateRestrictions(update); }
public void TargetOnEntityTypeReturnsCorrectUpdateRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location) { // Arrange const string template = @" <Annotations Target=""NS.Calendar""> {0} </Annotations>"; IEdmModel model = GetEdmModel(template, location); Assert.NotNull(model); // guard IEdmEntityType calendar = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Calendar"); Assert.NotNull(calendar); // guard // Act UpdateRestrictionsType update = model.GetRecord <UpdateRestrictionsType>(calendar); // Assert VerifyUpdateRestrictions(update); }
private static void VerifyUpdateRestrictions(UpdateRestrictionsType update) { Assert.NotNull(update); Assert.NotNull(update.Updatable); Assert.False(update.Updatable.Value); Assert.NotNull(update.NonUpdatableNavigationProperties); Assert.Equal(2, update.NonUpdatableNavigationProperties.Count); Assert.Equal("abc|RelatedEvents", String.Join("|", update.NonUpdatableNavigationProperties)); Assert.True(update.IsNonUpdatableNavigationProperty("abc")); Assert.True(update.IsNonUpdatableNavigationProperty("RelatedEvents")); Assert.False(update.IsNonUpdatableNavigationProperty("Others")); // MaxLevels Assert.NotNull(update.MaxLevels); Assert.Equal(8, update.MaxLevels); // Permissions Assert.NotNull(update.Permissions); PermissionType permission = Assert.Single(update.Permissions); Assert.Equal("authorizationName", permission.SchemeName); Assert.Equal(2, permission.Scopes.Count); // QueryOptions Assert.NotNull(update.QueryOptions); Assert.True(update.QueryOptions.ComputeSupported); Assert.False(update.QueryOptions.SortSupported); // CustomHeaders Assert.NotNull(update.CustomHeaders); Assert.Equal(2, update.CustomHeaders.Count); // CustomQueryOptions Assert.NotNull(update.CustomQueryOptions); Assert.Equal(2, update.CustomQueryOptions.Count); }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { ReadRestrictionsType read = EntitySet != null ? Context.Model.GetRecord <ReadRestrictionsType>(EntitySet) : Context.Model.GetRecord <ReadRestrictionsType>(Singleton); if (read == null || (read.ReadByKeyRestrictions == null && read.IsReadable) || (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable)) { AddOperation(item, OperationType.Get); } UpdateRestrictionsType update = EntitySet != null ? Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet) : Context.Model.GetRecord <UpdateRestrictionsType>(Singleton); if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Put); } }
/// <inheritdoc/> protected override void SetBasicInfo(OpenApiOperation operation) { // Summary string placeholderValue = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "media content"; operation.Summary = IsNavigationPropertyPath ? $"Update {placeholderValue} for the navigation property {NavigationProperty.Name} in {NavigationSource.Name}" : $"Update {placeholderValue} for {NavigationSourceSegment.EntityType.Name} in {NavigationSourceSegment.Identifier}"; // Description if (LastSegmentIsStreamPropertySegment) { IEdmVocabularyAnnotatable annotatable = GetAnnotatableElement(); string description; if (annotatable is IEdmNavigationProperty) { UpdateRestrictionsType updateRestriction = Context.Model.GetRecord <NavigationRestrictionsType>(annotatable, CapabilitiesConstants.NavigationRestrictions)? .RestrictedProperties?.FirstOrDefault()?.UpdateRestrictions; description = updateRestriction?.Description ?? Context.Model.GetDescriptionAnnotation(annotatable); } else { // Structural property description = Context.Model.GetDescriptionAnnotation(annotatable); } operation.Description = description; } // OperationId if (Context.Settings.EnableOperationId) { string identifier = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "Content"; operation.OperationId = GetOperationId("Update", identifier); } }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { bool isReadable = Context.Model.GetRecord <ReadRestrictionsType>(ComplexProperty, CapabilitiesConstants.ReadRestrictions)?.Readable ?? false; if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isReadable) || !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths) { AddOperation(item, OperationType.Get); } UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(ComplexProperty, CapabilitiesConstants.UpdateRestrictions); bool isUpdatable = update?.Updatable ?? false; if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isUpdatable) || !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths) { if (update != null && update.IsUpdateMethodPut) { AddOperation(item, OperationType.Put); } else { AddOperation(item, OperationType.Patch); } } if (Path.LastSegment is ODataComplexPropertySegment segment && segment.Property.Type.IsCollection()) { bool isInsertable = Context.Model.GetRecord <InsertRestrictionsType>(ComplexProperty, CapabilitiesConstants.InsertRestrictions)?.Insertable ?? false; if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isInsertable) || !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths) { AddOperation(item, OperationType.Post); } } }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmVocabularyAnnotatable target = entitySet; if (target == null) { target = NavigationSource as IEdmSingleton; } string navigationPropertyPath = String.Join("/", Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier)); NavigationRestrictionsType navigation = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions); NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath); // verify using individual first if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None) { return; } if (restriction == null || restriction.Navigability == null) { // if the individual has not navigability setting, use the global navigability setting if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None) { // Default navigability for all navigation properties of the annotation target. // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. return; } } // So far, we only consider the non-containment Debug.Assert(!NavigationProperty.ContainsTarget); // It seems OData supports to "GetRef, DeleteRef", // Here at this time,let's only consider the "delete" ReadRestrictionsType read = restriction?.ReadRestrictions; if (read == null || read.IsReadable) { AddOperation(item, OperationType.Get); } // Create the ref if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { InsertRestrictionsType insert = restriction?.InsertRestrictions; if (insert == null || insert.IsInsertable) { AddOperation(item, OperationType.Post); } } else { UpdateRestrictionsType update = restriction?.UpdateRestrictions; if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Put); } // delete the link DeleteRestrictionsType delete = restriction?.DeleteRestrictions; if (delete == null || delete.IsDeletable) { AddOperation(item, OperationType.Delete); } } }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmVocabularyAnnotatable target = entitySet; if (target == null) { target = NavigationSource as IEdmSingleton; } string navigationPropertyPath = String.Join("/", Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier)); NavigationRestrictionsType navigation = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions); NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath); // verify using individual first if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None) { return; } if (restriction == null || restriction.Navigability == null) { // if the individual has not navigability setting, use the global navigability setting if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None) { // Default navigability for all navigation properties of the annotation target. // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. return; } } // how about delete? // contaiment: Get / (Post - Collection | Patch - Single) // non-containment: only Get AddGetOperation(item, restriction); if (NavigationProperty.ContainsTarget) { if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { if (LastSegmentIsKeySegment) { // Need to check this scenario is valid or not? UpdateRestrictionsType update = restriction?.UpdateRestrictions; if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Patch); } } else { InsertRestrictionsType insert = restriction?.InsertRestrictions; if (insert == null || insert.IsInsertable) { AddOperation(item, OperationType.Post); } } } else { UpdateRestrictionsType update = restriction?.UpdateRestrictions; if (update == null || update.IsUpdatable) { AddOperation(item, OperationType.Patch); } } } }
protected override void Initialize(ODataContext context, ODataPath path) { base.Initialize(context, path); _updateRestrictions = Context.Model.GetRecord <UpdateRestrictionsType>(Singleton, CapabilitiesConstants.UpdateRestrictions); }
protected override void Initialize(ODataContext context, ODataPath path) { base.Initialize(context, path); _updateRestrictions = Context.Model.GetRecord <UpdateRestrictionsType>(ComplexPropertySegment.Property, CapabilitiesConstants.UpdateRestrictions); }