예제 #1
0
        /// <summary>
        /// Run the job
        /// </summary>
        public void Run(object sender, EventArgs e, object[] parameters)
        {
            try
            {
                this.m_stateManager.SetState(this, JobStateType.Running);

                using (AuthenticationContext.EnterSystemContext())
                {
                    this.m_tracer.TraceInfo("Will notify users of inactivity...");
                    int days                = parameters.Length > 0 ? (int)parameters[0] : 28;
                    var userRepository      = ApplicationServiceContext.Current.GetService <IRepositoryService <SecurityUser> >();
                    var entityRepository    = ApplicationServiceContext.Current.GetService <IRepositoryService <UserEntity> >();
                    var notificationService = ApplicationServiceContext.Current.GetService <INotificationService>();
                    var templateService     = ApplicationServiceContext.Current.GetService <INotificationTemplateFiller>();

                    DateTimeOffset cutoff = DateTimeOffset.Now.AddDays(-days);

                    int offset = 0, totalResults = 1;
                    while (offset < totalResults)
                    {
                        this.m_stateManager.SetProgress(this, "Pruning Users", (float)offset / (float)totalResults);
                        List <SecurityUser> actionedUser = new List <SecurityUser>(10);

                        // Users who haven't logged in
                        foreach (var usr in userRepository.Find(o => o.UserClass == ActorTypeKeys.HumanUser && o.LastLoginTime < cutoff, offset, 100, out totalResults))
                        {
                            // Cancel request?
                            if (this.m_cancelFlag)
                            {
                                break;
                            }

                            double daysSinceLastLogin = 0;
                            if (!usr.LastLoginTime.HasValue)
                            {
                                daysSinceLastLogin = DateTimeOffset.Now.Subtract(usr.CreationTime).TotalDays;
                            }
                            else
                            {
                                daysSinceLastLogin = DateTimeOffset.Now.Subtract(usr.LastLoginTime.Value).TotalDays;
                            }

                            // To which address?
                            String[] to = null;
                            if (usr.EmailConfirmed)
                            {
                                to = new string[] { $"mailto:{usr.Email}" }
                            }
                            ;
                            else if (usr.PhoneNumberConfirmed)
                            {
                                to = new string[] { $"tel:{usr.Email}" }
                            }
                            ;

                            // Template and action
                            string templateId = null;
                            if (daysSinceLastLogin > days + 7) // a week since we notified them, obsolete
                            {
                                actionedUser.Add(usr);
                                this.m_tracer.TraceVerbose("De-activating user {0}...", usr.UserName);
                                userRepository.Obsolete(usr.Key.Value);
                                templateId = "org.santedb.notification.security.user.inactiveRemoved";
                            }
                            else
                            {
                                templateId = "org.santedb.notification.security.user.inactiveWarned";
                            }

                            var entity = entityRepository.Find(o => o.SecurityUserKey == usr.Key, 0, 1, out int _).FirstOrDefault();
                            var lang   = entity?.GetPersonLanguages()?.FirstOrDefault(o => o.IsPreferred)?.LanguageCode;

                            var template = templateService.FillTemplate(templateId, lang, new
                            {
                                removalDays = Math.Round((days + 7) - daysSinceLastLogin),
                                removalDate = DateTime.Now.AddDays((days + 7) - daysSinceLastLogin).Date,
                                user        = usr,
                                entity      = entity
                            });

                            // Send the notification
                            this.m_tracer.TraceVerbose("Sending {0} notification to {1}...", templateId, usr.UserName);
                            notificationService.Send(to, template.Subject, template.Body);
                        }
                        offset += 100;

                        // Audit that we deleted users
                        if (actionedUser.Count > 0)
                        {
                            AuditUtil.AuditSecurityDeletionAction(actionedUser, true, new String[] { "obsoletionTime" });
                        }
                    }

                    this.m_stateManager.SetState(this, JobStateType.Completed);
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error pruning inactive users : {0}", ex);
                this.m_stateManager.SetProgress(this, ex.Message, 0.0f);
                this.m_stateManager.SetState(this, JobStateType.Aborted);
            }
            finally
            {
                this.m_cancelFlag = false;
            }
        }