Exemple #1
0
        /// <summary>
        /// Assigns CMS and AD roles to user.
        /// </summary>
        /// <param name="user">AD user</param>
        /// <param name="userInfo">CMS user</param>
        /// <param name="userRoles">Collection of <see cref="RoleInfo"/> objects user is in – infos are supposed to contain RoleGUID.</param>
        /// <param name="site">CMS roles</param>
        /// <param name="siteInfo">Site info object</param>
        private static void SetMemberships(IPrincipalObject user, UserInfo userInfo, SiteInfo siteInfo, ICollection <RoleInfo> userRoles, KeyValuePair <string, List <Guid> > site)
        {
            var roleGuids = Enumerable.Empty <Guid>()
                            .Union(site.Value)   // CMS role GUIDs user should be in
                            .Union(user.Groups); // AD role GUIDs user should be in (groups in which the user participates in AD and are imported to CMS)

            foreach (RoleInfo roleInfo in roleGuids
                     .Except(userRoles.Select(userRole => userRole.RoleGUID))
                     .Select(groupId => RoleInfo.Provider.Get().OnSite(siteInfo.SiteID).WhereEquals("RoleGuid", groupId).FirstOrDefault())
                     .Where(roleInfo => (roleInfo != null)))
            {
                // Add user to the role
                UserRoleInfo.Provider.Add(userInfo.UserID, roleInfo.RoleID);

                // Update collection of user roles (to reflect real roles user is in)
                userRoles.Add(roleInfo);

                MessageLog.LogEvent(ResHelper.GetString("Log_AssigningUserToRole", userInfo.UserName, roleInfo.RoleDisplayName));
            }
        }
Exemple #2
0
        /// <summary>
        /// Synchronizes memberships of given user.
        /// </summary>
        /// <param name="user">AD user</param>
        /// <param name="userInfo">CMS user</param>
        /// <param name="userRoles">Collection of <see cref="RoleInfo"/> objects user is in – infos are supposed to contain RoleGUID and RoleIsDomain.</param>
        private static void RemoveExcessiveMemberships(IPrincipalObject user, UserInfo userInfo, ISet <RoleInfo> userRoles)
        {
            // Add message to log
            MessageLog.LogEvent(ResHelper.GetString("Log_UpdatingMemberships", userInfo.UserName));

            // Get all user's roles that originate in AD and user is no longer member of
            var removedRoles = new List <RoleInfo>();

            foreach (var roleInfo in userRoles
                     .Where(role => role.RoleIsDomain)
                     .Where(userRole => !user.IsPrincipalInGroup(userRole.RoleGUID)))
            {
                // Remove user from CMS role
                UserRoleInfoProvider.DeleteUserRoleInfo(userInfo, roleInfo);

                // Store removed roles
                removedRoles.Add(roleInfo);
            }

            // Update set of user roles (to reflect real roles user is in)
            userRoles.ExceptWith(removedRoles);
        }
Exemple #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);
            }
        }
Exemple #4
0
        /// <summary>
        /// Loads users of given group.
        /// </summary>
        /// <param name="principalKey">Identifier (GUID) of group to load users from.</param>
        private void LoadGroupUsers(object principalKey)
        {
            DataTable usersTable = new DataTable();

            usersTable.Columns.Add(new DataColumn(COLUMN_SELECTED, typeof(Boolean)));
            usersTable.Columns.Add(new DataColumn(COLUMN_DISPLAYNAME, typeof(String)));
            usersTable.Columns.Add(new DataColumn(COLUMN_USERNAME, typeof(String)));
            usersTable.Columns.Add(new DataColumn(COLUMN_USERGUID, typeof(Guid)));

            // Get group based on node selected in tree
            IPrincipalObject group = ADProvider.GetPrincipalObject(principalKey);

            if (group != null)
            {
                // Get members of group
                List <IPrincipalObject> users = ADProvider.GetUsersOf(group);
                foreach (IPrincipalObject user in users)
                {
                    // Get user's identifier
                    object userIdentifier = user.Identifier;

                    // Get the display name of user
                    string displayName = !string.IsNullOrEmpty(user.DisplayName) ? user.DisplayName : user.Name;

                    // Create new row with the table schema
                    DataRow dr = usersTable.NewRow();

                    // Add row to table
                    usersTable.Rows.Add(dr);

                    // Add data to row
                    object[] dataRow = { user.IsSelected, displayName, user.GetCMSCodeName(true), userIdentifier };
                    dr.ItemArray = dataRow;
                }

                // Apply sorting
                usersTable.DefaultView.Sort = COLUMN_DISPLAYNAME;

                // Bind table as a grid's data source
                using (InvokeHelper ih = new InvokeHelper(grdUsers))
                {
                    ih.InvokeMethod(delegate
                    {
                        grdUsers.DataSource = usersTable;

                        // Adjust columns
                        DataGridViewColumn columnSelected = grdUsers.Columns[COLUMN_SELECTED];
                        if (columnSelected != null)
                        {
                            columnSelected.HeaderText   = ResHelper.GetString("General_Import");
                            columnSelected.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        }
                        DataGridViewColumn columnDisplayName = grdUsers.Columns[COLUMN_DISPLAYNAME];
                        if (columnDisplayName != null)
                        {
                            columnDisplayName.HeaderText   = ResHelper.GetString("General_DisplayName");
                            columnDisplayName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                            columnDisplayName.ReadOnly     = true;
                        }
                        DataGridViewColumn columnUserName = grdUsers.Columns[COLUMN_USERNAME];
                        if (columnUserName != null)
                        {
                            columnUserName.HeaderText   = ResHelper.GetString("General_CMSUsername");
                            columnUserName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                            columnUserName.ReadOnly     = true;
                        }
                        DataGridViewColumn columnUserGuid = grdUsers.Columns[COLUMN_USERGUID];
                        if (columnUserGuid != null)
                        {
                            columnUserGuid.Visible = false;
                        }

                        // Set enabled state
                        btnSelectAllUsers.Enabled   = (grdUsers.Rows.Count > 0);
                        btnDeselectAllUsers.Enabled = (grdUsers.Rows.Count > 0);
                    });
                }
            }

            // Do not interrupt mass actions
            if ((treeMassActions == null) || (!treeMassActions.IsAlive))
            {
                SetWait(false, string.Empty);
            }
        }