/// <summary> /// Bind the enforcement point /// </summary> protected void BindClinicalEnforcement <TData>(IDataPersistenceService <TData> persister) where TData : IdentifiedData { // Demand query persister.Querying += (o, e) => { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.QueryClinicalData).Demand(); }; // Demand insert persister.Inserting += (o, e) => { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.WriteClinicalData).Demand(); }; // Demand update persister.Updating += (o, e) => { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.WriteClinicalData).Demand(); }; // Obsoletion permission demand persister.Obsoleting += (o, e) => { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.DeleteClinicalData).Demand(); }; // Queried data filter persister.Queried += (o, e) => { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.ReadClinicalData).Demand(); DataQueryResultEventArgs <TData> dqre = e as DataQueryResultEventArgs <TData>; // Filter dataset if (dqre != null) { dqre.Results = dqre.Results.Where(i => ApplicationContext.Current.PolicyDecisionService.GetPolicyDecision(AuthenticationContext.Current.Principal, i) == OpenIZ.Core.Model.Security.PolicyGrantType.Grant); } }; }
/// <summary> /// Query function returning results and count control /// </summary> private IEnumerable <TData> Query(System.Linq.Expressions.Expression <Func <TData, bool> > query, int offset, int?count, out int totalResults, Guid queryId, bool countResults, bool fastQuery, IEnumerable <String> expandProperties = null) { if (query == null) { throw new ArgumentNullException(nameof(query)); } DataQueryPreEventArgs <TData> preArgs = new DataQueryPreEventArgs <TData>(query, offset, count); this.Querying?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceWarning("Pre-Event handler indicates abort query {0}", query); totalResults = preArgs.TotalResults; return(preArgs.Results); } #if PERFMON Stopwatch sw = new Stopwatch(); sw.Start(); #endif // Query object using (var context = this.CreateReadonlyConnection()) try { IEnumerable <TData> results = null; using (context.LockConnection()) { this.m_tracer.TraceVerbose("QUERY {0}", query); if (fastQuery) { context.DelayLoadMode = LoadState.PartialLoad; } else { context.DelayLoadMode = LoadState.FullLoad; } if (expandProperties != null) { context.LoadAssociations = expandProperties.ToArray(); } results = this.Query(context, query, offset, count ?? -1, out totalResults, queryId, countResults); } var postData = new DataQueryResultEventArgs <TData>(query, results, offset, count, totalResults); this.Queried?.Invoke(this, postData); totalResults = postData.TotalResults; // Remove from the cache foreach (var itm in context.CacheOnCommit.AsParallel()) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } return(postData.Results); } catch (NotSupportedException e) { this.m_tracer.TraceVerbose("Cannot perform LINQ query, switching to stored query sqp_{0}", typeof(TData).Name, e); // Build dictionary var httpValues = QueryExpressionBuilder.BuildQuery <TData>(query, true); var filter = new Dictionary <String, Object>(); foreach (var f in httpValues) { object existing = null; if (filter.TryGetValue(f.Key, out existing)) { if (!(existing is IList)) { existing = new List <Object>() { existing }; filter[f.Key] = existing; } (existing as IList).Add(f.Value); } else { filter.Add(f.Key, f.Value); } } // Query return(this.Query(String.Format("sqp_{0}", typeof(TData).Name), filter, offset, count, out totalResults, queryId)); } catch (Exception e) { this.m_tracer.TraceError("Error : {0}", e); throw; } #if PERFMON finally { sw.Stop(); ApplicationContext.Current.PerformanceLog(typeof(TData).Name, nameof(Query), query.ToString(), sw.Elapsed); } #endif }