示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
            }
        }