001package systems.dmx.accesscontrol.migrations;
002
003import systems.dmx.accesscontrol.AccessControlService;
004import systems.dmx.workspaces.WorkspacesService;
005
006import systems.dmx.core.ChildTopics;
007import systems.dmx.core.RelatedTopic;
008import systems.dmx.core.Topic;
009import systems.dmx.core.service.Inject;
010import systems.dmx.core.service.Migration;
011import systems.dmx.core.service.accesscontrol.SharingMode;
012
013import java.util.List;
014import java.util.logging.Logger;
015
016
017
018/**
019 * Converts the user accounts.
020 * Runs only in UPDATE mode.
021 * <p>
022 * Part of DM 4.5
023 */
024public class Migration8 extends Migration {
025
026    // ---------------------------------------------------------------------------------------------- Instance Variables
027
028    @Inject
029    private AccessControlService acService;
030
031    @Inject
032    private WorkspacesService wsService;
033
034    private Logger logger = Logger.getLogger(getClass().getName());
035
036    // -------------------------------------------------------------------------------------------------- Public Methods
037
038    @Override
039    public void run() {
040        // Note: at migration running time our plugin listeners are not yet registered. That means
041        // access control is not yet in effect. We have full READ/WRITE access to the database.
042        List<Topic> userAccounts = dmx.getTopicsByType("dmx.accesscontrol.user_account");
043        logger.info("########## Converting " + userAccounts.size() + " user accounts");
044        for (Topic userAccount : userAccounts) {
045            // compare to AccessControlPlugin.createUserAccount()
046            ChildTopics childTopics = userAccount.getChildTopics();
047            Topic usernameTopic = childTopics.getTopic("dmx.accesscontrol.username");
048            Topic passwordTopic = childTopics.getTopic("dmx.accesscontrol.password");
049            //
050            // 1) create private workspace
051            Topic privateWorkspace = wsService.createWorkspace(AccessControlService.DEFAULT_PRIVATE_WORKSPACE_NAME,
052                null, SharingMode.PRIVATE);
053            String username = usernameTopic.getSimpleValue().toString();
054            acService.setWorkspaceOwner(privateWorkspace, username);
055            //
056            // 2) assign user account and password to private workspace
057            long privateWorkspaceId = privateWorkspace.getId();
058            wsService.assignToWorkspace(userAccount, privateWorkspaceId);
059            wsService.assignToWorkspace(passwordTopic, privateWorkspaceId);
060            //
061            // 3) create memberships
062            createMemberships(usernameTopic);
063            //
064            // 4) assign username to "System" workspace
065            Topic systemWorkspace = wsService.getWorkspace(AccessControlService.SYSTEM_WORKSPACE_URI);
066            wsService.assignToWorkspace(usernameTopic, systemWorkspace.getId());
067        }
068    }
069
070    // ------------------------------------------------------------------------------------------------- Private Methods
071
072    private void createMemberships(Topic usernameTopic) {
073        String username = usernameTopic.getSimpleValue().toString();
074        List<RelatedTopic> workspaces = usernameTopic.getRelatedTopics("dmx.core.aggregation", "dmx.core.parent",
075            "dmx.core.child", "dmx.workspaces.workspace");
076        logger.info("######## User \"" + username + "\" is member of " + workspaces.size() + " workspaces");
077        for (RelatedTopic workspace : workspaces) {
078            long workspaceId = workspace.getId();
079            String owner = acService.getWorkspaceOwner(workspaceId);
080            boolean isOwner = username.equals(owner);
081            logger.info("##### Workspace \"" + workspace.getSimpleValue() + "\" (id=" + workspace.getId() +
082                "), owner: " + owner + " -> create " + (isOwner ? "NO " : "") + "Membership");
083            if (!isOwner) {
084                acService.createMembership(username, workspaceId);
085            }
086            workspace.getRelatingAssociation().delete();
087        }
088    }
089}