Ejemplo n.º 1
0
        public static void MergeReadRest(ReadRestrictionsType existing, ReadRestrictionsType newRead, string target)
        {
            if (existing.ReadByKeyRestrictions != null && newRead.ReadByKeyRestrictions != null)
            {
                throw new Exception($"Found mutltiple read by key restrctions for one target '{target}'.");
            }

            if (existing.ReadByKeyRestrictions == null && newRead.ReadByKeyRestrictions == null)
            {
                throw new Exception($"Found mutltiple read restrctions for one target '{target}'.");
            }

            if (existing.ReadByKeyRestrictions != null)
            {
                existing.Readable = newRead.Readable;

                if (newRead.Permissions != null)
                {
                    foreach (var item in newRead.Permissions)
                    {
                        existing.Append(item);
                    }
                }
            }
            else // newRead.ReadByKeyRestrictions != null
            {
                existing.ReadByKeyRestrictions = newRead.ReadByKeyRestrictions;
            }
        }
        /// <inheritdoc/>
        protected override void SetSecurity(OpenApiOperation operation)
        {
            ReadRestrictionsType read = EntitySet != null
                ? Context.Model.GetRecord <ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions)
                : Context.Model.GetRecord <ReadRestrictionsType>(Singleton, CapabilitiesConstants.ReadRestrictions);

            if (read == null)
            {
                return;
            }

            ReadRestrictionsBase readBase = read;

            if (read.ReadByKeyRestrictions != null)
            {
                readBase = read.ReadByKeyRestrictions;
            }

            if (readBase == null && readBase.Permissions == null)
            {
                return;
            }

            operation.Security = Context.CreateSecurityRequirements(readBase.Permissions).ToList();
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            if (EdmOperationImport.IsActionImport())
            {
                // Each action import is represented as a name/value pair whose name is the service-relative
                // resource path of the action import prepended with a forward slash, and whose value is a Path
                // Item Object containing the keyword post with an Operation Object as value that describes
                // how to invoke the action import.
                AddOperation(item, OperationType.Post);
            }
            else
            {
                // Each function import is represented as a name/value pair whose name is the service-relative
                // resource path of the function import prepended with a forward slash, and whose value is a Path
                // Item Object containing the keyword get with an Operation Object as value that describes
                // how to invoke the function import.

                // so far, <Term Name="ReadRestrictions" Type="Capabilities.ReadRestrictionsType" AppliesTo="EntitySet Singleton FunctionImport">
                ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(EdmOperationImport, CapabilitiesConstants.ReadRestrictions);
                if (read == null || read.IsReadable)
                {
                    AddOperation(item, OperationType.Get);
                }
            }
        }
        public void InitializReadRestrictionsTypeWithRecordSuccess()
        {
            // Assert
            IEdmRecordExpression record = new EdmRecordExpression(
                new EdmPropertyConstructor("Readable", new EdmBooleanConstant(false)),
                new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(
                                               new EdmRecordExpression(new EdmPropertyConstructor("Name", new EdmStringConstant("root query name"))))),
                // Root Permission
                // Root CustomHeaders
                new EdmPropertyConstructor("ReadByKeyRestrictions", new EdmRecordExpression(
                                               new EdmPropertyConstructor("Readable", new EdmBooleanConstant(true)),
                                               new EdmPropertyConstructor("CustomHeaders", new EdmCollectionExpression(
                                                                              new EdmRecordExpression(new EdmPropertyConstructor("Name", new EdmStringConstant("by key head name")))))
                                               // ByKey Permission
                                               // ByKey CustomQueryOptions
                                               ))
                );

            // Act
            ReadRestrictionsType read = new ReadRestrictionsType();

            read.Initialize(record);

            // Assert
            VerifyReadRestrictions(read);
        }
        private static void VerifyReadRestrictions(ReadRestrictionsType read)
        {
            Assert.NotNull(read);

            Assert.NotNull(read.Readable);
            Assert.False(read.Readable.Value);

            Assert.Null(read.Permissions);
            Assert.Null(read.CustomHeaders);

            Assert.NotNull(read.CustomQueryOptions);
            CustomParameter parameter = Assert.Single(read.CustomQueryOptions);

            Assert.Equal("root query name", parameter.Name);
            Assert.Null(parameter.DocumentationURL);
            Assert.Null(parameter.ExampleValues);

            // ReadByKeyRestrictions
            Assert.NotNull(read.ReadByKeyRestrictions);
            Assert.NotNull(read.ReadByKeyRestrictions.Readable);
            Assert.True(read.ReadByKeyRestrictions.Readable.Value);

            Assert.Null(read.ReadByKeyRestrictions.Permissions);
            Assert.Null(read.ReadByKeyRestrictions.CustomQueryOptions);

            Assert.NotNull(read.ReadByKeyRestrictions.CustomHeaders);
            parameter = Assert.Single(read.ReadByKeyRestrictions.CustomHeaders);
            Assert.Equal("by key head name", parameter.Name);
            Assert.Null(parameter.DocumentationURL);
            Assert.Null(parameter.ExampleValues);
        }
Ejemplo n.º 6
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(EntitySet);

            if (read == null ||
                (read.ReadByKeyRestrictions == null && read.IsReadable) ||
                (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable))
            {
                // If we don't have Read by key read restriction, we should check the set read restrction.
                AddOperation(item, OperationType.Get);
            }

            UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet);

            if (update == null || update.IsUpdatable)
            {
                AddOperation(item, OperationType.Patch);
            }

            DeleteRestrictionsType delete = Context.Model.GetRecord <DeleteRestrictionsType>(EntitySet);

            if (delete == null || delete.IsDeletable)
            {
                AddOperation(item, OperationType.Delete);
            }
        }
        protected override void AppendCustomParameters(OpenApiOperation operation)
        {
            ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);

            if (read == null)
            {
                return;
            }

            ReadRestrictionsBase readBase = read;

            if (read.ReadByKeyRestrictions != null)
            {
                readBase = read.ReadByKeyRestrictions;
            }

            if (readBase.CustomHeaders != null)
            {
                AppendCustomParameters(operation, readBase.CustomHeaders, ParameterLocation.Header);
            }

            if (readBase.CustomQueryOptions != null)
            {
                AppendCustomParameters(operation, readBase.CustomQueryOptions, ParameterLocation.Query);
            }
        }
Ejemplo n.º 8
0
        private void AddReadOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null || read.IsReadable)
            {
                AddOperation(item, OperationType.Get);
            }
        }
Ejemplo n.º 9
0
        public void Add(IDictionary <UriPath, IList <ApiPermissionType> > permissions)
        {
            IDictionary <string, IList <IRecord> > targetStringMerged = new Dictionary <string, IList <IRecord> >();

            foreach (var permission in permissions)
            {
                UriPath  path   = permission.Key;
                PathKind kind   = path.Kind;
                string   target = path.GetTargetString();

                IList <IRecord> records;
                if (!targetStringMerged.TryGetValue(target, out records))
                {
                    records = new List <IRecord>();
                    targetStringMerged[target] = records;
                }

                foreach (var perm in permission.Value)
                {
                    PermissionsRecord permissionRecord;
                    try
                    {
                        permissionRecord = ApiPermissionHelper.ConvertToRecord(kind, perm);

                        ReadRestrictionsType readRest = permissionRecord as ReadRestrictionsType;
                        if (readRest != null)
                        {
                            var existingReadRest = records.FirstOrDefault(r => r is ReadRestrictionsType);
                            if (existingReadRest != null)
                            {
                                MergeReadRest(existingReadRest as ReadRestrictionsType, readRest, target);
                                continue;
                            }
                        }

                        // TODO: verify only one Restriction existing for one target?

                        records.Add(permissionRecord as IRecord);
                    }
                    catch (Exception ex)
                    {
                        //var color = Console.BackgroundColor;
                        //Console.BackgroundColor = ConsoleColor.Red;
                        Console.WriteLine("    [PermssionError]: " + ex.Message);
                        //Console.BackgroundColor = color;

                        PermissionsError[target] = ex;
                    }
                }
            }

            foreach (var item in targetStringMerged)
            {
                Write(item.Key, item.Value);
            }
        }
Ejemplo n.º 10
0
        /// <inheritdoc/>
        protected override void SetSecurity(OpenApiOperation operation)
        {
            ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(Singleton, CapabilitiesConstants.ReadRestrictions);

            if (read == null || read.Permissions == null)
            {
                return;
            }

            operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList();
        }
        private void AddGetOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null)
            {
                AddOperation(item, OperationType.Get);
                return;
            }

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                // TODO: $ref also supports Get ?
                if (LastSegmentIsKeySegment)
                {
                    if (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.Readable != null)
                    {
                        if (read.ReadByKeyRestrictions.Readable.Value)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                    else
                    {
                        ReadRestrictionsType readEntity = Context.Model.GetRecord <ReadRestrictionsType>(_entityType);
                        if (readEntity?.IsReadable ?? true)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                }
                else
                {
                    if (read.IsReadable)
                    {
                        AddOperation(item, OperationType.Get);
                    }
                }
            }
            else
            {
                Debug.Assert(LastSegmentIsKeySegment == false);
                if (read.IsReadable)
                {
                    AddOperation(item, OperationType.Get);
                }
            }
        }
Ejemplo n.º 12
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(EntitySet);

            if (read == null || read.IsReadable)
            {
                AddOperation(item, OperationType.Get);
            }

            InsertRestrictionsType insert = Context.Model.GetRecord <InsertRestrictionsType>(EntitySet);

            if (insert == null || insert.IsInsertable)
            {
                AddOperation(item, OperationType.Post);
            }
        }
        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);
                }
            }
        }
Ejemplo n.º 14
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            // Retrieve a singleton.
            ReadRestrictionsType read = Context.Model.GetRecord <ReadRestrictionsType>(Singleton);

            if (read == null || read.IsReadable)
            {
                AddOperation(item, OperationType.Get);
            }

            // Update a singleton
            UpdateRestrictionsType update = Context.Model.GetRecord <UpdateRestrictionsType>(Singleton);

            if (update == null || update.IsUpdatable)
            {
                AddOperation(item, OperationType.Patch);
            }
        }
Ejemplo n.º 15
0
        public static PermissionsRecord ConvertToRecord(PathKind pathKind, ApiPermissionType perm)
        {
            PermissionsRecord record = null;

            switch (perm.HttpVerb)
            {
            case "GET":
                record = CreateGetPermissionRecord(pathKind);
                break;

            case "PATCH":
                record = CreatePatchPermissionRecord(pathKind);
                break;

            case "POST":
                record = CreatePostPermissionRecord(pathKind);
                break;

            case "DELETE":
                record = CreateDeletePermissionRecord(pathKind);
                break;

            default:
                throw new Exception($"Unknown http verb {perm.HttpVerb}");
            }

            if (record == null)
            {
                throw new Exception($"Invalid HttpVerb {perm.HttpVerb} in {pathKind} path");
            }

            ReadRestrictionsType read = record as ReadRestrictionsType;

            if (read != null && read.ReadByKeyRestrictions != null)
            {
                read.ReadByKeyRestrictions.InitializeFrom(perm);
                return(read);
            }

            record.InitializeFrom(perm);
            return(record);
        }
        /// <inheritdoc/>
        protected override void SetBasicInfo(OpenApiOperation operation)
        {
            // Summary
            string placeholderValue = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "media content";

            operation.Summary = IsNavigationPropertyPath
                ? $"Get {placeholderValue} for the navigation property {NavigationProperty.Name} from {NavigationSource.Name}"
                : $"Get {placeholderValue} for {NavigationSourceSegment.EntityType.Name} from {NavigationSourceSegment.Identifier}";

            // Description
            if (LastSegmentIsStreamPropertySegment)
            {
                IEdmVocabularyAnnotatable annotatable = GetAnnotatableElement();
                string description;

                if (annotatable is IEdmNavigationProperty)
                {
                    ReadRestrictionsType readRestriction = Context.Model.GetRecord <NavigationRestrictionsType>(annotatable, CapabilitiesConstants.NavigationRestrictions)?
                                                           .RestrictedProperties?.FirstOrDefault()?.ReadRestrictions;

                    description = LastSegmentIsKeySegment
                        ? readRestriction?.ReadByKeyRestrictions?.Description
                        : readRestriction?.Description
                                  ?? Context.Model.GetDescriptionAnnotation(annotatable);
                }
                else
                {
                    // Structural property
                    description = Context.Model.GetDescriptionAnnotation(annotatable);
                }

                operation.Description = description;
            }

            // OperationId
            if (Context.Settings.EnableOperationId)
            {
                string identifier = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "Content";
                operation.OperationId = GetOperationId("Get", identifier);
            }
        }
        public void TargetOnEntitySetReturnsCorrectReadRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
        {
            // Arrange
            const string template = @"
                <Annotations Target=""NS.Default/Calendars"">
                  {0}
                </Annotations>";

            IEdmModel model = GetEdmModel(template, location);

            Assert.NotNull(model); // guard

            IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");

            Assert.NotNull(calendars); // guard

            // Act
            ReadRestrictionsType read = model.GetRecord <ReadRestrictionsType>(calendars);

            // Assert
            VerifyReadRestrictions(read);
        }
Ejemplo n.º 18
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            ReadRestrictionsType read = EntitySet != null
                ? Context.Model.GetRecord <ReadRestrictionsType>(EntitySet)
                : Context.Model.GetRecord <ReadRestrictionsType>(Singleton);

            if (read == null ||
                (read.ReadByKeyRestrictions == null && read.IsReadable) ||
                (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable))
            {
                AddOperation(item, OperationType.Get);
            }

            UpdateRestrictionsType update = EntitySet != null
                ? Context.Model.GetRecord <UpdateRestrictionsType>(EntitySet)
                : Context.Model.GetRecord <UpdateRestrictionsType>(Singleton);

            if (update == null || update.IsUpdatable)
            {
                AddOperation(item, OperationType.Put);
            }
        }
Ejemplo n.º 19
0
        /// <inheritdoc/>
        protected override void SetBasicInfo(OpenApiOperation operation)
        {
            // Summary and Description
            ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions;
            string placeHolder = "Get ref of " + NavigationProperty.Name + " from " + NavigationSource.Name;

            operation.Summary     = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) ?? placeHolder;
            operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.LongDescription : readRestriction?.LongDescription)
                                    ?? Context.Model.GetDescriptionAnnotation(NavigationProperty);

            // OperationId
            if (Context.Settings.EnableOperationId)
            {
                string prefix = "GetRef";
                if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    prefix = "ListRef";
                }

                operation.OperationId = GetOperationId(prefix);
            }
        }
        /// <inheritdoc/>
        protected override void SetSecurity(OpenApiOperation operation)
        {
            IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)NavigationSourceSegment.NavigationSource;
            ReadRestrictionsType      read = Context.Model.GetRecord <ReadRestrictionsType>(annotatableNavigationSource, CapabilitiesConstants.ReadRestrictions);

            if (read == null)
            {
                return;
            }

            ReadRestrictionsBase readBase = read;

            if (read.ReadByKeyRestrictions != null)
            {
                readBase = read.ReadByKeyRestrictions;
            }

            if (readBase == null && readBase.Permissions == null)
            {
                return;
            }

            operation.Security = Context.CreateSecurityRequirements(readBase.Permissions).ToList();
        }
Ejemplo n.º 21
0
        private static ITerm CreateDefaultTerm()
        {
            ReadRestrictions term = new ReadRestrictions();

            term.Target   = "Ns.Container/Users";
            term.IsInLine = true;

            ReadRestrictionsType record = new ReadRestrictionsType();

            record.ReadByKeyRestrictions = new ReadByKeyRestrictions();

            PermissionType permission = new PermissionType
            {
                SchemeName = "Delegated (work or school account)",
                Scopes     = new List <ScopeType>
                {
                    new ScopeType {
                        Scope = "User.ReadBasic.All"
                    },
                    new ScopeType {
                        Scope = "User.Read.All"
                    },
                    new ScopeType {
                        Scope = "User.ReadWrite.All"
                    },
                    new ScopeType {
                        Scope = "Directory.Read.All"
                    },
                    new ScopeType {
                        Scope = "Directory.ReadWrite.All"
                    },
                    new ScopeType {
                        Scope = "Directory.AccessAsUser.All"
                    }
                }
            };

            record.ReadByKeyRestrictions.Append(permission);

            permission = new PermissionType
            {
                SchemeName = "Application",
                Scopes     = new List <ScopeType>
                {
                    new ScopeType {
                        Scope = "User.Read.All"
                    },
                    new ScopeType {
                        Scope = "User.ReadWrite.All"
                    },
                    new ScopeType {
                        Scope = "Directory.Read.All"
                    },
                    new ScopeType {
                        Scope = "Directory.ReadWrite.All"
                    },
                }
            };
            record.ReadByKeyRestrictions.Append(permission);

            term.Records.Add(record);

            return(term);
        }
Ejemplo n.º 22
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            string navigationPropertyPath = String.Join("/",
                                                        Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));

            NavigationRestrictionsType    navigation  = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);
            NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);

            // verify using individual first
            if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
            {
                return;
            }

            if (restriction == null || restriction.Navigability == null)
            {
                // if the individual has not navigability setting, use the global navigability setting
                if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
                {
                    // Default navigability for all navigation properties of the annotation target.
                    // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
                    return;
                }
            }

            // So far, we only consider the non-containment
            Debug.Assert(!NavigationProperty.ContainsTarget);

            // It seems OData supports to "GetRef, DeleteRef",
            // Here at this time,let's only consider the "delete"
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null || read.IsReadable)
            {
                AddOperation(item, OperationType.Get);
            }

            // Create the ref
            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                InsertRestrictionsType insert = restriction?.InsertRestrictions;
                if (insert == null || insert.IsInsertable)
                {
                    AddOperation(item, OperationType.Post);
                }
            }
            else
            {
                UpdateRestrictionsType update = restriction?.UpdateRestrictions;
                if (update == null || update.IsUpdatable)
                {
                    AddOperation(item, OperationType.Put);
                }

                // delete the link
                DeleteRestrictionsType delete = restriction?.DeleteRestrictions;
                if (delete == null || delete.IsDeletable)
                {
                    AddOperation(item, OperationType.Delete);
                }
            }
        }
Ejemplo n.º 23
0
        protected override void Initialize(ODataContext context, ODataPath path)
        {
            base.Initialize(context, path);

            _readRestrictions = Context.Model.GetRecord <ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);
        }