Beispiel #1
0
        /// <summary>
        /// Audit an operation that was exceuted
        /// </summary>
        private void AuditOperationAction(string resourceType, string operationName, OutcomeIndicator outcome, params Resource[] objects)
        {
            var audit = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.ApplicationActivity, new AuditCode(Hl7.Fhir.Utility.EnumUtility.GetLiteral(SystemRestfulInteraction.Batch), "http://hl7.org/fhir/ValueSet/system-restful-interaction"));

            AuditUtil.AddLocalDeviceActor(audit);
            AuditUtil.AddUserActor(audit);

            var handler = ExtensionUtil.GetOperation(resourceType, operationName);

            audit.AuditableObjects.Add(new AuditableObject()
            {
                IDTypeCode = AuditableObjectIdType.Uri,
                ObjectId   = handler?.Uri.ToString() ?? $"urn:uuid:{Guid.Empty}",
                QueryData  = RestOperationContext.Current?.IncomingRequest.Url.ToString(),
                ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList(),
                Role       = AuditableObjectRole.Job,
                Type       = AuditableObjectType.SystemObject
            });

            audit.AuditableObjects.AddRange(objects.SelectMany(o => this.CreateAuditObjects(o, AuditableObjectLifecycle.NotSet)));
            AuditUtil.SendAudit(audit);
        }
Beispiel #2
0
        /// <summary>
        /// Audit data action on FHIR interface
        /// </summary>
        private void AuditDataAction(TypeRestfulInteraction type, OutcomeIndicator outcome, params Resource[] objects)
        {
            AuditData audit = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.ApplicationActivity, new AuditCode(Hl7.Fhir.Utility.EnumUtility.GetLiteral(type), "http://hl7.org/fhir/ValueSet/type-restful-interaction"));
            AuditableObjectLifecycle lifecycle = AuditableObjectLifecycle.NotSet;

            switch (type)
            {
            case TypeRestfulInteraction.Create:
                audit.ActionCode      = ActionType.Create;
                audit.EventIdentifier = EventIdentifierType.Import;
                lifecycle             = AuditableObjectLifecycle.Creation;
                break;

            case TypeRestfulInteraction.Delete:
                audit.ActionCode      = ActionType.Delete;
                audit.EventIdentifier = EventIdentifierType.Import;
                lifecycle             = AuditableObjectLifecycle.LogicalDeletion;
                break;

            case TypeRestfulInteraction.HistoryInstance:
            case TypeRestfulInteraction.HistoryType:
            case TypeRestfulInteraction.SearchType:
                audit.ActionCode      = ActionType.Execute;
                audit.EventIdentifier = EventIdentifierType.Query;
                lifecycle             = AuditableObjectLifecycle.Disclosure;
                audit.AuditableObjects.Add(new AuditableObject()
                {
                    QueryData  = RestOperationContext.Current?.IncomingRequest.Url.ToString(),
                    Role       = AuditableObjectRole.Query,
                    Type       = AuditableObjectType.SystemObject,
                    ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Where(o => o.Equals("accept", StringComparison.OrdinalIgnoreCase)).Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList()
                });
                break;

            case TypeRestfulInteraction.Update:
            case TypeRestfulInteraction.Patch:
                audit.ActionCode      = ActionType.Update;
                audit.EventIdentifier = EventIdentifierType.Import;
                lifecycle             = AuditableObjectLifecycle.Amendment;
                break;

            case TypeRestfulInteraction.Vread:
            case TypeRestfulInteraction.Read:
                audit.ActionCode      = ActionType.Read;
                audit.EventIdentifier = EventIdentifierType.Query;
                lifecycle             = AuditableObjectLifecycle.Disclosure;
                audit.AuditableObjects.Add(new AuditableObject()
                {
                    QueryData  = RestOperationContext.Current?.IncomingRequest.Url.ToString(),
                    Role       = AuditableObjectRole.Query,
                    Type       = AuditableObjectType.SystemObject,
                    ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Where(o => o.Equals("accept", StringComparison.OrdinalIgnoreCase)).Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList()
                });
                break;
            }

            AuditUtil.AddLocalDeviceActor(audit);
            AuditUtil.AddUserActor(audit);

            audit.AuditableObjects.AddRange(objects.SelectMany(o => this.CreateAuditObjects(o, lifecycle)));

            AuditUtil.SendAudit(audit);
        }
        /// <summary>
        /// Hydrate the query
        /// </summary>
        /// <param name="queryId"></param>
        /// <returns></returns>
        private BisResultContext HydrateQuery(String queryId)
        {
            AuditData audit = new AuditData(DateTimeOffset.Now, ActionType.Execute, OutcomeIndicator.Success, EventIdentifierType.Query, AuditUtil.CreateAuditActionCode(EventTypeCodes.SecondaryUseQuery));

            try
            {
                // First we want to grab the appropriate source for this ID
                var viewDef = this.m_metadataRepository.Get <BiViewDefinition>(queryId);
                if (viewDef == null)
                {
                    var queryDef = this.m_metadataRepository.Get <BiQueryDefinition>(queryId);
                    if (queryDef == null) // Parameter value
                    {
                        var parmDef = this.m_metadataRepository.Get <BiParameterDefinition>(queryId);
                        if (parmDef == null)
                        {
                            throw new KeyNotFoundException($"Could not find a Parameter, Query or View to hydrate named {queryId}");
                        }
                        queryDef    = parmDef?.Values as BiQueryDefinition;
                        queryDef.Id = queryDef.Id ?? queryId;
                    }

                    viewDef = new BiViewDefinition()
                    {
                        Id    = queryDef.Id,
                        Query = queryDef
                    };
                }

                viewDef = SanteDB.BI.Util.BiUtils.ResolveRefs(viewDef) as BiViewDefinition;
                var dsource = viewDef.Query?.DataSources.FirstOrDefault(o => o.Name == "main") ?? viewDef.Query?.DataSources.FirstOrDefault();
                if (dsource == null)
                {
                    throw new KeyNotFoundException("Query does not contain a data source");
                }

                IBiDataSource providerImplementation = null;
                if (dsource.ProviderType != null && this.m_metadataRepository.IsLocal)
                {
                    providerImplementation = this.m_serviceManager.CreateInjected(dsource.ProviderType) as IBiDataSource;
                }
                else
                {
                    providerImplementation = ApplicationServiceContext.Current.GetService <IBiDataSource>(); // Global default
                }
                // Populate data about the query
                audit.AuditableObjects.Add(new AuditableObject()
                {
                    IDTypeCode    = AuditableObjectIdType.ReportNumber,
                    LifecycleType = AuditableObjectLifecycle.Report,
                    ObjectId      = queryId,
                    QueryData     = RestOperationContext.Current.IncomingRequest.Url.Query,
                    Role          = AuditableObjectRole.Query,
                    Type          = AuditableObjectType.SystemObject
                });

                var parameters = this.CreateParameterDictionary();

                // Aggregations and groups?
                if (RestOperationContext.Current.IncomingRequest.QueryString["_groupBy"] != null)
                {
                    var aggRx = new Regex(@"(\w*)\((.*?)\)");
                    viewDef.AggregationDefinitions = new List <BiAggregationDefinition>()
                    {
                        new BiAggregationDefinition()
                        {
                            Groupings = RestOperationContext.Current.IncomingRequest.QueryString.GetValues("_groupBy").Select(o => new BiSqlColumnReference()
                            {
                                ColumnSelector = o.Contains("::")  ? $"CAST({o.Substring(0, o.IndexOf(":"))} AS {o.Substring(o.IndexOf(":") + 2)})" : o,
                                Name           = o.Contains("::") ? o.Substring(0, o.IndexOf(":")) : o
                            }).ToList(),
                            Columns = RestOperationContext.Current.IncomingRequest.QueryString.GetValues("_select").Select(o => {
                                var match = aggRx.Match(o);
                                if (!match.Success)
                                {
                                    throw new InvalidOperationException("Aggregation function must be in format AGGREGATOR(COLUMN)");
                                }
                                return(new BiAggregateSqlColumnReference()
                                {
                                    Aggregation = (BiAggregateFunction)Enum.Parse(typeof(BiAggregateFunction), match.Groups[1].Value, true),
                                    ColumnSelector = match.Groups[2].Value,
                                    Name = match.Groups[2].Value
                                });
                            }).ToList()
                        }
                    };
                }

                int offset = 0, count = 100;
                if (!Int32.TryParse(RestOperationContext.Current.IncomingRequest.QueryString["_offset"] ?? "0", out offset))
                {
                    throw new FormatException("_offset is not in the correct format");
                }
                if (!Int32.TryParse(RestOperationContext.Current.IncomingRequest.QueryString["_count"] ?? "100", out count))
                {
                    throw new FormatException("_count is not in the correct format");
                }


                var queryData = providerImplementation.ExecuteView(viewDef, parameters, offset, count);
                return(queryData);
            }
            catch (KeyNotFoundException)
            {
                audit.Outcome = OutcomeIndicator.MinorFail;
                throw;
            }
            catch (Exception e)
            {
                audit.Outcome = OutcomeIndicator.MinorFail;
                this.m_tracer.TraceError("Error rendering query: {0}", e);
                throw new FaultException(500, $"Error rendering query {queryId}", e);
            }
            finally
            {
                AuditUtil.AddLocalDeviceActor(audit);
                AuditUtil.AddUserActor(audit);
                AuditUtil.SendAudit(audit);
            }
        }