/// <summary>
        /// Synchronized dispatch service
        /// </summary>
        public SynchronizedAuditDispatchService(IConfigurationManager configurationManager, IJobStateManagerService jobStateManager, IJobManagerService scheduleManager, IThreadPoolService threadPool, IQueueManagerService queueManagerService)
        {
            this.m_securityConfiguration = configurationManager.GetSection <SecurityConfigurationSection>();
            this.m_jobStateManager       = jobStateManager;
            this.m_queueManagerService   = queueManagerService;

            if (!scheduleManager.GetJobSchedules(this).Any())
            {
                scheduleManager.SetJobSchedule(this, new TimeSpan(0, 5, 0));
            }

            threadPool.QueueUserWorkItem(_ =>
            {
                try
                {
                    AuditData securityAlertData = new AuditData(DateTime.Now, ActionType.Execute, OutcomeIndicator.Success, EventIdentifierType.SecurityAlert, AuditUtil.CreateAuditActionCode(EventTypeCodes.AuditLoggingStarted));
                    AuditUtil.AddLocalDeviceActor(securityAlertData);
                    AuditUtil.SendAudit(securityAlertData);
                }
                catch (Exception ex)
                {
                    this.m_tracer.TraceError("Error starting up audit repository service: {0}", ex);
                }
            });
        }
 /// <summary>
 /// Creates a new job
 /// </summary>
 public MailSynchronizationJob(IConfigurationManager configurationManager, IMailMessageRepositoryService mailRepositoryService, IJobStateManagerService jobStateManagerService, ISynchronizationLogService synchronizationLogService)
 {
     this.m_configuration             = configurationManager.GetSection <SynchronizationConfigurationSection>();
     this.m_securityConfiguration     = configurationManager.GetSection <SecurityConfigurationSection>();
     this.m_mailRepository            = mailRepositoryService;
     this.m_jobStateManager           = jobStateManagerService;
     this.m_synchronizationLogService = synchronizationLogService;
 }
Esempio n. 3
0
        /// <summary>
        /// Get a bare bones configuration
        /// </summary>
        public static OpenIZConfiguration GetDefaultConfiguration()
        {
            // TODO: Bring up initial settings dialog and utility
            var retVal = new OpenIZConfiguration();

            // Inital data source
            DataConfigurationSection dataSection = new DataConfigurationSection()
            {
                MainDataSourceConnectionStringName = "openIzData",
                MessageQueueConnectionStringName   = "openIzQueue",
                ConnectionString = new System.Collections.Generic.List <ConnectionString>()
                {
                    new ConnectionString()
                    {
                        Name  = "openIzData",
                        Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "OpenIZ.sqlite")
                    },
                    new ConnectionString()
                    {
                        Name  = "openIzSearch",
                        Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "OpenIZ.ftsearch.sqlite")
                    },
                    new ConnectionString()
                    {
                        Name  = "openIzQueue",
                        Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "MessageQueue.sqlite")
                    },
                    new ConnectionString()
                    {
                        Name  = "openIzWarehouse",
                        Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "OpenIZ.warehouse.sqlite")
                    },
                    new ConnectionString()
                    {
                        Name  = "openIzAudit",
                        Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "OpenIZ.audit.sqlite")
                    }
                }
            };

            // Initial Applet configuration
            AppletConfigurationSection appletSection = new AppletConfigurationSection()
            {
                AppletDirectory  = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "applets"),
                AppletGroupOrder = new System.Collections.Generic.List <string>()
                {
                    "Patient Management",
                    "Encounter Management",
                    "Stock Management",
                    "Administration"
                },
                StartupAsset = "org.openiz.core",
                Security     = new AppletSecurityConfiguration()
                {
                    TrustedPublishers = new List <string>()
                    {
                        "84BD51F0584A1F708D604CF0B8074A68D3BEB973"
                    }
                }
            };

            // Initial applet style
            ApplicationConfigurationSection appSection = new ApplicationConfigurationSection()
            {
                Style        = StyleSchemeType.Dark,
                UserPrefDir  = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MINIMS", "userpref"),
                ServiceTypes = new List <string>()
                {
                    typeof(LocalPolicyDecisionService).AssemblyQualifiedName,
                    typeof(LocalPolicyInformationService).AssemblyQualifiedName,
                    typeof(LocalPatientService).AssemblyQualifiedName,
                    typeof(LocalPlaceService).AssemblyQualifiedName,
                    typeof(LocalAlertService).AssemblyQualifiedName,
                    typeof(LocalConceptService).AssemblyQualifiedName,
                    typeof(LocalEntityRepositoryService).AssemblyQualifiedName,
                    typeof(LocalOrganizationService).AssemblyQualifiedName,
                    typeof(LocalRoleProviderService).AssemblyQualifiedName,
                    typeof(LocalSecurityService).AssemblyQualifiedName,
                    typeof(LocalMaterialService).AssemblyQualifiedName,
                    typeof(LocalBatchService).AssemblyQualifiedName,
                    typeof(LocalActService).AssemblyQualifiedName,
                    typeof(SQLiteDatawarehouse).AssemblyQualifiedName,
                    typeof(LocalProviderService).AssemblyQualifiedName,
                    typeof(NetworkInformationService).AssemblyQualifiedName,
                    typeof(CarePlanManagerService).AssemblyQualifiedName,
                    typeof(BusinessRulesDaemonService).AssemblyQualifiedName,
                    typeof(LocalEntitySource).AssemblyQualifiedName,
                    typeof(MiniImsServer).AssemblyQualifiedName,
                    typeof(MemoryCacheService).AssemblyQualifiedName,
                    typeof(OpenIZThreadPool).AssemblyQualifiedName,
                    typeof(SimpleCarePlanService).AssemblyQualifiedName,
                    typeof(MemorySessionManagerService).AssemblyQualifiedName,
                    typeof(AmiUpdateManager).AssemblyQualifiedName,
                    typeof(AppletClinicalProtocolRepository).AssemblyQualifiedName,
                    typeof(MemoryQueryPersistenceService).AssemblyQualifiedName,
                    typeof(SimpleQueueFileProvider).AssemblyQualifiedName,
                    typeof(SimplePatchService).AssemblyQualifiedName,
                    typeof(SQLite.Net.Platform.Generic.SQLitePlatformGeneric).AssemblyQualifiedName,
                    typeof(SearchIndexService).AssemblyQualifiedName,
                    typeof(MiniAppletManagerService).AssemblyQualifiedName,
                    typeof(MemoryTickleService).AssemblyQualifiedName,
                    typeof(LocalTagPersistenceService).AssemblyQualifiedName,
                    typeof(SQLiteReportDatasource).AssemblyQualifiedName,
                    typeof(ReportExecutor).AssemblyQualifiedName,
                    typeof(XamarinBackupService).AssemblyQualifiedName,
                    typeof(AppletReportRepository).AssemblyQualifiedName
                },
                Cache = new CacheConfiguration()
                {
                    MaxAge         = new TimeSpan(0, 5, 0).Ticks,
                    MaxSize        = 1000,
                    MaxDirtyAge    = new TimeSpan(0, 20, 0).Ticks,
                    MaxPressureAge = new TimeSpan(0, 2, 0).Ticks
                }
            };



            // Security configuration
            var    wlan       = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(o => o.NetworkInterfaceType == NetworkInterfaceType.Ethernet && o.Description.StartsWith("wlan"));
            String macAddress = Guid.NewGuid().ToString();

            if (wlan != null)
            {
                macAddress = wlan.GetPhysicalAddress().ToString();
            }
            //else

            SecurityConfigurationSection secSection = new SecurityConfigurationSection()
            {
                DeviceName     = String.Format("MINI-IMS-{0}", macAddress).Replace(" ", ""),
                AuditRetention = new TimeSpan(30, 0, 0, 0, 0)
            };

            // Device key
            var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.openiz.org", macAddress));

            secSection.DeviceSecret = certificate?.Thumbprint;

            // Rest Client Configuration
            ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection()
            {
                RestClientType = typeof(RestClient)
            };

            // Trace writer
#if DEBUG
            DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
            {
                TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>()
                {
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                        InitializationData = "OpenIZ",
                        TraceWriter        = new LogTraceWriter(System.Diagnostics.Tracing.EventLevel.LogAlways, "OpenIZ")
                    },
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                        InitializationData = "OpenIZ",
                        TraceWriter        = new FileTraceWriter(System.Diagnostics.Tracing.EventLevel.LogAlways, "OpenIZ")
                    },
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                        InitializationData = "OpenIZ",
                        TraceWriter        = new ConsoleTraceWriter(System.Diagnostics.Tracing.EventLevel.LogAlways, "OpenIZ")
                    }
                }
            };
#else
            DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
            {
                TraceWriter = new List <TraceWriterConfiguration>()
                {
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                        InitializationData = "OpenIZ",
                        TraceWriter        = new FileTraceWriter(System.Diagnostics.Tracing.EventLevel.LogAlways, "OpenIZ")
                    }
                }
            };
#endif
            retVal.Sections.Add(appletSection);
            retVal.Sections.Add(dataSection);
            retVal.Sections.Add(diagSection);
            retVal.Sections.Add(appSection);
            retVal.Sections.Add(secSection);
            retVal.Sections.Add(serviceSection);
            retVal.Sections.Add(new SynchronizationConfigurationSection()
            {
                PollInterval = new TimeSpan(0, 5, 0)
            });
            return(retVal);
        }
        /// <summary>
        /// Start the daemon service
        /// </summary>
        public bool Start()
        {
            this.Starting?.Invoke(this, EventArgs.Empty);

            this.m_configuration         = ApplicationContext.Current.Configuration.GetSection <SynchronizationConfigurationSection>();
            this.m_securityConfiguration = ApplicationContext.Current.Configuration.GetSection <SecurityConfigurationSection>();

            // Application context has started
            ApplicationContext.Current.Started += (o, e) =>
            {
                try
                {
                    // We are to poll for alerts always (never push supported)
                    TimeSpan pollInterval = this.m_configuration.PollInterval == TimeSpan.MinValue ? new TimeSpan(0, 10, 0) : this.m_configuration.PollInterval;
                    this.m_alertRepository = ApplicationContext.Current.GetService <IAlertRepositoryService>();
                    Action <Object> pollAction = null;
                    pollAction = x =>
                    {
                        try
                        {
                            var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                            amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                            // Pull from alerts
                            if (!this.m_isRunning)
                            {
                                return;
                            }

                            // When was the last time we polled an alert?
                            var lastTime = SynchronizationLog.Current.GetLastTime(typeof(AlertMessage));

                            var syncTime = lastTime.HasValue ? new DateTimeOffset(lastTime.Value) : DateTimeOffset.Now.AddHours(-1);

                            // Poll action for all alerts to "everyone"
                            AmiCollection <AlertMessageInfo> serverAlerts = amiClient.GetAlerts(a => a.CreationTime >= lastTime && a.To.Contains("everyone"));


                            // TODO: We need to filter by users in which this tablet will be interested in

                            ParameterExpression userParameter = Expression.Parameter(typeof(SecurityUser), "u");
                            // User name filter
                            Expression userNameFilter = Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(this.m_securityConfiguration.DeviceName));

                            // Or eith other users which have logged into this tablet
                            foreach (var user in ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Query(u => u.LastLoginTime != null && u.UserName != this.m_securityConfiguration.DeviceName))
                            {
                                userNameFilter = Expression.OrElse(userNameFilter,
                                                                   Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName))
                                                                   );
                            }

                            ParameterExpression parmExpr       = Expression.Parameter(typeof(AlertMessage), "a");
                            Expression          timeExpression = Expression.GreaterThanOrEqual(
                                Expression.Convert(Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("CreationTime")), typeof(DateTimeOffset)),
                                Expression.Constant(syncTime)
                                ),
                            // this tablet expression
                                                userExpression = Expression.Call(
                                (MethodInfo)typeof(Enumerable).GetGenericMethod("Any", new Type[] { typeof(SecurityUser) }, new Type[] { typeof(IEnumerable <SecurityUser>), typeof(Func <SecurityUser, bool>) }),
                                Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("RcptTo")),
                                Expression.Lambda <Func <SecurityUser, bool> >(userNameFilter, userParameter));

                            serverAlerts.CollectionItem = serverAlerts.CollectionItem.Union(amiClient.GetAlerts(Expression.Lambda <Func <AlertMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList();

                            // Import the alerts
                            foreach (var itm in serverAlerts.CollectionItem)
                            {
                                this.m_tracer.TraceVerbose("Importing ALERT: [{0}]: {1}", itm.AlertMessage.TimeStamp, itm.AlertMessage.Subject);
                                itm.AlertMessage.Body = String.Format("<pre>{0}</pre>", itm.AlertMessage.Body);
                                this.m_alertRepository.BroadcastAlert(itm.AlertMessage);
                            }

                            // Push alerts which I have created or updated
                            //int tc = 0;
                            //foreach(var itm in this.m_alertRepository.Find(a=> (a.TimeStamp >= lastTime ) && a.Flags != AlertMessageFlags.System, 0, null, out tc))
                            //{
                            //    if (!String.IsNullOrEmpty(itm.To))
                            //    {
                            //        this.m_tracer.TraceVerbose("Sending ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject);
                            //        if (itm.UpdatedTime != null)
                            //            amiClient.UpdateAlert(itm.Key.ToString(), new AlertMessageInfo(itm));
                            //        else
                            //            amiClient.CreateAlert(new AlertMessageInfo(itm));
                            //    }
                            //}

                            SynchronizationLog.Current.Save(typeof(AlertMessage), null, null, null);
                        }
                        catch (Exception ex)
                        {
                            this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message);
                        }
                        finally
                        {
                            // Re-schedule myself in the poll interval time
                            ApplicationContext.Current.GetService <IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                        }
                    };

                    //ApplicationContext.Current.GetService<IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                    this.m_isRunning = true;

                    pollAction(null);
                }
                catch (Exception ex)
                {
                    this.m_tracer.TraceError("Error starting Alert Sync: {0}", ex.Message);
                }
                //this.m_alertRepository.Committed +=
            };

            this.Started?.Invoke(this, EventArgs.Empty);

            return(true);
        }
        /// <summary>
        /// Get a bare bones configuration
        /// </summary>
        public SanteDBConfiguration GetDefaultConfiguration()
        {
            // TODO: Bring up initial settings dialog and utility
            var retVal = new SanteDBConfiguration();

            // Initial Applet configuration
            AppletConfigurationSection appletSection = new AppletConfigurationSection()
            {
                AppletDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "applets"),
                StartupAsset    = "org.santedb.uicore",
                Security        = new AppletSecurityConfiguration()
                {
                    AllowUnsignedApplets = true,
                    TrustedPublishers    = new List <string>()
                    {
                        "82C63E1E9B87578D0727E871D7613F2F0FAF683B", "4326A4421216AC254DA93DC61B93160B08925BB1"
                    }
                }
            };

            // Initial applet style
            ApplicationConfigurationSection appSection = new ApplicationConfigurationSection()
            {
                Style       = StyleSchemeType.Dark,
                UserPrefDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "userpref"),
                Cache       = new CacheConfiguration()
                {
                    MaxAge         = new TimeSpan(0, 5, 0).Ticks,
                    MaxSize        = 1000,
                    MaxDirtyAge    = new TimeSpan(0, 20, 0).Ticks,
                    MaxPressureAge = new TimeSpan(0, 2, 0).Ticks
                }
            };

            // App service
            var appServiceSection = new ApplicationServiceContextConfigurationSection()
            {
                ThreadPoolSize   = Environment.ProcessorCount * 16,
                ServiceProviders = new List <TypeReferenceConfiguration>()
                {
                    new TypeReferenceConfiguration(typeof(AesSymmetricCrypographicProvider)),
                    new TypeReferenceConfiguration(typeof(MemoryTickleService)),
                    new TypeReferenceConfiguration(typeof(SHA256PasswordHasher)),
                    new TypeReferenceConfiguration(typeof(SanteDB.Core.Security.DefaultPolicyDecisionService)),
                    new TypeReferenceConfiguration(typeof(DataPolicyFilterService)),
                    new TypeReferenceConfiguration(typeof(NetworkInformationService)),
                    new TypeReferenceConfiguration(typeof(BusinessRulesDaemonService)),
                    new TypeReferenceConfiguration(typeof(AgsService)),
                    new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryCacheService)),
                    new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryAdhocCacheService)),
                    new TypeReferenceConfiguration(typeof(DefaultThreadPoolService)),
                    new TypeReferenceConfiguration(typeof(SimpleCarePlanService)),
                    new TypeReferenceConfiguration(typeof(MemorySessionManagerService)),
                    new TypeReferenceConfiguration(typeof(AmiUpdateManager)),
                    new TypeReferenceConfiguration(typeof(AppletClinicalProtocolRepository)),
                    new TypeReferenceConfiguration(typeof(AppletLocalizationService)),
                    new TypeReferenceConfiguration(typeof(MemoryQueryPersistenceService)),
                    new TypeReferenceConfiguration(typeof(AuditDaemonService)),
                    new TypeReferenceConfiguration(typeof(SimpleQueueFileProvider)),
                    new TypeReferenceConfiguration(typeof(SimplePatchService)),
                    new TypeReferenceConfiguration(typeof(DefaultBackupService)),
                    new TypeReferenceConfiguration(typeof(DcAppletManagerService)),
                    new TypeReferenceConfiguration(typeof(AppletBiRepository)),
                    new TypeReferenceConfiguration(typeof(DefaultOperatingSystemInfoService)),
                    new TypeReferenceConfiguration(typeof(AppletSubscriptionRepository)),
                    new TypeReferenceConfiguration(typeof(AmiSecurityChallengeProvider)),
                    new TypeReferenceConfiguration(typeof(InMemoryPivotProvider)),
                    new TypeReferenceConfiguration(typeof(DefaultDataSigningService)),
                    new TypeReferenceConfiguration(typeof(GenericConfigurationPushService)),
                    new TypeReferenceConfiguration(typeof(QrBarcodeGenerator)),
                    new TypeReferenceConfiguration(typeof(FileSystemDispatcherQueueService))
                }
            };

            // Security configuration
            SecurityConfigurationSection secSection = new SecurityConfigurationSection()
            {
                DeviceName           = Environment.MachineName,
                AuditRetention       = new TimeSpan(30, 0, 0, 0, 0),
                DomainAuthentication = DomainClientAuthentication.Inline
            };

            // Device key
            //var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.santedb.org", macAddress));
            //secSection.DeviceSecret = certificate?.Thumbprint;

            // Rest Client Configuration
            ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection()
            {
                RestClientType = typeof(RestClient)
            };

            // Trace writer
#if DEBUG
            DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
            {
                TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>()
                {
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.Informational,
                        InitializationData = "SanteDB",
                        TraceWriter        = typeof(LogTraceWriter)
                    },
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.Informational,
                        InitializationData = "SanteDB",
                        TraceWriter        = typeof(FileTraceWriter)
                    }
                }
            };
#else
            DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
            {
                TraceWriter = new List <TraceWriterConfiguration>()
                {
                    new TraceWriterConfiguration()
                    {
                        Filter             = System.Diagnostics.Tracing.EventLevel.Warning,
                        InitializationData = "SanteDB",
                        TraceWriter        = typeof(FileTraceWriter)
                    }
                }
            };
#endif
            retVal.Sections.Add(new FileSystemDispatcherQueueConfigurationSection()
            {
                QueuePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SanteDB", this.m_instanceName, "queue"),
            });
            retVal.Sections.Add(appServiceSection);
            retVal.Sections.Add(appletSection);
            retVal.Sections.Add(diagSection);
            retVal.Sections.Add(appSection);
            retVal.Sections.Add(secSection);
            retVal.Sections.Add(serviceSection);
            retVal.Sections.Add(new AuditAccountabilityConfigurationSection()
            {
                AuditFilters = new List <AuditFilterConfiguration>()
                {
                    // Audit any failure - No matter which event
                    new AuditFilterConfiguration(null, null, SanteDB.Core.Auditing.OutcomeIndicator.EpicFail | SanteDB.Core.Auditing.OutcomeIndicator.MinorFail | SanteDB.Core.Auditing.OutcomeIndicator.SeriousFail, true, true),
                    // Audit anything that creates, reads, or updates data
                    new AuditFilterConfiguration(SanteDB.Core.Auditing.ActionType.Create | SanteDB.Core.Auditing.ActionType.Read | SanteDB.Core.Auditing.ActionType.Update | SanteDB.Core.Auditing.ActionType.Delete, null, null, true, true)
                }
            });

            retVal.Sections.Add(new DcDataConfigurationSection()
            {
                MainDataSourceConnectionStringName = "santeDbData",
                MessageQueueConnectionStringName   = "santeDbQueue"
            });
            retVal.AddSection(AgsService.GetDefaultConfiguration());
            retVal.Sections.Add(new SynchronizationConfigurationSection()
            {
                PollInterval      = new TimeSpan(0, 5, 0),
                ForbiddenResouces = new List <SynchronizationForbidConfiguration>()
                {
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "DeviceEntity"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ApplicationEntity"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "Concept"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ConceptSet"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "Place"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "ReferenceTerm"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.All, "AssigningAuthority"),
                    new SynchronizationForbidConfiguration(SynchronizationOperationType.Obsolete, "UserEntity")
                }
            });

            foreach (var t in AppDomain.CurrentDomain.GetAssemblies()
                     .Where(a => !a.IsDynamic)
                     .SelectMany(a =>
            {
                try
                {
                    return(a.ExportedTypes);
                }
                catch (Exception)
                {
                    return(Type.EmptyTypes);
                }
            })
                     .Where(t => typeof(IInitialConfigurationProvider).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface))
            {
                retVal = (Activator.CreateInstance(t) as IInitialConfigurationProvider).Provide(retVal);
            }
            return(retVal);
        }
        /// <summary>
        /// Configure the setting
        /// </summary>
        public void Configure(SanteDBConfiguration configuration, IDictionary <string, string> settings)
        {
            var secSection = configuration.GetSection <SecurityConfigurationSection>();

            if (secSection == null)
            {
                secSection = new SecurityConfigurationSection()
                {
                    PasswordRegex      = @"^(?=.*\d){1,}(?=.*[a-z]){1,}(?=.*[A-Z]){1,}(?=.*[^\w\d]){1,}.{6,}$",
                    PepExemptionPolicy = PolicyEnforcementExemptionPolicy.NoExemptions,

                    SecurityPolicy = new List <SecurityPolicyConfiguration>()
                    {
                        new SecurityPolicyConfiguration(SecurityPolicyIdentification.PasswordHistory, true),
                        new SecurityPolicyConfiguration(SecurityPolicyIdentification.MaxInvalidLogins, 5),
                        new SecurityPolicyConfiguration(SecurityPolicyIdentification.SessionLength, (PolicyValueTimeSpan) new TimeSpan(1, 0, 0)),
                        new SecurityPolicyConfiguration(SecurityPolicyIdentification.RefreshLength, (PolicyValueTimeSpan) new TimeSpan(1, 30, 0))
                    },
                    Signatures = new List <SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration>()
                    {
                        new SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration()
                        {
                            Algorithm  = SanteDB.Core.Security.Configuration.SignatureAlgorithm.HS256,
                            HmacSecret = "@SanteDBDefault$$$409",
                            KeyName    = "jwsdefault"
                        },
                        new SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration()
                        {
                            Algorithm  = SanteDB.Core.Security.Configuration.SignatureAlgorithm.HS256,
                            HmacSecret = "@SanteDBDefault$$$409",
                            KeyName    = "default"
                        }
                    }
                };
                configuration.AddSection(secSection);
            }

            if (settings.TryGetValue(PasswordPatternSetting, out string passwordRegex))
            {
                secSection.PasswordRegex = passwordRegex;
            }

            if (settings.TryGetValue(LockoutSetting, out string lockout))
            {
                if (!Int32.TryParse(lockout, out int lockoutInt))
                {
                    throw new ArgumentException($"{lockout} is not a valid integer");
                }
                secSection.SetPolicy(SecurityPolicyIdentification.MaxInvalidLogins, lockoutInt);
            }

            if (settings.TryGetValue(SessionLengthSetting, out string sessionLength))
            {
                if (!TimeSpan.TryParse(lockout, out TimeSpan sessionLengthTs))
                {
                    throw new ArgumentException($"{lockout} is not a valid integer");
                }
                secSection.SetPolicy(SecurityPolicyIdentification.SessionLength, (PolicyValueTimeSpan)sessionLengthTs);
            }

            foreach (var set in settings)
            {
                // Key setting
                if (set.Key.StartsWith(KeySetting))
                {
                    var keyName = set.Key.Substring(KeySetting.Length);
                    secSection.Signatures.RemoveAll(o => o.KeyName == keyName);

                    var keyConfigData = set.Value.Split(':');
                    if (keyConfigData.Length != 2)
                    {
                        throw new ArgumentException($"Signature key {set.Key} is invalid, format is - (rs256|rs512|hs256):(keyvalue)");
                    }

                    switch (keyConfigData[0].ToLowerInvariant())
                    {
                    case "hs256":
                        secSection.Signatures.Add(new SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration()
                        {
                            Algorithm  = SanteDB.Core.Security.Configuration.SignatureAlgorithm.HS256,
                            HmacSecret = keyConfigData[1],
                            KeyName    = keyName
                        });
                        break;

                    case "rs256":
                        secSection.Signatures.Add(new SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration()
                        {
                            Algorithm     = SanteDB.Core.Security.Configuration.SignatureAlgorithm.RS256,
                            FindType      = System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint,
                            StoreLocation = System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,
                            StoreName     = System.Security.Cryptography.X509Certificates.StoreName.My,
                            FindValue     = keyConfigData[1],
                            KeyName       = keyName
                        });
                        break;

                    case "rs512":
                        secSection.Signatures.Add(new SanteDB.Core.Security.Configuration.SecuritySignatureConfiguration()
                        {
                            Algorithm     = SanteDB.Core.Security.Configuration.SignatureAlgorithm.RS512,
                            FindType      = System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint,
                            StoreLocation = System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,
                            StoreName     = System.Security.Cryptography.X509Certificates.StoreName.My,
                            FindValue     = keyConfigData[1],
                            KeyName       = keyName
                        });
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Load the configuration file
        /// </summary>
        public SanteDBConfiguration Load()
        {
            if (!String.IsNullOrEmpty(this.m_configPath))
            {
                using (var fs = File.OpenRead(this.m_configPath))
                {
                    return(SanteDBConfiguration.Load(fs));
                }
            }
            else
            {
                var retVal = new SanteDBConfiguration();

                // Inital data source
                DcDataConfigurationSection dataSection = new DcDataConfigurationSection()
                {
                    MainDataSourceConnectionStringName = "santeDbData",
                    MessageQueueConnectionStringName   = "santeDbData",
                    MailDataStore    = "santeDbData",
                    ConnectionString = new System.Collections.Generic.List <ConnectionString>()
                    {
                        new ConnectionString()
                        {
                            Name     = "santeDbData",
                            Value    = $"dbfile={(String.IsNullOrEmpty(this.m_dataPath) ? "SanteDB.debug.sqlite" : this.m_dataPath )}",
                            Provider = "sqlite"
                        }
                    }
                };

                JavascriptRulesConfigurationSection jsConfiguration = new JavascriptRulesConfigurationSection()
                {
                    DebugMode       = true,
                    WorkerInstances = 1
                };

                // Initial Applet configuration
                AppletConfigurationSection appletSection = new AppletConfigurationSection()
                {
                    Security = new AppletSecurityConfiguration()
                    {
                        AllowUnsignedApplets = true,
                        TrustedPublishers    = new List <string>()
                        {
                            "82C63E1E9B87578D0727E871D7613F2F0FAF683B"
                        }
                    }
                };

                // Initial applet style
                ApplicationConfigurationSection appSection = new ApplicationConfigurationSection()
                {
                    Style       = StyleSchemeType.Dark,
                    UserPrefDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SdbDebug", "userpref"),
                    Cache       = new CacheConfiguration()
                    {
                        MaxAge         = new TimeSpan(0, 5, 0).Ticks,
                        MaxSize        = 1000,
                        MaxDirtyAge    = new TimeSpan(0, 20, 0).Ticks,
                        MaxPressureAge = new TimeSpan(0, 2, 0).Ticks
                    }
                };

                // Application service section
                ApplicationServiceContextConfigurationSection appServiceSection = new ApplicationServiceContextConfigurationSection()
                {
                    ThreadPoolSize   = Environment.ProcessorCount,
                    ServiceProviders = new List <TypeReferenceConfiguration>()
                    {
                        new TypeReferenceConfiguration(typeof(SanteDB.Core.Security.DefaultPolicyDecisionService)),
                        new TypeReferenceConfiguration(typeof(SQLitePolicyInformationService)),
                        new TypeReferenceConfiguration(typeof(LocalRepositoryFactoryService)),
                        //typeof(LocalAlertService).AssemblyQualifiedName,
                        new TypeReferenceConfiguration(typeof(LocalTagPersistenceService)),
                        new TypeReferenceConfiguration(typeof(NetworkInformationService)),
                        new TypeReferenceConfiguration(typeof(BusinessRulesDaemonService)),
                        new TypeReferenceConfiguration(typeof(PersistenceEntitySource)),
                        new TypeReferenceConfiguration(typeof(SanteDB.Caching.Memory.MemoryCacheService)),
                        new TypeReferenceConfiguration(typeof(SanteDB.Core.Services.Impl.DefaultThreadPoolService)),
                        new TypeReferenceConfiguration(typeof(MemorySessionManagerService)),
                        new TypeReferenceConfiguration(typeof(AmiUpdateManager)),
                        new TypeReferenceConfiguration(typeof(AppletClinicalProtocolRepository)),
                        new TypeReferenceConfiguration(typeof(MemoryQueryPersistenceService)),
                        new TypeReferenceConfiguration(typeof(SimpleQueueFileProvider)),
                        new TypeReferenceConfiguration(typeof(SimpleCarePlanService)),
                        new TypeReferenceConfiguration(typeof(SimplePatchService)),
                        new TypeReferenceConfiguration(typeof(DebugAppletManagerService)),
                        new TypeReferenceConfiguration(typeof(SQLiteConnectionManager)),
                        new TypeReferenceConfiguration(typeof(SQLitePersistenceService)),
                        new TypeReferenceConfiguration(typeof(SQLite.Net.Platform.SqlCipher.SQLitePlatformSqlCipher))
                    }
                };

                // Security configuration
                SecurityConfigurationSection secSection = new SecurityConfigurationSection()
                {
                    DeviceName     = Environment.MachineName,
                    AuditRetention = new TimeSpan(30, 0, 0, 0, 0)
                };

                // Device key
                //var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.santedb.org", macAddress));
                //secSection.DeviceSecret = certificate?.Thumbprint;

                // Rest Client Configuration
                ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection()
                {
                    RestClientType = typeof(RestClient)
                };

                // Trace writer
                DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
                {
                    TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>()
                    {
                        new TraceWriterConfiguration()
                        {
                            Filter             = System.Diagnostics.Tracing.EventLevel.Error,
                            InitializationData = "SanteDB",
                            TraceWriter        = typeof(ConsoleTraceWriter)
                        },
                        new TraceWriterConfiguration()
                        {
                            Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                            InitializationData = "SanteDB",
                            TraceWriter        = typeof(FileTraceWriter)
                        }
                    }
                };

                retVal.Sections.Add(appServiceSection);
                retVal.Sections.Add(appletSection);
                retVal.Sections.Add(dataSection);
                retVal.Sections.Add(diagSection);
                retVal.Sections.Add(appSection);
                retVal.Sections.Add(secSection);
                retVal.Sections.Add(serviceSection);
                retVal.Sections.Add(jsConfiguration);
                retVal.Sections.Add(new SynchronizationConfigurationSection()
                {
                    PollInterval = new TimeSpan(0, 5, 0)
                });

                return(retVal);
            }
        }
        /// <summary>
        /// Load the configuration file
        /// </summary>
        public void Load()
        {
            if (!String.IsNullOrEmpty(this.m_configPath))
            {
                using (var fs = File.OpenRead(this.m_configPath))
                {
                    this.m_configuration = OpenIZConfiguration.Load(fs);
                }
            }
            else
            {
                this.m_configuration = new OpenIZConfiguration();

                // Inital data source
                DataConfigurationSection dataSection = new DataConfigurationSection()
                {
                    MainDataSourceConnectionStringName = "openIzData",
                    MessageQueueConnectionStringName   = "openIzData",
                    ConnectionString = new System.Collections.Generic.List <ConnectionString>()
                    {
                        new ConnectionString()
                        {
                            Name  = "openIzData",
                            Value = String.IsNullOrEmpty(this.m_dataPath) ?
                                    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Minims", "OpenIZ.sqlite") :
                                    this.m_dataPath
                        }
                    }
                };

                // Initial Applet configuration
                AppletConfigurationSection appletSection = new AppletConfigurationSection()
                {
                    Security = new AppletSecurityConfiguration()
                    {
                        AllowUnsignedApplets = true,
                        TrustedPublishers    = new List <string>()
                        {
                            "84BD51F0584A1F708D604CF0B8074A68D3BEB973"
                        }
                    }
                };

                // Initial applet style
                ApplicationConfigurationSection appSection = new ApplicationConfigurationSection()
                {
                    Style        = StyleSchemeType.Dark,
                    UserPrefDir  = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "OizDebug", "userpref"),
                    ServiceTypes = new List <string>()
                    {
                        typeof(LocalPolicyDecisionService).AssemblyQualifiedName,
                        typeof(LocalPolicyInformationService).AssemblyQualifiedName,
                        typeof(LocalPatientService).AssemblyQualifiedName,
                        typeof(LocalPlaceService).AssemblyQualifiedName,
                        //typeof(LocalAlertService).AssemblyQualifiedName,
                        typeof(LocalConceptService).AssemblyQualifiedName,
                        typeof(LocalEntityRepositoryService).AssemblyQualifiedName,
                        typeof(LocalOrganizationService).AssemblyQualifiedName,
                        typeof(LocalRoleProviderService).AssemblyQualifiedName,
                        typeof(LocalSecurityService).AssemblyQualifiedName,
                        typeof(LocalMaterialService).AssemblyQualifiedName,
                        typeof(LocalBatchService).AssemblyQualifiedName,
                        typeof(LocalActService).AssemblyQualifiedName,
                        typeof(LocalProviderService).AssemblyQualifiedName,
                        typeof(LocalTagPersistenceService).AssemblyQualifiedName,
                        typeof(NetworkInformationService).AssemblyQualifiedName,
                        typeof(BusinessRulesDaemonService).AssemblyQualifiedName,
                        typeof(LocalEntitySource).AssemblyQualifiedName,
                        typeof(MemoryCacheService).AssemblyQualifiedName,
                        typeof(OpenIZThreadPool).AssemblyQualifiedName,
                        typeof(MemorySessionManagerService).AssemblyQualifiedName,
                        typeof(AmiUpdateManager).AssemblyQualifiedName,
                        typeof(AppletClinicalProtocolRepository).AssemblyQualifiedName,
                        typeof(MemoryQueryPersistenceService).AssemblyQualifiedName,
                        typeof(SimpleQueueFileProvider).AssemblyQualifiedName,
                        typeof(SimpleCarePlanService).AssemblyQualifiedName,
                        typeof(SimplePatchService).AssemblyQualifiedName,
                        typeof(DebugAppletManagerService).AssemblyQualifiedName,
                        typeof(SQLiteConnectionManager).AssemblyQualifiedName,
                        typeof(LocalPersistenceService).AssemblyQualifiedName
                    },
                    Cache = new CacheConfiguration()
                    {
                        MaxAge         = new TimeSpan(0, 5, 0).Ticks,
                        MaxSize        = 1000,
                        MaxDirtyAge    = new TimeSpan(0, 20, 0).Ticks,
                        MaxPressureAge = new TimeSpan(0, 2, 0).Ticks
                    }
                };

                appSection.ServiceTypes.Add(typeof(SQLite.Net.Platform.Generic.SQLitePlatformGeneric).AssemblyQualifiedName);

                // Security configuration
                SecurityConfigurationSection secSection = new SecurityConfigurationSection()
                {
                    DeviceName     = Environment.MachineName,
                    AuditRetention = new TimeSpan(30, 0, 0, 0, 0)
                };

                // Device key
                //var certificate = X509CertificateUtils.FindCertificate(X509FindType.FindBySubjectName, StoreLocation.LocalMachine, StoreName.My, String.Format("DN={0}.mobile.openiz.org", macAddress));
                //secSection.DeviceSecret = certificate?.Thumbprint;

                // Rest Client Configuration
                ServiceClientConfigurationSection serviceSection = new ServiceClientConfigurationSection()
                {
                    RestClientType = typeof(RestClient)
                };

                // Trace writer
                DiagnosticsConfigurationSection diagSection = new DiagnosticsConfigurationSection()
                {
                    TraceWriter = new System.Collections.Generic.List <TraceWriterConfiguration>()
                    {
                        new TraceWriterConfiguration()
                        {
                            Filter             = System.Diagnostics.Tracing.EventLevel.Error,
                            InitializationData = "OpenIZ",
                            TraceWriter        = new ConsoleTraceWriter(System.Diagnostics.Tracing.EventLevel.Warning, "OpenIZ")
                        },
                        new TraceWriterConfiguration()
                        {
                            Filter             = System.Diagnostics.Tracing.EventLevel.LogAlways,
                            InitializationData = "OpenIZ",
                            TraceWriter        = new FileTraceWriter(System.Diagnostics.Tracing.EventLevel.Warning, "OpenIZ")
                        }
                    }
                };
                this.m_configuration.Sections.Add(appletSection);
                this.m_configuration.Sections.Add(dataSection);
                this.m_configuration.Sections.Add(diagSection);
                this.m_configuration.Sections.Add(appSection);
                this.m_configuration.Sections.Add(secSection);
                this.m_configuration.Sections.Add(serviceSection);
                this.m_configuration.Sections.Add(new SynchronizationConfigurationSection()
                {
                    PollInterval = new TimeSpan(0, 5, 0)
                });
            }
        }
 /// <summary>
 /// DI constructor for ADO CHallenge
 /// </summary>
 public AdoSecurityChallengeProvider(IConfigurationManager configurationManager, IPolicyEnforcementService pepService)
 {
     this.m_policyEnforcementService = pepService;
     this.m_configuration            = configurationManager.GetSection <AdoPersistenceConfigurationSection>();
     this.m_securityConfiguration    = configurationManager.GetSection <SecurityConfigurationSection>();
 }