Migrate existing users to sec$User objects

Hello,

I am creating a new Cuba application where I will be using LDAP.

All I want to do is to migrate some already existing users from an external DB to sec$User objects in order not to insert every user manually in the Users table.

I already set up and LDAP connection and it works and I also created one more Data Store where I have the table of the users I want to import as users in my application in the Users table.

My question is how can I take the records from the external table and insert them into the Cuba’s Users table?

Thank you in advance,
Marko

1 Like

Hi Marko,

CUBA Studio has a built-in migration tool for such cases. Please check this tutorial, particularly this step, and if you still have questions, don’t hesitate to ask here.

1 Like

Hi Olga,

thanks for the reply.

I have already done this step and what I get with this is the table where I have all the users from the external DB and that is great.

What I need now is to tell CUBA that these are the users I want to use for the LDAP authentication.

By following the documentation about the LDAP integration I get that we need to have the user in the System Users table only with it’s username and without the password.

Now, by making the migration I am getting all the usernames of the users but how can I tell the CUBA to look in this table for the user’s usernames or how can I import all these usernames in the CUBA’s System Users table?

Regards

Hi Marko,

If you have already created entities from an additional datastore, and what you need now is to migrate the data itself, you can create a JMX bean which will load the list of records from the additional datastore and save their fields’ data in the Users table of your main datastore.

Let’s take our usual sample-sales app as an example. After running createDb task in sample-sales, I connect the sales DB which already has some data as an additional datastore in my main app. Then I use the migration tool to create the Customer entity in the main app.

Next, I create a JMX bean in the core module:

@ManagedResource(description = "Users import procedure")
public interface UsersImportMBean {
    @ManagedOperation(description = "Gets all customers from sample-sales app and saves as users in current app")
    String importUsersFromSalesCustomer();
}

Here’s the import logic:

package com.company.demo.core;

import com.company.demo.entity.Customer;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.Transaction;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.PasswordEncryption;
import com.haulmont.cuba.security.app.Authenticated;
import com.haulmont.cuba.security.entity.Group;
import com.haulmont.cuba.security.entity.User;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.List;
import java.util.UUID;

@Component("demo_UsersImportMBean")
public class UsersImport implements UsersImportMBean {
    @Inject
    private Persistence persistence;
    @Inject
    private Metadata metadata;
    @Inject
    private PasswordEncryption passwordEncryption;

    @Authenticated
    @Override
    public String importUsersFromSalesCustomer() {
        try {
            try (Transaction txSales = persistence.createTransaction("sales")) {
                EntityManager emSales = persistence.getEntityManager("sales");
                Query query = emSales.createQuery(
                        "select c from demo$Customer c", Customer.class
                );
                List<Customer> customers = query.getResultList();
                if (!customers.isEmpty()) {
                    try (Transaction txMain = persistence.createTransaction()) {
                        EntityManager emMain = persistence.getEntityManager();
                        Group group = emMain.find(Group.class, UUID.fromString("0fa2b1a5-1d68-4d69-9fbd-dff348347f93"));
                        for (Customer customer : customers) {
                            User user = metadata.create(User.class);
                            String login = customer.getName().replaceAll(" ", "_").toLowerCase();
                            user.setLogin(login);
                            user.setPassword( passwordEncryption.getPasswordHash(user.getId(), "1"));
                            user.setChangePasswordAtNextLogon(true);
                            user.setName(customer.getName());
                            user.setEmail(customer.getEmail());
                            user.setGroup(group);
                            emMain.persist(user);
                        }
                        txMain.commit();
                    }
                }
                return customers.size() + " users imported";
            }
        } catch (Throwable e) {
            return ExceptionUtils.getStackTrace(e);
        }
    }
}

Then I register the new bean in spring.xml:

    <bean id="demo_MBeanExporter" lazy-init="false"
          class="com.haulmont.cuba.core.sys.jmx.MBeanExporter">
        <property name="beans">
            <map>
                <entry key="$app-core.demo:type=UsersImport"
                       value-ref="demo_UsersImportMBean"/>
            </map>
        </property>
    </bean>

Now the importUsersFromSalesCustomer() method is available in JMX console, and running it will create new users in the main datastore.

I’ve attached the sample project, it should work out-of-the-box if you run the sample-sales first.
demo.zip (74.4 KB)

3 Likes

Hello Olga,

Thank you so much about your detailed reply.

I succeeded what I wanted just by following your documentation.

1 Like