public PermissionValidationResponse Validate(PermissionValidationRequest request)
        {
            var allowedResources = new List <CRN>();
            var deniedResources  = new List <CRN>();

            var requestedResources = this.resourceFinder.Find(request.Resource).ToList();

            if (!Validator.TryValidate(() => ValidateResources(requestedResources, request), out var resourceValidationResult))
            {
                return(PermissionValidationResponse.InvalidFromResourceValidation(request, resourceValidationResult));
            }

            var issuedGrants = this.permissionGrantFinder.Find(request.Principal, request.Schema);

            foreach (var g in issuedGrants)
            {
                // apply policy at ticket issue time
                if (!this.policyApplicator.IsGrantValid(g))
                {
                    continue;
                }

                var grantedResources             = this.resourceFinder.Find(g.Resource);
                var intersection                 = grantedResources.Intersect(requestedResources);
                var preValidationDeniedResources = requestedResources.Where(r => !intersection.Contains(r)).Select(r => r.Identifier).ToList();
                foreach (var validResource in intersection)
                {
                    Validator.TryValidate(
                        () => this.resourceValidator.Validate(validResource.Identifier, request.Action),
                        out var result);

                    var resourceActionAllowed = g.Actions.Contains(request.Action);
                    if (!resourceActionAllowed || !result.IsValid)
                    {
                        deniedResources.Add(validResource.Identifier);
                        continue;
                    }

                    allowedResources.Add(validResource.Identifier);
                }

                if (preValidationDeniedResources.Any())
                {
                    deniedResources.AddRange(preValidationDeniedResources);
                }
            }

            allowedResources = allowedResources.Distinct().ToList();
            deniedResources  = deniedResources.Distinct().ToList();
            return(PermissionValidationResponse.From(request, allowedResources, deniedResources));
        }
示例#2
0
        public PermissionTicket Request(params PermissionTicketRequest[] request)
        {
            if (request == null || request.Length == 0)
            {
                return(PermissionTicket.Invalid());
            }

            var requestHash = string.Join(".", request.Select(r => r.GetHash()));

            var ticket = this.storage.Find(requestHash);
            var existingTicketExpired = ticket != null && ticket.IsExpired(DateTimeOffset.UtcNow);

            if (!existingTicketExpired && ticket != null)
            {
                return(ticket);
            }

            this.storage.Remove(requestHash);

            var responses = new PermissionValidationResponse[request.Length];

            for (var i = 0; i < request.Length; i++)
            {
                responses[i] = this.validator.Validate(request[i]);
            }

            ticket = PermissionTicket.FromValidation(responses);
            ticket.WithExpiry(DateTimeOffset.UtcNow.AddMinutes(DefaultTicketDurationMinutes));

            if (ticket.IsValid)
            {
                this.storage.Add(requestHash, ticket);
            }

            return(ticket);
        }