Exemplo n.º 1
0
 public LoginSwitch( UserLoginService service,
                     IInterServiceInventoryServices interInventoryService,
                     IInventoryService inventoryService,
                     IGridService gridService,
                     UserConfig config)
 {
     m_UserLoginService = service;
     m_RealXtendLogin = new RealXtendLogin(service, interInventoryService, inventoryService, this, gridService, config);
 }
Exemplo n.º 2
0
 public RealXtendLogin(UserLoginService service,
                     IInterServiceInventoryServices interInventoryService,
                     IInventoryService inventoryService,
                     LoginSwitch loginSwitch,
                     IGridService gridService,
                     UserConfig config)
 {
     m_UserLoginService = service;
     m_interInventoryService = interInventoryService;
     m_InventoryService = inventoryService;
     m_LoginSwitch = loginSwitch;
     m_GridService = gridService;
     m_UserConfig = config;
     m_defaultHomeX = m_UserConfig.DefaultX;
     m_defaultHomeY = m_UserConfig.DefaultY;
     m_OpenSimMap = new OpenSimMap(config.GridServerURL, m_GridService);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Maps the users.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        private void MapUsers(IQueryable <Row> tableData)
        {
            var lookupContext = new RockContext();
            var personService = new PersonService(lookupContext);

            int rockAuthenticatedTypeId = EntityTypeCache.Read("Rock.Security.Authentication.Database").Id;

            int secondaryEmailAttributeId = new AttributeService(lookupContext).GetByEntityTypeId(PersonEntityTypeId)
                                            .Where(a => a.Key == "SecondaryEmail").Select(a => a.Id).FirstOrDefault();
            var secondaryEmailAttribute = AttributeCache.Read(SecondaryEmailAttributeId);

            int staffGroupId      = new GroupService(lookupContext).GetByGuid(new Guid(Rock.SystemGuid.Group.GROUP_STAFF_MEMBERS)).Id;
            int memberGroupRoleId = new GroupTypeRoleService(lookupContext).Queryable()
                                    .Where(r => r.Guid.Equals(new Guid("00F3AC1C-71B9-4EE5-A30E-4C48C8A0BF1F")))
                                    .Select(r => r.Id).FirstOrDefault();

            var userLoginService  = new UserLoginService(lookupContext);
            var importedUserCount = userLoginService.Queryable().Where(u => u.ForeignId != null).Count();

            var allUsers = userLoginService.Queryable()
                           .ToDictionary(t => t.UserName.Trim(), t => t.PersonId);

            var newUserLogins     = new List <UserLogin>();
            var newStaffMembers   = new List <GroupMember>();
            var updatedPersonList = new List <Person>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying user import ({0:N0} found, {1:N0} already exist).", totalRows, importedUserCount));

            foreach (var row in tableData)
            {
                int?   individualId = row["LinkedIndividualID"] as int?;
                string userName     = row["UserLogin"] as string;
                int?   userId       = row["UserID"] as int?;
                if (userId != null && individualId != null && !string.IsNullOrWhiteSpace(userName) && !allUsers.ContainsKey(userName))
                {
                    int?personId = GetPersonAliasId(individualId, null);
                    if (personId != null)
                    {
                        DateTime?createdDate = row["UserCreatedDate"] as DateTime?;
                        string   userPhone   = row["UserPhone"] as string;
                        string   userEmail   = row["UserEmail"] as string;
                        string   userTitle   = row["UserTitle"] as string;
                        bool?    isEnabled   = row["IsUserEnabled"] as bool?;
                        bool?    isStaff     = row["IsStaff"] as bool?;
                        bool     isActive    = isEnabled ?? false;

                        var user = new UserLogin();
                        user.CreatedDateTime        = createdDate;
                        user.CreatedByPersonAliasId = ImportPersonAlias.Id;
                        user.EntityTypeId           = rockAuthenticatedTypeId;
                        user.IsConfirmed            = isEnabled;
                        user.UserName  = userName.Trim();
                        user.PersonId  = personId;
                        user.ForeignId = userId.ToString();

                        if (isStaff == true)
                        {
                            // add this user to the staff group
                            var staffMember = new GroupMember();
                            staffMember.GroupId                = staffGroupId;
                            staffMember.PersonId               = (int)personId;
                            staffMember.GroupRoleId            = memberGroupRoleId;
                            staffMember.CreatedDateTime        = createdDate;
                            staffMember.CreatedByPersonAliasId = ImportPersonAlias.Id;
                            staffMember.GroupMemberStatus      = isActive ? GroupMemberStatus.Active : GroupMemberStatus.Inactive;

                            newStaffMembers.Add(staffMember);
                        }

                        // set user login email to primary email
                        if (!string.IsNullOrWhiteSpace(userEmail) && userEmail.IsEmail())
                        {
                            var    person         = personService.Queryable(includeDeceased: true).FirstOrDefault(p => p.Id == personId);
                            string secondaryEmail = string.Empty;
                            userEmail = userEmail.Trim();
                            if (string.IsNullOrWhiteSpace(person.Email))
                            {
                                person.Email           = userEmail.Left(75);
                                person.IsEmailActive   = isEnabled;
                                person.EmailPreference = EmailPreference.EmailAllowed;
                                person.EmailNote       = userTitle;
                                lookupContext.SaveChanges(DisableAudit);
                            }
                            else if (!person.Email.Equals(userEmail))
                            {
                                secondaryEmail = userEmail;
                            }

                            if (!string.IsNullOrWhiteSpace(secondaryEmail))
                            {
                                person.Attributes      = new Dictionary <string, AttributeCache>();
                                person.AttributeValues = new Dictionary <string, AttributeValue>();
                                AddPersonAttribute(secondaryEmailAttribute, person, secondaryEmail);
                            }

                            updatedPersonList.Add(person);
                        }

                        // other Attributes to save?
                        // UserBio
                        // DepartmentName
                        // IsPastor

                        newUserLogins.Add(user);
                        completed++;

                        if (completed % percentage < 1)
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress(percentComplete, string.Format("{0:N0} users imported ({1}% complete).", completed, percentComplete));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SaveNewUserLogins(newUserLogins, newStaffMembers, updatedPersonList);

                            updatedPersonList.Clear();
                            newUserLogins.Clear();
                            newStaffMembers.Clear();
                            ReportPartialProgress();
                        }
                    }
                }
                else
                {
                    LogException("User Import", string.Format("User: {0} - UserName: {1} is not linked to a person or already exists.", userId, userName));
                }
            }

            if (newUserLogins.Any())
            {
                SaveNewUserLogins(newUserLogins, newStaffMembers, updatedPersonList);
            }

            ReportProgress(100, string.Format("Finished user import: {0:N0} users imported.", completed));
        }
Exemplo n.º 4
0
 /// <summary>
 /// Start up the login service
 /// </summary>
 /// <param name="inventoryService"></param>
 protected virtual void StartupLoginService()
 {
     m_loginService = new UserLoginService(
         m_userDataBaseService, new LibraryRootFolder(Cfg.LibraryXmlfile, Cfg.LibraryName), Cfg.MapServerURI, Cfg.ProfileServerURI, Cfg, Cfg.DefaultStartupMsg, new RegionProfileServiceProxy());
 }
Exemplo n.º 5
0
        private System.Threading.Tasks.Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            if (!string.IsNullOrEmpty(context.UserName) && !string.IsNullOrEmpty(context.Password))
            {
                var rockContext      = new RockContext();
                var userLoginService = new UserLoginService(rockContext);
                //Older Avalanche Clients use __PHONENUMBER__+1 prefix vs the newer SMS_ prefix
                //This makes sure we are using the new ROCK external sms authentication
                var userName = context.UserName.Replace("__PHONENUMBER__+1", "SMS_");

                //SMS login does not use the phone number as the username.
                //Instead we need to change it to use the person's id.
                if (userName.StartsWith("SMS_"))
                {
                    string error;
                    var    smsAuthentication = new SMSAuthentication();
                    var    person            = smsAuthentication.GetNumberOwner(userName.Split('_').Last(), rockContext, out error);
                    if (person != null)
                    {
                        userName = string.Format("SMS_{0}", person.Id);
                    }
                    //If we cannot find a person, do nothing and just pass through the existing username
                }
                var userLogin = userLoginService.GetByUserName(userName);
                if (userLogin != null && userLogin.EntityType != null)
                {
                    var component = AuthenticationContainer.GetComponent(userLogin.EntityType.Name);
                    if (component != null && component.IsActive &&
                        (!component.RequiresRemoteAuthentication || component.TypeName == "Rock.Security.ExternalAuthentication.SMSAuthentication"))
                    {
                        if (component.Authenticate(userLogin, context.Password))
                        {
                            if ((userLogin.IsConfirmed ?? true) && !(userLogin.IsLockedOut ?? false))
                            {
                                OAuthContext         oAuthContext         = new OAuthContext();
                                ClientScopeService   clientScopeService   = new ClientScopeService(oAuthContext);
                                AuthorizationService authorizationService = new AuthorizationService(oAuthContext);
                                ClientService        clientService        = new ClientService(oAuthContext);

                                var scopes = (context.Scope.FirstOrDefault() ?? "").Split(',');

                                bool     scopesApproved   = false;
                                Client   OAuthClient      = clientService.GetByApiKey(context.ClientId.AsGuid());
                                string[] authorizedScopes = authorizationService.Queryable().Where(a => a.Client.Id == OAuthClient.Id && a.UserLogin.UserName == userName && a.Active == true).Select(a => a.Scope.Identifier).ToArray <string>();
                                if (!clientScopeService.Queryable().Where(cs => cs.ClientId == OAuthClient.Id && cs.Active == true).Any() ||
                                    (authorizedScopes != null && scopes.Where(s => !authorizedScopes.Select(a => a.ToLower()).Contains(s.ToLower())).Count() == 0))
                                {
                                    scopesApproved = true;
                                }

                                if (scopesApproved)
                                {
                                    var identity = new ClaimsIdentity(new GenericIdentity(userName, OAuthDefaults.AuthenticationType));

                                    //only allow claims that have been requested and the client has been authorized for
                                    foreach (var scope in scopes.Where(s => clientScopeService.Queryable().Where(cs => cs.ClientId == OAuthClient.Id && cs.Active == true).Select(cs => cs.Scope.Identifier.ToLower()).Contains(s.ToLower())))
                                    {
                                        identity.AddClaim(new Claim("urn:oauth:scope", scope));
                                    }
                                    UserLoginService.UpdateLastLogin(userName);
                                    context.Validated(identity);
                                    return(System.Threading.Tasks.Task.FromResult(0));
                                }
                                else
                                {
                                    context.SetError("Authentication Error", "All scopes are not authorized for this user.");
                                }
                            }
                            if (!userLogin.IsConfirmed ?? true)
                            {
                                context.SetError("Authentication Error", "Account email is unconfirmed.");
                            }
                            if (userLogin.IsLockedOut ?? false)
                            {
                                context.SetError("Authentication Error", "Account is locked.");
                            }
                        }
                        else
                        {
                            context.SetError("Authentication Error", "Invalid Username/Password.");
                        }
                    }
                    else
                    {
                        context.SetError("Authentication Error", "Invalid Authentication Configuration.");
                    }
                }
                else
                {
                    context.SetError("Authentication Error", "Invalid Username/Password.");
                }
            }
            else
            {
                context.SetError("Authentication Error", "Invalid Username/Password.");
            }

            context.Rejected();
            return(System.Threading.Tasks.Task.FromResult(0));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Provides an end method for an asynchronous process.
        /// </summary>
        /// <param name="result">An IAsyncResult that contains information about the status of the process.</param>
        public void EndProcessRequest(IAsyncResult result)
        {
            // restore the context from the asyncResult.AsyncState
            HttpContext context = (HttpContext)result.AsyncState;

            try
            {
                context.Response.Clear();

                bool isBinaryFile = (bool)context.Items["isBinaryFile"];

                if (isBinaryFile)
                {
                    var rockContext = new RockContext();

                    bool       requiresViewSecurity = false;
                    BinaryFile binaryFile           = new BinaryFileService(rockContext).EndGet(result, context, out requiresViewSecurity);
                    if (binaryFile != null)
                    {
                        //// if the binaryFile's BinaryFileType requires security, check security
                        //// note: we put a RequiresViewSecurity flag on BinaryFileType because checking security for every file would be slow (~40ms+ per request)
                        if (requiresViewSecurity)
                        {
                            var    currentUser   = new UserLoginService(rockContext).GetByUserName(UserLogin.GetCurrentUserName());
                            Person currentPerson = currentUser != null ? currentUser.Person : null;
                            binaryFile.BinaryFileType = binaryFile.BinaryFileType ?? new BinaryFileTypeService(rockContext).Get(binaryFile.BinaryFileTypeId.Value);
                            if (!binaryFile.IsAuthorized(Authorization.VIEW, currentPerson))
                            {
                                SendNotAuthorized(context);
                                return;
                            }
                        }

                        SendFile(context, binaryFile.ContentStream, binaryFile.MimeType, binaryFile.FileName, binaryFile.Guid.ToString("N"));
                        return;
                    }
                }
                else
                {
                    Stream fileContents            = (Stream)context.Items["fileContents"];
                    string physicalContentFileName = context.Items["physicalContentFileName"] as string;

                    if (fileContents != null)
                    {
                        string mimeType = System.Web.MimeMapping.GetMimeMapping(physicalContentFileName);
                        string fileName = Path.GetFileName(physicalContentFileName);
                        SendFile(context, fileContents, mimeType, fileName, "");
                        return;
                    }
                }

                context.Response.StatusCode        = 404;
                context.Response.StatusDescription = "Unable to find the requested file.";
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, context);
                try
                {
                    context.Response.StatusCode        = 500;
                    context.Response.StatusDescription = ex.Message;
                    context.Response.Flush();
                    context.ApplicationInstance.CompleteRequest();
                }
                catch (Exception ex2)
                {
                    ExceptionLogService.LogException(ex2, context);
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Loads the UserLogin data.
        /// </summary>
        /// <param name="csvData">The CSV data.</param>
        private int LoadUserLogin(CSVInstance csvData)
        {
            var lookupContext    = new RockContext();
            var userLoginService = new UserLoginService(lookupContext);

            var newUserLoginList      = new List <UserLogin>();
            var existingUserLoginList = new List <UserLogin>();

            existingUserLoginList.AddRange(userLoginService.Queryable().AsNoTracking().Where(a => a.ForeignId == null));

            int completed            = 0;
            int importedCount        = 0;
            int alreadyImportedCount = userLoginService.Queryable().AsNoTracking().Count(a => a.ForeignKey != null);

            ReportProgress(0, string.Format("Starting user login import ({0:N0} already exist).", alreadyImportedCount));

            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string rowUserLoginId                 = row[UserLoginId];
                string rowUserLoginPersonId           = row[UserLoginPersonId];
                string rowUserLoginUserName           = row[UserLoginUserName];
                string rowUserLoginPassword           = row[UserLoginPassword];
                string rowUserLoginDateCreated        = row[UserLoginDateCreated];
                string rowUserLoginAuthenticationType = row[UserLoginAuthenticationType];
                string rowUserLoginIsConfirmed        = row[UserLoginIsConfirmed];

                int?rowLoginId           = rowUserLoginId.AsType <int?>();
                int authenticationTypeId = EntityTypeCache.Get(rowUserLoginAuthenticationType).Id;

                //
                // Find this person in the database.
                //
                var personKeys = GetPersonKeys(rowUserLoginPersonId);
                if (personKeys == null || personKeys.PersonId == 0)
                {
                    ReportProgress(0, string.Format("Person key {0} not found", rowUserLoginPersonId));
                }

                //
                // Verify the authentication type exists.
                //
                if (authenticationTypeId < 1)
                {
                    ReportProgress(0, string.Format("Authentication type {0} not found", rowUserLoginAuthenticationType));
                }

                //
                // Check that this user login record doesn't already exist.
                //
                bool exists = false;

                if (existingUserLoginList.Count > 0)
                {
                    exists = userLoginService.Queryable().AsNoTracking().Any(a => a.UserName.ToLower() == rowUserLoginUserName.ToLower());
                }

                if (exists == false && alreadyImportedCount > 0)
                {
                    exists = userLoginService.Queryable().AsNoTracking().Any(a => a.ForeignKey == rowUserLoginId);
                }

                if (!exists && personKeys != null && personKeys.PersonId != 0 && authenticationTypeId > 0)
                {
                    //
                    // Create and populate the new user login record.
                    //
                    UserLogin login = new UserLogin();
                    login.CreatedDateTime        = ParseDateOrDefault(rowUserLoginDateCreated, DateTime.Now);
                    login.CreatedByPersonAliasId = ImportPersonAliasId;
                    login.EntityTypeId           = authenticationTypeId;
                    login.IsConfirmed            = ParseBoolOrDefault(rowUserLoginIsConfirmed, true);
                    login.UserName   = rowUserLoginUserName;
                    login.Password   = rowUserLoginPassword;
                    login.PersonId   = personKeys.PersonId;
                    login.ForeignKey = rowUserLoginId;
                    login.ForeignId  = rowLoginId;

                    //
                    // Force not confirmed if no password provided for database logins.
                    //
                    if (rowUserLoginAuthenticationType == "Rock.Security.Authentication.Database" && string.IsNullOrWhiteSpace(rowUserLoginPassword))
                    {
                        login.IsConfirmed = false;
                    }

                    //
                    // Add the record for delayed saving.
                    //
                    newUserLoginList.Add(login);
                    importedCount++;
                }

                //
                // Notify user of our status.
                //
                completed++;
                if (completed % (ReportingNumber * 10) < 1)
                {
                    ReportProgress(0, string.Format("{0:N0} user login records processed, {1:N0} imported.", completed, importedCount));
                }

                if (completed % ReportingNumber < 1)
                {
                    SaveUserLogin(newUserLoginList);
                    lookupContext.SaveChanges();
                    ReportPartialProgress();

                    // Clear out variables
                    newUserLoginList.Clear();
                    userLoginService = new UserLoginService(lookupContext);
                }
            }

            //
            // Save any final changes to new records
            //
            if (newUserLoginList.Any())
            {
                SaveUserLogin(newUserLoginList);
            }

            //
            // Save any other changes to existing items.
            //
            lookupContext.SaveChanges();
            lookupContext.Dispose();

            ReportProgress(0, string.Format("Finished user login import: {0:N0} records added.", importedCount));

            return(completed);
        }
Exemplo n.º 8
0
        public HttpResponseMessage CreateAccount(Account account)
        {
            OAuthContext  oAuthContext  = new OAuthContext();
            ClientService clientService = new ClientService(oAuthContext);
            var           clientId      = HttpContext.Current.User.Identity.Name;
            Client        oAuthClient   = clientService.GetByApiKey(clientId.AsGuid());

            if (oAuthClient.Active)
            {
                var              rockContext      = new Rock.Data.RockContext();
                PersonService    personService    = new PersonService(rockContext);
                UserLoginService userLoginService = new UserLoginService(rockContext);

                // Validate the Model
                if (!string.IsNullOrEmpty(account.Username))
                {
                    // Make sure the username is unique
                    UserLogin user = userLoginService.GetByUserName(account.Username);
                    if (user != null)
                    {
                        ModelState.AddModelError("Account.Username", "Username already exists");
                    }

                    // Make sure the password is valid
                    if (!UserLoginService.IsPasswordValid(account.Password))
                    {
                        ModelState.AddModelError("Account.Password", UserLoginService.FriendlyPasswordRules());
                    }

                    // Make sure this person meets the minimum age requirement
                    var birthday = account.Birthdate ?? Rock.RockDateTime.Today;
                    if (RockDateTime.Today.AddYears(MINIMUM_AGE * -1) < birthday)
                    {
                        ModelState.AddModelError("Account.Birthdate", string.Format("We are sorry, you must be at least {0} years old to create an account.", MINIMUM_AGE));
                    }
                }
                if (!ModelState.IsValid)
                {
                    return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
                }

                // Try to match the person
                var matchPerson = personService.GetByMatch(account.FirstName, account.LastName, account.Birthdate, account.EmailAddress, account.MobileNumber, null, null);

                bool   confirmed = false;
                Person person    = new Person();
                if (matchPerson != null && matchPerson.Count() == 1)
                {
                    var mobilePhone = matchPerson.First().PhoneNumbers.Where(pn => pn.NumberTypeValueId == DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid()).Id).FirstOrDefault();
                    // The emails MUST match for security
                    if (matchPerson.First().Email == account.EmailAddress && (mobilePhone == null || mobilePhone.Number.Right(10) == account.MobileNumber.Right(10)))
                    {
                        person = matchPerson.First();

                        // If they don't have a current mobile phone, go ahead and set it
                        if (mobilePhone == null)
                        {
                            string cleanNumber = PhoneNumber.CleanNumber(account.MobileNumber);
                            var    phoneNumber = new PhoneNumber {
                                NumberTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid()).Id
                            };
                            person.PhoneNumbers.Add(phoneNumber);
                            phoneNumber.CountryCode        = cleanNumber.Length > 10 ? cleanNumber.Left(10 - cleanNumber.Length) : PhoneNumber.DefaultCountryCode();
                            phoneNumber.Number             = cleanNumber.Right(10);
                            phoneNumber.IsMessagingEnabled = true;
                        }

                        // Make sure the gender matches
                        person.Gender = account.Gender;

                        confirmed = true;
                    }
                }

                // If we don't have a match, create a new web prospect
                if (!confirmed)
                {
                    DefinedValueCache dvcConnectionStatus = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_CONNECTION_STATUS_WEB_PROSPECT.AsGuid());
                    DefinedValueCache dvcRecordStatus     = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_PENDING.AsGuid());

                    person.FirstName         = account.FirstName;
                    person.LastName          = account.LastName;
                    person.NickName          = account.NickName;
                    person.Email             = account.EmailAddress;
                    person.IsEmailActive     = true;
                    person.EmailPreference   = EmailPreference.EmailAllowed;
                    person.RecordTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                    if (dvcConnectionStatus != null)
                    {
                        person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                    }

                    if (dvcRecordStatus != null)
                    {
                        person.RecordStatusValueId = dvcRecordStatus.Id;
                    }

                    person.Gender = account.Gender;

                    var birthday = account.Birthdate;
                    if (birthday.HasValue)
                    {
                        person.BirthMonth = birthday.Value.Month;
                        person.BirthDay   = birthday.Value.Day;
                        if (birthday.Value.Year != DateTime.MinValue.Year)
                        {
                            person.BirthYear = birthday.Value.Year;
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(account.MobileNumber))
                    {
                        string cleanNumber = PhoneNumber.CleanNumber(account.MobileNumber);
                        var    phoneNumber = new PhoneNumber {
                            NumberTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid()).Id
                        };
                        person.PhoneNumbers.Add(phoneNumber);
                        phoneNumber.CountryCode        = cleanNumber.Length > 10 ? cleanNumber.Left(10 - cleanNumber.Length) : PhoneNumber.DefaultCountryCode();
                        phoneNumber.Number             = cleanNumber.Right(10);
                        phoneNumber.IsMessagingEnabled = true;
                    }

                    PersonService.SaveNewPerson(person, rockContext);
                }
                UserLogin userLogin = null;

                if (!string.IsNullOrWhiteSpace(account.Username) && UserLoginService.IsPasswordValid(account.Password))
                {
                    // Create the user login (only require confirmation if we didn't match the person)
                    userLogin = UserLoginService.Create(
                        rockContext,
                        person,
                        AuthenticationServiceType.Internal,
                        EntityTypeCache.Get(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                        account.Username,
                        account.Password,
                        confirmed);
                }
                else if (!string.IsNullOrWhiteSpace(account.EmailAddress) && !confirmed)
                {
                    userLogin = userLoginService.Queryable()
                                .Where(u => u.UserName == ("SMS_" + person.Id.ToString()))
                                .FirstOrDefault();

                    // Create an unconfirmed SMS user login if does not exist
                    if (userLogin == null)
                    {
                        var entityTypeId = EntityTypeCache.Get("Rock.Security.ExternalAuthentication.SMSAuthentication").Id;

                        userLogin = new UserLogin()
                        {
                            UserName     = "******" + person.Id.ToString(),
                            EntityTypeId = entityTypeId,
                            IsConfirmed  = false,
                            PersonId     = person.Id
                        };
                        userLoginService.Add(userLogin);
                    }
                }
                // Send an email to confirm the account.
                if (userLogin != null && userLogin.IsConfirmed != true)
                {
                    // For mobile we will make a custom/short confirmation code
                    var mobileConfirmationCode = new BigInteger(MD5.Create().ComputeHash(userLogin.Guid.ToByteArray())).ToString().Right(6);
                    var mergeFields            = Rock.Lava.LavaHelper.GetCommonMergeFields(null, person);
                    mergeFields.Add("MobileConfirmationCode", mobileConfirmationCode);
                    mergeFields.Add("ConfirmAccountUrl", GlobalAttributesCache.Get().GetValue("PublicApplicationRoot").EnsureTrailingForwardslash() + "ConfirmAccount");
                    mergeFields.Add("Person", userLogin.Person);
                    mergeFields.Add("User", userLogin);

                    var recipients = new List <RockEmailMessageRecipient>();
                    recipients.Add(new RockEmailMessageRecipient(userLogin.Person, mergeFields));

                    var message = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.SECURITY_CONFIRM_ACCOUNT.AsGuid());
                    message.SetRecipients(recipients);
                    message.AppRoot = GlobalAttributesCache.Get().GetValue("PublicApplicationRoot").EnsureTrailingForwardslash();
                    message.CreateCommunicationRecord = false;
                    message.Send();
                }

                rockContext.SaveChanges();

                return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, new StandardResponse()
                {
                    Message = string.Format("Account has been created.{0}", confirmed?"": " An email has been sent to confirm the email address."),
                    Result = StandardResponse.ResultCode.Success
                }
                                                                ));
            }

            return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden));
        }
Exemplo n.º 9
0
        public IHttpActionResult GetLaunchPacket(string deviceIdentifier = null, bool?notificationsEnabled = null)
        {
            var site = MobileHelper.GetCurrentApplicationSite();
            var additionalSettings = site?.AdditionalSettings.FromJsonOrNull <AdditionalSiteSettings>();
            var rockContext        = new Rock.Data.RockContext();
            var person             = GetPerson(rockContext);
            var deviceData         = Request.GetHeader("X-Rock-DeviceData").FromJsonOrNull <DeviceData>();

            if (additionalSettings == null || !additionalSettings.LastDeploymentDate.HasValue)
            {
                return(NotFound());
            }

            // Ensure the user login is still active, otherwise log them out.
            var principal = ControllerContext.Request.GetUserPrincipal();

            if (person != null && !principal.Identity.Name.StartsWith("rckipid="))
            {
                var userLogin = new UserLoginService(rockContext).GetByUserName(principal.Identity.Name);

                if (userLogin?.IsConfirmed != true || userLogin?.IsLockedOut == true)
                {
                    person = null;
                }
            }

            var launchPacket = new LaunchPacket
            {
                RockVersion         = Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber(),
                LatestVersionId     = additionalSettings.LastDeploymentVersionId ?? ( int )(additionalSettings.LastDeploymentDate.Value.ToJavascriptMilliseconds() / 1000),
                IsSiteAdministrator = site.IsAuthorized(Rock.Security.Authorization.EDIT, person)
            };

            if (deviceData.DeviceType == DeviceType.Phone)
            {
                launchPacket.LatestVersionSettingsUrl = additionalSettings.PhoneUpdatePackageUrl;
            }
            else if (deviceData.DeviceType == DeviceType.Tablet)
            {
                launchPacket.LatestVersionSettingsUrl = additionalSettings.TabletUpdatePackageUrl;
            }
            else
            {
                return(NotFound());
            }

            if (person != null)
            {
                //var principal = ControllerContext.Request.GetUserPrincipal();

                launchPacket.CurrentPerson           = MobileHelper.GetMobilePerson(person, site);
                launchPacket.CurrentPerson.AuthToken = MobileHelper.GetAuthenticationToken(principal.Identity.Name);

                UserLoginService.UpdateLastLogin(principal.Identity.Name);
            }

            //
            // Get or create the personal device.
            //
            if (deviceIdentifier.IsNotNullOrWhiteSpace())
            {
                var mobileDeviceTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSONAL_DEVICE_TYPE_MOBILE).Id;
                var personalDeviceService   = new PersonalDeviceService(rockContext);
                var personalDevice          = personalDeviceService.Queryable()
                                              .Where(a => a.DeviceUniqueIdentifier == deviceIdentifier && a.PersonalDeviceTypeValueId == mobileDeviceTypeValueId && a.SiteId == site.Id)
                                              .FirstOrDefault();

                if (personalDevice == null)
                {
                    personalDevice = new PersonalDevice
                    {
                        DeviceUniqueIdentifier    = deviceIdentifier,
                        PersonalDeviceTypeValueId = mobileDeviceTypeValueId,
                        SiteId               = site.Id,
                        PlatformValueId      = deviceData.DevicePlatform.GetDevicePlatformValueId(),
                        PersonAliasId        = person?.PrimaryAliasId,
                        NotificationsEnabled = true,
                        Manufacturer         = deviceData.Manufacturer,
                        Model            = deviceData.Model,
                        Name             = deviceData.Name,
                        LastSeenDateTime = RockDateTime.Now
                    };

                    personalDeviceService.Add(personalDevice);
                    rockContext.SaveChanges();
                }
                else
                {
                    // A change is determined as one of the following:
                    // 1) A change in Name, Manufacturer, Model, or NotificationsEnabled.
                    // 2) Device not being active.
                    // 3) Not seen in 24 hours.
                    // 4) Signed in with a different person.
                    var hasDeviceChanged = !personalDevice.IsActive ||
                                           personalDevice.Name != deviceData.Name ||
                                           personalDevice.Manufacturer != deviceData.Manufacturer ||
                                           personalDevice.Model != deviceData.Model ||
                                           personalDevice.NotificationsEnabled != (notificationsEnabled ?? true) ||
                                           !personalDevice.LastSeenDateTime.HasValue ||
                                           personalDevice.LastSeenDateTime.Value.AddDays(1) < RockDateTime.Now ||
                                           (person != null && personalDevice.PersonAliasId != person.PrimaryAliasId);

                    if (hasDeviceChanged)
                    {
                        personalDevice.IsActive         = true;
                        personalDevice.Manufacturer     = deviceData.Manufacturer;
                        personalDevice.Model            = deviceData.Model;
                        personalDevice.Name             = deviceData.Name;
                        personalDevice.LastSeenDateTime = RockDateTime.Now;

                        if (notificationsEnabled.HasValue)
                        {
                            personalDevice.NotificationsEnabled = notificationsEnabled.Value;
                        }

                        // Update the person tied to the device, but never blank it out.
                        if (person != null && personalDevice.PersonAliasId != person.PrimaryAliasId)
                        {
                            personalDevice.PersonAliasId = person.PrimaryAliasId;
                        }

                        rockContext.SaveChanges();
                    }
                }

                launchPacket.PersonalDeviceGuid = personalDevice.Guid;
            }

            return(Ok(launchPacket));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Sends the notification.
        /// </summary>
        /// <param name="ex">The ex.</param>
        private void SendNotification(Exception ex)
        {
            int?pageId = (Context.Items["Rock:PageId"] ?? string.Empty).ToString().AsIntegerOrNull();
            int?siteId = (Context.Items["Rock:SiteId"] ?? string.Empty).ToString().AsIntegerOrNull();

            PersonAlias personAlias = null;
            Person      person      = null;

            try
            {
                var user = UserLoginService.GetCurrentUser();
                if (user != null && user.Person != null)
                {
                    person      = user.Person;
                    personAlias = user.Person.PrimaryAlias;
                }
            }
            catch
            {
                // ignore exception
            }

            try
            {
                ExceptionLogService.LogException(ex, Context, pageId, siteId, personAlias);
            }
            catch
            {
                // ignore exception
            }

            try
            {
                bool sendNotification = true;

                var globalAttributesCache = GlobalAttributesCache.Get();

                string filterSettings = globalAttributesCache.GetValue("EmailExceptionsFilter");
                if (!string.IsNullOrWhiteSpace(filterSettings))
                {
                    // Get the current request's list of server variables
                    var serverVarList = Context.Request.ServerVariables;

                    string[] nameValues = filterSettings.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string nameValue in nameValues)
                    {
                        string[] nameAndValue = nameValue.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
                        {
                            if (nameAndValue.Length == 2)
                            {
                                switch (nameAndValue[0].ToLower())
                                {
                                case "type":
                                {
                                    if (ex.GetType().Name.ToLower().Contains(nameAndValue[1].ToLower()))
                                    {
                                        sendNotification = false;
                                    }

                                    break;
                                }

                                case "source":
                                {
                                    if (ex.Source.ToLower().Contains(nameAndValue[1].ToLower()))
                                    {
                                        sendNotification = false;
                                    }

                                    break;
                                }

                                case "message":
                                {
                                    if (ex.Message.ToLower().Contains(nameAndValue[1].ToLower()))
                                    {
                                        sendNotification = false;
                                    }

                                    break;
                                }

                                case "stacktrace":
                                {
                                    if (ex.StackTrace.ToLower().Contains(nameAndValue[1].ToLower()))
                                    {
                                        sendNotification = false;
                                    }

                                    break;
                                }

                                default:
                                {
                                    var serverValue = serverVarList[nameAndValue[0]];
                                    if (serverValue != null && serverValue.ToUpper().Contains(nameAndValue[1].ToUpper().Trim()))
                                    {
                                        sendNotification = false;
                                    }

                                    break;
                                }
                                }
                            }
                        }

                        if (!sendNotification)
                        {
                            break;
                        }
                    }
                }

                if (!sendNotification)
                {
                    return;
                }

                // get email addresses to send to
                string emailAddressesList = globalAttributesCache.GetValue("EmailExceptionsList");
                if (!string.IsNullOrWhiteSpace(emailAddressesList))
                {
                    string[] emailAddresses = emailAddressesList.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (emailAddresses.Length > 0)
                    {
                        string siteName = "Rock";
                        if (siteId.HasValue)
                        {
                            var site = SiteCache.Get(siteId.Value);
                            if (site != null)
                            {
                                siteName = site.Name;
                            }
                        }

                        var exceptionDetails = string.Format(
                            "An error occurred{0} on the {1} site on page: <br>{2}<p>{3}</p>",
                            person != null ? " for " + person.FullName : string.Empty,
                            siteName,
                            Context.Request.UrlProxySafe().OriginalString,
                            FormatException(ex, string.Empty));

                        // setup merge codes for email
                        var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);
                        mergeFields.Add("ExceptionDetails", exceptionDetails);

                        try
                        {
                            mergeFields.Add("Exception", ex);
                        }
                        catch
                        {
                            // ignore
                        }

                        mergeFields.Add("Person", person);
                        var recipients = new List <RockEmailMessageRecipient>();
                        foreach (string emailAddress in emailAddresses)
                        {
                            recipients.Add(RockEmailMessageRecipient.CreateAnonymous(emailAddress, mergeFields));
                        }

                        if (recipients.Any())
                        {
                            var message = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.CONFIG_EXCEPTION_NOTIFICATION.AsGuid());
                            message.SetRecipients(recipients);
                            message.Send();
                        }
                    }
                }
            }
            catch
            {
                // ignore exception
            }
        }
Exemplo n.º 11
0
        private void btn_Login_Click(object sender, EventArgs e)
        {
            User_Service               service = new User_Service();
            JobOrderStatus_Load        frm;  //압연
            JobOrderStatus             frm1; //제선
            JobOrderStatus_Package     frm2; // 포장
            JobOrderStatus_Steelmaking frm3; //제강
            UserLoginService           loginService = new UserLoginService();

            if (service.UserLogin(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim()) == 0)
            {
                MessageBox.Show("아이디 또는 비밀번호가 일치하지 않습니다", "알림");
                txt_UserID.Text  = "";
                txt_UserPwd.Text = "";
                txt_UserID.Focus();
                return;
            }
            else if (service.GetUserType(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim()) == "압연")
            {
                frm = new JobOrderStatus_Load(main);
                frm.BringToFront();
                frm.MdiParent = main;
                frm.Dock      = DockStyle.Fill;
                frm.Show();
                this.Hide();
                main.lbl_name.Text            = service.GetUserName(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim());
                main.label3.Text              = "님";
                main.btn_NonOperation.Enabled = true;
                main.btn_logout.Enabled       = true;
                main.btn_Home.Enabled         = true;
                Global.User_ID = Convert.ToInt32(txt_UserID.Text);
                loginService.InsertLoginPOP(Global.User_ID);
            }

            else if (service.GetUserType(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim()) == "제선")
            {
                frm1 = new JobOrderStatus(main);
                frm1.BringToFront();
                frm1.MdiParent = main;
                frm1.Dock      = DockStyle.Fill;
                frm1.Show();
                this.Hide();
                main.lbl_name.Text            = service.GetUserName(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim());
                main.label3.Text              = "님";
                main.btn_NonOperation.Enabled = true;
                main.btn_logout.Enabled       = true;
                main.btn_Home.Enabled         = true;
                Global.User_ID = Convert.ToInt32(txt_UserID.Text);
                loginService.InsertLoginPOP(Global.User_ID);
            }

            else if (service.GetUserType(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim()) == "제강")
            {
                frm3 = new JobOrderStatus_Steelmaking(main);
                frm3.BringToFront();
                frm3.MdiParent = main;
                frm3.Dock      = DockStyle.Fill;
                frm3.Show();
                this.Hide();
                main.lbl_name.Text            = service.GetUserName(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim());
                main.label3.Text              = "님";
                main.btn_NonOperation.Enabled = true;
                main.btn_logout.Enabled       = true;
                main.btn_Home.Enabled         = true;
                Global.User_ID = Convert.ToInt32(txt_UserID.Text);
                loginService.InsertLoginPOP(Global.User_ID);
            }

            else
            {
                frm2 = new JobOrderStatus_Package(main);
                frm2.BringToFront();
                frm2.MdiParent = main;
                frm2.Dock      = DockStyle.Fill;
                frm2.Show();
                this.Hide();
                main.lbl_name.Text            = service.GetUserName(txt_UserID.Text.Trim(), txt_UserPwd.Text.Trim());
                main.label3.Text              = "님";
                main.btn_NonOperation.Enabled = true;
                main.btn_logout.Enabled       = true;
                main.btn_Home.Enabled         = true;
                Global.User_ID = Convert.ToInt32(txt_UserID.Text);
                loginService.InsertLoginPOP(Global.User_ID);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Represents an event called for each validated token request
        /// to allow the user code to decide how the request should be handled.
        /// </summary>
        /// <param name="context">The context instance associated with this event.</param>
        public override Task HandleTokenRequest(HandleTokenRequestContext context)
        {
            // Only handle grant_type=password requests and let ASOS
            // process grant_type=refresh_token requests automatically.
            if (context.Request.IsPasswordGrantType())
            {
                UserLogin            user                = null;
                ClaimsIdentity       identity            = null;
                IEnumerable <string> allowedClientScopes = null;
                var loginValid = false;

                // Do all the data access here so we can dispose of the rock context asap.
                using (var rockContext = new RockContext())
                {
                    var userLoginService = new UserLoginService(rockContext);
                    user = userLoginService.GetByUserName(context.Request.Username);

                    // Populate the entity type for use later.
                    _ = user.EntityType;

                    allowedClientScopes = RockIdentityHelper.NarrowRequestedScopesToApprovedScopes(rockContext, context.Request.ClientId, context.Request.GetScopes()).ToList();
                    var allowedClientClaims = RockIdentityHelper.GetAllowedClientClaims(rockContext, context.Request.ClientId, allowedClientScopes);
                    identity = RockIdentityHelper.GetRockClaimsIdentity(user, allowedClientClaims, context.Request.ClientId);

                    var component = AuthenticationContainer.GetComponent(user.EntityType.Name);
                    if (component != null && component.IsActive && !component.RequiresRemoteAuthentication)
                    {
                        loginValid = component.AuthenticateAndTrack(user, context.Request.Password);
                        rockContext.SaveChanges();
                    }
                }

                if (identity == null || allowedClientScopes == null)
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidClient,
                        description: "Invalid client configuration.");
                    return(Task.FromResult(0));
                }

                if (user == null || !loginValid)
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidGrant,
                        description: "Invalid credentials.");
                    return(Task.FromResult(0));
                }

                // Ensure the user is allowed to sign in.
                if (!user.IsConfirmed.HasValue || !user.IsConfirmed.Value || (user.IsPasswordChangeRequired != null && user.IsPasswordChangeRequired.Value))
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.InvalidGrant,
                        description: "The specified user is not allowed to sign in.");
                    return(Task.FromResult(0));
                }

                // Create a new authentication ticket holding the user identity.
                var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());

                // Set the list of scopes granted to the client application.
                ticket.SetScopes(allowedClientScopes);

                // Set the resource servers the access token should be issued for.
                ticket.SetResources("resource_server");
                context.Validate(ticket);
            }

            if (context.Request.IsClientCredentialsGrantType())
            {
                // We don't need to validate the client id here because it was already validated in the ValidateTokenRequest method.
                var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationType);

                identity.AddClaim(OpenIdConnectConstants.Claims.Subject, context.Request.ClientId, OpenIdConnectConstants.Destinations.AccessToken);

                // Create a new authentication ticket holding the user identity.
                var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());

                context.Validate(ticket);
            }

            return(Task.FromResult(0));
        }
Exemplo n.º 13
0
        /// <summary>
        /// Handles the Click event of the btnLogin control.
        /// NOTE: This is the btnLogin for Internal Auth
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnLogin_Click(object sender, EventArgs e)
        {
            if (Page.IsValid)
            {
                var rockContext      = new RockContext();
                var userLoginService = new UserLoginService(rockContext);
                var userLogin        = userLoginService.GetByUserName(tbUserName.Text);
                if (userLogin != null && userLogin.EntityType != null)
                {
                    var component = AuthenticationContainer.GetComponent(userLogin.EntityType.Name);
                    if (component != null && component.IsActive && !component.RequiresRemoteAuthentication)
                    {
                        if (component.Authenticate(userLogin, tbPassword.Text))
                        {
                            if ((userLogin.IsConfirmed ?? true) && !(userLogin.IsLockedOut ?? false))
                            {
                                var authentication = HttpContext.Current.GetOwinContext().Authentication;

                                UserLoginService.UpdateLastLogin(tbUserName.Text);

                                Rock.Security.Authorization.SetAuthCookie(tbUserName.Text, cbRememberMe.Checked, false);

                                CreateOAuthIdentity(userLogin);

                                if (!string.IsNullOrEmpty(PageParameter("ReturnUrl")) && IsLocalUrl(PageParameter("ReturnUrl")))
                                {
                                    Response.Redirect(PageParameter("ReturnUrl"));
                                }
                                else
                                {
                                }
                            }
                            else
                            {
                                var globalMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);

                                if (userLogin.IsLockedOut ?? false)
                                {
                                    lLockedOutCaption.Text = GetAttributeValue("LockedOutCaption").ResolveMergeFields(globalMergeFields);

                                    pnlLogin.Visible     = false;
                                    pnlLockedOut.Visible = true;
                                }
                                else
                                {
                                    SendConfirmation(userLogin);

                                    lConfirmCaption.Text = GetAttributeValue("ConfirmCaption").ResolveMergeFields(globalMergeFields);

                                    pnlLogin.Visible        = false;
                                    pnlConfirmation.Visible = true;
                                }
                            }

                            return;
                        }
                    }
                }
            }

            string helpUrl = string.Empty;

            if (!string.IsNullOrWhiteSpace(GetAttributeValue("HelpPage")))
            {
                helpUrl = LinkedPageUrl("HelpPage");
            }
            else
            {
                helpUrl = ResolveRockUrl("~/ForgotUserName");
            }

            DisplayError(string.Format("Sorry, we couldn't find an account matching that username/password. Can we help you <a href='{0}'>recover your account information</a>?", helpUrl));
        }
Exemplo n.º 14
0
        private void BindGrid()
        {
            var qry = new UserLoginService().Queryable()
                      .Where(l => !_personId.HasValue || l.PersonId == _personId.Value);

            // username filter
            string usernameFilter = gfSettings.GetUserPreference("Username");

            if (!string.IsNullOrWhiteSpace(usernameFilter))
            {
                qry = qry.Where(l => l.UserName.StartsWith(usernameFilter));
            }

            // provider filter
            Guid guid = Guid.Empty;

            if (Guid.TryParse(gfSettings.GetUserPreference("Authentication Provider"), out guid))
            {
                qry = qry.Where(l => l.EntityType.Guid.Equals(guid));
            }

            // created filter
            var drp = new DateRangePicker();

            drp.DelimitedValues = gfSettings.GetUserPreference("Created");
            if (drp.LowerValue.HasValue)
            {
                qry = qry.Where(l => l.CreationDateTime >= drp.LowerValue.Value);
            }
            if (drp.UpperValue.HasValue)
            {
                DateTime upperDate = drp.UpperValue.Value.Date.AddDays(1);
                qry = qry.Where(l => l.CreationDateTime < upperDate);
            }

            // last login filter
            var drp2 = new DateRangePicker();

            drp2.DelimitedValues = gfSettings.GetUserPreference("Last Login");
            if (drp2.LowerValue.HasValue)
            {
                qry = qry.Where(l => l.LastLoginDateTime >= drp2.LowerValue.Value);
            }
            if (drp2.UpperValue.HasValue)
            {
                DateTime upperDate = drp2.UpperValue.Value.Date.AddDays(1);
                qry = qry.Where(l => l.LastLoginDateTime < upperDate);
            }

            // Is Confirmed filter
            bool isConfirmed = false;

            if (bool.TryParse(gfSettings.GetUserPreference("Is Confirmed"), out isConfirmed))
            {
                qry = qry.Where(l => l.IsConfirmed == isConfirmed || (!isConfirmed && l.IsConfirmed == null));
            }

            // is locked out filter
            bool isLockedOut = false;

            if (bool.TryParse(gfSettings.GetUserPreference("Is Locked Out"), out isLockedOut))
            {
                qry = qry.Where(l => l.IsLockedOut == isLockedOut || (!isLockedOut && l.IsLockedOut == null));
            }

            // Sort
            SortProperty sortProperty = gUserLogins.SortProperty;

            if (sortProperty == null)
            {
                sortProperty = new SortProperty(new GridViewSortEventArgs("UserName", SortDirection.Ascending));
            }

            gUserLogins.DataSource = qry.Sort(sortProperty)
                                     .Select(l => new
            {
                Id                = l.Id,
                UserName          = l.UserName,
                PersonId          = l.PersonId,
                PersonName        = l.Person.LastName + ", " + l.Person.NickName,
                ProviderName      = l.EntityType.FriendlyName,
                CreationDateTime  = l.CreationDateTime,
                LastLoginDateTime = l.LastLoginDateTime,
                IsConfirmed       = l.IsConfirmed,
                IsLockedOut       = l.IsLockedOut
            }
                                             ).ToList();
            gUserLogins.DataBind();
        }
Exemplo n.º 15
0
        /// <summary>
        /// Handles the SaveClick event of the modalDetails control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void mdDetails_SaveClick(object sender, EventArgs e)
        {
            if (_canEdit)
            {
                UserLogin userLogin = null;
                var       service   = new UserLoginService();

                int userLoginId = int.Parse(hfIdValue.Value);

                if (userLoginId != 0)
                {
                    userLogin = service.Get(userLoginId);
                }

                if (userLogin == null)
                {
                    userLogin = new UserLogin();
                    service.Add(userLogin, CurrentPersonId);
                }

                userLogin.UserName    = tbUserName.Text;
                userLogin.IsConfirmed = cbIsConfirmed.Checked;
                userLogin.IsLockedOut = cbIsLockedOut.Checked;

                var entityType = EntityTypeCache.Read(compProvider.SelectedValue.AsGuid());
                if (entityType != null)
                {
                    userLogin.EntityTypeId = entityType.Id;

                    if (!string.IsNullOrWhiteSpace(tbPassword.Text))
                    {
                        var component = AuthenticationContainer.GetComponent(entityType.Name);
                        if (component != null && component.ServiceType == AuthenticationServiceType.Internal)
                        {
                            if (tbPassword.Text == tbPasswordConfirm.Text)
                            {
                                if (UserLoginService.IsPasswordValid(tbPassword.Text))
                                {
                                    userLogin.Password = component.EncodePassword(userLogin, tbPassword.Text);
                                    userLogin.LastPasswordChangedDateTime = DateTime.Now;
                                }
                                else
                                {
                                    nbErrorMessage.Title   = "Invalid Password";
                                    nbErrorMessage.Text    = UserLoginService.FriendlyPasswordRules();
                                    nbErrorMessage.Visible = true;
                                    return;
                                }
                            }
                            else
                            {
                                nbErrorMessage.Title   = "Invalid Password";
                                nbErrorMessage.Text    = "Password and Confirmation do not match.";
                                nbErrorMessage.Visible = true;
                                return;
                            }
                        }
                    }
                }

                if (!userLogin.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                RockTransactionScope.WrapTransaction(() =>
                {
                    service.Save(userLogin, CurrentPersonId);
                });

                mdDetails.Hide();
                BindGrid();
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Sends the notification.
        /// </summary>
        /// <param name="ex">The ex.</param>
        private void SendNotification(Exception ex)
        {
            int?        pageId      = (Context.Items["Rock:PageId"] ?? "").ToString().AsIntegerOrNull();;
            int?        siteId      = (Context.Items["Rock:SiteId"] ?? "").ToString().AsIntegerOrNull();;
            PersonAlias personAlias = null;

            try
            {
                var user = UserLoginService.GetCurrentUser();
                if (user != null && user.Person != null)
                {
                    personAlias = user.Person.PrimaryAlias;
                }
            }
            catch { }

            try
            {
                ExceptionLogService.LogException(ex, Context, pageId, siteId, personAlias);
            }
            catch { }

            try
            {
                string siteName = "Rock";
                if (siteId.HasValue)
                {
                    var site = SiteCache.Read(siteId.Value);
                    if (site != null)
                    {
                        siteName = site.Name;
                    }
                }

                // setup merge codes for email
                var mergeObjects = GlobalAttributesCache.GetMergeFields(null);
                mergeObjects.Add("ExceptionDetails", "An error occurred on the " + siteName + " site on page: <br>" + Context.Request.Url.OriginalString + "<p>" + FormatException(ex, ""));

                // get email addresses to send to
                var    globalAttributesCache = GlobalAttributesCache.Read();
                string emailAddressesList    = globalAttributesCache.GetValue("EmailExceptionsList");

                if (!string.IsNullOrWhiteSpace(emailAddressesList))
                {
                    string[] emailAddresses = emailAddressesList.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    var recipients = new List <RecipientData>();
                    foreach (string emailAddress in emailAddresses)
                    {
                        recipients.Add(new RecipientData(emailAddress, mergeObjects));
                    }

                    if (recipients.Any())
                    {
                        bool sendNotification = true;

                        string filterSettings = globalAttributesCache.GetValue("EmailExceptionsFilter");
                        var    serverVarList  = Context.Request.ServerVariables;

                        if (!string.IsNullOrWhiteSpace(filterSettings) && serverVarList.Count > 0)
                        {
                            string[] nameValues = filterSettings.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string nameValue in nameValues)
                            {
                                string[] nameAndValue = nameValue.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
                                {
                                    if (nameAndValue.Length == 2)
                                    {
                                        var serverValue = serverVarList[nameAndValue[0]];
                                        if (serverValue != null && serverValue.ToUpper().Contains(nameAndValue[1].ToUpper().Trim()))
                                        {
                                            sendNotification = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (sendNotification)
                        {
                            Email.Send(Rock.SystemGuid.SystemEmail.CONFIG_EXCEPTION_NOTIFICATION.AsGuid(), recipients);
                        }
                    }
                }
            }
            catch { }
        }
Exemplo n.º 17
0
        private System.Threading.Tasks.Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            if (!string.IsNullOrEmpty(context.UserName) && !string.IsNullOrEmpty(context.Password))
            {
                var rockContext      = new RockContext();
                var userLoginService = new UserLoginService(rockContext);
                var userName         = context.UserName;

                var userLogin = userLoginService.GetByUserName(userName);
                if (userLogin != null && userLogin.EntityType != null)
                {
                    var component = AuthenticationContainer.GetComponent(userLogin.EntityType.Name);
                    if (component != null && component.IsActive &&
                        (!component.RequiresRemoteAuthentication || component.TypeName == "Rock.Security.ExternalAuthentication.SMSAuthentication"))
                    {
                        if (component.Authenticate(userLogin, context.Password))
                        {
                            if ((userLogin.IsConfirmed ?? true) && !(userLogin.IsLockedOut ?? false))
                            {
                                OAuthContext         oAuthContext         = new OAuthContext();
                                ClientScopeService   clientScopeService   = new ClientScopeService(oAuthContext);
                                AuthorizationService authorizationService = new AuthorizationService(oAuthContext);
                                ClientService        clientService        = new ClientService(oAuthContext);

                                var scopes = (context.Scope.FirstOrDefault() ?? "").Split(',');

                                bool     scopesApproved   = false;
                                Client   OAuthClient      = clientService.GetByApiKey(context.ClientId.AsGuid());
                                string[] authorizedScopes = authorizationService.Queryable().Where(a => a.Client.Id == OAuthClient.Id && a.UserLogin.UserName == userName && a.Active == true).Select(a => a.Scope.Identifier).ToArray <string>();
                                if (!clientScopeService.Queryable().Where(cs => cs.ClientId == OAuthClient.Id && cs.Active == true).Any() ||
                                    (authorizedScopes != null && scopes.Where(s => !authorizedScopes.Select(a => a.ToLower()).Contains(s.ToLower())).Count() == 0))
                                {
                                    scopesApproved = true;
                                }

                                if (scopesApproved)
                                {
                                    var identity = new ClaimsIdentity(new GenericIdentity(userName, OAuthDefaults.AuthenticationType));

                                    //only allow claims that have been requested and the client has been authorized for
                                    foreach (var scope in scopes.Where(s => clientScopeService.Queryable().Where(cs => cs.ClientId == OAuthClient.Id && cs.Active == true).Select(cs => cs.Scope.Identifier.ToLower()).Contains(s.ToLower())))
                                    {
                                        identity.AddClaim(new Claim("urn:oauth:scope", scope));
                                    }
                                    UserLoginService.UpdateLastLogin(userName);
                                    context.Validated(identity);
                                    return(System.Threading.Tasks.Task.FromResult(0));
                                }
                                else
                                {
                                    context.Rejected();
                                    context.SetError("Authentication Error", "All scopes are not authorized for this user.");
                                }
                            }
                            if (!userLogin.IsConfirmed ?? true)
                            {
                                context.Rejected();
                                context.SetError("Authentication Error", "Account email is unconfirmed.");
                            }
                            if (userLogin.IsLockedOut ?? false)
                            {
                                context.Rejected();
                                context.SetError("Authentication Error", "Account is locked.");
                            }
                        }
                        else
                        {
                            context.Rejected();
                            context.SetError("Authentication Error", "Invalid Username/Password.");
                        }
                    }
                    else
                    {
                        context.Rejected();
                        context.SetError("Authentication Error", "Invalid Authentication Configuration.");
                    }
                }
                else
                {
                    context.Rejected();
                    context.SetError("Authentication Error", "Invalid Username/Password.");
                }
            }
            else
            {
                context.Rejected();
                context.SetError("Authentication Error", "Invalid Username/Password.");
            }

            return(System.Threading.Tasks.Task.FromResult(0));
        }
Exemplo n.º 18
0
        protected void btnGenerate_Click(object sender, EventArgs e)
        {
            if (!Page.IsValid)
            {
                return;
            }

            pnlPhoneNumber.Visible = false;
            RockContext        rockContext        = new RockContext();
            PhoneNumberService phoneNumberService = new PhoneNumberService(rockContext);
            var numberOwners = phoneNumberService.Queryable()
                               .Where(pn => pn.Number == PhoneNumber)
                               .Select(pn => pn.Person)
                               .DistinctBy(p => p.Id)
                               .ToList();

            if (numberOwners.Count == 0)
            {
                lbNoNumber.Text     = GetAttributeValue("NoNumberMessage");
                pnlNoNumber.Visible = true;
                return;
            }

            if (numberOwners.Count > 1)
            {
                if (GetAttributeValue("DuplicateNumberPage").AsGuidOrNull() == null)
                {
                    btnResolution.Visible = false;
                }
                lbDuplicateNumber.Text     = GetAttributeValue("DuplicateMessage");
                pnlDuplicateNumber.Visible = true;
                return;
            }

            var person = numberOwners.FirstOrDefault();

            UserLoginService userLoginService = new UserLoginService(rockContext);
            var userLogin = userLoginService.Queryable()
                            .Where(u => u.UserName == ("__PHONENUMBER__" + PhoneNumber))
                            .FirstOrDefault();

            if (userLogin == null)
            {
                var entityTypeId = EntityTypeCache.Read("Avalanche.Security.Authentication.PhoneNumber").Id;

                userLogin = new UserLogin()
                {
                    UserName     = "******" + PhoneNumber,
                    EntityTypeId = entityTypeId,
                };
                userLoginService.Add(userLogin);
            }

            userLogin.PersonId = person.Id;
            userLogin.LastPasswordChangedDateTime = Rock.RockDateTime.Now;
            userLogin.FailedPasswordAttemptWindowStartDateTime = Rock.RockDateTime.Now;
            userLogin.FailedPasswordAttemptCount = 0;
            userLogin.IsConfirmed = true;
            userLogin.Password    = new Random().Next(100000, 999999).ToString();

            rockContext.SaveChanges();

            var recipients = new List <RecipientData>();

            recipients.Add(new RecipientData(PhoneNumber));

            var smsMessage = new RockSMSMessage();

            smsMessage.SetRecipients(recipients);

            // Get the From value
            Guid?fromGuid = GetAttributeValue("From").AsGuidOrNull();

            if (fromGuid.HasValue)
            {
                var fromValue = DefinedValueCache.Read(fromGuid.Value, rockContext);
                if (fromValue != null)
                {
                    smsMessage.FromNumber = DefinedValueCache.Read(fromValue.Id);
                }
            }

            var mergeObjects = new Dictionary <string, object> {
                { "password", userLogin.Password }
            };
            var message = GetAttributeValue("Message").ResolveMergeFields(mergeObjects, null);

            smsMessage.Message = message;

            var ipAddress = GetIpAddress();

            if (SMSRecords.ReserveItems(ipAddress, PhoneNumber))
            {
                pnlCode.Visible = true;
                var delay = SMSRecords.GetDelay(ipAddress, PhoneNumber);
                Task.Run(() => { SendSMS(smsMessage, ipAddress, PhoneNumber, delay); });
            }
            else
            {
                LogException(new Exception(string.Format("Unable to reserve for SMS message: IP: {0} PhoneNumber: {1}", ipAddress, PhoneNumber)));
                pnlRateLimited.Visible = true;
            }
        }
Exemplo n.º 19
0
        public HttpResponseMessage ForgotPassword([FromBody] string email)
        {
            OAuthContext  oAuthContext  = new OAuthContext();
            ClientService clientService = new ClientService(oAuthContext);
            var           clientId      = HttpContext.Current.User.Identity.Name;
            Client        oAuthClient   = clientService.GetByApiKey(clientId.AsGuid());

            if (oAuthClient.Active)
            {
                var              response         = new StandardResponse();
                var              rockContext      = new Rock.Data.RockContext();
                PersonService    personService    = new PersonService(rockContext);
                UserLoginService userLoginService = new UserLoginService(rockContext);
                bool             hasAccountWithPasswordResetAbility = false;
                var              results = new List <IDictionary <string, object> >();

                // Check to make sure we have accounts matching the email address given
                foreach (Person person in personService.GetByEmail(email)
                         .Where(p => p.Users.Any()))
                {
                    var users = new List <UserLogin>();
                    foreach (UserLogin user in userLoginService.GetByPersonId(person.Id))
                    {
                        if (user.EntityType != null)
                        {
                            var component = Rock.Security.AuthenticationContainer.GetComponent(user.EntityType.Name);
                            if (component != null && !component.RequiresRemoteAuthentication)
                            {
                                users.Add(user);
                                hasAccountWithPasswordResetAbility = true;
                            }
                        }
                    }

                    var resultsDictionary = new Dictionary <string, object>();
                    resultsDictionary.Add("Person", person);
                    resultsDictionary.Add("Users", users);
                    results.Add(resultsDictionary);
                }
                var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null);

                // If we found matching accounts that have the ability to be reset, go ahead and send the email
                if (results.Count > 0 && hasAccountWithPasswordResetAbility)
                {
                    mergeFields.Add("Results", results.ToArray());

                    var emailMessage = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.SECURITY_FORGOT_USERNAME.AsGuid());
                    emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(email, mergeFields));
                    emailMessage.AppRoot = GlobalAttributesCache.Get().GetValue("PublicApplicationRoot").EnsureTrailingForwardslash();
                    emailMessage.CreateCommunicationRecord = false;
                    emailMessage.Send();
                    response.Result  = StandardResponse.ResultCode.Success;
                    response.Message = "Forgot password email has been sent successfully.";
                }
                else
                {
                    // the person either has no user accounts or none of them are allowed to have their passwords reset (Facebook/Google/SMS/etc)
                    response.Result  = StandardResponse.ResultCode.Error;
                    response.Message = "No accounts associated with this email address are able to be reset via email.";
                }
                return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, response));
            }

            return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden));
        }
Exemplo n.º 20
0
        /// <summary>
        /// Translates the notes.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        public void TranslateNotes(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();

            var importedUsers = new UserLoginService(lookupContext).Queryable().AsNoTracking()
                                .Where(u => u.ForeignId != null)
                                .ToDictionary(t => t.ForeignId, t => t.PersonId);

            var noteList = new List <Note>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying note import ({totalRows:N0} found).");
            foreach (var row in tableData.Where(r => r != null))
            {
                var noteType         = row["Note_Type_Name"] as string;
                var text             = row["Note_Text"] as string;
                var individualId     = row["Individual_ID"] as int?;
                var householdId      = row["Household_ID"] as int?;
                var noteTypeActive   = row["NoteTypeActive"] as bool?;
                var noteArchived     = row["NoteArchived"] as bool?;
                var noteTextArchived = row["NoteTextArchived"] as bool?;
                var dateCreated      = row["NoteCreated"] as DateTime?;

                // see if pre-import helper fix is present
                var noteArchivedFlag     = row["NoteArchived"] as int?;
                var noteTextArchivedFlag = row["NoteTextArchived"] as int?;
                noteArchived     = noteArchived.HasValue ? noteArchived : noteArchivedFlag > 0;
                noteTextArchived = noteTextArchived.HasValue ? noteTextArchived : noteTextArchivedFlag > 0;

                var noteExcluded = noteArchived == true || noteTextArchived == true;
                var personKeys   = GetPersonKeys(individualId, householdId);
                if (personKeys != null && !string.IsNullOrWhiteSpace(text) && noteTypeActive == true && !noteExcluded)
                {
                    int?creatorAliasId = null;
                    var userId         = row["NoteCreatedByUserID"] as int?;

                    if (userId.HasValue && PortalUsers.ContainsKey((int)userId))
                    {
                        creatorAliasId = PortalUsers[(int)userId];
                    }

                    var noteTypeId = noteType.StartsWith("General", StringComparison.InvariantCultureIgnoreCase) ? (int?)PersonalNoteTypeId : null;
                    var note       = AddEntityNote(lookupContext, PersonEntityTypeId, personKeys.PersonId, string.Empty, text, false, false, noteType, noteTypeId, false, dateCreated,
                                                   $"Note imported {ImportDateTime}", creatorAliasId);

                    noteList.Add(note);
                    completedItems++;

                    if (completedItems % percentage < 1)
                    {
                        var percentComplete = completedItems / percentage;
                        ReportProgress(percentComplete, $"{completedItems:N0} notes imported ({percentComplete}% complete).");
                    }
                    else if (completedItems % ReportingNumber < 1)
                    {
                        SaveNotes(noteList);
                        ReportPartialProgress();
                        noteList.Clear();
                    }
                }
            }

            if (noteList.Any())
            {
                SaveNotes(noteList);
            }

            ReportProgress(100, $"Finished note import: {completedItems:N0} notes imported.");
        }
Exemplo n.º 21
0
        public IHttpActionResult PostInteractions([FromBody] List <MobileInteractionSession> sessions, Guid?personalDeviceGuid = null)
        {
            var person    = GetPerson();
            var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress;

            using (var rockContext = new Data.RockContext())
            {
                var interactionChannelService   = new InteractionChannelService(rockContext);
                var interactionComponentService = new InteractionComponentService(rockContext);
                var interactionSessionService   = new InteractionSessionService(rockContext);
                var interactionService          = new InteractionService(rockContext);
                var userLoginService            = new UserLoginService(rockContext);
                var channelMediumTypeValue      = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE);
                var pageEntityTypeId            = EntityTypeCache.Get(typeof(Model.Page)).Id;

                //
                // Check to see if we have a site and the API key is valid.
                //
                if (MobileHelper.GetCurrentApplicationSite() == null)
                {
                    return(StatusCode(System.Net.HttpStatusCode.Forbidden));
                }

                //
                // Get the personal device identifier if they provided it's unique identifier.
                //
                int?personalDeviceId = null;
                if (personalDeviceGuid.HasValue)
                {
                    personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value);
                }

                //
                // Create a quick way to cache data since we have to loop twice.
                //
                var interactionComponentLookup = new Dictionary <string, int>();

                //
                // Helper method to get a cache key for looking up the component Id.
                //
                string GetComponentCacheKey(MobileInteraction mi)
                {
                    return($"{mi.AppId}:{mi.PageGuid}:{mi.ChannelGuid}:{mi.ChannelId}:{mi.ComponentId}:{mi.ComponentName}");
                }

                //
                // Interactions Components will now try to load from cache which
                // causes problems if we are inside a transaction. So first loop through
                // everything and make sure all our components and channels exist.
                //
                var prePassInteractions = sessions.SelectMany(a => a.Interactions)
                                          .DistinctBy(a => GetComponentCacheKey(a));

                //
                // It's safe to do this pre-pass outside the transaction since we are just creating
                // the channels and components (if necessary), which is going to have to be done at
                // at some point no matter what.
                //
                foreach (var mobileInteraction in prePassInteractions)
                {
                    //
                    // Lookup the interaction channel, and create it if it doesn't exist
                    //
                    if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue)
                    {
                        var site = SiteCache.Get(mobileInteraction.AppId.Value);
                        var page = PageCache.Get(mobileInteraction.PageGuid.Value);

                        if (site == null || page == null)
                        {
                            continue;
                        }

                        //
                        // Try to find an existing interaction channel.
                        //
                        var interactionChannelId = InteractionChannelCache.GetChannelIdByTypeIdAndEntityId(channelMediumTypeValue.Id, site.Id, site.Name, pageEntityTypeId, null);

                        //
                        // Get an existing or create a new component.
                        //
                        var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, page.Id, page.InternalName);

                        interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                    }
                    else if (mobileInteraction.ChannelId.HasValue || mobileInteraction.ChannelGuid.HasValue)
                    {
                        int?interactionChannelId = null;

                        if (mobileInteraction.ChannelId.HasValue)
                        {
                            interactionChannelId = mobileInteraction.ChannelId.Value;
                        }
                        else if (mobileInteraction.ChannelGuid.HasValue)
                        {
                            interactionChannelId = InteractionChannelCache.Get(mobileInteraction.ChannelGuid.Value)?.Id;
                        }

                        if (interactionChannelId.HasValue)
                        {
                            if (mobileInteraction.ComponentId.HasValue)
                            {
                                // Use the provided component identifier.
                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), mobileInteraction.ComponentId.Value);
                            }
                            else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace())
                            {
                                int interactionComponentId;

                                // Get or create a new component with the details we have.
                                if (mobileInteraction.ComponentEntityId.HasValue)
                                {
                                    interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId.Value, mobileInteraction.ComponentEntityId, mobileInteraction.ComponentName);
                                }
                                else
                                {
                                    var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName);

                                    rockContext.SaveChanges();

                                    interactionComponentId = interactionComponent.Id;
                                }

                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                            }
                        }
                    }
                }

                //
                // Now wrap the actual interaction creation inside a transaction. We should
                // probably move this so it uses the InteractionTransaction class for better
                // performance. This is so we can inform the client that either everything
                // saved or that nothing saved. No partial saves here.
                //
                rockContext.WrapTransaction(() =>
                {
                    foreach (var mobileSession in sessions)
                    {
                        var interactionGuids         = mobileSession.Interactions.Select(i => i.Guid).ToList();
                        var existingInteractionGuids = interactionService.Queryable()
                                                       .Where(i => interactionGuids.Contains(i.Guid))
                                                       .Select(i => i.Guid)
                                                       .ToList();

                        //
                        // Loop through all interactions that don't already exist and add each one.
                        //
                        foreach (var mobileInteraction in mobileSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid)))
                        {
                            string cacheKey = GetComponentCacheKey(mobileInteraction);

                            if (!interactionComponentLookup.ContainsKey(cacheKey))
                            {
                                // Shouldn't happen, but just in case.
                                continue;
                            }

                            var interactionComponentId = interactionComponentLookup[cacheKey];

                            //
                            // Add the interaction
                            //
                            var interaction = interactionService.CreateInteraction(interactionComponentId,
                                                                                   mobileInteraction.EntityId,
                                                                                   mobileInteraction.Operation,
                                                                                   mobileInteraction.Summary,
                                                                                   mobileInteraction.Data,
                                                                                   person?.PrimaryAliasId,
                                                                                   RockDateTime.ConvertLocalDateTimeToRockDateTime(mobileInteraction.DateTime.LocalDateTime),
                                                                                   mobileSession.Application,
                                                                                   mobileSession.OperatingSystem,
                                                                                   mobileSession.ClientType,
                                                                                   null,
                                                                                   ipAddress,
                                                                                   mobileSession.Guid);

                            interaction.Guid                  = mobileInteraction.Guid;
                            interaction.PersonalDeviceId      = personalDeviceId;
                            interaction.RelatedEntityTypeId   = mobileInteraction.RelatedEntityTypeId;
                            interaction.RelatedEntityId       = mobileInteraction.RelatedEntityId;
                            interaction.ChannelCustom1        = mobileInteraction.ChannelCustom1;
                            interaction.ChannelCustom2        = mobileInteraction.ChannelCustom2;
                            interaction.ChannelCustomIndexed1 = mobileInteraction.ChannelCustomIndexed1;

                            interactionService.Add(interaction);

                            // Attempt to process this as a communication interaction.
                            ProcessCommunicationInteraction(mobileSession, mobileInteraction, rockContext);
                        }
                    }

                    rockContext.SaveChanges();
                });
            }

            return(Ok());
        }
Exemplo n.º 22
0
        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler" /> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
        /// <exception cref="WebFaultException">Must be logged in</exception>
        public virtual void ProcessRequest(HttpContext context)
        {
            if (!context.User.Identity.IsAuthenticated)
            {
                // If not, see if there's a valid token
                string authToken = context.Request.Headers["Authorization-Token"];
                if (string.IsNullOrWhiteSpace(authToken))
                {
                    authToken = context.Request.Params["apikey"];
                }

                if (!string.IsNullOrWhiteSpace(authToken))
                {
                    var userLoginService = new UserLoginService(new Rock.Data.RockContext());
                    var userLogin        = userLoginService.Queryable().Where(u => u.ApiKey == authToken).FirstOrDefault();
                    if (userLogin != null)
                    {
                        var identity  = new GenericIdentity(userLogin.UserName);
                        var principal = new GenericPrincipal(identity, null);
                        context.User = principal;
                    }
                }
            }

            var    currentUser   = UserLoginService.GetCurrentUser();
            Person currentPerson = currentUser != null ? currentUser.Person : null;

            try
            {
                HttpFileCollection hfc          = context.Request.Files;
                HttpPostedFile     uploadedFile = hfc.AllKeys.Select(fk => hfc[fk]).FirstOrDefault();

                // No file or no data?  No good.
                if (uploadedFile == null || uploadedFile.ContentLength == 0)
                {
                    throw new Rock.Web.FileUploadException("No File Specified", System.Net.HttpStatusCode.BadRequest);
                }

                // Check to see if this is a BinaryFileType/BinaryFile or just a plain content file
                bool isBinaryFile = context.Request.QueryString["isBinaryFile"].AsBoolean();

                if (isBinaryFile)
                {
                    ProcessBinaryFile(context, uploadedFile, currentPerson);
                }
                else
                {
                    if (!context.User.Identity.IsAuthenticated)
                    {
                        throw new Rock.Web.FileUploadException("Must be logged in", System.Net.HttpStatusCode.Forbidden);
                    }
                    else
                    {
                        ProcessContentFile(context, uploadedFile);
                    }
                }
            }
            catch (Rock.Web.FileUploadException fex)
            {
                ExceptionLogService.LogException(fex, context);
                context.Response.TrySkipIisCustomErrors = true;
                context.Response.StatusCode             = (int)fex.StatusCode;
                context.Response.Write(fex.Detail);
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, context);
                context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
                context.Response.Write("error: " + ex.Message);
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Execute method to write transaction to the database.
        /// </summary>
        public void Execute()
        {
            if (PageShortLinkId.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var userAgent = (this.UserAgent ?? string.Empty).Trim();
                    if (userAgent.Length > 450)
                    {
                        userAgent = userAgent.Substring(0, 450);   // trim super long useragents to fit in pageViewUserAgent.UserAgent
                    }

                    // get user agent info
                    var clientType = InteractionDeviceType.GetClientType(userAgent);

                    // don't log visits from crawlers
                    if (clientType != "Crawler")
                    {
                        // lookup the interaction channel, and create it if it doesn't exist
                        int channelMediumTypeValueId = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_URLSHORTENER.AsGuid()).Id;
                        InteractionChannelService interactionChannelService = new InteractionChannelService(rockContext);
                        var interactionChannel = interactionChannelService.Queryable()
                                                 .Where(a => a.ChannelTypeMediumValueId == channelMediumTypeValueId)
                                                 .FirstOrDefault();
                        if (interactionChannel == null)
                        {
                            interactionChannel      = new InteractionChannel();
                            interactionChannel.Name = "Short Links";
                            interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                            interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Get <Rock.Model.PageShortLink>().Id;;
                            interactionChannel.Guid = SystemGuid.InteractionChannel.SHORT_LINKS.AsGuid();
                            interactionChannelService.Add(interactionChannel);
                            rockContext.SaveChanges();
                        }

                        // check that the page exists as a component
                        var interactionComponent = new InteractionComponentService(rockContext).GetComponentByEntityId(interactionChannel.Id, PageShortLinkId.Value, Token);
                        if (Url.IsNotNullOrWhiteSpace())
                        {
                            if (interactionComponent.ComponentSummary != Url)
                            {
                                interactionComponent.ComponentSummary = Url;
                            }

                            var urlDataJson = new { Url = Url }.ToJson();
                            if (interactionComponent.ComponentData != urlDataJson)
                            {
                                interactionComponent.ComponentData = urlDataJson;
                            }
                        }

                        rockContext.SaveChanges();

                        // Add the interaction
                        if (interactionComponent != null)
                        {
                            int?personAliasId = null;
                            if (UserName.IsNotNullOrWhiteSpace())
                            {
                                var currentUser = new UserLoginService(rockContext).GetByUserName(UserName);
                                personAliasId = currentUser?.Person?.PrimaryAlias?.Id;
                            }

                            ClientInfo client        = uaParser.Parse(userAgent);
                            var        clientOs      = client.OS.ToString();
                            var        clientBrowser = client.UserAgent.ToString();

                            new InteractionService(rockContext).AddInteraction(interactionComponent.Id, null, "View", Url, personAliasId, DateViewed,
                                                                               clientBrowser, clientOs, clientType, userAgent, IPAddress, this.SessionId?.AsGuidOrNull());
                            rockContext.SaveChanges();
                        }
                    }
                }
            }
        }
Exemplo n.º 24
0
        public object UpdateProfile(MobilePerson profile)
        {
            var user = UserLoginService.GetCurrentUser(false);

            if (user == null)
            {
                return(ActionStatusCode(System.Net.HttpStatusCode.Unauthorized));
            }

            var personId    = user.PersonId.Value;
            var rockContext = new Data.RockContext();

            var personService      = new PersonService(rockContext);
            var phoneNumberService = new PhoneNumberService(rockContext);
            var person             = personService.Get(personId);

            person.NickName  = person.NickName == person.FirstName ? profile.FirstName : person.NickName;
            person.FirstName = profile.FirstName;
            person.LastName  = profile.LastName;
            person.Gender    = ( Gender )profile.Gender;

            if (GetAttributeValue(AttributeKeys.BirthDateShow).AsBoolean())
            {
                person.SetBirthDate(profile.BirthDate?.Date);
            }

            if (GetAttributeValue(AttributeKeys.CampusShow).AsBoolean())
            {
                person.PrimaryFamily.CampusId = profile.CampusGuid.HasValue ? CampusCache.Get(profile.CampusGuid.Value)?.Id : null;
            }

            if (GetAttributeValue(AttributeKeys.EmailShow).AsBoolean())
            {
                person.Email = profile.Email;
            }

            if (GetAttributeValue(AttributeKeys.MobilePhoneShow).AsBoolean())
            {
                int phoneNumberTypeId = DefinedValueCache.Get(SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE).Id;

                var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == phoneNumberTypeId);
                if (phoneNumber == null)
                {
                    phoneNumber = new PhoneNumber {
                        NumberTypeValueId = phoneNumberTypeId
                    };
                    person.PhoneNumbers.Add(phoneNumber);
                }

                // TODO: What to do with country code?
                phoneNumber.CountryCode = PhoneNumber.CleanNumber("+1");
                phoneNumber.Number      = PhoneNumber.CleanNumber(profile.MobilePhone);

                if (string.IsNullOrWhiteSpace(phoneNumber.Number))
                {
                    person.PhoneNumbers.Remove(phoneNumber);
                    phoneNumberService.Delete(phoneNumber);
                }
            }

            if (GetAttributeValue(AttributeKeys.AddressShow).AsBoolean())
            {
                var addressTypeGuid = SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid();

                var groupLocationService = new GroupLocationService(rockContext);

                var dvHomeAddressType = DefinedValueCache.Get(addressTypeGuid);
                var familyAddress     = groupLocationService.Queryable().Where(l => l.GroupId == person.PrimaryFamily.Id && l.GroupLocationTypeValueId == dvHomeAddressType.Id).FirstOrDefault();

                if (familyAddress != null && string.IsNullOrWhiteSpace(profile.HomeAddress.Street1))
                {
                    // delete the current address
                    groupLocationService.Delete(familyAddress);
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(profile.HomeAddress.Street1))
                    {
                        if (familyAddress == null)
                        {
                            familyAddress = new GroupLocation();
                            groupLocationService.Add(familyAddress);
                            familyAddress.GroupLocationTypeValueId = dvHomeAddressType.Id;
                            familyAddress.GroupId           = person.PrimaryFamily.Id;
                            familyAddress.IsMailingLocation = true;
                            familyAddress.IsMappedLocation  = true;
                        }
                        else if (familyAddress.Location.Street1 != profile.HomeAddress.Street1)
                        {
                            // user clicked move so create a previous address
                            var previousAddress = new GroupLocation();
                            groupLocationService.Add(previousAddress);

                            var previousAddressValue = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_PREVIOUS.AsGuid());
                            if (previousAddressValue != null)
                            {
                                previousAddress.GroupLocationTypeValueId = previousAddressValue.Id;
                                previousAddress.GroupId = person.PrimaryFamily.Id;

                                Location previousAddressLocation = new Location
                                {
                                    Street1    = familyAddress.Location.Street1,
                                    Street2    = familyAddress.Location.Street2,
                                    City       = familyAddress.Location.City,
                                    State      = familyAddress.Location.State,
                                    PostalCode = familyAddress.Location.PostalCode,
                                    Country    = familyAddress.Location.Country
                                };

                                previousAddress.Location = previousAddressLocation;
                            }
                        }

                        // TODO: ???
                        //familyAddress.IsMailingLocation = cbIsMailingAddress.Checked;
                        //familyAddress.IsMappedLocation = cbIsPhysicalAddress.Checked;

                        familyAddress.Location = new LocationService(rockContext).Get(
                            profile.HomeAddress.Street1,
                            "",
                            profile.HomeAddress.City,
                            profile.HomeAddress.State,
                            profile.HomeAddress.PostalCode,
                            profile.HomeAddress.Country,
                            person.PrimaryFamily,
                            true);

                        // since there can only be one mapped location, set the other locations to not mapped
                        if (familyAddress.IsMappedLocation)
                        {
                            var groupLocations = groupLocationService.Queryable()
                                                 .Where(l => l.GroupId == person.PrimaryFamily.Id && l.Id != familyAddress.Id).ToList();

                            foreach (var groupLocation in groupLocations)
                            {
                                groupLocation.IsMappedLocation = false;
                            }
                        }

                        rockContext.SaveChanges();
                    }
                }
            }

            rockContext.SaveChanges();

            var mobilePerson = MobileHelper.GetMobilePerson(person, MobileHelper.GetCurrentApplicationSite());

            mobilePerson.AuthToken = MobileHelper.GetAuthenticationToken(user.UserName);

            return(ActionOk(mobilePerson));
        }
 public UserServerEventDispatchModule(UserManager userManager, MessageServersConnector messagesService, UserLoginService loginService)
 {
     m_userManager     = userManager;
     m_messagesService = messagesService;
     m_loginService    = loginService;
 }
Exemplo n.º 26
0
        /// <summary>
        /// Processes the binary file request.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ProcessBinaryFileRequest(HttpContext context)
        {
            int  fileId   = context.Request.QueryString["id"].AsInteger();
            Guid fileGuid = context.Request.QueryString["guid"].AsGuid();

            if (fileId == 0 && fileGuid.Equals(Guid.Empty))
            {
                SendNotFound(context);
            }

            var rockContext = new RockContext();

            var binaryFileQuery = new BinaryFileService(rockContext).Queryable();

            if (fileGuid != Guid.Empty)
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Guid == fileGuid);
            }
            else
            {
                binaryFileQuery = binaryFileQuery.Where(a => a.Id == fileId);
            }

            //// get just the binaryFileMetaData (not the file content) just in case we can get the filecontent faster from the cache
            //// a null ModifiedDateTime shouldn't happen, but just in case, set it to DateTime.MaxValue so we error on the side of not getting it from the cache
            var binaryFileMetaData = binaryFileQuery.Select(a => new
            {
                BinaryFileType_AllowCaching         = a.BinaryFileType.AllowCaching,
                BinaryFileType_RequiresViewSecurity = a.BinaryFileType.RequiresViewSecurity,
                ModifiedDateTime = a.ModifiedDateTime ?? DateTime.MaxValue,
                a.MimeType,
                a.FileName
            }).FirstOrDefault();

            if (binaryFileMetaData == null)
            {
                SendNotFound(context);
                return;
            }

            //// if the binaryFile's BinaryFileType requires view security, check security
            //// note: we put a RequiresViewSecurity flag on BinaryFileType because checking security for every image would be slow (~40ms+ per image request)
            if (binaryFileMetaData.BinaryFileType_RequiresViewSecurity)
            {
                var        currentUser    = new UserLoginService(rockContext).GetByUserName(UserLogin.GetCurrentUserName());
                Person     currentPerson  = currentUser != null ? currentUser.Person : null;
                BinaryFile binaryFileAuth = new BinaryFileService(rockContext).Queryable("BinaryFileType").First(a => a.Guid == fileGuid || a.Id == fileId);
                if (!binaryFileAuth.IsAuthorized(Authorization.VIEW, currentPerson))
                {
                    SendNotAuthorized(context);
                    return;
                }
            }


            Stream fileContent = null;

            try
            {
                // Is it cached
                string cacheName          = UrlQueryToCachedFileName(context.Request.QueryString, binaryFileMetaData.MimeType);
                string physCachedFilePath = context.Request.MapPath(string.Format("~/App_Data/Cache/{0}", cacheName));
                if (binaryFileMetaData.BinaryFileType_AllowCaching && File.Exists(physCachedFilePath))
                {
                    //// Compare the File's LastWrite DateTime (which comes from the OS's clock), adjust it for the Rock OrgTimeZone, then compare to BinaryFile's ModifiedDateTime (which is already in OrgTimeZone).
                    //// If the BinaryFile record in the database is less recent than the last time this was cached, it is safe to use the Cached version.
                    //// NOTE: A BinaryFile record is typically just added and never modified (a modify is just creating a new BinaryFile record and deleting the old one), so the cached version will probably always be the correct choice.
                    DateTime cachedFileDateTime = RockDateTime.ConvertLocalDateTimeToRockDateTime(File.GetLastWriteTime(physCachedFilePath));
                    if (binaryFileMetaData.ModifiedDateTime < cachedFileDateTime)
                    {
                        // NOTE: the cached file has already been resized (the size is part of the cached file's filename), so we don't need to resize it again
                        fileContent = FetchFromCache(physCachedFilePath);
                    }
                }

                if (fileContent == null)
                {
                    // If we didn't get it from the cache, get it from the binaryFileService
                    BinaryFile binaryFile = GetFromBinaryFileService(context, fileId, fileGuid);

                    if (binaryFile != null)
                    {
                        fileContent = binaryFile.ContentStream;
                    }

                    // If we got the image from the binaryFileService, it might need to be resized and cached
                    if (fileContent != null)
                    {
                        // If more than 1 query string param is passed in, or the mime type is TIFF, assume resize is needed
                        // Note: we force "image/tiff" to get resized so that it gets converted into a jpg (browsers don't like tiffs)
                        if (context.Request.QueryString.Count > 1 || binaryFile.MimeType == "image/tiff")
                        {
                            // if it isn't an SVG file, do a Resize
                            if (binaryFile.MimeType != "image/svg+xml")
                            {
                                fileContent = GetResized(context.Request.QueryString, fileContent);
                            }
                        }

                        if (binaryFileMetaData.BinaryFileType_AllowCaching)
                        {
                            Cache(fileContent, physCachedFilePath);

                            // Reset stream
                            if (fileContent.CanSeek)
                            {
                                fileContent.Seek(0, SeekOrigin.Begin);
                            }
                            else
                            {
                                fileContent = FetchFromCache(physCachedFilePath);
                            }
                        }
                    }
                }

                if (fileContent == null)
                {
                    // if we couldn't get the file from the binaryFileServie or the cache, respond with NotFound
                    SendNotFound(context);
                    return;
                }

                // respond with File
                if (binaryFileMetaData.BinaryFileType_AllowCaching)
                {
                    // if binaryFileType is set to allowcaching, also tell the browser to cache it for 365 days
                    context.Response.Cache.SetLastModified(binaryFileMetaData.ModifiedDateTime);
                    context.Response.Cache.SetMaxAge(new TimeSpan(365, 0, 0, 0));
                }

                context.Response.ContentType = binaryFileMetaData.MimeType != "image/tiff" ? binaryFileMetaData.MimeType : "image/jpg";

                using (var responseStream = fileContent)
                {
                    context.Response.AddHeader("content-disposition", "inline;filename=" + binaryFileMetaData.FileName.MakeValidFileName());
                    if (responseStream.CanSeek)
                    {
                        responseStream.Seek(0, SeekOrigin.Begin);
                    }
                    responseStream.CopyTo(context.Response.OutputStream);
                    context.Response.Flush();
                }
            }
            finally
            {
                if (fileContent != null)
                {
                    fileContent.Dispose();
                }
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");

            // Counters for displaying results
            int groupsSynced  = 0;
            int groupsChanged = 0;

            try
            {
                // get groups set to sync
                var groupIdsThatSync = new List <int>();
                using (var rockContext = new RockContext())
                {
                    groupIdsThatSync = new GroupService(rockContext)
                                       .Queryable().AsNoTracking()
                                       .Where(g => g.SyncDataViewId != null)
                                       .Select(a => a.Id)
                                       .ToList();
                }

                foreach (var syncGroupId in groupIdsThatSync)
                {
                    bool hasGroupChanged = false;

                    // Use a fresh rockContext per group so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the dataview source is slow
                        rockContext.Database.CommandTimeout = 180;

                        // Get the Group
                        var syncGroup = new GroupService(rockContext)
                                        .Queryable().AsNoTracking()
                                        .FirstOrDefault(t => t.Id == syncGroupId);

                        // Ensure that the group's Sync Data View is a person dataview
                        if (syncGroup.SyncDataView.EntityTypeId == EntityTypeCache.Read(typeof(Person)).Id)
                        {
                            List <string> errorMessages = new List <string>();

                            // Get the person id's from the dataview (source)
                            var personService       = new PersonService(rockContext);
                            var parameterExpression = personService.ParameterExpression;
                            var whereExpression     = syncGroup.SyncDataView.GetExpression(personService, parameterExpression, out errorMessages);
                            var sourcePersonIds     = new PersonService(rockContext)
                                                      .Get(parameterExpression, whereExpression)
                                                      .Select(q => q.Id)
                                                      .ToList();

                            // Get the person id's in the group (target)
                            var targetPersonIds = new GroupMemberService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(gm => gm.GroupId == syncGroup.Id)
                                                  .Select(gm => gm.PersonId)
                                                  .ToList();

                            // Delete people from the group that are no longer in the dataview
                            foreach (var personId in targetPersonIds.Where(t => !sourcePersonIds.Contains(t)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Delete any group members with the person id
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    foreach (var groupMember in groupMemberService
                                             .Queryable()
                                             .Where(m =>
                                                    m.GroupId == syncGroupId &&
                                                    m.PersonId == personId)
                                             .ToList())
                                    {
                                        groupMemberService.Delete(groupMember);
                                    }
                                    groupMemberContext.SaveChanges();

                                    // If the Group has an exit email, and person has an email address, send them the exit email
                                    if (syncGroup.ExitSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhitespace())
                                        {
                                            // Send the exit email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", syncGroup);
                                            mergeFields.Add("Person", person);
                                            var emailMessage = new RockEmailMessage(syncGroup.ExitSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            emailMessage.Send();
                                        }
                                    }
                                }

                                hasGroupChanged = true;
                            }

                            // Add people to the group that are in the dataview and not currently in the group
                            int groupRoleId = syncGroup.GroupType.DefaultGroupRoleId ?? syncGroup.GroupType.Roles.FirstOrDefault().Id;
                            foreach (var personId in sourcePersonIds.Where(s => !targetPersonIds.Contains(s)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Add new person to the group
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    var newGroupMember     = new GroupMember {
                                        Id = 0
                                    };
                                    newGroupMember.PersonId          = personId;
                                    newGroupMember.GroupId           = syncGroup.Id;
                                    newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                    newGroupMember.GroupRoleId       = groupRoleId;
                                    groupMemberService.Add(newGroupMember);
                                    groupMemberContext.SaveChanges();

                                    // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                    if (syncGroup.WelcomeSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhitespace())
                                        {
                                            // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                            // account, add one for them.
                                            string newPassword = string.Empty;
                                            bool   createLogin = syncGroup.AddUserAccountsDuringSync ?? false;
                                            if (createLogin && !person.Users.Any())
                                            {
                                                newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                UserLogin login = UserLoginService.Create(
                                                    groupMemberContext,
                                                    person,
                                                    AuthenticationServiceType.Internal,
                                                    EntityTypeCache.Read(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                    username,
                                                    newPassword,
                                                    true,
                                                    requirePasswordReset);
                                            }

                                            // Send the welcome email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", syncGroup);
                                            mergeFields.Add("Person", person);
                                            mergeFields.Add("NewPassword", newPassword);
                                            mergeFields.Add("CreateLogin", createLogin);
                                            var emailMessage = new RockEmailMessage(syncGroup.WelcomeSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            emailMessage.Send();
                                        }
                                    }
                                }

                                hasGroupChanged = true;
                            }

                            // Increment Groups Changed Counter (if people were deleted or added to the group)
                            if (hasGroupChanged)
                            {
                                groupsChanged++;
                            }

                            // Increment the Groups Synced Counter
                            groupsSynced++;

                            // If the group changed, and it was a security group, flush the security for the group
                            if (hasGroupChanged && (syncGroup.IsSecurityRole || syncGroup.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid())))
                            {
                                Rock.Security.Role.Flush(syncGroup.Id);
                            }
                        }
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was sync'ed";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were sync'ed", groupsSynced);
                }
                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);
                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Maps the notes.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        public void MapNotes(IQueryable <Row> tableData)
        {
            var lookupContext   = new RockContext();
            var categoryService = new CategoryService(lookupContext);
            var personService   = new PersonService(lookupContext);

            var noteTypes        = new NoteTypeService(lookupContext).Queryable().AsNoTracking().ToList();
            var personalNoteType = noteTypes.FirstOrDefault(nt => nt.Guid == new Guid(Rock.SystemGuid.NoteType.PERSON_TIMELINE_NOTE));

            var importedUsers = new UserLoginService(lookupContext).Queryable().AsNoTracking()
                                .Where(u => u.ForeignId != null)
                                .ToDictionary(t => t.ForeignId, t => t.PersonId);

            var noteList = new List <Note>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying note import ({0:N0} found).", totalRows));
            foreach (var row in tableData.Where(r => r != null))
            {
                string text           = row["Note_Text"] as string;
                int?   individualId   = row["Individual_ID"] as int?;
                int?   householdId    = row["Household_ID"] as int?;
                var    noteTypeActive = row["NoteTypeActive"] as Boolean?;

                bool noteArchived = false;
                if (row.Columns.FirstOrDefault(v => v.Name.Equals("IsInactive")) != null)
                {
                    /* =====================================================================
                     *  the NoteArchived column *should* work, but OrcaMDF won't read it...
                     *  instead check for a manually added column: IsInactive int null
                     *       var noteActive = row["NoteArchived"] as Boolean?;
                     *       if ( noteActive == null ) throw new NullReferenceException();
                     * /* ===================================================================== */
                    var rowInactiveValue = row["IsInactive"] as int?;
                    noteArchived = rowInactiveValue.Equals(1);
                }

                var personKeys = GetPersonKeys(individualId, householdId);
                if (personKeys != null && !string.IsNullOrWhiteSpace(text) && noteTypeActive == true && !noteArchived)
                {
                    DateTime?dateCreated = row["NoteCreated"] as DateTime?;
                    string   noteType    = row["Note_Type_Name"] as string;

                    var note = new Note();
                    note.CreatedDateTime = dateCreated;
                    note.EntityId        = personKeys.PersonId;

                    // These replace methods don't like being chained together
                    text = Regex.Replace(text, @"\t|\&nbsp;", " ");
                    text = text.Replace("&#45;", "-");
                    text = text.Replace("&lt;", "<");
                    text = text.Replace("&gt;", ">");
                    text = text.Replace("&amp;", "&");
                    text = text.Replace("&quot;", @"""");
                    text = text.Replace("&#x0D", string.Empty);

                    note.Text = text.Trim();

                    int?userId = row["NoteCreatedByUserID"] as int?;
                    if (userId != null && importedUsers.ContainsKey(userId))
                    {
                        var userKeys = ImportedPeople.FirstOrDefault(p => p.PersonId == (int)importedUsers[userId]);
                        if (userKeys != null)
                        {
                            note.CreatedByPersonAliasId = userKeys.PersonAliasId;
                        }
                    }

                    int?matchingNoteTypeId = null;
                    if (!noteType.StartsWith("General", StringComparison.InvariantCultureIgnoreCase))
                    {
                        matchingNoteTypeId = noteTypes.Where(nt => nt.Name == noteType).Select(i => (int?)i.Id).FirstOrDefault();
                    }
                    else
                    {
                        matchingNoteTypeId = personalNoteType.Id;
                    }

                    if (matchingNoteTypeId != null)
                    {
                        note.NoteTypeId = (int)matchingNoteTypeId;
                    }
                    else
                    {
                        // create the note type
                        var newNoteType = new NoteType();
                        newNoteType.EntityTypeId = personalNoteType.EntityTypeId;
                        newNoteType.EntityTypeQualifierColumn = string.Empty;
                        newNoteType.EntityTypeQualifierValue  = string.Empty;
                        newNoteType.UserSelectable            = true;
                        newNoteType.IsSystem = false;
                        newNoteType.Name     = noteType;
                        newNoteType.Order    = 0;

                        lookupContext.NoteTypes.Add(newNoteType);
                        lookupContext.SaveChanges(DisableAuditing);

                        noteTypes.Add(newNoteType);
                        note.NoteTypeId = newNoteType.Id;
                    }

                    noteList.Add(note);
                    completed++;

                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} notes imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveNotes(noteList);
                        ReportPartialProgress();
                        noteList.Clear();
                    }
                }
            }

            if (noteList.Any())
            {
                SaveNotes(noteList);
            }

            ReportProgress(100, string.Format("Finished note import: {0:N0} notes imported.", completed));
        }
Exemplo n.º 29
0
        /// <summary>
        /// Gets the name of the Twitter user.
        /// </summary>
        /// <param name="twitterUser">The Twitter user.</param>
        /// <param name="accessToken">The access token.</param>
        /// <returns></returns>
        public static string GetTwitterUser(dynamic twitterUser, string accessToken = "")
        {
            string username    = string.Empty;
            string twitterId   = twitterUser.id_str;
            string twitterLink = "https://twitter.com/" + twitterUser.screen_name;

            string    userName = "******" + twitterId;
            UserLogin user     = null;

            using (var rockContext = new RockContext())
            {
                // Query for an existing user
                var userLoginService = new UserLoginService(rockContext);
                user = userLoginService.GetByUserName(userName);

                // If no user was found, see if we can find a match in the person table
                if (user == null)
                {
                    // Get name and email from twitterUser object and then split the name
                    string fullName      = twitterUser.name;
                    string firstName     = null;
                    string lastName      = null;
                    var    personService = new PersonService(rockContext);
                    personService.SplitName(fullName, out firstName, out lastName);
                    string email = string.Empty;
                    try { email = twitterUser.email; }
                    catch { }

                    Person person = null;

                    // If person had an email, get the first person with the same name and email address.
                    if (!string.IsNullOrWhiteSpace(email))
                    {
                        var people = personService.GetByMatch(firstName, lastName, email);
                        if (people.Count() == 1)
                        {
                            person = people.First();
                        }
                    }

                    var personRecordTypeId  = DefinedValueCache.Read(SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                    var personStatusPending = DefinedValueCache.Read(SystemGuid.DefinedValue.PERSON_RECORD_STATUS_PENDING.AsGuid()).Id;

                    rockContext.WrapTransaction(() =>
                    {
                        // If not an existing person, create a new one
                        if (person == null)
                        {
                            person                     = new Person();
                            person.IsSystem            = false;
                            person.RecordTypeValueId   = personRecordTypeId;
                            person.RecordStatusValueId = personStatusPending;
                            person.FirstName           = firstName;
                            person.LastName            = lastName;
                            person.Email               = email;
                            person.IsEmailActive       = true;
                            person.EmailPreference     = EmailPreference.EmailAllowed;
                            person.Gender              = Gender.Unknown;
                            if (person != null)
                            {
                                PersonService.SaveNewPerson(person, rockContext, null, false);
                            }
                        }

                        if (person != null)
                        {
                            int typeId = EntityTypeCache.Read(typeof(Facebook)).Id;
                            user       = UserLoginService.Create(rockContext, person, AuthenticationServiceType.External, typeId, userName, "Twitter", true);
                        }
                    });
                }

                if (user != null)
                {
                    username = user.UserName;

                    if (user.PersonId.HasValue)
                    {
                        var converter = new ExpandoObjectConverter();

                        var personService = new PersonService(rockContext);
                        var person        = personService.Get(user.PersonId.Value);
                        if (person != null)
                        {
                            string twitterImageUrl     = twitterUser.profile_image_url;
                            bool   twitterImageDefault = twitterUser.default_profile_image;
                            twitterImageUrl = twitterImageUrl.Replace("_normal", "");
                            // If person does not have a photo, use their Twitter photo if it exists
                            if (!person.PhotoId.HasValue && !twitterImageDefault && !string.IsNullOrWhiteSpace(twitterImageUrl))
                            {
                                // Download the photo from the url provided
                                var restClient   = new RestClient(twitterImageUrl);
                                var restRequest  = new RestRequest(Method.GET);
                                var restResponse = restClient.Execute(restRequest);
                                if (restResponse.StatusCode == HttpStatusCode.OK)
                                {
                                    var bytes = restResponse.RawBytes;

                                    // Create and save the image
                                    BinaryFileType fileType = new BinaryFileTypeService(rockContext).Get(Rock.SystemGuid.BinaryFiletype.PERSON_IMAGE.AsGuid());
                                    if (fileType != null)
                                    {
                                        var binaryFileService = new BinaryFileService(rockContext);
                                        var binaryFile        = new BinaryFile();
                                        binaryFileService.Add(binaryFile);
                                        binaryFile.IsTemporary    = false;
                                        binaryFile.BinaryFileType = fileType;
                                        binaryFile.MimeType       = "image/jpeg";
                                        binaryFile.FileName       = user.Person.NickName + user.Person.LastName + ".jpg";
                                        binaryFile.ContentStream  = new MemoryStream(bytes);

                                        rockContext.SaveChanges();

                                        person.PhotoId = binaryFile.Id;
                                        rockContext.SaveChanges();
                                    }
                                }
                            }

                            // Save the Twitter social media link
                            var twitterAttribute = AttributeCache.Read(Rock.SystemGuid.Attribute.PERSON_TWITTER.AsGuid());
                            if (twitterAttribute != null)
                            {
                                person.LoadAttributes(rockContext);
                                person.SetAttributeValue(twitterAttribute.Key, twitterLink);
                                person.SaveAttributeValues(rockContext);
                            }
                        }
                    }
                }

                return(username);
            }
        }
Exemplo n.º 30
0
        private void ShowView()
        {
            pnlEdit.Visible = false;
            pnlView.Visible = true;

            // Show the page list block
            this.HideSecondaryBlocks(false);

            var applicationId = PageParameter(PageParameterKey.SiteId).AsInteger();

            // We're being instructed to build a new site.
            if (applicationId == 0)
            {
                ShowEdit();
                return;
            }

            var rockContext = new RockContext();
            var site        = new SiteService(rockContext).Get(applicationId);

            if (site == null)
            {
                nbMessages.Text = "Could not find the application.";
            }

            pdAuditDetails.SetEntity(site, ResolveRockUrl("~"));

            hlblInactive.Visible = !site?.IsActive ?? true;

            DescriptionList viewContent = new DescriptionList();

            viewContent.Add("Description", site.Description);
            viewContent.Add("Enable Page Views", site.EnablePageViews.ToString());

            // Display the page view retention duration
            if (site.EnablePageViews)
            {
                int channelMediumWebsiteValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid()).Id;
                var retentionDuration           = new InteractionChannelService(new RockContext()).Queryable()
                                                  .Where(c => c.ChannelTypeMediumValueId == channelMediumWebsiteValueId && c.ChannelEntityId == site.Id)
                                                  .Select(c => c.RetentionDuration)
                                                  .FirstOrDefault();

                if (retentionDuration.HasValue)
                {
                    viewContent.Add("Page View Retention", retentionDuration.Value.ToString() + " days");
                }
            }

            // Get API key
            var additionalSettings = JsonConvert.DeserializeObject <AppleTvApplicationSettings>(site.AdditionalSettings);
            var apiKeyLogin        = new UserLoginService(rockContext).Get(additionalSettings.ApiKeyId ?? 0);

            viewContent.Add("API Key", apiKeyLogin != null ? apiKeyLogin.ApiKey : string.Empty);


            // Print the content to the screen
            lViewContent.Text = viewContent.Html;

            lBlockTitle.Text = site.Name;
        }
Exemplo n.º 31
0
        public HttpResponseMessage ProcessMobileCheckin(string param)
        {
            try
            {
                var session = HttpContext.Current.Session;

                var currentCheckInState = session["CheckInState"] as CheckInState;
                if (currentCheckInState.CheckIn.SearchType.Guid != Constants.CHECKIN_SEARCH_TYPE_USERLOGIN.AsGuid())
                {
                    throw new Exception(); //We'll catch this later and return a forbidden
                }

                var localDeviceConfigCookie = HttpContext.Current.Request.Cookies[CheckInCookieKey.LocalDeviceConfig].Value;
                var localDevice             = localDeviceConfigCookie.FromJsonOrNull <LocalDeviceConfiguration>();

                var rockContext = new Rock.Data.RockContext();

                UserLoginService userLoginService = new UserLoginService(rockContext);
                var family = userLoginService.Queryable().AsNoTracking()
                             .Where(u => u.UserName == currentCheckInState.CheckIn.SearchValue)
                             .Select(u => u.Person.PrimaryFamily)
                             .FirstOrDefault();
                var checkinFamily = new CheckInFamily
                {
                    Group    = family.Clone(false),
                    Caption  = family.ToString(),
                    Selected = true
                };
                currentCheckInState.CheckIn.Families.Add(checkinFamily);
                SaveState(session, currentCheckInState);

                Guid   blockGuid        = ( Guid )session["BlockGuid"];
                var    block            = BlockCache.Get(blockGuid);
                Guid?  workflowGuid     = block.GetAttributeValue("WorkflowType").AsGuidOrNull();
                string workflowActivity = block.GetAttributeValue("WorkflowActivity");

                List <string> errors;
                var           workflowService = new WorkflowService(rockContext);
                var           workflowType    = WorkflowTypeCache.Get(workflowGuid.Value);

                var CurrentWorkflow = Rock.Model.Workflow.Activate(workflowType, currentCheckInState.Kiosk.Device.Name, rockContext);

                var activityType = workflowType.ActivityTypes.Where(a => a.Name == workflowActivity).FirstOrDefault();
                if (activityType != null)
                {
                    WorkflowActivity.Activate(activityType, CurrentWorkflow, rockContext);
                    if (workflowService.Process(CurrentWorkflow, currentCheckInState, out errors))
                    {
                        if (errors.Any())
                        {
                            var innerException = new Exception(string.Join(" -- ", errors));
                            ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details.", innerException));
                        }

                        // Keep workflow active for continued processing
                        CurrentWorkflow.CompletedDateTime = null;
                        SaveState(session, currentCheckInState);
                        List <CheckInFamily> families = currentCheckInState.CheckIn.Families;
                        families = families.OrderBy(f => f.Caption).ToList();
                        return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, param));
                    }
                    else
                    {
                        if (errors.Any())
                        {
                            var innerException = new Exception(string.Join(" -- ", errors));
                            ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details.", innerException));
                        }
                        else
                        {
                            ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details."));
                        }
                    }
                }
                else
                {
                    return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, string.Format("Workflow type does not have a '{0}' activity type", workflowActivity)));
                }
                return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, String.Join("\n", errors)));
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, HttpContext.Current);
                return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden, "Forbidden"));
            }
        }
Exemplo n.º 32
0
        /// <summary>
        /// Maps the users.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        public void MapUsers(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();
            var personService = new PersonService(lookupContext);

            var rockAuthenticatedTypeId = EntityTypeCache.Read(typeof(Rock.Security.Authentication.Database)).Id;

            var staffGroupId = new GroupService(lookupContext).GetByGuid(new Guid(Rock.SystemGuid.Group.GROUP_STAFF_MEMBERS)).Id;

            var memberGroupRoleId = new GroupTypeRoleService(lookupContext).Queryable()
                                    .Where(r => r.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_SECURITY_GROUP_MEMBER)))
                                    .Select(r => r.Id).FirstOrDefault();

            var userLoginService  = new UserLoginService(lookupContext);
            var importedUserCount = userLoginService.Queryable().Count(u => u.ForeignId != null);

            var newUserLogins     = new List <UserLogin>();
            var newStaffMembers   = new List <GroupMember>();
            var updatedPersonList = new List <Person>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying user import ({totalRows:N0} found, {importedUserCount:N0} already exist).");

            foreach (var row in tableData.Where(r => r != null))
            {
                var individualId = row["LinkedIndividualID"] as int?;
                var userName     = row["UserLogin"] as string;
                var userId       = row["UserID"] as int?;
                if (userId.HasValue && individualId.HasValue && !string.IsNullOrWhiteSpace(userName))
                {
                    var personKeys = GetPersonKeys(individualId, null);
                    if (personKeys != null)
                    {
                        var createdDate = row["UserCreatedDate"] as DateTime?;
                        var userEmail   = row["UserEmail"] as string;
                        var userTitle   = row["UserTitle"] as string;
                        var userPhone   = row["UserPhone"] as string;
                        var isEnabled   = row["IsUserEnabled"] as bool?;
                        var isStaff     = row["IsStaff"] as bool?;
                        var isActive    = isEnabled ?? false;

                        var user = AddUserLogin(lookupContext, rockAuthenticatedTypeId, personKeys.PersonId, userName.Trim(), null, isEnabled, false, createdDate, userId.ToString(), ImportPersonAliasId);
                        if (user != null)
                        {
                            // track the user's id and person alias for use with notes
                            PortalUsers.AddOrReplace((int)userId, personKeys.PersonAliasId);

                            if (isStaff == true)
                            {
                                // add this user to the staff group
                                var staffMember = new GroupMember
                                {
                                    GroupId                = staffGroupId,
                                    PersonId               = personKeys.PersonId,
                                    GroupRoleId            = memberGroupRoleId,
                                    CreatedDateTime        = createdDate,
                                    CreatedByPersonAliasId = ImportPersonAliasId,
                                    GroupMemberStatus      = isActive ? GroupMemberStatus.Active : GroupMemberStatus.Inactive
                                };

                                newStaffMembers.Add(staffMember);
                            }

                            // set user login email to person's primary email if one isn't set
                            if (!string.IsNullOrWhiteSpace(userEmail) && userEmail.IsEmail())
                            {
                                var person = !updatedPersonList.Any(p => p.Id == personKeys.PersonId)
                                    ? personService.Queryable(includeDeceased: true).FirstOrDefault(p => p.Id == personKeys.PersonId)
                                    : updatedPersonList.FirstOrDefault(p => p.Id == personKeys.PersonId);

                                if (person != null && string.IsNullOrWhiteSpace(person.Email))
                                {
                                    person.Email           = userEmail.Left(75);
                                    person.EmailNote       = userTitle;
                                    person.IsEmailActive   = isEnabled != false;
                                    person.EmailPreference = EmailPreference.EmailAllowed;
                                    lookupContext.SaveChanges(DisableAuditing);
                                    updatedPersonList.Add(person);
                                }
                            }

                            newUserLogins.Add(user);
                            completedItems++;

                            if (completedItems % percentage < 1)
                            {
                                var percentComplete = completedItems / percentage;
                                ReportProgress(percentComplete, $"{completedItems:N0} users imported ({percentComplete}% complete).");
                            }
                            else if (completedItems % ReportingNumber < 1)
                            {
                                SaveUsers(newUserLogins, newStaffMembers);

                                updatedPersonList.Clear();
                                newUserLogins.Clear();
                                newStaffMembers.Clear();
                                ReportPartialProgress();
                            }
                        }
                    }
                }
                else
                {
                    LogException("User Import", $"User: {userId} - UserName: {userName} is not linked to a person or already exists.");
                }
            }

            if (newUserLogins.Any())
            {
                SaveUsers(newUserLogins, newStaffMembers);
            }

            ReportProgress(100, $"Finished user import: {completedItems:N0} users imported.");
        }