Update to ODL.Edm 7.6.1.beta: Permission, Custom Heads, etc
This commit is contained in:
parent
f362c34e31
commit
1589b2622a
|
@ -695949,9 +695949,9 @@
|
|||
},
|
||||
"microsoft.graph.rgbColor": {
|
||||
"value": {
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0
|
||||
"b": "AA==",
|
||||
"g": "AA==",
|
||||
"r": "AA=="
|
||||
}
|
||||
},
|
||||
"microsoft.graph.mimeContent": {
|
||||
|
|
|
@ -515204,9 +515204,9 @@
|
|||
},
|
||||
"microsoft.graph.rgbColor": {
|
||||
"value": {
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0
|
||||
"b": "AA==",
|
||||
"g": "AA==",
|
||||
"r": "AA=="
|
||||
}
|
||||
},
|
||||
"microsoft.graph.deviceCategory": {
|
||||
|
|
|
@ -515204,9 +515204,9 @@
|
|||
},
|
||||
"microsoft.graph.rgbColor": {
|
||||
"value": {
|
||||
"b": 0,
|
||||
"g": 0,
|
||||
"r": 0
|
||||
"b": "AA==",
|
||||
"g": "AA==",
|
||||
"r": "AA=="
|
||||
}
|
||||
},
|
||||
"microsoft.graph.deviceCategory": {
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.Key;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name
|
||||
public override string Identifier
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.NavigationProperty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name { get => NavigationProperty.Name; }
|
||||
public override string Identifier { get => NavigationProperty.Name; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings) => NavigationProperty.Name;
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override IEdmEntityType EntityType => NavigationSource.EntityType();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name { get => NavigationSource.Name; }
|
||||
public override string Identifier { get => NavigationSource.Name; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ODataSegmentKind Kind => ODataSegmentKind.NavigationSource;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.OperationImport;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name { get => OperationImport.Name; }
|
||||
public override string Identifier { get => OperationImport.Name; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings)
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.Operation;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name { get => Operation.Name; }
|
||||
public override string Identifier { get => Operation.Name; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings)
|
||||
|
|
|
@ -60,9 +60,9 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public abstract ODataSegmentKind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of this segment.
|
||||
/// Gets the identifier of this segment.
|
||||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
public abstract string Identifier { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path item name for this segment.
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.TypeCast;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name { get => EntityType.FullTypeName(); }
|
||||
public override string Identifier { get => EntityType.FullTypeName(); }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings) => EntityType.FullTypeName();
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Microsoft.OpenApi.OData
|
|||
public static class EdmModelOpenApiExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/>.
|
||||
/// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/> using default settings.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The converted Open API document object, <see cref="OpenApiDocument"/>.</returns>
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = permission.Scheme.Authorization
|
||||
Id = permission.SchemeName
|
||||
}
|
||||
}
|
||||
] = new List<string>(permission.Scopes?.Select(c => c.Scope) ?? new List<string>())
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OData.Edm" Version="7.6.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.OData.Edm" Version="7.6.1-beta" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -27,7 +27,10 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
IEdmFunctionImport functionImport = EdmOperationImport as IEdmFunctionImport;
|
||||
//The parameters array contains a Parameter Object for each parameter of the function overload,
|
||||
// and it contains specific Parameter Objects for the allowed system query options.
|
||||
operation.Parameters = Context.CreateParameters(functionImport);
|
||||
foreach (var param in Context.CreateParameters(functionImport))
|
||||
{
|
||||
operation.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Generator;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation
|
||||
{
|
||||
|
@ -68,6 +70,38 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
base.SetResponses(operation);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
OperationRestrictionsType restriction = Context.Model.GetRecord<OperationRestrictionsType>(EdmOperationImport, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restriction == null || restriction.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
operation.Security = Context.CreateSecurityRequirements(restriction.Permissions).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
{
|
||||
OperationRestrictionsType restriction = Context.Model.GetRecord<OperationRestrictionsType>(EdmOperationImport, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restriction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (restriction.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation, restriction.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (restriction.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation, restriction.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetTags(OpenApiOperation operation)
|
||||
{
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
// OperationId
|
||||
if (Context.Settings.EnableOperationId)
|
||||
{
|
||||
string operationId = String.Join(".", Path.Segments.Where(s => !(s is ODataKeySegment)).Select(s => s.Name));
|
||||
string operationId = String.Join(".", Path.Segments.Where(s => !(s is ODataKeySegment)).Select(s => s.Identifier));
|
||||
if (EdmOperation.IsAction())
|
||||
{
|
||||
operation.OperationId = operationId;
|
||||
|
@ -154,40 +154,32 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
/// <inheritdoc/>
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
IEnumerable<OperationRestrictionType> restrictions = Context.Model.GetCollection<OperationRestrictionType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restrictions == null || !restrictions.Any())
|
||||
OperationRestrictionsType restriction = Context.Model.GetRecord<OperationRestrictionsType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restriction == null || restriction.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: how to use the collection?
|
||||
OperationRestrictionType operationRestriction = restrictions.First();
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { operationRestriction.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(restriction.Permissions).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
{
|
||||
IEnumerable<OperationRestrictionType> restrictions = Context.Model.GetCollection<OperationRestrictionType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restrictions == null || !restrictions.Any())
|
||||
OperationRestrictionsType restriction = Context.Model.GetRecord<OperationRestrictionsType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
|
||||
if (restriction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: how to use the collection?
|
||||
OperationRestrictionType operationRestriction = restrictions.First();
|
||||
|
||||
if (operationRestriction.CustomHeaders != null)
|
||||
if (restriction.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, operationRestriction.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, restriction.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (operationRestriction.CustomQueryOptions != null)
|
||||
if (restriction.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, operationRestriction.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, restriction.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,14 +71,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
DeleteRestrictionsType delete = Context.Model.GetRecord<DeleteRestrictionsType>(EntitySet, CapabilitiesConstants.DeleteRestrictions);
|
||||
if (delete == null || delete.Permission == null)
|
||||
if (delete == null || delete.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { delete.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(delete.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
|
@ -91,12 +89,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (delete.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, delete.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, delete.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (delete.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, delete.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, delete.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,14 +110,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
readBase = read.ReadByKeyRestrictions;
|
||||
}
|
||||
|
||||
if (readBase == null && readBase.Permission == null)
|
||||
if (readBase == null && readBase.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { readBase.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(readBase.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
|
@ -136,12 +134,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (readBase.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, readBase.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, readBase.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (readBase.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, readBase.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, readBase.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,14 +83,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(EntitySet, CapabilitiesConstants.UpdateRestrictions);
|
||||
if (update == null || update.Permission == null)
|
||||
if (update == null || update.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { update.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
|
@ -103,12 +101,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (update.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, update.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (update.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, update.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,14 +165,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);
|
||||
if (read == null || read.Permission == null)
|
||||
if (read == null || read.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { read.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
|
@ -185,12 +183,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (read.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, read.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, read.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (read.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, read.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, read.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,14 +109,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
InsertRestrictionsType insert = Context.Model.GetRecord<InsertRestrictionsType>(EntitySet, CapabilitiesConstants.InsertRestrictions);
|
||||
if (insert == null || insert.Permission == null)
|
||||
if (insert == null || insert.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { insert.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(insert.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
|
@ -129,12 +127,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (insert.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, insert.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, insert.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
|
||||
if (insert.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, insert.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, insert.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Generator;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation
|
||||
{
|
||||
|
@ -198,5 +201,51 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.ReadRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReadRestrictionsBase readBase = Restriction.ReadRestrictions;
|
||||
if (LastSegmentIsKeySegment)
|
||||
{
|
||||
if (Restriction.ReadRestrictions.ReadByKeyRestrictions != null)
|
||||
{
|
||||
readBase = Restriction.ReadRestrictions.ReadByKeyRestrictions;
|
||||
}
|
||||
}
|
||||
|
||||
operation.Security = Context.CreateSecurityRequirements(readBase.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.ReadRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReadRestrictionsBase readBase = Restriction.ReadRestrictions;
|
||||
if (LastSegmentIsKeySegment)
|
||||
{
|
||||
if (Restriction.ReadRestrictions.ReadByKeyRestrictions != null)
|
||||
{
|
||||
readBase = Restriction.ReadRestrictions.ReadByKeyRestrictions;
|
||||
}
|
||||
}
|
||||
|
||||
if (readBase.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation, readBase.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (readBase.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation, readBase.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ using Microsoft.OpenApi.Any;
|
|||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation
|
||||
{
|
||||
|
@ -33,6 +34,11 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
/// </summary>
|
||||
protected string NavigationPropertyPath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the navigation restriction.
|
||||
/// </summary>
|
||||
protected NavigationPropertyRestriction Restriction { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a bool value indicating whether the last segment is a key segment.
|
||||
/// </summary>
|
||||
|
@ -56,10 +62,25 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
NavigationProperty = npSegment.NavigationProperty;
|
||||
|
||||
NavigationPropertyPath = string.Join("/",
|
||||
path.Segments.OfType<ODataNavigationPropertySegment>().Select(p => p.NavigationProperty.Name));
|
||||
Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));
|
||||
|
||||
// So far, we haven't defined the HttpRequest for the navigation property path.
|
||||
// Request = Context.FindRequest(NavigationSource, OperationType.ToString());
|
||||
IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet;
|
||||
IEdmSingleton singleton = NavigationSource as IEdmSingleton;
|
||||
|
||||
NavigationRestrictionsType navigation;
|
||||
if (entitySet != null)
|
||||
{
|
||||
navigation = Context.Model.GetRecord<NavigationRestrictionsType>(entitySet, CapabilitiesConstants.NavigationRestrictions);
|
||||
}
|
||||
else
|
||||
{
|
||||
navigation = Context.Model.GetRecord<NavigationRestrictionsType>(singleton, CapabilitiesConstants.NavigationRestrictions);
|
||||
}
|
||||
|
||||
if (navigation != null && navigation.RestrictedProperties != null)
|
||||
{
|
||||
Restriction = navigation.RestrictedProperties.FirstOrDefault(r => r.NavigationProperty != null && r.NavigationProperty == NavigationPropertyPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
|
@ -76,5 +77,34 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
base.SetResponses(operation);
|
||||
}
|
||||
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.UpdateRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operation.Security = Context.CreateSecurityRequirements(Restriction.UpdateRestrictions.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.UpdateRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Restriction.UpdateRestrictions.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation, Restriction.UpdateRestrictions.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (Restriction.UpdateRestrictions.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation, Restriction.UpdateRestrictions.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
|
@ -99,5 +100,33 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
base.SetResponses(operation);
|
||||
}
|
||||
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.InsertRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
operation.Security = Context.CreateSecurityRequirements(Restriction.InsertRestrictions.Permissions).ToList();
|
||||
}
|
||||
|
||||
protected override void AppendCustomParameters(OpenApiOperation operation)
|
||||
{
|
||||
if (Restriction == null || Restriction.InsertRestrictions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Restriction.InsertRestrictions.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation, Restriction.InsertRestrictions.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (Restriction.InsertRestrictions.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation, Restriction.InsertRestrictions.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
/// <param name="parameters">The parameters.</param>
|
||||
/// <param name="customParameters">The custom parameters.</param>
|
||||
/// <param name="location">The parameter location.</param>
|
||||
protected static void AppendCustomParameters(IList<OpenApiParameter> parameters, IList<CustomParameter> customParameters, ParameterLocation location)
|
||||
protected static void AppendCustomParameters(OpenApiOperation operation, IList<CustomParameter> customParameters, ParameterLocation location)
|
||||
{
|
||||
foreach (var param in customParameters)
|
||||
{
|
||||
|
@ -206,7 +206,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
}
|
||||
}
|
||||
|
||||
parameters.Add(parameter);
|
||||
operation.Parameters.Add(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,14 +100,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(Singleton, CapabilitiesConstants.ReadRestrictions);
|
||||
if (read == null || read.Permission == null)
|
||||
if (read == null || read.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { read.Permission.Scheme }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -121,12 +119,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (read.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, read.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, read.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (read.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, read.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, read.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,14 +84,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(Singleton, CapabilitiesConstants.UpdateRestrictions);
|
||||
if (update == null || update.Permission == null)
|
||||
if (update == null || update.Permissions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the Permission should be collection, however current ODL supports the single permission.
|
||||
// Will update after ODL change.
|
||||
operation.Security = Context.CreateSecurityRequirements(new[] { update.Permission }).ToList();
|
||||
operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -105,12 +103,12 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (update.CustomHeaders != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, update.CustomHeaders, ParameterLocation.Header);
|
||||
AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header);
|
||||
}
|
||||
|
||||
if (update.CustomQueryOptions != null)
|
||||
{
|
||||
AppendCustomParameters(operation.Parameters, update.CustomQueryOptions, ParameterLocation.Query);
|
||||
AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
|
@ -49,22 +50,33 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
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);
|
||||
if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
|
||||
NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);
|
||||
|
||||
// verify using individual first
|
||||
if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
|
||||
{
|
||||
// This check should be done when retrieve the path, but, here is for verification.
|
||||
return;
|
||||
}
|
||||
|
||||
string navigationPropertyPath = String.Join("/",
|
||||
Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Name));
|
||||
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
|
||||
if (navigation == null || !navigation.IsRestrictedProperty(navigationPropertyPath))
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
AddGetOperation(item, restriction);
|
||||
|
||||
if (NavigationProperty.ContainsTarget)
|
||||
{
|
||||
|
@ -73,16 +85,16 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
if (LastSegmentIsKeySegment)
|
||||
{
|
||||
// Need to check this scenario is valid or not?
|
||||
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(target, CapabilitiesConstants.UpdateRestrictions);
|
||||
if (update == null || !update.IsNonUpdatableNavigationProperty(navigationPropertyPath))
|
||||
UpdateRestrictionsType update = restriction?.UpdateRestrictions;
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertRestrictionsType insert = Context.Model.GetRecord<InsertRestrictionsType>(target, CapabilitiesConstants.InsertRestrictions);
|
||||
if (insert == null || !insert.IsNonInsertableNavigationProperty(navigationPropertyPath))
|
||||
InsertRestrictionsType insert = restriction?.InsertRestrictions;
|
||||
if (insert == null || insert.IsInsertable)
|
||||
{
|
||||
AddOperation(item, OperationType.Post);
|
||||
}
|
||||
|
@ -90,8 +102,8 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
}
|
||||
else
|
||||
{
|
||||
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(target, CapabilitiesConstants.UpdateRestrictions);
|
||||
if (update == null || !update.IsNonUpdatableNavigationProperty(navigationPropertyPath))
|
||||
UpdateRestrictionsType update = restriction?.UpdateRestrictions;
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
|
@ -99,6 +111,52 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
}
|
||||
}
|
||||
|
||||
private void AddGetOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
|
||||
{
|
||||
ReadRestrictionsType read = restriction?.ReadRestrictions;
|
||||
if (read == null)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
{
|
||||
if (LastSegmentIsKeySegment)
|
||||
{
|
||||
if (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.Readable != null)
|
||||
{
|
||||
if (read.ReadByKeyRestrictions.Readable.Value)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read.IsReadable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read.IsReadable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(LastSegmentIsKeySegment == false);
|
||||
if (read.IsReadable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
|
|
|
@ -32,10 +32,20 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public int? MaxLevels { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Members of collections can be updated via a PATCH request with a `/$filter(...)/$each` segment.
|
||||
/// </summary>
|
||||
public bool? FilterSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Members of collections can be updated via a PATCH request with a type-cast segment and a `/$each` segment.
|
||||
/// </summary>
|
||||
public bool? TypecastSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the required scopes to perform the insert.
|
||||
/// </summary>
|
||||
public PermissionType Permission { get; private set; }
|
||||
public IList<PermissionType> Permissions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Supported or required custom headers.
|
||||
|
@ -47,6 +57,16 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public IList<CustomParameter> CustomQueryOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A brief description of the request.
|
||||
/// </summary>
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A lengthy description of the request.
|
||||
/// </summary>
|
||||
public string LongDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports delete.
|
||||
/// </summary>
|
||||
|
@ -82,14 +102,26 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// MaxLevels
|
||||
MaxLevels = (int?)record.GetInteger("MaxLevels");
|
||||
|
||||
// Permission
|
||||
Permission = record.GetRecord<PermissionType>("Permission");
|
||||
// FilterSegmentSupported
|
||||
FilterSegmentSupported = record.GetBoolean("FilterSegmentSupported");
|
||||
|
||||
// TypecastSegmentSupported
|
||||
TypecastSegmentSupported = record.GetBoolean("TypecastSegmentSupported");
|
||||
|
||||
// Permissions
|
||||
Permissions = record.GetCollection<PermissionType>("Permissions");
|
||||
|
||||
// CustomHeaders
|
||||
CustomHeaders = record.GetCollection<CustomParameter>("CustomHeaders");
|
||||
|
||||
// CustomQueryOptions
|
||||
CustomQueryOptions = record.GetCollection<CustomParameter>("CustomQueryOptions");
|
||||
|
||||
// Description
|
||||
Description = record.GetString("Description");
|
||||
|
||||
// LongDescription
|
||||
LongDescription = record.GetString("LongDescription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public bool? Expandable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the $expand is supported for stream properties and media resources.
|
||||
/// </summary>
|
||||
public bool? StreamsExpandable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties which cannot be used in $expand expressions.
|
||||
/// </summary>
|
||||
|
@ -55,6 +60,9 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// Expandable
|
||||
Expandable = record.GetBoolean("Expandable");
|
||||
|
||||
// StreamsExpandable
|
||||
StreamsExpandable = record.GetBoolean("StreamsExpandable");
|
||||
|
||||
// NonExpandableProperties
|
||||
NonExpandableProperties = record.GetCollectionPropertyPath("NonExpandableProperties");
|
||||
|
||||
|
|
|
@ -37,10 +37,15 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public long? MaxLevels { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Entities of a specific derived type can be created by specifying a type-cast segment.
|
||||
/// </summary>
|
||||
public bool? TypecastSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the required scopes to perform the insert.
|
||||
/// </summary>
|
||||
public PermissionType Permission { get; private set; }
|
||||
public IList<PermissionType> Permissions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Support for query options with insert requests.
|
||||
|
@ -57,6 +62,16 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public IList<CustomParameter> CustomQueryOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A brief description of the request.
|
||||
/// </summary>
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A lengthy description of the request.
|
||||
/// </summary>
|
||||
public string LongDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports insert.
|
||||
/// </summary>
|
||||
|
@ -92,8 +107,11 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// MaxLevels
|
||||
MaxLevels = record.GetInteger("MaxLevels");
|
||||
|
||||
// Permission
|
||||
Permission = record.GetRecord<PermissionType>("Permission");
|
||||
// TypecastSegmentSupported
|
||||
TypecastSegmentSupported = record.GetBoolean("TypecastSegmentSupported");
|
||||
|
||||
// Permissions
|
||||
Permissions = record.GetCollection<PermissionType>("Permissions");
|
||||
|
||||
// QueryOptions
|
||||
QueryOptions = record.GetRecord<ModificationQueryOptionsType>("QueryOptions");
|
||||
|
@ -103,6 +121,12 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
|
||||
// CustomHeaders
|
||||
CustomQueryOptions = record.GetCollection<CustomParameter>("CustomQueryOptions");
|
||||
|
||||
// Description
|
||||
Description = record.GetString("Description");
|
||||
|
||||
// LongDescription
|
||||
LongDescription = record.GetString("LongDescription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,20 @@ using Microsoft.OpenApi.OData.Edm;
|
|||
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Complex Type: Org.OData.Capabilities.V1.OperationRestrictionType
|
||||
/// Be note: in ODL 7.6, it's named as "OperationRestriction", after that, it will be changed as "OperationRestrictionType"
|
||||
/// Complex Type: Org.OData.Capabilities.V1.OperationRestrictionsType
|
||||
/// </summary>
|
||||
[Term("Org.OData.Capabilities.V1.OperationRestrictions")]
|
||||
internal class OperationRestrictionType : IRecord
|
||||
internal class OperationRestrictionsType : IRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Bound action or function can be invoked on a collection-valued binding parameter path with a '/$filter(...)' segment.
|
||||
/// </summary>
|
||||
public bool? FilterSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the List of required scopes to invoke an action or function.
|
||||
/// </summary>
|
||||
public PermissionType Permission { get; private set; }
|
||||
public IList<PermissionType> Permissions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Supported or required custom headers.
|
||||
|
@ -40,8 +44,11 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
{
|
||||
Utils.CheckArgumentNull(record, nameof(record));
|
||||
|
||||
// Permission
|
||||
Permission = record.GetRecord<PermissionType>("Permission");
|
||||
// FilterSegmentSupported
|
||||
FilterSegmentSupported = record.GetBoolean("FilterSegmentSupported");
|
||||
|
||||
// Permissions
|
||||
Permissions = record.GetCollection<PermissionType>("Permissions");
|
||||
|
||||
// CustomHeaders
|
||||
CustomHeaders = record.GetCollection<CustomParameter>("CustomHeaders");
|
|
@ -3,11 +3,11 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
||||
{
|
||||
|
@ -17,14 +17,14 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
internal class PermissionType : IRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the auth flow scheme name.
|
||||
/// Gets the Authorization flow scheme name.
|
||||
/// </summary>
|
||||
public SecurityScheme Scheme { get; private set; }
|
||||
public string SchemeName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of scopes that can provide access to the resource.
|
||||
/// </summary>
|
||||
public IEnumerable<ScopeType> Scopes { get; private set; }
|
||||
public IList<ScopeType> Scopes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Init the <see cref="PermissionType"/>.
|
||||
|
@ -34,8 +34,8 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
{
|
||||
Utils.CheckArgumentNull(record, nameof(record));
|
||||
|
||||
// Scheme
|
||||
Scheme = record.GetRecord<SecurityScheme>("Scheme");
|
||||
// SchemeName
|
||||
SchemeName = record.GetString("SchemeName");
|
||||
|
||||
// Scopes
|
||||
Scopes = record.GetCollection<ScopeType>("Scopes");
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// <summary>
|
||||
/// Gets the List of required scopes to invoke an action or function
|
||||
/// </summary>
|
||||
public PermissionType Permission { get; private set; }
|
||||
public IList<PermissionType> Permissions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Supported or required custom headers.
|
||||
|
@ -35,6 +35,16 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public IList<CustomParameter> CustomQueryOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A brief description of the request.
|
||||
/// </summary>
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A lengthy description of the request.
|
||||
/// </summary>
|
||||
public string LongDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports update.
|
||||
/// </summary>
|
||||
|
@ -52,14 +62,20 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// Readable
|
||||
Readable = record.GetBoolean("Readable");
|
||||
|
||||
// Permission
|
||||
Permission = record.GetRecord<PermissionType>("Permission");
|
||||
// Permissions
|
||||
Permissions = record.GetCollection<PermissionType>("Permissions");
|
||||
|
||||
// CustomHeaders
|
||||
CustomHeaders = record.GetCollection<CustomParameter>("CustomHeaders");
|
||||
|
||||
// CustomQueryOptions
|
||||
CustomQueryOptions = record.GetCollection<CustomParameter>("CustomQueryOptions");
|
||||
|
||||
// Description
|
||||
Description = record.GetString("Description");
|
||||
|
||||
// LongDescription
|
||||
LongDescription = record.GetString("LongDescription");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public bool? Supported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Supports instance annotations in $select list.
|
||||
/// </summary>
|
||||
public bool? InstanceAnnotationsSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the $expand within $select is supported.
|
||||
/// </summary>
|
||||
|
@ -71,6 +76,9 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// Supported
|
||||
Supported = record.GetBoolean("Supported");
|
||||
|
||||
// Expandable
|
||||
InstanceAnnotationsSupported = record.GetBoolean("InstanceAnnotationsSupported");
|
||||
|
||||
// Expandable
|
||||
Expandable = record.GetBoolean("Expandable");
|
||||
|
||||
|
|
|
@ -23,6 +23,26 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public bool? Updatable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value indicating Entities can be upserted.
|
||||
/// </summary>
|
||||
public bool? Upsertable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value indicating Entities can be inserted, updated, and deleted via a PATCH request with a delta payload.
|
||||
/// </summary>
|
||||
public bool? DeltaUpdateSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value indicating Members of collections can be updated via a PATCH request with a '/$filter(...)/$each' segment.
|
||||
/// </summary>
|
||||
public bool? FilterSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value indicating Members of collections can be updated via a PATCH request with a type-cast segment and a '/$each' segment.
|
||||
/// </summary>
|
||||
public bool? TypecastSegmentSupported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the navigation properties which do not allow rebinding.
|
||||
/// </summary>
|
||||
|
@ -35,9 +55,9 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
public long? MaxLevels { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the required scopes to perform update.
|
||||
/// Gets the Required permissions. One of the specified sets of scopes is required to perform the update.
|
||||
/// </summary>
|
||||
public PermissionType Permission { get; private set; }
|
||||
public IList<PermissionType> Permissions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the support for query options with update requests.
|
||||
|
@ -54,6 +74,16 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
/// </summary>
|
||||
public IList<CustomParameter> CustomQueryOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A brief description of the request.
|
||||
/// </summary>
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets A lengthy description of the request.
|
||||
/// </summary>
|
||||
public string LongDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports update.
|
||||
/// </summary>
|
||||
|
@ -83,14 +113,26 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
// Updatable
|
||||
Updatable = record.GetBoolean("Updatable");
|
||||
|
||||
// Upsertable
|
||||
Upsertable = record.GetBoolean("Upsertable");
|
||||
|
||||
// DeltaUpdateSupported
|
||||
DeltaUpdateSupported = record.GetBoolean("DeltaUpdateSupported");
|
||||
|
||||
// FilterSegmentSupported
|
||||
FilterSegmentSupported = record.GetBoolean("FilterSegmentSupported");
|
||||
|
||||
// TypecastSegmentSupported
|
||||
TypecastSegmentSupported = record.GetBoolean("TypecastSegmentSupported");
|
||||
|
||||
// NonUpdatableNavigationProperties
|
||||
NonUpdatableNavigationProperties = record.GetCollectionPropertyPath("NonUpdatableNavigationProperties");
|
||||
|
||||
// MaxLevels
|
||||
MaxLevels = record.GetInteger("MaxLevels");
|
||||
|
||||
// Permission
|
||||
Permission = record.GetRecord<PermissionType>("Permission");
|
||||
// Permissions
|
||||
Permissions = record.GetCollection<PermissionType>("Permissions");
|
||||
|
||||
// QueryOptions
|
||||
QueryOptions = record.GetRecord<ModificationQueryOptionsType>("QueryOptions");
|
||||
|
@ -100,6 +142,12 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
|
|||
|
||||
// CustomQueryOptions
|
||||
CustomQueryOptions = record.GetCollection<CustomParameter>("CustomQueryOptions");
|
||||
|
||||
// Description
|
||||
Description = record.GetString("Description");
|
||||
|
||||
// LongDescription
|
||||
LongDescription = record.GetString("LongDescription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary
|
|||
internal class TermAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ODataPath"/> class.
|
||||
/// Initializes a new instance of <see cref="TermAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="qualifiedName">The qualified name of this term.</param>
|
||||
public TermAttribute(string qualifiedName)
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.OData.Edm, Version=7.6.0.30605, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.OData.Edm.7.6.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll</HintPath>
|
||||
<Reference Include="Microsoft.OData.Edm, Version=7.6.1.30918, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.OData.Edm.7.6.1-beta\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.OpenApi, Version=1.1.2.0, Culture=neutral, PublicKeyToken=3f5743946376f042, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.OpenApi.1.1.2\lib\net46\Microsoft.OpenApi.dll</HintPath>
|
||||
<Reference Include="Microsoft.OpenApi, Version=1.1.4.0, Culture=neutral, PublicKeyToken=3f5743946376f042, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.OpenApi.1.1.4\lib\net46\Microsoft.OpenApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OoasGui
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.OData.Edm" version="7.6.0" targetFramework="net461" />
|
||||
<package id="Microsoft.OpenApi" version="1.1.2" targetFramework="net461" />
|
||||
<package id="Microsoft.OData.Edm" version="7.6.1-beta" targetFramework="net461" />
|
||||
<package id="Microsoft.OpenApi" version="1.1.4" targetFramework="net461" />
|
||||
</packages>
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
@ -46,7 +49,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmActionReturnsCorrectOperationId(bool enableOperationId)
|
||||
public void CreateOperationForEdmActionImportReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
|
@ -84,5 +87,155 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OperationRestrictionsTermWorksToCreateOperationForEdmActionImport(bool enableAnnotation)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<Action Name=""ResetDataSource"" />
|
||||
<EntityContainer Name=""GraphService"">
|
||||
<ActionImport Name=""ResetDataSource"" Action=""NS.ResetDataSource"" >
|
||||
{0}
|
||||
</ActionImport>
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>
|
||||
";
|
||||
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.OperationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
string csdl = string.Format(template, enableAnnotation ? annotation : "");
|
||||
|
||||
var edmModel = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
|
||||
Assert.NotNull(edmModel);
|
||||
IEdmOperationImport operationImport = edmModel.EntityContainer.FindOperationImports("ResetDataSource").FirstOrDefault();
|
||||
Assert.NotNull(operationImport);
|
||||
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataOperationImportSegment(operationImport));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom query options
|
||||
Assert.Contains(@"
|
||||
""parameters"": [
|
||||
{
|
||||
""name"": ""odata-debug"",
|
||||
""in"": ""query"",
|
||||
""description"": ""Debug support for OData services"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Service responds with self-contained..."",
|
||||
""value"": ""html""
|
||||
},
|
||||
""example-2"": {
|
||||
""description"": ""Service responds with JSON document..."",
|
||||
""value"": ""json""
|
||||
}
|
||||
}
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
@ -139,5 +142,116 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OperationRestrictionsTermWorksToCreateOperationForEdmAction(bool enableAnnotation)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""user"" />
|
||||
<Action Name=""getMemberGroups"" IsBound=""true"">
|
||||
<Parameter Name=""bindingParameter"" Type=""NS.user"" Nullable=""false"" />
|
||||
{0}
|
||||
</Action>
|
||||
<EntityContainer Name=""GraphService"">
|
||||
<Singleton Name=""me"" Type=""NS.user"" />
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>
|
||||
";
|
||||
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.OperationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
string csdl = string.Format(template, enableAnnotation ? annotation : "");
|
||||
|
||||
var edmModel = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
|
||||
Assert.NotNull(edmModel);
|
||||
IEdmSingleton me = edmModel.EntityContainer.FindSingleton("me");
|
||||
Assert.NotNull(me);
|
||||
IEdmAction action = edmModel.SchemaElements.OfType<IEdmAction>().SingleOrDefault();
|
||||
Assert.NotNull(action);
|
||||
Assert.Equal("getMemberGroups", action.Name);
|
||||
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me),
|
||||
new ODataOperationSegment(action));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
@ -85,5 +88,133 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OperationRestrictionsTermWorksToCreateOperationForEdmFunctionImport(bool enableAnnotation)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<Function Name=""GetNearestAirport"">
|
||||
<Parameter Name=""lat"" Type=""Edm.Double"" Nullable=""false"" />
|
||||
<Parameter Name=""lon"" Type=""Edm.Double"" Nullable=""false"" />
|
||||
<ReturnType Type=""Edm.String"" />
|
||||
</Function>
|
||||
<EntityContainer Name=""GraphService"">
|
||||
<FunctionImport Name=""GetNearestAirport"" Function=""NS.GetNearestAirport"" >
|
||||
{0}
|
||||
</FunctionImport>
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>
|
||||
";
|
||||
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.OperationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""myhead1"" />
|
||||
<PropertyValue Property=""Required"" Bool=""true"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
string csdl = string.Format(template, enableAnnotation ? annotation : "");
|
||||
|
||||
var edmModel = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
|
||||
Assert.NotNull(edmModel);
|
||||
IEdmOperationImport operationImport = edmModel.EntityContainer.FindOperationImports("GetNearestAirport").FirstOrDefault();
|
||||
Assert.NotNull(operationImport);
|
||||
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataOperationImportSegment(operationImport));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
Assert.Contains(@"
|
||||
{
|
||||
""name"": ""myhead1"",
|
||||
""in"": ""header"",
|
||||
""required"": true,
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
}
|
||||
}
|
||||
".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
@ -143,5 +142,117 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OperationRestrictionsTermWorksToCreateOperationForEdmFunction(bool enableAnnotation)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""user"" />
|
||||
<Function Name=""getMemberGroups"" IsBound=""true"">
|
||||
<Parameter Name=""bindingParameter"" Type=""NS.user"" Nullable=""false"" />
|
||||
<ReturnType Type=""Edm.String"" Nullable=""false"" />
|
||||
{0}
|
||||
</Function>
|
||||
<EntityContainer Name=""GraphService"">
|
||||
<Singleton Name=""me"" Type=""NS.user"" />
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>
|
||||
";
|
||||
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.OperationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
string csdl = string.Format(template, enableAnnotation ? annotation : "");
|
||||
|
||||
var edmModel = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
|
||||
Assert.NotNull(edmModel);
|
||||
IEdmSingleton me = edmModel.EntityContainer.FindSingleton("me");
|
||||
Assert.NotNull(me);
|
||||
IEdmFunction function = edmModel.SchemaElements.OfType<IEdmFunction>().SingleOrDefault();
|
||||
Assert.NotNull(function);
|
||||
Assert.Equal("getMemberGroups", function.Name);
|
||||
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me),
|
||||
new ODataOperationSegment(function));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -57,5 +59,109 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(delete.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityDeleteReturnsSecurityForDeleteRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.DeleteRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers), new ODataKeySegment(customers.EntityType()));
|
||||
|
||||
// Act
|
||||
var delete = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(delete);
|
||||
Assert.NotNull(delete.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, delete.Security.Count);
|
||||
|
||||
string json = delete.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
Assert.Contains(delete.Parameters, p => p.Name == "odata-debug" && p.In == Models.ParameterLocation.Query);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(delete.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -100,6 +102,114 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityGetOperationReturnsSecurityForReadRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""ReadByKeyRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers), new ODataKeySegment(customers.EntityType()));
|
||||
|
||||
// Act
|
||||
var get = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
Assert.NotNull(get.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, get.Security.Count);
|
||||
|
||||
string json = get.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
Assert.Contains(get.Parameters, p => p.Name == "odata-debug" && p.In == Models.ParameterLocation.Header);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(get.Security);
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyParameter(string annotation, bool hasRestriction, bool supported, string queryOption)
|
||||
{
|
||||
// Arrange
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -57,5 +59,109 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(patch.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityPatchReturnsSecurityForUpdateRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers), new ODataKeySegment(customers.EntityType()));
|
||||
|
||||
// Act
|
||||
var patch = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(patch);
|
||||
Assert.NotNull(patch.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, patch.Security.Count);
|
||||
|
||||
string json = patch.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
Assert.Contains(patch.Parameters, p => p.Name == "odata-debug" && p.In == Models.ParameterLocation.Header);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(patch.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ using System.Xml.Linq;
|
|||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -206,6 +208,108 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select", false);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntitySetGetOperationReturnsSecurityForReadRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(enableAnnotation ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers));
|
||||
|
||||
// Act
|
||||
var get = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
Assert.NotNull(get.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, get.Security.Count);
|
||||
|
||||
string json = get.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(get.Security);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -53,5 +56,113 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(post.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntitySetPostReturnsSecurityForInsertRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers));
|
||||
|
||||
// Act
|
||||
var post = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(post);
|
||||
Assert.NotNull(post.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, post.Security.Count);
|
||||
|
||||
string json = post.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// Parameters
|
||||
Assert.Single(post.Parameters);
|
||||
|
||||
Assert.Equal(ParameterLocation.Header, post.Parameters[0].In);
|
||||
Assert.Equal("odata-debug", post.Parameters[0].Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(post.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.PathItem.Tests;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
|
@ -61,5 +63,148 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationGetOperationReturnsSecurityForReadRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""Orders"" />
|
||||
<PropertyValue Property=""ReadRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel edmModel = NavigationPropertyPathItemHandlerTest.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
Assert.NotNull(edmModel);
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
IEdmEntitySet entitySet = edmModel.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
IEdmEntityType entityType = entitySet.EntityType();
|
||||
|
||||
IEdmNavigationProperty property = entityType.DeclaredNavigationProperties().FirstOrDefault(c => c.Name == "Orders");
|
||||
Assert.NotNull(property);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet),
|
||||
new ODataKeySegment(entityType),
|
||||
new ODataNavigationPropertySegment(property));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom header
|
||||
Assert.Contains(@"
|
||||
{
|
||||
""name"": ""odata-debug"",
|
||||
""in"": ""query"",
|
||||
""description"": ""Debug support for OData services"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Service responds with self-contained..."",
|
||||
""value"": ""html""
|
||||
},
|
||||
""example-2"": {
|
||||
""description"": ""Service responds with JSON document..."",
|
||||
""value"": ""json""
|
||||
}
|
||||
}
|
||||
}".ChangeLineBreaks(), json);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.PathItem.Tests;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
@ -62,5 +64,150 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationPatchOperationReturnsSecurityForUpdateRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""Orders"" />
|
||||
<PropertyValue Property=""UpdateRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Description"" String=""A brief description of GET '/me' request."" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel edmModel = NavigationPropertyPathItemHandlerTest.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
Assert.NotNull(edmModel);
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
IEdmEntitySet entitySet = edmModel.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
IEdmEntityType entityType = entitySet.EntityType();
|
||||
|
||||
IEdmNavigationProperty property = entityType.DeclaredNavigationProperties().FirstOrDefault(c => c.Name == "Orders");
|
||||
Assert.NotNull(property);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet),
|
||||
new ODataKeySegment(entityType),
|
||||
new ODataNavigationPropertySegment(property),
|
||||
new ODataKeySegment(property.DeclaringEntityType()));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom header
|
||||
Assert.Contains(@"
|
||||
{
|
||||
""name"": ""odata-debug"",
|
||||
""in"": ""header"",
|
||||
""description"": ""Debug support for OData services"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Service responds with self-contained..."",
|
||||
""value"": ""html""
|
||||
},
|
||||
""example-2"": {
|
||||
""description"": ""Service responds with JSON document..."",
|
||||
""value"": ""json""
|
||||
}
|
||||
}
|
||||
}".ChangeLineBreaks(), json);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.PathItem.Tests;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
@ -62,5 +64,149 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationPostOperationReturnsSecurityForInsertRestrictions(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""Orders"" />
|
||||
<PropertyValue Property=""InsertRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Description"" String=""A brief description of GET '/me' request."" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
IEdmModel edmModel = NavigationPropertyPathItemHandlerTest.GetEdmModel(enableAnnotation ? annotation : "");
|
||||
Assert.NotNull(edmModel);
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
IEdmEntitySet entitySet = edmModel.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
IEdmEntityType entityType = entitySet.EntityType();
|
||||
|
||||
IEdmNavigationProperty property = entityType.DeclaredNavigationProperties().FirstOrDefault(c => c.Name == "Orders");
|
||||
Assert.NotNull(property);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet),
|
||||
new ODataKeySegment(entityType),
|
||||
new ODataNavigationPropertySegment(property));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom header
|
||||
Assert.Contains(@"
|
||||
{
|
||||
""name"": ""odata-debug"",
|
||||
""in"": ""header"",
|
||||
""description"": ""Debug support for OData services"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Service responds with self-contained..."",
|
||||
""value"": ""html""
|
||||
},
|
||||
""example-2"": {
|
||||
""description"": ""Service responds with JSON document..."",
|
||||
""value"": ""json""
|
||||
}
|
||||
}
|
||||
}".ChangeLineBreaks(), json);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ using System.Xml.Linq;
|
|||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -105,6 +107,136 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void ReadRestrictionsTermWorksToCreateOperationForSingletonGetOperation(bool enableAnnotation)
|
||||
{
|
||||
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""User.Read.All"" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Description"" String=""A brief description of GET '/me' request."" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""odata-debug"" />
|
||||
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
<PropertyValue Property=""ExampleValues"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""html"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Value"" String=""json"" />
|
||||
<PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
// Arrange
|
||||
var edmModel = GetEdmModel(enableAnnotation ? annotation : "");
|
||||
|
||||
Assert.NotNull(edmModel);
|
||||
IEdmSingleton me = edmModel.EntityContainer.FindSingleton("Me");
|
||||
Assert.NotNull(me);
|
||||
|
||||
ODataContext context = new ODataContext(edmModel);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.NotNull(operation.Security);
|
||||
|
||||
if (enableAnnotation)
|
||||
{
|
||||
Assert.Equal(2, operation.Security.Count);
|
||||
|
||||
string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""Delegated (work or school account)"": [
|
||||
""User.ReadBasic.All"",
|
||||
""User.Read.All""
|
||||
]
|
||||
},
|
||||
{
|
||||
""Application"": [
|
||||
""User.Read.All"",
|
||||
""Directory.Read.All""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom header
|
||||
Assert.Contains(@"
|
||||
""parameters"": [
|
||||
{
|
||||
""name"": ""odata-debug"",
|
||||
""in"": ""header"",
|
||||
""description"": ""Debug support for OData services"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Service responds with self-contained..."",
|
||||
""value"": ""html""
|
||||
},
|
||||
""example-2"": {
|
||||
""description"": ""Service responds with JSON document..."",
|
||||
""value"": ""json""
|
||||
}
|
||||
}
|
||||
},
|
||||
{".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(operation.Security);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -75,32 +77,24 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""MaxLevels"" Int=""8"" />
|
||||
<PropertyValue Property=""Permission"">
|
||||
<Record Type=""Org.OData.Capabilities.V1.PermissionType"">
|
||||
<PropertyValue Property=""Scheme"">
|
||||
<Record Type=""Org.OData.Authorization.V1.SecurityScheme"">
|
||||
<PropertyValue Property=""Authorization"" String=""authorizationName"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>RequiredScopes1</String>
|
||||
<String>RequiredScopes2</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName1"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p1,p2"" />
|
||||
</Record>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName2"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p3,p4"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.PermissionType"">
|
||||
<PropertyValue Property=""SchemeName"" String=""authorizationName"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName1"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p1,p2"" />
|
||||
</Record>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName2"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p3,p4"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""QueryOptions"">
|
||||
<Record>
|
||||
|
@ -207,6 +201,65 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
var securityRequirement = Assert.Single(securityRequirements);
|
||||
Assert.Equal("authorizationName", securityRequirement.Key.Reference.Id);
|
||||
Assert.Equal(new[] { "scopeName1", "scopeName2" }, securityRequirement.Value);
|
||||
|
||||
string json = patch.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
||||
Assert.Contains(@"
|
||||
""security"": [
|
||||
{
|
||||
""authorizationName"": [
|
||||
""scopeName1"",
|
||||
""scopeName2""
|
||||
]
|
||||
}
|
||||
],".ChangeLineBreaks(), json);
|
||||
|
||||
// with custom header
|
||||
Assert.Contains(@"
|
||||
""parameters"": [
|
||||
{
|
||||
""name"": ""HeadName1"",
|
||||
""in"": ""header"",
|
||||
""description"": ""Description1"",
|
||||
""required"": true,
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Description11"",
|
||||
""value"": ""value1""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
""name"": ""HeadName2"",
|
||||
""in"": ""header"",
|
||||
""description"": ""Description2"",
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Description22"",
|
||||
""value"": ""value2""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
""name"": ""QueryName1"",
|
||||
""in"": ""query"",
|
||||
""description"": ""Description3"",
|
||||
""required"": true,
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""examples"": {
|
||||
""example-1"": {
|
||||
""description"": ""Description33"",
|
||||
""value"": ""value3""
|
||||
}
|
||||
}
|
||||
}".ChangeLineBreaks(), json);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -179,17 +179,72 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CollectionNavigationPropertyData))]
|
||||
[MemberData(nameof(SingleNavigationPropertyData))]
|
||||
public void CreatePathItemForNavigationPropertyAndReadRestrictions(bool hasRestrictions, string navigationPropertyPath)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""{0}"" />
|
||||
<PropertyValue Property=""ReadRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Readable"" Bool=""false"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>", navigationPropertyPath);
|
||||
|
||||
IEdmModel model = GetEdmModel(hasRestrictions ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
|
||||
ODataPath path = CreatePath(entitySet, navigationPropertyPath, false);
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
|
||||
if (hasRestrictions)
|
||||
{
|
||||
Assert.DoesNotContain(pathItem.Operations, o => o.Key == OperationType.Get);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Contains(pathItem.Operations, o => o.Key == OperationType.Get);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CollectionNavigationPropertyData))]
|
||||
public void CreatePathItemForNavigationPropertyAndInsertRestrictions(bool hasRestrictions, string navigationPropertyPath)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"">
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""NonInsertableNavigationProperties"" >
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<NavigationPropertyPath>{0}</NavigationPropertyPath>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""{0}"" />
|
||||
<PropertyValue Property=""InsertRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Insertable"" Bool=""false"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
|
@ -233,11 +288,18 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""NonUpdatableNavigationProperties"" >
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<NavigationPropertyPath>{0}</NavigationPropertyPath>
|
||||
<Record>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""{0}"" />
|
||||
<PropertyValue Property=""UpdateRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Updatable"" Bool=""false"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
||||
{
|
||||
#if false
|
||||
public class BatchSupportedTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsBatchSupportedEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
BatchSupported batch = new BatchSupported();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.BatchSupported, batch.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultBatchSupportedValues()
|
||||
{
|
||||
// Arrange
|
||||
BatchSupported batch = new BatchSupported();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
bool result = batch.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.True(batch.IsSupported);
|
||||
Assert.Null(batch.Supported);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline, true)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline, false)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine, true)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine, false)]
|
||||
public void EntitySetContainerReturnsCorrectBatchSupportedValue(EdmVocabularyAnnotationSerializationLocation location, bool support)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(location, support);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
// Act
|
||||
BatchSupported batch = new BatchSupported();
|
||||
bool result = batch.Load(model, model.EntityContainer);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(batch.Supported);
|
||||
Assert.Equal(support, batch.Supported.Value);
|
||||
Assert.Equal(support, batch.IsSupported);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(EdmVocabularyAnnotationSerializationLocation location, bool supported)
|
||||
{
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
model.AddElement(container);
|
||||
IEdmTerm term = model.FindTerm(CapabilitiesConstants.BatchSupported);
|
||||
Assert.NotNull(term);
|
||||
|
||||
IEdmBooleanConstantExpression boolean = new EdmBooleanConstant(supported);
|
||||
EdmVocabularyAnnotation annotation = new EdmVocabularyAnnotation(container, term, boolean);
|
||||
annotation.SetSerializationLocation(model, location);
|
||||
model.SetVocabularyAnnotation(annotation);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -35,8 +35,9 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
new EdmPropertyConstructor("NonDeletableNavigationProperties",
|
||||
new EdmCollectionExpression(new EdmNavigationPropertyPathExpression("abc"), new EdmNavigationPropertyPathExpression("RelatedEvents"))),
|
||||
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(42)),
|
||||
new EdmPropertyConstructor("Permission", new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("Scheme", new EdmRecordExpression(new EdmPropertyConstructor("Authorization", new EdmStringConstant("schemeName")))))),
|
||||
new EdmPropertyConstructor("Permissions", new EdmCollectionExpression(
|
||||
new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("SchemeName", new EdmStringConstant("schemeName"))))),
|
||||
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(
|
||||
new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("Name", new EdmStringConstant("odata-debug")),
|
||||
|
@ -113,14 +114,12 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""MaxLevels"" Int=""42"" />
|
||||
<PropertyValue Property=""Permission"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Scheme"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Authorization"" String=""schemeName"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""SchemeName"" String=""schemeName"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"" >
|
||||
<Collection>
|
||||
|
@ -157,8 +156,8 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
|
||||
Assert.True(delete.IsNonDeletableNavigationProperty("RelatedEvents"));
|
||||
|
||||
Assert.NotNull(delete.Permission);
|
||||
Assert.Equal("schemeName", delete.Permission.Scheme.Authorization);
|
||||
Assert.NotNull(delete.Permissions);
|
||||
//Assert.Equal("schemeName", delete.Permissions);
|
||||
|
||||
Assert.Null(delete.CustomHeaders);
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
Assert.False(insert.IsNonInsertableNavigationProperty("MyUnknownNavigationProperty"));
|
||||
|
||||
Assert.Null(insert.QueryOptions);
|
||||
Assert.Null(insert.Permission);
|
||||
Assert.Null(insert.Permissions);
|
||||
Assert.Null(insert.CustomHeaders);
|
||||
|
||||
Assert.NotNull(insert.MaxLevels);
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Xunit;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
||||
{
|
||||
|
|
|
@ -15,13 +15,13 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
||||
{
|
||||
public class OperationRestrictionTypeTests
|
||||
public class OperationRestrictionsTypeTests
|
||||
{
|
||||
[Fact]
|
||||
public void TermAttributeAttachedOnOperationRestrictionType()
|
||||
{
|
||||
// Arrange & Act
|
||||
string qualifiedName = Utils.GetTermQualifiedName<OperationRestrictionType>();
|
||||
string qualifiedName = Utils.GetTermQualifiedName<OperationRestrictionsType>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Org.OData.Capabilities.V1.OperationRestrictions", qualifiedName);
|
||||
|
@ -38,12 +38,12 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
new EdmPropertyConstructor("Description", new EdmStringConstant("head desc")),
|
||||
new EdmPropertyConstructor("DocumentationURL", new EdmStringConstant("http://any3")),
|
||||
new EdmPropertyConstructor("Required", new EdmBooleanConstant(true)))))
|
||||
// Permission
|
||||
// Permissions
|
||||
// CustomQueryOptions
|
||||
);
|
||||
|
||||
// Act
|
||||
OperationRestrictionType operation = new OperationRestrictionType();
|
||||
OperationRestrictionsType operation = new OperationRestrictionsType();
|
||||
operation.Initialize(record);
|
||||
|
||||
// Assert
|
||||
|
@ -75,7 +75,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
Assert.NotNull(edmOperation);
|
||||
|
||||
// Act
|
||||
OperationRestrictionType operation = model.GetRecord<OperationRestrictionType>(edmOperation, "NS.MyOperationRestriction");
|
||||
OperationRestrictionsType operation = model.GetRecord<OperationRestrictionsType>(edmOperation, "NS.MyOperationRestriction");
|
||||
|
||||
// Assert
|
||||
VerifyOperationRestrictions(operation);
|
||||
|
@ -103,11 +103,12 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
return model;
|
||||
}
|
||||
|
||||
private static void VerifyOperationRestrictions(OperationRestrictionType operation)
|
||||
private static void VerifyOperationRestrictions(OperationRestrictionsType operation)
|
||||
{
|
||||
Assert.NotNull(operation);
|
||||
|
||||
Assert.Null(operation.Permission);
|
||||
Assert.Null(operation.FilterSegmentSupported);
|
||||
Assert.Null(operation.Permissions);
|
||||
Assert.Null(operation.CustomQueryOptions);
|
||||
|
||||
Assert.NotNull(operation.CustomHeaders);
|
|
@ -23,7 +23,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
PermissionType permission = new PermissionType();
|
||||
|
||||
// Assert
|
||||
Assert.Null(permission.Scheme);
|
||||
Assert.Null(permission.SchemeName);
|
||||
Assert.Null(permission.Scopes);
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
{
|
||||
// Arrange
|
||||
IEdmRecordExpression record = new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("Scheme", new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("Authorization", new EdmStringConstant("scheme name")))),
|
||||
new EdmPropertyConstructor("SchemeName", new EdmStringConstant("scheme name")),
|
||||
new EdmPropertyConstructor("Scopes", new EdmCollectionExpression(new EdmRecordExpression(
|
||||
new EdmPropertyConstructor("Scope", new EdmStringConstant("scope name"))))));
|
||||
|
||||
|
@ -61,11 +60,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
// Arrange
|
||||
string annotation = @"<Annotation Term=""NS.MyTerm"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Scheme"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Authorization"" String=""scheme name"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""SchemeName"" String=""scheme name"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
|
@ -110,9 +105,8 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
{
|
||||
Assert.NotNull(permission);
|
||||
|
||||
Assert.NotNull(permission.Scheme);
|
||||
Assert.Equal("scheme name", permission.Scheme.Authorization);
|
||||
Assert.Null(permission.Scheme.RequiredScopes);
|
||||
Assert.NotNull(permission.SchemeName);
|
||||
Assert.Equal("scheme name", permission.SchemeName);
|
||||
|
||||
Assert.NotNull(permission.Scopes);
|
||||
ScopeType scope = Assert.Single(permission.Scopes);
|
||||
|
|
|
@ -146,7 +146,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
Assert.NotNull(read.Readable);
|
||||
Assert.False(read.Readable.Value);
|
||||
|
||||
Assert.Null(read.Permission);
|
||||
Assert.Null(read.Permissions);
|
||||
Assert.Null(read.CustomHeaders);
|
||||
|
||||
Assert.NotNull(read.CustomQueryOptions);
|
||||
|
@ -160,7 +160,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
Assert.NotNull(read.ReadByKeyRestrictions.Readable);
|
||||
Assert.True(read.ReadByKeyRestrictions.Readable.Value);
|
||||
|
||||
Assert.Null(read.ReadByKeyRestrictions.Permission);
|
||||
Assert.Null(read.ReadByKeyRestrictions.Permissions);
|
||||
Assert.Null(read.ReadByKeyRestrictions.CustomQueryOptions);
|
||||
|
||||
Assert.NotNull(read.ReadByKeyRestrictions.CustomHeaders);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Data.Odbc;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
|
@ -100,32 +101,24 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""MaxLevels"" Int=""8"" />
|
||||
<PropertyValue Property=""Permission"">
|
||||
<Record Type=""Org.OData.Capabilities.V1.PermissionType"">
|
||||
<PropertyValue Property=""Scheme"">
|
||||
<Record Type=""Org.OData.Authorization.V1.SecurityScheme"">
|
||||
<PropertyValue Property=""Authorization"" String=""authorizationName"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>RequiredScopes1</String>
|
||||
<String>RequiredScopes2</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName1"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p1,p2"" />
|
||||
</Record>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName2"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p3,p4"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<PropertyValue Property=""Permissions"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.PermissionType"">
|
||||
<PropertyValue Property=""SchemeName"" String=""authorizationName"" />
|
||||
<PropertyValue Property=""Scopes"">
|
||||
<Collection>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName1"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p1,p2"" />
|
||||
</Record>
|
||||
<Record Type=""Org.OData.Capabilities.V1.ScopeType"">
|
||||
<PropertyValue Property=""Scope"" String=""scopeName2"" />
|
||||
<PropertyValue Property=""RestrictedProperties"" String=""p3,p4"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""QueryOptions"">
|
||||
<Record>
|
||||
|
@ -235,6 +228,12 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
|
|||
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);
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.OData.Edm, Version=7.6.0.30605, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.OData.Edm.7.6.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll</HintPath>
|
||||
<Reference Include="Microsoft.OData.Edm, Version=7.6.1.30918, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.OData.Edm.7.6.1-beta\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.OpenApi, Version=1.1.2.0, Culture=neutral, PublicKeyToken=3f5743946376f042, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.OpenApi.1.1.2\lib\net46\Microsoft.OpenApi.dll</HintPath>
|
||||
<Reference Include="Microsoft.OpenApi, Version=1.1.4.0, Culture=neutral, PublicKeyToken=3f5743946376f042, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.OpenApi.1.1.4\lib\net46\Microsoft.OpenApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.OData.Edm" version="7.6.0" targetFramework="net461" />
|
||||
<package id="Microsoft.OpenApi" version="1.1.2" targetFramework="net461" />
|
||||
<package id="Microsoft.OData.Edm" version="7.6.1-beta" targetFramework="net461" />
|
||||
<package id="Microsoft.OpenApi" version="1.1.4" targetFramework="net461" />
|
||||
</packages>
|
Loading…
Reference in a new issue