public void TestNotAResource() { //Arrange string ScopeString = "patient/ObsXX.read"; IScopeParse ScopeParse = new ScopeParse(); //Act var ParseOk = ScopeParse.Parse(ScopeString, out ISmartScope SmartScope); //Assert Assert.IsFalse(ParseOk); }
public void TestNotPatientOrUserEntity() { //Arrange string ScopeString = "patX/Patient.read"; IScopeParse ScopeParse = new ScopeParse(); //Act var ParseOk = ScopeParse.Parse(ScopeString, out ISmartScope SmartScope); //Assert Assert.IsFalse(ParseOk); }
public void TestActionErrorMissing() { //Arrange string ScopeString = "patient/Observation"; IScopeParse ScopeParse = new ScopeParse(); //Act var ParseOk = ScopeParse.Parse(ScopeString, out ISmartScope SmartScope); //Assert Assert.IsFalse(ParseOk); }
public void TestResourceAll() { //Arrange string ScopeString = "patient/*.read"; IScopeParse ScopeParse = new ScopeParse(); //Act var ParseOk = ScopeParse.Parse(ScopeString, out ISmartScope SmartScope); //Assert Assert.IsTrue(ParseOk); Assert.AreEqual(SmartEnum.Entity.Patient, SmartScope.Entity); Assert.AreEqual(FHIRAllTypes.Resource, SmartScope.Resource); Assert.AreEqual(SmartEnum.Action.Read, SmartScope.Action); }
public void TestActionReadWrite() { //Arrange string ScopeString = "patient/Observation.*"; IScopeParse ScopeParse = new ScopeParse(); //Act var ParseOk = ScopeParse.Parse(ScopeString, out ISmartScope SmartScope); //Assert Assert.IsTrue(ParseOk); Assert.AreEqual(SmartEnum.Entity.Patient, SmartScope.Entity); Assert.AreEqual(FHIRAllTypes.Observation, SmartScope.Resource); Assert.AreEqual(SmartEnum.Action.All, SmartScope.Action); }
public ISmartScopeOutcome ProcessScopes(PyroSearchParameters PyroSearchParameters, FHIRAllTypes ServiceResourceType, bool Read, bool Write) { ISmartScopeOutcome SmartScopeOutcome = new SmartScopeOutcome() { ScopesOK = false }; // If FHIRApiAuthentication = false then no need to check and scopes, ScopesOK! if (!IGlobalProperties.FHIRApiAuthentication) { SmartScopeOutcome.ScopesOK = true; return(SmartScopeOutcome); } SmartEnum.Action SmartAction = GetActionEnum(Read, Write); if (System.Threading.Thread.CurrentPrincipal != null && System.Threading.Thread.CurrentPrincipal is ClaimsPrincipal Principal) { //Get Client Id, we need to log this somewere, maybe FHIR AuditEventy? System.Security.Claims.Claim ClientClaim = Principal.Claims.SingleOrDefault(x => x.Type == ClientIdName); //Get tye scopes List <System.Security.Claims.Claim> ScopeClaim = Principal.Claims.Where(x => x.Type == ScopeName).ToList(); //This should be injected ScopeParse ScopeParse = new ScopeParse(); List <ISmartScope> ScopeList = new List <ISmartScope>(); foreach (var ScopeString in ScopeClaim) { ISmartScope SmartScope = new SmartScope(); if (ScopeParse.Parse(ScopeString.Value, out SmartScope)) { ScopeList.Add(SmartScope); } else { string Message = $"Unable to parse the SMART on FHIR scope given. Scope was {ScopeString.Value}"; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Exception, Message); throw new Common.Exceptions.PyroException(System.Net.HttpStatusCode.InternalServerError, OpOut, Message); } } IEnumerable <ISmartScope> FoundScopesList = ScopeList.Where(x => x.Resource == ServiceResourceType && (x.Action == SmartAction || x.Action == SmartEnum.Action.All)); if (FoundScopesList.Count() > 0) { if (PyroSearchParameters.IncludeList != null && PyroSearchParameters.IncludeList.Count > 0) { foreach (var Include in PyroSearchParameters.IncludeList) { FoundScopesList = ScopeList.Where(x => x.Resource == Include.SourceResourceType && (x.Action == SmartAction || x.Action == SmartEnum.Action.All)); if (FoundScopesList.Count() == 0) { //Reject string Message = $"You do not have permission to access the {Include.SourceResourceType.GetLiteral()} Resource type found within your include or revinclude search parameters."; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } } var SearchParametersThatHaveChainParametersList = PyroSearchParameters.SearchParametersList.Where(x => x.ChainedSearchParameter != null); if (SearchParametersThatHaveChainParametersList != null && SearchParametersThatHaveChainParametersList.Count() > 0) { foreach (ISearchParameterBase Chain in SearchParametersThatHaveChainParametersList) { string ResourceWithNoScopeAccess = RecursiveChainScoped(Chain, ScopeList, SmartAction); if (!string.IsNullOrWhiteSpace(ResourceWithNoScopeAccess)) { //Reject string Message = $"You do not have permission to access {ResourceWithNoScopeAccess} resources types which was one of the resources types within your chained search parameter."; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } } //ALL GOOD! We have a scope for the resource and action. all ok. SmartScopeOutcome.ScopesOK = true; return(SmartScopeOutcome); } else { string Message = string.Empty; if (SmartAction == SmartEnum.Action.All) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Read or Write."; } else if (SmartAction == SmartEnum.Action.Read) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Read."; } else if (SmartAction == SmartEnum.Action.Read) { Message = $"You do not have permission to access Resources {ServiceResourceType.GetLiteral()} types for Write."; } var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Forbidden, Message); SmartScopeOutcome.OperationOutcome = OpOut; SmartScopeOutcome.ScopesOK = false; return(SmartScopeOutcome); } } else { //System.Threading.Thread.CurrentPrincipal was null string Message = "Internal Server Error: System.Threading.Thread.CurrentPrincipal was null"; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Exception, Message); throw new Common.Exceptions.PyroException(System.Net.HttpStatusCode.InternalServerError, OpOut, Message); } }