public async Task <bool> CheckAccess(ResourceInfo resourceInfo, ActionInfo actionInfo, bool pullAttributeAssignments, bool pullReportingChain) { // Impersonation Access Check var impersonationUser = GetImpersonationUser(this.httpContext); if (!string.IsNullOrEmpty(impersonationUser)) { // If attempting to impersonate but has no access to do so if (!this.ImpersonationCheckAccessResult) { return(false); } // If attempting to impersonate and has access and the action being checked is impersonation else if (actionInfo.Id == ImpersonationActionId) { return(true); } } var subjectInfo = new SubjectInfo(); this.AddUserMetadataToSubjectInfo(subjectInfo, this.CurrentUser); if (pullAttributeAssignments) { if (this.CurrentUserAttributeAssignments != null) { foreach (var attributeAssignment in this.CurrentUserAttributeAssignments) { // Special cases if (attributeAssignment.Name == ExpensePortalConstant.Subject.AttributeName.SafeLimit) { // Add as integer var safeLimit = int.Parse(attributeAssignment.Values.First()); subjectInfo.AddAttribute(attributeAssignment.Name, safeLimit); } else if (attributeAssignment.Name == ExpensePortalConstant.Subject.AttributeName.Org) { // Append * to the end for wild card comparison subjectInfo.AddAttribute(attributeAssignment.Name, $"{attributeAssignment.Values.First()}*"); } else { attributeAssignment.Values.Where(v => !string.IsNullOrEmpty(v)).ToList().ForEach(v => subjectInfo.AddAttribute(attributeAssignment.Name, v)); } } } } if (pullReportingChain) { List <string> managers; lock (this.memoryCache) { managers = this.memoryCache.Get(this.CurrentUser.UserPrincipalName) as List <string>; if (managers == null) { // Note: Use .Result for now as await can't be used inside a lock managers = this.userMetadataService.GetUserReportingChain(this.CurrentUser.UserPrincipalName).Result; this.memoryCache.Set(this.CurrentUser.UserPrincipalName, managers); } } foreach (var manager in managers) { subjectInfo.AddAttribute(ExpensePortalConstant.Subject.AttributeName.ReportingChain, manager); } var owner = resourceInfo.GetAttribute(ExpensePortalConstant.Resource.AttributeName.OwnerAlias).First().ToString(); if (string.IsNullOrEmpty(owner)) { throw new ArgumentException("Resource.OwnerAlias is required when pulling reporting chain."); } List <string> ownerManagers; lock (this.memoryCache) { ownerManagers = this.memoryCache.Get($"{owner}@{this.expenseDemoOptions.ClientOptions.TenantName}") as List <string>; if (ownerManagers == null) { // Note: Use .Result for now as await can't be used inside a lock ownerManagers = this.userMetadataService.GetUserReportingChain($"{owner}@{this.expenseDemoOptions.ClientOptions.TenantName}").Result; this.memoryCache.Set($"{owner}@{this.expenseDemoOptions.ClientOptions.TenantName}", ownerManagers); } } foreach (var manager in ownerManagers) { resourceInfo.AddAttribute(ExpensePortalConstant.Resource.AttributeName.OwnerReportingChain, manager); } ; } return(await this.policyDecisionPoint.CheckAccess(new CheckAccessRequest(subjectInfo, resourceInfo, actionInfo, null, this.authorizationClientOptions.MiddlewareOptions.GetMemberGroups)).ConfigureAwait(false)); }