asked on May 19

I am running into an issue in which I need to pull users either from an AD Forest or from an IdP and then create those trustee's within Laserfiche's ecosystem. This has spurred up as with our security model we have designed, we are needing to implement the use of security tags to manage security within Laserfiche. This being the case, we have found that we need to synchronize users and groups from an AD and then respect their memberships.

 

Our environment is clustered with all Laserfiche components that support clustering through MSFC clustered via that and others load balanced via AWS. Each component is version 11, except for LFDS which is running version 12 for Graph API support.

 

We have tried different approaches using the LicenseManagerObjects.dll that is packaged with Laserfiche and pulling the users from LFDS works flawlessly, including respecting the memberships of groups defined in LFDS (manually created).

 

Within LFDS we have found that AD sync does NOT synchronize groups, rather only their members and respects licensing via their memberships. This poses an issue in which we can synchronize all of the users, and then respect memberships of groups defined in LFDS but NOT their actual AD groups which will be the group used when managing the security within Laserfiche.

 

I have attached the Workflow that we are currently using which has been able to manage the user side of the import.

 

namespace WorkflowActivity.Scripting.SDKScript
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.LicenseManager.LMO;
    using System.Linq;


    /// <summary>
    /// Provides one or more methods that can be run when the workflow scripting activity is performed.
    /// </summary>
    public class Script1 : RAScriptClass110
    {
        /// <summary>
        /// This method is run when the activity is performed.
        /// </summary>
        protected override void Execute()
        {
            // Initialize the repository session
            string repositoryName = "";
            string username = "";
            string password = "";
            using (Session session = new Session())
            {
                try
                {

                    WorkflowApi.TrackInformation("Connecting to repository...");
                    // Connect to the repository
                    RepositoryRegistration repository = new RepositoryRegistration(repositoryName, repositoryName);
                    session.Connect(repository);
                    session.LogIn(username, password);
                    WorkflowApi.TrackInformation("Connected to repository.");

                    Laserfiche.RepositoryAccess.Server server = new Laserfiche.RepositoryAccess.Server(session);

                    WorkflowApi.TrackInformation("Server connected.");

                    // Get the repository

                    Repository repo = server.GetRepository(repository);
                    WorkflowApi.TrackInformation("Repository: " + repo.RepositoryPath);

                    string serverName = "";
                    string realmName = "";
                    bool useSSL = true;

                    Laserfiche.LicenseManager.LMO.Server lmoServer = Laserfiche.LicenseManager.LMO.Server.Connect(serverName, useSSL);
                    WorkflowApi.TrackInformation("Connected to LMO server.");
                    // Get the license information
                    Database lmoDatabase = lmoServer.GetDatabaseByRealmName(realmName);
                    WorkflowApi.TrackInformation("Database: " + lmoDatabase.Name);

                    SessionTokenParameters sessionTokenParameters = new SessionTokenParameters();
                    lmoDatabase.Login(sessionTokenParameters);
                    WorkflowApi.TrackInformation("Logged in to LMO database.");

                    List<User> allUsers = lmoDatabase.GetAllUsersEx(0, 0);
                    WorkflowApi.TrackInformation("Total users: " + allUsers.Count.ToString());
                    List<Group> allGroups = lmoDatabase.GetAllGroups();
                    WorkflowApi.TrackInformation("Total groups: " + allGroups.Count.ToString());

                    // Create users and groups in the repository
                    CreateRepositoryObjects(allUsers, allGroups, RASession);
                }
                catch (Exception e)
                {
                    WorkflowApi.TrackInformation("Fatal failure: " + e.ToString());
                    //session.Close();
                }

                //session.Close();
            }
        }

        private void CreateRepositoryObjects(List<User> allUsers, List<Group> allGroups, Session session)
        {
            //WorkflowApi.TrackInformation("Creating " + allUsers.Count + " users in the repository...");
            foreach (var user in allUsers)
            {
                try
                {
                    Dictionary<String, TrusteeInfo> winTrustees = new Dictionary<String, TrusteeInfo>();
                    // Determine account type and create user accordingly
                    if (user is Laserfiche.LicenseManager.LMO.ActiveDirectoryUser) // Likely a Windows account
                    {
                        // create the windows account
                        TrusteeInfo trustee = new TrusteeInfo();

                        // set the feature rights and set it to read only
                        trustee.FeatureRights = FeatureRights.Scan | FeatureRights.Search | FeatureRights.Print | FeatureRights.Export;
                        Trustee.SetInfo(user.Name, trustee, session);

                        // grant logon access to the windows account (Trust)
                        AccountReference ar = new AccountReference(user.Name, session);
                        Repository.GrantLogOnAccess(ar, session);

                        // add to win trustees
                        winTrustees.Add(string.Join(" ", user.DisplayName.ToLower().Split(' ')), trustee);
                    }
                    if (user is Laserfiche.LicenseManager.LMO.SamlUser)
                    {
                        // Create Laserfiche Directory Account
                        // create the laserfiche directory account
                        TrusteeInfo trustee = new TrusteeInfo();
                        trustee.FeatureRights = FeatureRights.Scan | FeatureRights.Search | FeatureRights.Print | FeatureRights.Export;
                        Trustee.SetInfo(user.Name, trustee, session);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to create user " + user.Name + ": " + ex.Message);
                }
            }

            //WorkflowApi.TrackInformation("Creating " + allGroups.Count + " groups in the repository...");
            foreach (Group grp in allGroups)
            {
                try
                {
                    // Create Laserfiche Directory Account NOT Laserfiche "Repository Account"
                    WorkflowApi.TrackInformation(grp.Name);
                    // create the laserfiche directory account
                    TrusteeInfo trustee = new TrusteeInfo();
                    trustee.FeatureRights = FeatureRights.Scan | FeatureRights.Search | FeatureRights.Print | FeatureRights.Export;
                    Trustee.SetInfo(grp.Name, trustee, session);
                    //WorkflowApi.TrackInformation(trustee.LfdsName);
                    // grant logon access to the laserfiche directory account (Trust)

                    AccountReference ar = new AccountReference(grp.Name, session);
                    Repository.GrantLogOnAccess(ar, session);
                    // verify user created
                    WorkflowApi.TrackInformation("Created group: " + grp.Name);
                }
                catch (Exception ex)
                {
                    WorkflowApi.TrackInformation("Failed to create group " + grp.Name + ": " + ex.Message);
                }
            }

            WorkflowApi.TrackInformation("Assigning users to groups explicitly...");
            Dictionary<string, List<Group>> allUserGroups = new Dictionary<string, List<Group>>();

            // Build user-to-group mapping
            foreach (var group in allGroups)
            {
                var groupMembers = group.GetMembers();
                foreach (var trusteeSID in groupMembers.Keys)
                {
                    if (!allUserGroups.ContainsKey(trusteeSID))
                        allUserGroups[trusteeSID] = new List<Group>();

                    allUserGroups[trusteeSID].Add(group);
                }
            }

            // Assign users to their respective groups
            foreach (var user in allUsers)
            {
                if (!allUserGroups.ContainsKey(user.SIDString))
                {
                    WorkflowApi.TrackInformation("User " + user.Name + " does not belong to any group.");
                    continue;
                }
                WorkflowApi.TrackInformation("Assigning " + user.Name + "to groups...");

                foreach (var group in allUserGroups[user.SIDString])
                {
                    WorkflowApi.TrackInformation("Adding " + user.Name + " to group " + group.Name + "...");
                    try
                    {
                        Dictionary<string, string> currentMembers = group.GetMembers();
                        List<string> newMembers = currentMembers.Keys.ToList();

                        if (!newMembers.Contains(user.SIDString))
                        {
                            WorkflowApi.TrackInformation("Adding " + user.Name + " to " + group.Name);
                            newMembers.Add(user.SIDString);
                            group.SetMembers(newMembers);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Failed to add user " + user.Name + " to group " + group.Name + ": " + ex.Message);
                    }
                }
            }
        }
    }
}

 

Has anyone ever attempted something similar to this, and if so what were the results and do you have guidance on achieving this?

0 0