/// <summary>
        /// Synchronize security locally
        /// </summary>
        private void SynchronizeSecurity(string deviceSecret, string deviceName, IPrincipal principal)
        {
            // Create a security user and ensure they exist!
            var localPip      = ApplicationContext.Current.GetService <IOfflinePolicyInformationService>();
            var localIdp      = ApplicationContext.Current.GetService <IOfflineDeviceIdentityProviderService>();
            var sdPersistence = ApplicationContext.Current.GetService <IDataPersistenceService <SecurityDevice> >();

            if (localIdp != null &&
                !String.IsNullOrEmpty(deviceSecret) && principal is IClaimsPrincipal &&
                ApplicationContext.Current.ConfigurationPersister.IsConfigured)
            {
                using (AuthenticationContext.EnterContext(principal))
                {
                    IClaimsPrincipal cprincipal = principal as IClaimsPrincipal;
                    var amiPip = new AmiPolicyInformationService();

                    IIdentity localDeviceIdentity = null;
                    lock (this.m_lockObject)
                    {
                        try
                        {
                            localDeviceIdentity = localIdp.GetIdentity(deviceName);
                            Guid sid = Guid.Parse(cprincipal.FindFirst(SanteDBClaimTypes.SanteDBDeviceIdentifierClaim).Value);
                            if (localDeviceIdentity == null)
                            {
                                localDeviceIdentity = localIdp.CreateIdentity(sid, deviceName, deviceSecret, AuthenticationContext.SystemPrincipal);
                            }
                            else
                            {
                                localIdp.ChangeSecret(deviceName, deviceSecret, AuthenticationContext.SystemPrincipal);
                            }
                        }
                        catch (Exception ex)
                        {
                            this.m_tracer.TraceWarning("Insertion of local cache credential failed: {0}", ex);
                        }

                        // Ensure policies exist from the claim
                        foreach (var itm in cprincipal.Claims.Where(o => o.Type == SanteDBClaimTypes.SanteDBGrantedPolicyClaim))
                        {
                            if (localPip.GetPolicy(itm.Value) == null)
                            {
                                try
                                {
                                    var policy = amiPip.GetPolicy(itm.Value);
                                    localPip.CreatePolicy(policy, AuthenticationContext.SystemPrincipal);
                                }
                                catch (Exception e)
                                {
                                    this.m_tracer.TraceWarning("Cannot update local policy information : {0}", e.Message);
                                }
                            }
                        }

                        localPip.AddPolicies(localDeviceIdentity, PolicyGrantType.Grant, AuthenticationContext.SystemPrincipal, cprincipal.Claims.Where(o => o.Type == SanteDBClaimTypes.SanteDBGrantedPolicyClaim).Select(o => o.Value).ToArray());
                    }
                }
            }
        }
        /// <summary>
        /// Run the job
        /// </summary>
        public void Run(object sender, EventArgs e, object[] parameters)
        {
            using (AuthenticationContext.EnterSystemContext())
            {
                try
                {
                    this.m_jobStateManager.SetState(this, JobStateType.Running);
                    var amiPip = new AmiPolicyInformationService();

                    try
                    {
                        foreach (var itm in amiPip.GetPolicies())
                        {
                            this.m_offlinePip.CreatePolicy(itm, AuthenticationContext.SystemPrincipal);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.m_tracer.TraceError("Error synchronizing system policies - {0}", ex);
                    }

                    var systemRoles = new String[] { "SYNCHRONIZERS", "ADMINISTRATORS", "ANONYMOUS", "DEVICE", "SYSTEM", "USERS", "CLINICAL_STAFF", "LOCAL_USERS" };

                    // Synchronize the groups
                    foreach (var rol in this.m_offlineRps.GetAllRoles().Union(systemRoles))
                    {
                        try
                        {
                            var group = this.m_securityRepository.GetRole(rol);
                            if (group == null)
                            {
                                this.m_offlineRps.CreateRole(rol, AuthenticationContext.SystemPrincipal);
                                group = this.m_securityRepository.GetRole(rol);
                            }

                            var activePolicies = amiPip.GetPolicies(group);
                            // Create local policy if not exists
                            foreach (var pol in activePolicies)
                            {
                                if (this.m_offlinePip.GetPolicy(pol.Policy.Oid) == null)
                                {
                                    this.m_offlinePip.CreatePolicy(pol.Policy, AuthenticationContext.SystemPrincipal);
                                }
                            }

                            // Clear policies
                            var localPol = this.m_offlinePip.GetPolicies(group);
                            // Remove policies which no longer are granted
                            var noLongerGrant = localPol.Where(o => !activePolicies.Any(a => a.Policy.Oid == o.Policy.Oid));
                            this.m_offlinePip.RemovePolicies(group, AuthenticationContext.SystemPrincipal, noLongerGrant.Select(o => o.Policy.Oid).ToArray());
                            // Assign policies
                            foreach (var pgroup in activePolicies.GroupBy(o => o.Rule))
                            {
                                this.m_offlinePip.AddPolicies(group, pgroup.Key, AuthenticationContext.SystemPrincipal, pgroup.Select(o => o.Policy.Oid).ToArray());
                            }
                        }
                        catch (Exception)
                        {
                            this.m_tracer.TraceWarning("Could not sync {rol}");
                        }
                    }

                    // Query for challenges
                    if (this.m_securityChallenge != null)
                    {
                        var challenges = this.m_amiIntegrationService.Find <SecurityChallenge>(o => o.ObsoletionTime == null, 0, 10);
                        if (challenges != null)
                        {
                            foreach (var itm in challenges.Item.OfType <SecurityChallenge>())
                            {
                                if (this.m_securityChallenge.Get(itm.Key.Value, null, true, AuthenticationContext.SystemPrincipal) == null)
                                {
                                    this.m_securityChallenge.Insert(itm, TransactionMode.Commit, AuthenticationContext.SystemPrincipal);
                                }
                            }
                        }
                    }

                    if (this.m_tickleWasSent) // a previous tickle was sent - let's notify the user that the sync is working again
                    {
                        this.m_tickleWasSent = false;
                        this.m_tickleService.SendTickle(new Tickler.Tickle(Guid.Empty, Tickler.TickleType.Information, Strings.locale_syncRestored));
                    }
                    this.m_jobStateManager.SetState(this, JobStateType.Completed);
                }
                catch (Exception ex)
                {
                    this.m_jobStateManager.SetState(this, JobStateType.Aborted);
                    this.m_jobStateManager.SetProgress(this, ex.Message, 0.0f);
                    if (!this.m_tickleWasSent)
                    {
                        this.m_tickleService.SendTickle(new Tickler.Tickle(Guid.Empty, Tickler.TickleType.Danger, String.Format($"{Strings.locale_downloadError}: {Strings.locale_downloadErrorBody}", "Security Policy")));
                        this.m_tickleWasSent = true;
                    }
                    this.m_tracer.TraceWarning("Could not refresh system policies: {0}", ex);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Synchronize the security settings
        /// </summary>
        /// <param name="password"></param>
        /// <param name="principal"></param>
        private void SynchronizeSecurity(string password, IPrincipal principal)
        {
            // Create a security user and ensure they exist!
            var localRp  = ApplicationContext.Current.GetService <IOfflineRoleProviderService>();
            var localPip = ApplicationContext.Current.GetService <IOfflinePolicyInformationService>();
            var localIdp = ApplicationContext.Current.GetService <IOfflineIdentityProviderService>();

            if (localRp == null || localPip == null || localIdp == null)
            {
                return;
            }

            if (!String.IsNullOrEmpty(password) && principal is IClaimsPrincipal &&
                ApplicationContext.Current.ConfigurationPersister.IsConfigured)
            {
                using (AuthenticationContext.EnterContext(principal))
                {
                    IClaimsPrincipal cprincipal = principal as IClaimsPrincipal;
                    var amiPip = new AmiPolicyInformationService();

                    // We want to impersonate SYSTEM
                    //AndroidApplicationContext.Current.SetPrincipal(cprincipal);

                    // Ensure policies exist from the claim
                    foreach (var itm in cprincipal.Claims.Where(o => o.Type == SanteDBClaimTypes.SanteDBGrantedPolicyClaim).ToArray())
                    {
                        if (localPip.GetPolicy(itm.Value) == null)
                        {
                            try
                            {
                                var policy = amiPip.GetPolicy(itm.Value);
                                localPip.CreatePolicy(policy, AuthenticationContext.SystemPrincipal);
                            }
                            catch (Exception e)
                            {
                                this.m_tracer.TraceWarning("Cannot update local policy information : {0}", e.Message);
                            }
                        }
                    }

                    // Ensure roles exist from the claim
                    var localRoles = localRp.GetAllRoles();
                    foreach (var itm in cprincipal.Claims.Where(o => o.Type == SanteDBClaimTypes.DefaultRoleClaimType).ToArray())
                    {
                        // Ensure policy exists
                        try
                        {
                            var amiPolicies = amiPip.GetPolicies(new SecurityRole()
                            {
                                Name = itm.Value
                            }).ToArray();
                            foreach (var pol in amiPolicies)
                            {
                                if (localPip.GetPolicy(pol.Policy.Oid) == null)
                                {
                                    var policy = amiPip.GetPolicy(pol.Policy.Oid);
                                    localPip.CreatePolicy(policy, AuthenticationContext.SystemPrincipal);
                                }
                            }

                            // Local role doesn't exist
                            if (!localRoles.Contains(itm.Value))
                            {
                                localRp.CreateRole(itm.Value, AuthenticationContext.SystemPrincipal);
                            }
                            localRp.AddPoliciesToRoles(amiPolicies, new String[] { itm.Value }, AuthenticationContext.SystemPrincipal);
                        }
                        catch (Exception e)
                        {
                            this.m_tracer.TraceWarning("Could not fetch / refresh policies: {0}", e.Message);
                        }
                    }

                    var localUser = ApplicationContext.Current.ConfigurationPersister.IsConfigured ? localIdp.GetIdentity(principal.Identity.Name) : null;

                    try
                    {
                        Guid sid = Guid.Parse(cprincipal.FindFirst(SanteDBClaimTypes.Sid).Value);
                        if (localUser == null)
                        {
                            localIdp.CreateIdentity(sid, principal.Identity.Name, password, AuthenticationContext.SystemPrincipal);
                        }
                        else
                        {
                            localIdp.ChangePassword(principal.Identity.Name, password, AuthenticationContext.SystemPrincipal);
                        }

                        // Copy security attributes
                        var localSu = ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Get(sid, null, true, AuthenticationContext.SystemPrincipal);
                        localSu.Email         = cprincipal.FindFirst(SanteDBClaimTypes.Email)?.Value;
                        localSu.PhoneNumber   = cprincipal.FindFirst(SanteDBClaimTypes.Telephone)?.Value;
                        localSu.LastLoginTime = DateTime.Now;
                        ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Update(localSu, TransactionMode.Commit, AuthenticationContext.SystemPrincipal);

                        // Add user to roles
                        // TODO: Remove users from specified roles?
                        localRp.AddUsersToRoles(new String[] { principal.Identity.Name }, cprincipal.Claims.Where(o => o.Type == SanteDBClaimTypes.DefaultRoleClaimType).Select(o => o.Value).ToArray(), AuthenticationContext.SystemPrincipal);
                        // Unlock the account
                        localIdp.SetLockout(principal.Identity.Name, false, principal);
                    }
                    catch (Exception ex)
                    {
                        this.m_tracer.TraceWarning("Insertion of local cache credential failed: {0}", ex);
                    }
                }
            }
        }