Package org.jasig.portal

Source Code of org.jasig.portal.RDBMUserIdentityStore$PortalUser

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package  org.jasig.portal;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.sql.DataSource;

import net.sf.ehcache.Ehcache;
import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.groups.IEntityGroup;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.groups.ILockableEntityGroup;
import org.jasig.portal.jpa.BasePortalJpaDao;
import org.jasig.portal.layout.dao.IStylesheetUserPreferencesDao;
import org.jasig.portal.layout.om.IStylesheetUserPreferences;
import org.jasig.portal.persondir.ILocalAccountDao;
import org.jasig.portal.persondir.ILocalAccountPerson;
import org.jasig.portal.portlet.dao.IPortletEntityDao;
import org.jasig.portal.portlet.om.IPortletEntity;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.PersonFactory;
import org.jasig.portal.services.GroupService;
import org.jasig.portal.spring.locator.CounterStoreLocator;
import org.jasig.portal.utils.SerializableObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionOperations;
import org.springframework.transaction.support.TransactionTemplate;

import com.googlecode.ehcache.annotations.Cacheable;

/**
* SQL implementation for managing creation and removal of User Portal Data
* @author Susan Bramhall, Yale University (modify by Julien Marchal, University Nancy 2; Eric Dalquist - edalquist@unicon.net)
* @version $Revision$
*/
@Service("userIdentityStore")
public class RDBMUserIdentityStore  implements IUserIdentityStore {

    private static final Log log = LogFactory.getLog(RDBMUserIdentityStore.class);
    private static final String PROFILE_TABLE = "UP_USER_PROFILE";

    //*********************************************************************
    // Constants
    private static final String templateAttrName = "uPortalTemplateUserName";

    private String defaultTemplateUserName;
    private JdbcOperations jdbcOperations;
    private TransactionOperations transactionOperations;
    private IPortletEntityDao portletEntityDao;
    private IStylesheetUserPreferencesDao stylesheetUserPreferencesDao;
    private ILocalAccountDao localAccountDao;
    private Ehcache userLockCache;

    @Value("${org.jasig.portal.services.Authentication.defaultTemplateUserName}")
    public void setDefaultTemplateUserName(String defaultTemplateUserName) {
        this.defaultTemplateUserName = defaultTemplateUserName;
    }

    @Autowired
    public void setPortletEntityDao(@Qualifier("persistence") IPortletEntityDao portletEntityDao) {
        this.portletEntityDao = portletEntityDao;
    }

    @Autowired
    public void setStylesheetUserPreferencesDao(IStylesheetUserPreferencesDao stylesheetUserPreferencesDao) {
        this.stylesheetUserPreferencesDao = stylesheetUserPreferencesDao;
    }

    @Autowired
    public void setLocalAccountDao(ILocalAccountDao localAccountDao) {
        this.localAccountDao = localAccountDao;
    }

    @Autowired
    @Qualifier("org.jasig.portal.RDBMUserIdentityStore.userLockCache")
    public void setUserLockCache(Ehcache userLockCache) {
        this.userLockCache = new SelfPopulatingCache(userLockCache, new CacheEntryFactory() {

            @Override
            public Object createEntry(Object key) throws Exception {
                return new SerializableObject();
            }
        });
    }

    @Autowired
    public void setPlatformTransactionManager(@Qualifier(BasePortalJpaDao.PERSISTENCE_UNIT_NAME) PlatformTransactionManager platformTransactionManager) {
        this.transactionOperations = new TransactionTemplate(platformTransactionManager);
    }

    @javax.annotation.Resource(name=BasePortalJpaDao.PERSISTENCE_UNIT_NAME)
    public void setDataSource(DataSource dataSource) {
        this.jdbcOperations = new JdbcTemplate(dataSource);
    }

    private Serializable getLock(IPerson person) {
        final String username = (String)person.getAttribute(IPerson.USERNAME);
        return this.userLockCache.get(username);
    }

    /**
     * getuPortalUID -  return a unique uPortal key for a user.
     *    calls alternate signature with createPortalData set to false.
     * @param person the person object
     * @return uPortalUID number
     * @throws Exception if no user is found.
     */
    public int getPortalUID (IPerson person) throws AuthorizationException {
        int uPortalUID=-1;
        uPortalUID=this.getPortalUID(person, false);
        return uPortalUID;
    }

    @Override
    public void removePortalUID(final String userName) {
        this.transactionOperations.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                if (PersonFactory.GUEST_USERNAME.equals(userName)) {
                    throw new IllegalArgumentException("CANNOT RESET LAYOUT FOR A GUEST USER");
                }

                final int userId = jdbcOperations.queryForInt("SELECT USER_ID FROM UP_USER WHERE USER_NAME=?", userName);

                final int type = jdbcOperations.queryForInt("SELECT ENTITY_TYPE_ID FROM UP_ENTITY_TYPE WHERE ENTITY_TYPE_NAME = ?", IPerson.class.getName());

                jdbcOperations.update("DELETE FROM UP_PERMISSION WHERE PRINCIPAL_KEY=? AND PRINCIPAL_TYPE=?", userName, type);


                final List<Integer> groupIds = jdbcOperations.queryForList(
                        "SELECT M.GROUP_ID " +
                                "FROM UP_GROUP_MEMBERSHIP M, UP_GROUP G, UP_ENTITY_TYPE E " +
                                "WHERE M.GROUP_ID = G.GROUP_ID " +
                                "  AND G.ENTITY_TYPE_ID = E.ENTITY_TYPE_ID " +
                                "  AND  E.ENTITY_TYPE_NAME = 'org.jasig.portal.security.IPerson'" +
                                "  AND  M.MEMBER_KEY =? AND  M.MEMBER_IS_GROUP = 'F'", Integer.class, userName);


                // Remove from local group
                // Delete from DeleteUser.java and place here
                // must be made before delete user in UP_USER
                for (final Integer groupId : groupIds) {
                    jdbcOperations.update("DELETE FROM UP_GROUP_MEMBERSHIP WHERE MEMBER_KEY=? AND GROUP_ID=?", userName, groupId);
                }

                jdbcOperations.update("DELETE FROM UP_USER            WHERE USER_ID = ?", userId);
                jdbcOperations.update("DELETE FROM UP_USER_LAYOUT     WHERE USER_ID = ?", userId);
                jdbcOperations.update("DELETE FROM UP_USER_PROFILE    WHERE USER_ID = ?", userId);
                jdbcOperations.update("DELETE FROM UP_LAYOUT_PARAM    WHERE USER_ID = ?", userId);
                jdbcOperations.update("DELETE FROM UP_LAYOUT_STRUCT   WHERE USER_ID = ?", userId);
                jdbcOperations.update("DELETE FROM UP_USER_LOCALE     WHERE USER_ID = ?", userId);

                //Purge all portlet entity data
                final Set<IPortletEntity> portletEntities = portletEntityDao.getPortletEntitiesForUser(userId);
                for (final IPortletEntity portletEntity : portletEntities) {
                    portletEntityDao.deletePortletEntity(portletEntity);
                }


                //Purge all stylesheet preference data
                final List<? extends IStylesheetUserPreferences> stylesheetUserPreferences = stylesheetUserPreferencesDao.getStylesheetUserPreferencesForUser(userId);
                for (final IStylesheetUserPreferences stylesheetUserPreference : stylesheetUserPreferences) {
                    stylesheetUserPreferencesDao.deleteStylesheetUserPreferences(stylesheetUserPreference);
                }

                final ILocalAccountPerson person = localAccountDao.getPerson(userName);
                if (person != null) {
                    localAccountDao.deleteAccount(person);
                }
            }
        });
    }

    /**
     *
     * removeuPortalUID
     * @param   uPortalUID integer key to uPortal data for a user
     * @throws SQLException exception if a sql error is encountered
     */
    @Override
    public void removePortalUID(final int uPortalUID) {

        this.transactionOperations.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                final String name = jdbcOperations.queryForObject("SELECT USER_NAME FROM UP_USER WHERE USER_ID=?", String.class, uPortalUID);
                if (name == null) {
                    log.warn("No user exists for id " + uPortalUID + " Nothing will be deleted");
                    return;
                }

                removePortalUID(name);
            }
        });
    }

    /**
     * Return the username to be used for authorization (exit hook)
     * @param person
     * @return usernmae
     */
    public String getUsername(IPerson person) {
        return (String)person.getAttribute(IPerson.USERNAME);
    }

    /**
     * Get the portal user ID for this person object.
     * @param person
     * @param createPortalData indicating whether to try to create all uPortal data for this user from template prototype
     * @return uPortalUID number or -1 if unable to create user.
     * @throws AuthorizationException if createPortalData is false and no user is found
     *  or if a sql error is encountered
     */
    public int getPortalUID (IPerson person, boolean createPortalData) throws AuthorizationException {
        int uid;
        String username = (String)person.getAttribute(IPerson.USERNAME);

        // only synchronize a non-guest request.
        if (PersonFactory.GUEST_USERNAME.equals(username)) {
            uid = __getPortalUID(person, createPortalData);
        } else {
            Object lock = getLock(person);
            synchronized (lock) {
                uid = __getPortalUID(person, createPortalData);
            }
        }
        return uid;
    }

    /* (non-javadoc)
     * @see org.jasig.portal.IUserIdentityStore#getPortalUserName(int)
     */
    public String getPortalUserName(final int uPortalUID) {
        final List<String> results = this.jdbcOperations.queryForList(
                "SELECT USER_NAME FROM UP_USER WHERE USER_ID=?", String.class, uPortalUID);
        return DataAccessUtils.singleResult(results);
    }

    /* (non-Javadoc)
    * @see org.jasig.portal.IUserIdentityStore#getPortalUserId(java.lang.String)
    */
    @Override
    public Integer getPortalUserId(String userName) {
        final List<Integer> results = this.jdbcOperations.queryForList(
                "SELECT USER_ID FROM UP_USER WHERE USER_NAME=?", Integer.class, userName);
        return DataAccessUtils.singleResult(results);
    }

    private static final String IS_DEFAULT_USER_QUERY =
            "SELECT count(*)\n" +
                    "FROM up_user upuA\n" +
                    "  right join up_user upuB on upuA.USER_ID = upuB.USER_DFLT_USR_ID\n" +
                    "WHERE upuA.user_name=?";

    /* (non-Javadoc)
   * @see org.jasig.portal.IUserIdentityStore#isDefaultUser(java.lang.String)
   */
    @Override
    @Cacheable(cacheName="org.jasig.portal.RDBMUserIdentityStore.isDefaultUser")
    public boolean isDefaultUser(String username) {
        final int defaultUserCount = this.jdbcOperations.queryForInt(IS_DEFAULT_USER_QUERY, username);
        return defaultUserCount > 0;
    }

    private int __getPortalUID (IPerson person, boolean createPortalData) throws AuthorizationException {
        PortalUser portalUser = null;

        try {
            String userName = getUsername(person);
            String templateName = getTemplateName(person);
            portalUser = getPortalUser(userName);

            if (createPortalData) {
                //If we are allowed to modify the database

                if (portalUser != null) {
                    //If the user has logged in we may have to update their template user information

                    boolean hasSavedLayout = userHasSavedLayout(portalUser.getUserId());
                    if (!hasSavedLayout) {

                        TemplateUser templateUser = getTemplateUser(templateName);
                        if (portalUser.getDefaultUserId() != templateUser.getUserId()) {
                            //Update user data with new template user's data
                            updateUser(portalUser.getUserId(), person, templateUser);
                        }
                    }
                } else {
                    //User hasn't logged in before, some data needs to be created for them based on their template user

                    // Retrieve the information for the template user
                    TemplateUser templateUser = getTemplateUser(templateName);
                    if (templateUser == null) {
                        throw new AuthorizationException("No information found for template user = " + templateName + ". Cannot create new account for " + userName);
                    }

                    // Get a new user ID for this user
                    int newUID = getNewPortalUID(person);

                    // Add new user to all appropriate tables
                    int newPortalUID = addNewUser(newUID, person, templateUser);
                    portalUser = new PortalUser();
                    portalUser.setUserId(newPortalUID);
                }
            } else if (portalUser == null) {
                //If this is a new user and we can't create them
                throw new AuthorizationException("No portal information exists for user " + userName);
            }

        } catch (Exception e) {
            final String msg = "Failed to obtain a portal user Id for the specified person:  " + person;
            throw new RuntimeException(msg, e);
        }

        return portalUser.getUserId();
    }

    protected int getNewPortalUID(IPerson person) throws Exception {
        return CounterStoreLocator.getCounterStore().getNextId("UP_USER");
    }

    static final protected void commit (Connection connection) {
        try {
            if (RDBMServices.getDbMetaData().supportsTransactions())
                connection.commit();
        } catch (Exception e) {
            log.error( "RDBMUserIdentityStore::commit(): " + e);
        }
    }

    static final protected void rollback (Connection connection) {
        try {
            if (RDBMServices.getDbMetaData().supportsTransactions())
                connection.rollback();
        } catch (Exception e) {
            log.error( "RDBMUserIdentityStore::rollback(): " + e);
        }
    }

    /**
     * Gets the PortalUser data store object for the specified user name.
     *
     * @param userName The user's name
     * @return A PortalUser object or null if the user doesn't exist.
     * @throws Exception
     */
    protected PortalUser getPortalUser(final String userName) throws Exception {
        return jdbcOperations.execute(new ConnectionCallback<PortalUser>() {
            @Override
            public PortalUser doInConnection(Connection con) throws SQLException, DataAccessException {

                PortalUser portalUser = null;
                PreparedStatement pstmt = null;

                try {
                    String query = "SELECT USER_ID, USER_DFLT_USR_ID FROM UP_USER WHERE USER_NAME=?";

                    pstmt = con.prepareStatement(query);
                    pstmt.setString(1, userName);

                    ResultSet rs = null;
                    try {
                        if (log.isDebugEnabled())
                            log.debug("RDBMUserIdentityStore::getPortalUID(userName=" + userName + "): " + query);
                        rs = pstmt.executeQuery();
                        if (rs.next()) {
                            portalUser = new PortalUser();
                            portalUser.setUserId(rs.getInt("USER_ID"));
                            portalUser.setUserName(userName);
                            portalUser.setDefaultUserId(rs.getInt("USER_DFLT_USR_ID"));
                        }
                    } finally {
                        try { rs.close(); } catch (Exception e) {}
                    }
                } finally {
                    try { pstmt.close(); } catch (Exception e) {}
                }

                return portalUser;
            }
        });
    }

    protected String getTemplateName(IPerson person) {
        String templateName = (String)person.getAttribute(templateAttrName);
        // Just use the default template if requested template not populated
        if (templateName == null || templateName.equals("")) {
            templateName = defaultTemplateUserName;
        }
        return templateName;
    }

    /**
     * Gets the TemplateUser data store object for the specified template user name.
     *
     * @param templateUserName The template user's name
     * @return A TemplateUser object or null if the user doesn't exist.
     * @throws Exception
     */
    protected TemplateUser getTemplateUser(final String templateUserName) throws Exception {
        return jdbcOperations.execute(new ConnectionCallback<TemplateUser>() {
            @Override
            public TemplateUser doInConnection(Connection con) throws SQLException, DataAccessException {

                TemplateUser templateUser = null;
                PreparedStatement pstmt = null;
                try {
                    String query = "SELECT USER_ID, USER_DFLT_LAY_ID FROM UP_USER WHERE USER_NAME=?";

                    pstmt = con.prepareStatement(query);
                    pstmt.setString(1, templateUserName);

                    ResultSet rs = null;
                    try {
                        if (log.isDebugEnabled())
                            log.debug("RDBMUserIdentityStore::getTemplateUser(templateUserName=" + templateUserName + "): " + query);
                        rs = pstmt.executeQuery();
                        if (rs.next()) {
                            templateUser = new TemplateUser();
                            templateUser.setUserName(templateUserName);
                            templateUser.setUserId(rs.getInt("USER_ID"));
                            templateUser.setDefaultLayoutId(rs.getInt("USER_DFLT_LAY_ID"));
                        } else {
                            if (!templateUserName.equals(defaultTemplateUserName)) {
                                try {
                                    templateUser = getTemplateUser(defaultTemplateUserName);
                                }
                                catch (Exception e) {
                                    throw new SQLException(e);
                                }
                            }
                        }
                    } finally {
                        try { rs.close(); } catch (Exception e) {}
                    }
                } finally {
                    try { pstmt.close(); } catch (Exception e) {}
                }
                return templateUser;
            }
        });
    }

    protected boolean userHasSavedLayout(final int userId) throws Exception {
        return jdbcOperations.execute(new ConnectionCallback<Boolean>() {
            @Override
            public Boolean doInConnection(Connection con) throws SQLException, DataAccessException {

                boolean userHasSavedLayout = false;
                PreparedStatement pstmt = null;
                try {
                    String query = "SELECT * FROM UP_USER_PROFILE WHERE USER_ID=? AND LAYOUT_ID IS NOT NULL AND LAYOUT_ID!=0";

                    pstmt = con.prepareStatement(query);
                    pstmt.setInt(1, userId);

                    ResultSet rs = null;
                    try {
                        if (log.isDebugEnabled())
                            log.debug("RDBMUserIdentityStore::getTemplateUser(userId=" + userId + "): " + query);
                        rs = pstmt.executeQuery();
                        if (rs.next()) {
                            userHasSavedLayout = true;
                        }
                    } finally {
                        try { rs.close(); } catch (Exception e) {}
                    }
                } finally {
                    try { pstmt.close(); } catch (Exception e) {}
                }
                return userHasSavedLayout;

            }
        });
    }

    private ILockableEntityGroup getSafeLockableGroup(IEntityGroup eg, IGroupMember gm) {
        if (log.isTraceEnabled()) {
            log.trace("Creating lockable group for group/member: " + eg + "/" + gm);
        }

        ILockableEntityGroup leg = null;

        try {
            if (eg.isEditable()) {
                leg = GroupService.findLockableGroup(eg.getKey(), gm.getKey());
            }
        } catch (Exception e) {
            // Bummer.  but the only thing to do is to press on
            log.error("Unable to create lockable group for group/member: " + eg + "/" + gm, e);
        }

        return leg;
    }

    /**
     * Remove a person from a group.  This method catches and logs exceptions
     * exceptions encountered performing the removal.
     * @param person person to be removed (used for logging)
     * @param me member representing the person
     * @param eg group from which the user should be removed
     */
    private void removePersonFromGroup(IPerson person, IGroupMember me, IEntityGroup eg) {
        if (log.isTraceEnabled()) {
            log.trace("Removing " + person + " from group " + eg);
        }
        try {
            if (eg.isEditable()) {
                eg.removeMember(me);
                eg.updateMembers();
            }
        } catch (Exception e) {
            // Bummer.  but the only thing to do is to press on
            log.error("Unable to remove " + person + " from group " + eg, e);
        }
    }

    /**
     * Add a person to a group. This method catches and logs exceptions encountered
     * performing the removal.
     * @param person person to be added (used for logging)
     * @param me member representing the person
     * @param eg group to which the user should be added
     */
    private void addPersonToGroup(IPerson person, IGroupMember me, IEntityGroup eg) {
        if (log.isTraceEnabled()) {
            log.trace("Adding " + person + " to group " + eg);
        }
        try {
            if (eg.isEditable()) {
                eg.addMember(me);
                eg.updateMembers();
            }
        } catch (Exception e) {
            log.error("Unable to add " + person + " to group " + eg, e);
        }
    }

    protected void updateUser(final int userId, final IPerson person, final TemplateUser templateUser) throws Exception {
        // Remove my existing group memberships
        IGroupMember me = GroupService.getGroupMember(person.getEntityIdentifier());
        Iterator myExistingGroups = me.getContainingGroups();
        while (myExistingGroups.hasNext()) {
            IEntityGroup eg = (IEntityGroup)myExistingGroups.next();
            ILockableEntityGroup leg = getSafeLockableGroup(eg, me);
            if (leg != null) {
                removePersonFromGroup(person, me, leg);
            }
        }

        // Copy template user's groups memberships
        IGroupMember template = GroupService.getEntity(templateUser.getUserName(), org.jasig.portal.security.IPerson.class);
        Iterator templateGroups = template.getContainingGroups();
        while (templateGroups.hasNext()) {
            IEntityGroup eg = (IEntityGroup)templateGroups.next();
            ILockableEntityGroup leg = getSafeLockableGroup(eg, me);
            if (leg != null) {
                addPersonToGroup(person, me, leg);
            }
        }

        this.transactionOperations.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                return jdbcOperations.execute(new ConnectionCallback<Object>() {
                    @Override
                    public Object doInConnection(Connection con) throws SQLException, DataAccessException {

                        PreparedStatement deleteStmt = null;
                        PreparedStatement queryStmt = null;
                        PreparedStatement insertStmt = null;
                        try {
                            // Update UP_USER
                            String update =
                                    "UPDATE UP_USER " +
                                            "SET USER_DFLT_USR_ID=?, " +
                                            "USER_DFLT_LAY_ID=?, " +
                                            "NEXT_STRUCT_ID=null " +
                                            "WHERE USER_ID=?";

                            insertStmt = con.prepareStatement(update);
                            insertStmt.setInt(1, templateUser.getUserId());
                            insertStmt.setInt(2, templateUser.getDefaultLayoutId());
                            insertStmt.setInt(3, userId);

                            if (log.isDebugEnabled())
                                log.debug("RDBMUserIdentityStore::addNewUser(): " + update);
                            insertStmt.executeUpdate();
                            insertStmt.close();

                            // Start copying...
                            ResultSet rs = null;
                            String delete = null;
                            String query = null;
                            String insert = null;
                            try {
                                // Update UP_USER_PROFILE
                                delete =
                                        "DELETE FROM UP_USER_PROFILE " +
                                                "WHERE USER_ID=?";
                                deleteStmt = con.prepareStatement(delete);
                                deleteStmt.setInt(1, userId);
                                if (log.isDebugEnabled())
                                    log.debug("RDBMUserIdentityStore::updateUser(USER_ID=" + userId + "): " + delete);
                                deleteStmt.executeUpdate();
                                deleteStmt.close();

                                query =
                                        "SELECT USER_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, " +
                                                "STRUCTURE_SS_ID, THEME_SS_ID " +
                                                "FROM UP_USER_PROFILE " +
                                                "WHERE USER_ID=?";
                                queryStmt = con.prepareStatement(query);
                                queryStmt.setInt(1, templateUser.getUserId());
                                if (log.isDebugEnabled())
                                    log.debug("RDBMUserIdentityStore::updateUser(USER_ID=" + templateUser.getUserId() + "): " + query);
                                rs = queryStmt.executeQuery();

                                insert =
                                        "INSERT INTO UP_USER_PROFILE (USER_ID, PROFILE_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, LAYOUT_ID, STRUCTURE_SS_ID, THEME_SS_ID) " +
                                                "VALUES(?, ?, ?, ?, ?, NULL, ?, ?)";
                                insertStmt = con.prepareStatement(insert);
                                while (rs.next()) {
                                    int id = getNextKey();

                                    String profileFname = rs.getString("PROFILE_FNAME");
                                    String profileName = rs.getString("PROFILE_NAME");
                                    String description = rs.getString("DESCRIPTION");
                                    int structure = rs.getInt("STRUCTURE_SS_ID");
                                    int theme = rs.getInt("THEME_SS_ID");

                                    insertStmt.setInt(1, userId);
                                    insertStmt.setInt(2, id);
                                    insertStmt.setString(3, profileFname);
                                    insertStmt.setString(4, profileName);
                                    insertStmt.setString(5, description);
                                    insertStmt.setInt(6, structure);
                                    insertStmt.setInt(7, theme);

                                    if (log.isDebugEnabled())
                                        log.debug("RDBMUserIdentityStore::updateUser(USER_ID=" + userId + ", PROFILE_FNAME=" + profileFname + ", PROFILE_NAME=" + profileName + ", DESCRIPTION=" + description + "): " + insert);
                                    insertStmt.executeUpdate();
                                }
                                rs.close();
                                queryStmt.close();
                                insertStmt.close();

                                // If we made it all the way though, commit the transaction
                                if (RDBMServices.getDbMetaData().supportsTransactions())
                                    con.commit();

                            }
                            finally {
                                try { rs.close(); } catch (Exception e) {}
                            }
                        }
                        finally {
                            try { deleteStmt.close(); } catch (Exception e) {}
                            try { queryStmt.close(); } catch (Exception e) {}
                            try { insertStmt.close(); } catch (Exception e) {}
                        }

                        return null;
                    }
                });
            }
        });
    }

    protected int addNewUser(final int newUID, final IPerson person, final TemplateUser templateUser) throws Exception {
        // Copy template user's groups memberships
        IGroupMember me = GroupService.getGroupMember(person.getEntityIdentifier());
        IGroupMember template = GroupService.getEntity(templateUser.getUserName(), Class.forName("org.jasig.portal.security.IPerson"));
        Iterator templateGroups = template.getContainingGroups();
        while (templateGroups.hasNext()) {
            IEntityGroup eg = (IEntityGroup)templateGroups.next();
            ILockableEntityGroup leg = getSafeLockableGroup(eg, me);
            if (leg != null) {
                addPersonToGroup(person, me, leg);
            }
        }

        return this.transactionOperations.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                return jdbcOperations.execute(new ConnectionCallback<Integer>() {
                    @Override
                    public Integer doInConnection(Connection con) throws SQLException, DataAccessException {

                        int uPortalUID = -1;
                        PreparedStatement queryStmt = null;
                        PreparedStatement insertStmt = null;
                        try {
                            // Add to UP_USER
                            String insert =
                                    "INSERT INTO UP_USER (USER_ID, USER_NAME, USER_DFLT_USR_ID, USER_DFLT_LAY_ID, NEXT_STRUCT_ID, LST_CHAN_UPDT_DT)" +
                                            "VALUES (?, ?, ?, ?, null, null)";

                            String userName = getUsername(person);

                            insertStmt = con.prepareStatement(insert);
                            insertStmt.setInt(1, newUID);
                            insertStmt.setString(2, userName);
                            insertStmt.setInt(3, templateUser.getUserId());
                            insertStmt.setInt(4, templateUser.getDefaultLayoutId());

                            if (log.isDebugEnabled())
                                log.debug("RDBMUserIdentityStore::addNewUser(USER_ID=" + newUID + ", USER_NAME=" + userName + ", USER_DFLT_USR_ID=" + templateUser.getUserId() + ", USER_DFLT_LAY_ID=" + templateUser.getDefaultLayoutId() + "): " + insert);
                            insertStmt.executeUpdate();
                            insertStmt.close();
                            insertStmt = null;


                            // Start copying...
                            ResultSet rs = null;
                            String query = null;
                            try {
                                // Add to UP_USER_PROFILE
                                query =
                                        "SELECT USER_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, " +
                                                "STRUCTURE_SS_ID, THEME_SS_ID " +
                                                "FROM UP_USER_PROFILE " +
                                                "WHERE USER_ID=?";
                                queryStmt = con.prepareStatement(query);
                                queryStmt.setInt(1, templateUser.getUserId());
                                if (log.isDebugEnabled())
                                    log.debug("RDBMUserIdentityStore::addNewUser(USER_ID=" + templateUser.getUserId() + "): " + query);
                                rs = queryStmt.executeQuery();

                                insert =
                                        "INSERT INTO UP_USER_PROFILE (USER_ID, PROFILE_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, LAYOUT_ID, STRUCTURE_SS_ID, THEME_SS_ID) " +
                                                "VALUES(?, ?, ?, ?, ?, NULL, ?, ?)";
                                insertStmt = con.prepareStatement(insert);
                                while (rs.next()) {
                                    int id = getNextKey();

                                    String profileFname = rs.getString("PROFILE_FNAME");
                                    String profileName = rs.getString("PROFILE_NAME");
                                    String description = rs.getString("DESCRIPTION");
                                    int structure = rs.getInt("STRUCTURE_SS_ID");
                                    int theme = rs.getInt("THEME_SS_ID");

                                    insertStmt.setInt(1, newUID);
                                    insertStmt.setInt(2, id);
                                    insertStmt.setString(3, profileFname);
                                    insertStmt.setString(4, profileName);
                                    insertStmt.setString(5, description);
                                    insertStmt.setInt(6, structure);
                                    insertStmt.setInt(7, theme);

                                    if (log.isDebugEnabled())
                                        log.debug("RDBMUserIdentityStore::addNewUser(USER_ID=" + newUID + ", PROFILE_FNAME=" + profileFname + ", PROFILE_NAME=" + profileName + ", DESCRIPTION=" + description + "): " + insert);
                                    insertStmt.executeUpdate();
                                }
                                rs.close();
                                queryStmt.close();

                                if (insertStmt != null) {
                                    insertStmt.close();
                                    insertStmt = null;
                                }


                                // If we made it all the way though, commit the transaction
                                if (RDBMServices.getDbMetaData().supportsTransactions())
                                    con.commit();

                                uPortalUID = newUID;

                            } finally {
                                try { if (rs != null) rs.close(); } catch (Exception e) {}
                            }
                        } finally {
                            try { if (queryStmt != null) queryStmt.close(); } catch (Exception e) {}
                            try { if (insertStmt != null) insertStmt.close(); } catch (Exception e) {}
                        }

                        return uPortalUID;

                    }
                });
            }
        });
    }

    private int getNextKey()
    {
        return CounterStoreLocator.getCounterStore().getNextId(PROFILE_TABLE);
    }

    protected class PortalUser {
        String userName;
        int userId;
        int defaultUserId;
        public String getUserName() { return userName; }
        public int getUserId() { return userId; }
        public int getDefaultUserId() { return defaultUserId; }
        public void setUserName(String userName) { this.userName = userName; }
        public void setUserId(int userId) { this.userId = userId; }
        public void setDefaultUserId(int defaultUserId) { this.defaultUserId = defaultUserId; }
    }

    protected class TemplateUser {
        String userName;
        int userId;
        int defaultLayoutId;
        public String getUserName() { return userName; }
        public int getUserId() { return userId; }
        public int getDefaultLayoutId() { return defaultLayoutId; }
        public void setUserName(String userName) { this.userName = userName; }
        public void setUserId(int userId) { this.userId = userId; }
        public void setDefaultLayoutId(int defaultLayoutId) { this.defaultLayoutId = defaultLayoutId; }
    }

}


TOP

Related Classes of org.jasig.portal.RDBMUserIdentityStore$PortalUser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.