Example #1
0
        /// <summary>
        /// An extension method that provides simpler syntax when using the <see cref="IOpenApiAccessChecker"/>
        /// to check access for a single operation.
        /// </summary>
        /// <param name="checker">The underlying <see cref="IOpenApiAccessChecker"/> to use.</param>
        /// <param name="context">The current <see cref="IOpenApiContext"/>.</param>
        /// <param name="path">The request path.</param>
        /// <param name="operationId">The request Operation Id.</param>
        /// <param name="httpMethod">The request Http method.</param>
        /// <returns>A task that resolves to the result of the access check.</returns>
        public static async Task <AccessControlPolicyResult> CheckAccessPolicyAsync(
            this IOpenApiAccessChecker checker,
            IOpenApiContext context,
            string path,
            string operationId,
            string httpMethod)
        {
            var request = new AccessCheckOperationDescriptor(path, operationId, httpMethod);
            IDictionary <AccessCheckOperationDescriptor, AccessControlPolicyResult> result = await checker.CheckAccessPoliciesAsync(context, request).ConfigureAwait(false);

            return(result.Values.Single());
        }
Example #2
0
        /// <summary>
        /// Searches through a <see cref="HalDocument"/> and removes any links that the current
        /// principal does not have access to.
        /// </summary>
        /// <param name="that">
        /// The <see cref="IOpenApiAccessChecker"/> that will be used to check the individual links.
        /// </param>
        /// <param name="target">
        /// The <see cref="HalDocument"/> to check.
        /// </param>
        /// <param name="context">
        /// The <see cref="IOpenApiContext"/> used to get information about the current principal.
        /// </param>
        /// <param name="options">
        /// The <see cref="HalDocumentLinkRemovalOptions"/> to apply when checking links.
        /// </param>
        /// <returns>A task that completes when all links have been checked.</returns>
        public static async Task RemoveForbiddenLinksAsync(this IOpenApiAccessChecker that, HalDocument target, IOpenApiContext context, HalDocumentLinkRemovalOptions options = default)
        {
            // First, we need to build a collection of all the links. For each one we need:
            // 1. The link itself.
            // 2. The HalDocument(s) to which it belongs - it is possible that we may encounter the same link twice and we need to be able to deal with that
            // 3. The link relation name.
            var linkMap = new Dictionary <(string, OpenApiWebLink), List <HalDocument> >();

            AddHalDocumentLinksToMap(
                target,
                linkMap,
                (options & HalDocumentLinkRemovalOptions.NonRecursive) == 0,
                (options & HalDocumentLinkRemovalOptions.Unsafe) != 0);

            // Build a second map of operation descriptors (needed to invoke the access policy check) to our OpenApiWebLinks.
            var operationDescriptorMap = linkMap
                                         .Keys
                                         .Select(link => (Descriptor: new AccessCheckOperationDescriptor(link.Item2.Href, link.Item2.OperationId, link.Item2.OperationType.ToString().ToLowerInvariant()), Link: link))
                                         .GroupBy(x => x.Descriptor)
                                         .ToDictionary(descriptor => descriptor.Key, descriptor => descriptor.Select(link => link.Link).ToArray());

            AccessCheckOperationDescriptor[] operationDescriptors = operationDescriptorMap.Keys.ToArray();

            // Perform the access policy check.
            IDictionary <AccessCheckOperationDescriptor, AccessControlPolicyResult> accessCheckResults = await that.CheckAccessPoliciesAsync(context, operationDescriptors).ConfigureAwait(false);

            // Now use the results of the access policy check to remove links/documents that don't belong because the access policy denies them.
            foreach (KeyValuePair <AccessCheckOperationDescriptor, AccessControlPolicyResult> accessCheckResult in accessCheckResults.Where(result => !result.Value.Allow))
            {
                foreach ((string, OpenApiWebLink)link in operationDescriptorMap[accessCheckResult.Key])
                {
                    foreach (HalDocument document in linkMap[link])
                    {
                        document.RemoveLink(link.Item1, link.Item2);

                        // Also remove from embedded resources if present.
                        document.RemoveEmbeddedResource(link.Item1, link.Item2);
                    }
                }
            }
        }
 /// <summary>
 /// Creates an instance of the <see cref="OpenApiOperationInvoker{TRequest, TResponse}"/>.
 /// </summary>
 /// <param name="operationLocator">The operation locator.</param>
 /// <param name="parameterBuilder">The parameter builder.</param>
 /// <param name="accessChecker">The access checker.</param>
 /// <param name="exceptionMapper">The exception mapper.</param>
 /// <param name="resultBuilder">The result builder.</param>
 /// <param name="configuration">The <see cref="IOpenApiConfiguration"/>.</param>
 /// <param name="auditContext">The audit context.</param>
 /// <param name="logger">The logger.</param>
 /// <param name="operationsInstrumentation">Operations instrumentation.</param>
 /// <param name="exceptionsInstrumentation">Exceptions instrumentation.</param>
 public OpenApiOperationInvoker(
     IOpenApiServiceOperationLocator operationLocator,
     IOpenApiParameterBuilder <TRequest> parameterBuilder,
     IOpenApiAccessChecker accessChecker,
     IOpenApiExceptionMapper exceptionMapper,
     IOpenApiResultBuilder <TResponse> resultBuilder,
     IOpenApiConfiguration configuration,
     IAuditContext auditContext,
     ILogger <OpenApiOperationInvoker <TRequest, TResponse> > logger,
     IOperationsInstrumentation <OpenApiOperationInvoker <TRequest, TResponse> > operationsInstrumentation,
     IExceptionsInstrumentation <OpenApiOperationInvoker <TRequest, TResponse> > exceptionsInstrumentation)
 {
     this.operationLocator          = operationLocator;
     this.parameterBuilder          = parameterBuilder;
     this.accessChecker             = accessChecker;
     this.exceptionMapper           = exceptionMapper;
     this.resultBuilder             = resultBuilder;
     this.auditContext              = auditContext;
     this.logger                    = logger;
     this.operationsInstrumentation = operationsInstrumentation;
     this.configuration             = configuration;
     this.exceptionsInstrumentation = exceptionsInstrumentation;
 }