Example #1
0
        /// <summary>
        /// Deletes domain objects that exist in CMS and doesn't exist in AD.
        /// </summary>
        /// <param name="usersChanged">Records removed users for CMS event log.</param>
        /// <param name="rolesChanged">Records removed roles for CMS event log.</param>
        private static void DeleteNonExistingObjects(CumulatedChanges usersChanged, CumulatedChanges rolesChanged)
        {
            // Remove CMS (domain) roles that do not exist in AD anymore
            IQueryable <RoleInfo> excessiveRoles = RoleInfo.Provider
                                                   .Get()
                                                   .WhereTrue("RoleIsDomain")
                                                   .WhereNotEquals("RoleGUID", Guid.Empty)
                                                   .WhereGreaterThan("RoleID", 0)
                                                   .Columns("RoleID", "RoleGUID", "RoleName")
                                                   .Where(x => !PrincipalProvider.Exists(x.RoleGUID));

            foreach (var role in excessiveRoles)
            {
                // Delete role
                RoleInfo.Provider.Delete(role);

                // Store deleted role GUID and name for EventLog
                rolesChanged.Add(role.RoleGUID, role.RoleDisplayName, ChangeActionEnum.Deleted);

                // Add message to log
                MessageLog.LogEvent(ResHelper.GetString("Log_DeletingRole", role.RoleDisplayName));
            }

            // Remove CMS (domain) users that do not exist in AD anymore
            IQueryable <UserInfo> excessiveUsers = UserInfo.Provider
                                                   .Get()
                                                   .WhereTrue("UserIsDomain")
                                                   .WhereNotEquals("UserGUID", Guid.Empty)
                                                   .WhereGreaterThan("UserID", 0)
                                                   .Columns("UserID", "UserGUID", "UserName")
                                                   .Where(x => !PrincipalProvider.Exists(x.UserGUID));

            foreach (var user in excessiveUsers)
            {
                // Delete user
                UserInfo.Provider.Delete(user);

                // Store deleted user GUID and name for EventLog
                usersChanged.Add(user.UserGUID, user.UserName, ChangeActionEnum.Deleted);

                // Add message to log
                MessageLog.LogEvent(ResHelper.GetString("Log_DeletingUser", user.UserName));
            }
        }
Example #2
0
        /// <summary>
        /// Imports role to CMS.
        /// </summary>
        /// <param name="roleName">Name of role</param>
        /// <param name="displayName">Display name of role</param>
        /// <param name="siteId">ID of site</param>
        /// <param name="roleDescription">Role description</param>
        /// <param name="roleGuid">GUID of role</param>
        /// <param name="updateExistingObject">Determines whether update object if already exists</param>
        /// <param name="rolesChanged">Records added and updated roles for CMS event log</param>
        private static void ImportRole(string roleName, string displayName, int siteId, string roleDescription, Guid roleGuid, bool updateExistingObject, CumulatedChanges rolesChanged)
        {
            // Try to get role info by GUID, by GUID in code name, by name
            var roleInfo = RoleInfo.Provider.Get().OnSite(siteId).WhereEquals("RoleGuid", roleGuid).FirstOrDefault()
                           ?? RoleInfo.Provider.Get().OnSite(siteId).WhereEquals("RoleGuid", ValidationHelper.GetGuid(roleName, Guid.Empty)).FirstOrDefault()
                           ?? RoleInfo.Provider.Get(roleName, siteId);
            var newRole = roleInfo == null;

            if (newRole)
            {
                // Create new instance of role
                roleInfo = new RoleInfo();

                // Set new role properties
                roleInfo.SiteID = siteId;

                // Mark role as domain role
                roleInfo.RoleIsDomain = true;
            }
            else
            {
                // Don't update object
                if (!updateExistingObject)
                {
                    return;
                }
            }
            if (roleInfo.RoleIsDomain)
            {
                // Set role name
                roleInfo.RoleName = roleName;

                // Set display name
                roleInfo.RoleDisplayName = displayName;

                // Set description
                roleInfo.RoleDescription = roleDescription;

                // Set GUID
                roleInfo.RoleGUID = roleGuid;

                try
                {
                    if (!roleInfo.ChangedColumns().Any())
                    {
                        return;
                    }

                    // Store created/updated role ID for EventLog
                    rolesChanged.Add(roleInfo.RoleGUID, roleInfo.RoleDisplayName, newRole ? ChangeActionEnum.Created : ChangeActionEnum.Updated);

                    // Store role into database
                    RoleInfo.Provider.Set(roleInfo);
                }
                catch (CodeNameNotUniqueException)
                {
                    MessageLog.LogEvent(ResHelper.GetString("Log_RoleNameNotUnique", roleName));
                    warnings++;
                }
            }
            else
            {
                MessageLog.LogEvent(ResHelper.GetString("Log_RoleIsNotDomain", roleInfo.RoleDisplayName));
                warnings++;
            }
        }
Example #3
0
        private static void ImportWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                BackgroundWorker worker = (BackgroundWorker)sender;

                // Save import profile
                if (ImportProfile.SaveImportProfile && !ImportProfile.UsesConsole)
                {
                    SaveFile(SaveImportProfile);
                }

                // Decide whether to import
                if (!ImportProfile.ImportNow && !ImportProfile.UsesConsole)
                {
                    return;
                }

                using (new CMSActionContext()
                {
                    LogEvents = false, ContinuousIntegrationAllowObjectSerialization = false
                })
                {
                    #region "Initialization"

                    // Import canceled
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    DateTime start = DateTime.Now;

                    // Initialize CMS context
                    CMSInit();

                    if (ImportProfile.UsesConsole)
                    {
                        // Ensure object in case they are not present in import profile
                        EnsureObjects();
                    }

                    if (ImportProfile.ImportUsersOnlyFromSelectedRoles)
                    {
                        // Narrow down imported users according to imported roles
                        ImportProfile.Users.Clear();
                    }

                    // Import canceled
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    // Initialize cumulative changed users and roles storages
                    var rolesChanged = new CumulatedChanges(WellKnownEventLogEventsEnum.RolesCreated, WellKnownEventLogEventsEnum.RolesUpdated, WellKnownEventLogEventsEnum.RolesDeleted);
                    var usersChanged = new CumulatedChanges(WellKnownEventLogEventsEnum.UsersCreated, WellKnownEventLogEventsEnum.UsersUpdated, WellKnownEventLogEventsEnum.UsersDeleted);

                    #endregion

                    // Delete non-existing objects (this also prevents conflicting code names)
                    if (ImportProfile.DeleteNotExistingObjects)
                    {
                        DeleteNonExistingObjects(usersChanged, rolesChanged);
                    }

                    #region "Role import"

                    foreach (var siteInfo in ImportProfile
                             .Sites
                             .Select(site => SiteInfo.Provider.Get(site.Key))
                             .Where(info => info != null))
                    {
                        foreach (Guid groupGuid in ImportProfile.Groups)
                        {
                            // Import canceled
                            if (worker.CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            // Try to get group
                            IPrincipalObject group = PrincipalProvider.GetPrincipalObject(groupGuid);

                            // If group is still null
                            if (group == null)
                            {
                                MessageLog.LogEvent(ResHelper.GetString("Log_SkippingNonExistingObject"));
                                warnings++;
                                // If deleting of not existing objects is enabled
                                if (ImportProfile.DeleteNotExistingObjects)
                                {
                                    DeleteRole(siteInfo, groupGuid);
                                }
                            }
                            else
                            {
                                // Get role description
                                string roleDescription = String.Empty;
                                if (ImportProfile.ImportRoleDescription && (group.Description != null))
                                {
                                    roleDescription = group.Description;
                                }

                                // Get correct role name format
                                string roleCodeName = group.GetCMSCodeName(true);

                                // Get role display name
                                string roleDisplayName = group.GetCMSDisplayName();

                                // Get safe role name
                                roleCodeName = ValidationHelper.GetSafeRoleName(roleCodeName, siteInfo.SiteName);

                                if (!String.IsNullOrEmpty(roleCodeName))
                                {
                                    // Add message to log
                                    MessageLog.LogEvent(ResHelper.GetString("Log_ImportingRole", roleDisplayName, CMS.Helpers.ResHelper.LocalizeString(siteInfo.DisplayName)));

                                    // Import role
                                    ImportRole(roleCodeName, roleDisplayName, siteInfo.SiteID, roleDescription, groupGuid, ImportProfile.UpdateObjectData, rolesChanged);

                                    if (ImportProfile.ImportUsersOnlyFromSelectedRoles)
                                    {
                                        ImportProfile.Users.AddRange(PrincipalProvider.GetUsersOf(group).Select(u => u.Identifier));
                                    }
                                }
                                else
                                {
                                    // Add message to log
                                    MessageLog.LogEvent(ResHelper.GetString("Log_SkippingEmptyRolename", group.Identifier));
                                    warnings++;
                                }
                            }
                        }
                    }

                    // Log created and updated and removed roles to EventLog
                    rolesChanged.WriteEventsToEventLog();

                    #endregion

                    #region "User import"

                    foreach (var user in ImportProfile
                             .Users
                             .Distinct()
                             .Select(userGuid => PrincipalProvider.GetPrincipalObject(userGuid)))
                    {
                        // Import canceled
                        if (worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        if (user == null)
                        {
                            MessageLog.LogEvent(ResHelper.GetString("Log_SkippingNonExistingObject"));
                            continue;
                        }

                        string domainName = user.GetCMSCodeName(true);

                        if (!String.IsNullOrEmpty(domainName))
                        {
                            // Get user info object
                            UserInfo userInfo = (UserInfo.Provider.Get((Guid)user.Identifier) ?? UserInfo.Provider.Get(domainName));
                            bool     newUser  = (userInfo == null);

                            // When is desired to import new users only from selected roles
                            if (newUser && ImportProfile.ImportNewUsersOnlyFromSelectedRoles)
                            {
                                // Skip users that does not belong to one of selected role
                                bool skip = ImportProfile.Groups.Cast <Guid>().All(groupGuid => !user.IsPrincipalInGroup(groupGuid));
                                if (skip)
                                {
                                    MessageLog.LogEvent(ResHelper.GetString("Log_SkippingDoesNotBelongToSelectedRole", domainName));
                                    continue;
                                }
                            }

                            if (ImportProfile.UpdateObjectData || newUser)
                            {
                                if (userInfo == null)
                                {
                                    userInfo = new UserInfo();
                                    // Add message to log
                                    MessageLog.LogEvent(ResHelper.GetString("Log_ImportingUser", domainName));
                                }
                                else
                                {
                                    // Add message to log
                                    MessageLog.LogEvent(ResHelper.GetString("Log_UpdatingUser", domainName));
                                }

                                using (var transaction = new CMSTransactionScope())
                                {
                                    if (newUser)
                                    {
                                        userInfo.UserIsDomain = true;
                                        userInfo.UserGUID     = (Guid)user.Identifier;

                                        // Set privilege level
                                        UserPrivilegeLevelEnum privilegeLevel = ImportProfile.ConfigureAsCMSEditor ? UserPrivilegeLevelEnum.Editor : UserPrivilegeLevelEnum.None;
                                        userInfo.SiteIndependentPrivilegeLevel = privilegeLevel;
                                    }

                                    if (userInfo.UserIsDomain)
                                    {
                                        // Set user's properties
                                        userInfo.UserIsExternal = true;
                                        userInfo.UserName       = domainName;
                                        userInfo.Enabled        = ValidationHelper.GetBoolean(user.Enabled, true);

                                        // Bind properties
                                        foreach (KeyValuePair <string, string> property in ImportProfile.UserProperties)
                                        {
                                            // Get attribute
                                            object attribute = user.GetProperty(property.Value);

                                            if (attribute != null)
                                            {
                                                try
                                                {
                                                    string attrValue;

                                                    // Get string representation of the attribute
                                                    if (attribute is float || attribute is double || attribute is decimal)
                                                    {
                                                        attrValue = String.Format(CultureInfo.InvariantCulture, "{0}", attribute);
                                                    }
                                                    else if (attribute.GetType() == typeof(byte[]))
                                                    {
                                                        attrValue = PrincipalProvider.GetSID(attribute);
                                                    }
                                                    else if (attribute.GetType().BaseType == typeof(MarshalByRefObject))
                                                    {
                                                        attrValue = PrincipalProvider.GetTimeFromInterval(attribute);
                                                    }
                                                    else
                                                    {
                                                        attrValue = attribute.ToString();
                                                    }

                                                    // Set property
                                                    userInfo.SetValue(property.Key, LimitLengthForField(attrValue, property.Key));
                                                }
                                                catch
                                                {
                                                    MessageLog.LogEvent(ResHelper.GetString("Log_ErrorParsingAttr", property.Value));
                                                    warnings++;
                                                }
                                            }
                                            else
                                            {
                                                FormFieldInfo field = UserFormInfo.GetFormField(property.Key);
                                                userInfo.SetValue(property.Key, field.GetPropertyValue(FormFieldPropertyEnum.DefaultValue));
                                            }
                                        }

                                        // Create full name if empty
                                        if (String.IsNullOrEmpty(userInfo.FullName))
                                        {
                                            userInfo.FullName = user.GetCMSDisplayName();
                                        }

                                        // Store user info object and its user-settings
                                        if (userInfo.ChangedColumns().Any())
                                        {
                                            // Store created/updated user for EventLog
                                            // User name is used, because AD accounts does not have to have first and/or given name specified (e.g. Guest, …)
                                            usersChanged.Add(userInfo.UserGUID, userInfo.UserName, newUser ? ChangeActionEnum.Created : ChangeActionEnum.Updated);

                                            UserInfo.Provider.Set(userInfo);
                                        }
                                    }
                                    else
                                    {
                                        MessageLog.LogEvent(ResHelper.GetString("Log_UserIsNotDomain", userInfo.UserName));
                                        warnings++;
                                    }

                                    transaction.Commit();
                                }
                            }
                            else
                            {
                                MessageLog.LogEvent(ResHelper.GetString("Log_SkippingExistingUser", domainName));
                            }

                            // Import canceled
                            if (worker.CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            // Assign user to sites and roles (for domain users only)
                            if (!userInfo.UserIsDomain)
                            {
                                continue;
                            }


                            #region "Membership (roles) synchronization"

                            if (!newUser && !ImportProfile.UpdateMemberships && !ImportProfile.UpdateMemberships)
                            {
                                // No membership synchronization will be performed
                                continue;
                            }

                            // Initialize collection to cumulate membership changes
                            var memberShipChanges = new CumulatedRolesMembership();

                            // Load all user roles from DB
                            var userRoles = new HashSet <RoleInfo>(newUser
                                ? Enumerable.Empty <RoleInfo>() // non-existing user cannot be present in a single role (in DB)
                                : RoleInfo.Provider
                                                                   .Get()
                                                                   .WhereIn("RoleID",
                                                                            UserRoleInfo.Provider
                                                                            .Get()
                                                                            .WhereEquals("UserID", userInfo.UserID)
                                                                            .Column("RoleID"))
                                                                   .Columns("RoleID", "RoleGUID", "RoleDisplayName", "RoleIsDomain"));

                            // Store user's roles before membership synchronization
                            memberShipChanges.SetRolesBefore(userRoles);
                            foreach (KeyValuePair <string, List <Guid> > site in ImportProfile.Sites)
                            {
                                // Get site info object
                                var siteInfo = SiteInfo.Provider.Get(site.Key);
                                if (siteInfo != null)
                                {
                                    try
                                    {
                                        // Add user to this site
                                        UserSiteInfo.Provider.Add(userInfo.UserID, siteInfo.SiteID);
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageLog.LogEvent(ResHelper.GetString("Log_GeneralWarning", ex.Message));
                                        warnings++;
                                    }

                                    // Assign user to roles already existing in CMS
                                    if (newUser || ImportProfile.UpdateMemberships)
                                    {
                                        SetMemberships(user, userInfo, siteInfo, userRoles, site);
                                    }

                                    // Remove user from roles they is member no more
                                    if (!newUser && ImportProfile.UpdateMemberships)
                                    {
                                        RemoveExcessiveMemberships(user, userInfo, userRoles);
                                    }
                                }
                                else
                                {
                                    MessageLog.LogEvent(ResHelper.GetString("Log_SiteNotExist", site.Key));
                                    warnings++;
                                }
                            }

                            // Store user's roles after membership synchronization
                            memberShipChanges.SetRolesAfter(userRoles);

                            // Log created and removed memberships to EventLog
                            memberShipChanges.WriteEventsToEventLog(userInfo.UserName);

                            #endregion
                        }
                        else
                        {
                            // Add message to log
                            MessageLog.LogEvent(ResHelper.GetString("Log_SkippingEmptyUsername", user.Identifier));
                            warnings++;
                        }
                    }

                    // Log created and updated and deleted users to EventLog
                    usersChanged.WriteEventsToEventLog();

                    #endregion

                    // Import canceled
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    TimeSpan duration = DateTime.Now - start;

                    if (!worker.CancellationPending)
                    {
                        // Add message to log
                        MessageLog.LogEvent(warnings == 0
                            ? ResHelper.GetString("Log_ImportComplete", duration.Hours, duration.Minutes, duration.Seconds)
                            : ResHelper.GetString("Log_ImportCompleteWithWarnings", warnings, duration.Hours, duration.Minutes, duration.Seconds));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageLog.LogError(ResHelper.GetString("Error_General"), ex);
            }
        }