All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jresearch.commons.flexess.umi.BaseUmiUserManager Maven / Gradle / Ivy

There is a newer version: 1.0.198
Show newest version
package org.jresearch.commons.flexess.umi;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Nonnull;

import org.jresearch.commons.base.domain.filters.UserFilter;
import org.jresearch.commons.base.mail.IMailService;
import org.jresearch.commons.base.manager.api.IBusinessTypeManager;
import org.jresearch.commons.base.manager.api.IMailTemplateManager;
import org.jresearch.commons.base.manager.api.IUserManager;
import org.jresearch.commons.base.manager.api.IUserProfileManager;
import org.jresearch.commons.base.manager.api.UserNotFoundException;
import org.jresearch.commons.base.manager.api.UserUpdateException;
import org.jresearch.commons.base.manager.api.obj.IMailTemplate;
import org.jresearch.commons.base.manager.api.obj.ISystemEvent;
import org.jresearch.commons.base.manager.api.obj.IUserProfile;
import org.jresearch.commons.base.ref.manager.api.obj.IAttributeValue;
import org.jresearch.commons.base.ref.manager.api.obj.IBusinessType;
import org.jresearch.commons.base.ref.manager.api.obj.IParamType;
import org.jresearch.commons.gwt.flexess.server.service.EmailResetAuthenticationData;
import org.jresearch.commons.gwt.flexess.server.service.EmailSignUpData;
import org.jresearch.flexess.umi.api.AuthenticationException;
import org.jresearch.flexess.umi.api.ConnectionException;
import org.jresearch.flexess.umi.api.IAttributeInfo;
import org.jresearch.flexess.umi.api.IAttributePresentationInfo;
import org.jresearch.flexess.umi.api.IAuthenticationData;
import org.jresearch.flexess.umi.api.IListSettings;
import org.jresearch.flexess.umi.api.IResetAuthenticationData;
import org.jresearch.flexess.umi.api.ISearchCriteria;
import org.jresearch.flexess.umi.api.ISignUpData;
import org.jresearch.flexess.umi.api.IUmiUserManager;
import org.jresearch.flexess.umi.api.IUser;
import org.jresearch.flexess.umi.api.ResetAuthenticationException;
import org.jresearch.flexess.umi.api.UmiException;
import org.jresearch.flexess.umi.api.UnknownUserException;
import org.jresearch.flexess.umi.api.UnsupportedAuthenticationMethodException;
import org.jresearch.flexess.umi.api.connection.ConnectionStatusType;
import org.jresearch.flexess.umi.api.connection.IConnectionStatus;
import org.jresearch.flexess.umi.api.connection.impl.ConnectionStatus;
import org.jresearch.flexess.umi.api.impl.AttributeInfo;
import org.jresearch.flexess.umi.api.impl.AttributePresentationInfo;
import org.jresearch.flexess.umi.api.impl.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import ma.glasnost.orika.MapperFacade;

/**
 * General mapping of the user management into Flexess. Should reflect all
 * necessary user attributes to compute security rules.
 *
 * @author kot
 */
public class BaseUmiUserManager implements IUmiUserManager, ApplicationContextAware {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String USER_ID = "id"; //$NON-NLS-1$

    private final static ConnectionStatus initStatus = new ConnectionStatus(ConnectionStatusType.OK, "Communicate with general user manager"); //$NON-NLS-1$

    /**
     * The application must define own user manager (extend
     * {@link org.jresearch.commons.base.manager.impl.UserManager}) and populate
     * it as a Spring bean to correct work of Base UmiUser Manager
     */
    @Autowired
    private IUserManager appUserManager;
    private IUserProfileManager profileManager;
    private IBusinessTypeManager businessTypeManager;
    private IMailService mailService;
    private IMailTemplateManager mailTemplateManager;
    private Collection userLocators;

    @Autowired
    private MapperFacade mapper;
    private List attributeInfo;
    private final Map> attributePresentationInfo = new HashMap<>();

    @Override
    public Collection getAttributeInfo() {
        if (attributeInfo == null) {
            attributeInfo = createAttributeInfo();
        }
        return attributeInfo;
    }

    public List createAttributeInfo() {
        final List result = new LinkedList<>();
        final List types = businessTypeManager.getUserBusinessTypes();
        for (final IBusinessType type : types) {
            result.add(createAttributeInfo(type));
        }
        result.add(createAttributeInfo(BaseUmiUserManager.USER_ID));
        return result;
    }

    private static IAttributeInfo createAttributeInfo(final IBusinessType type) {
        final AttributeInfo result = createAttribute(type);
        final String code = type.getParameterType().getCode();
        if (IParamType.BOOLEAN.equals(code)) {
            result.setType(Boolean.class);
        } else if (IParamType.DATE.equals(code) || IParamType.TIME.equals(code)) {
            result.setType(Date.class);
        } else if (IParamType.LONG.equals(code)) {
            result.setType(Long.class);
        } else if (IParamType.STRING.equals(code)) {
            result.setType(String.class);
        }
        return result;
    }

    private static AttributeInfo createAttribute(final IBusinessType type) {
        final AttributeInfo info = new AttributeInfo();
        info.setId(type.getCode());
        return info;
    }

    /**
     * Default mapping by name.
     *
     * @param attribute
     *            - name of attribute to create attribute information.
     * @return {@link IAttributeInfo} mapped from given name
     */
    public static IAttributeInfo createAttributeInfo(final String attribute) {
        final AttributeInfo info = new AttributeInfo();
        info.setId(USER_ID);
        info.setType(String.class);
        return info;
    }

    @Override
    public Collection getAttributePresentationInfo(final Locale locale) throws ConnectionException {
        List result = attributePresentationInfo.get(locale);
        if (result == null) {
            result = createAttriPresentationbuteInfo(locale);
            attributePresentationInfo.put(locale, result);
        }
        return result;
    }

    private List createAttriPresentationbuteInfo(final Locale locale) {
        final List result = new LinkedList<>();
        final List types = businessTypeManager.getUserBusinessTypes();
        for (final IBusinessType type : types) {
            result.add(createAttributePresentationInfo(type, locale));
        }
        result.add(createAttributePresentationInfo(BaseUmiUserManager.USER_ID, locale));
        return result;
    }

    private static IAttributePresentationInfo createAttributePresentationInfo(final IBusinessType type, final Locale locale) {
        final AttributePresentationInfo info = new AttributePresentationInfo();
        info.setId(type.getCode());
        info.setName(type.getName(locale));
        info.setDescription(type.getDescription(locale));
        return info;
    }

    /**
     * Default mapping by name.
     *
     * @param attribute
     *            - name of attribute to create attribute information.
     * @return {@link IAttributeInfo} mapped from given name
     */
    public static IAttributePresentationInfo createAttributePresentationInfo(final String attribute, final Locale locale) {
        final AttributePresentationInfo info = new AttributePresentationInfo();
        info.setId(USER_ID);
        info.setName(Messages.getString("UserManager.loginName", locale)); //$NON-NLS-1$
        info.setDescription(Messages.getString("UserManager.loginDescription", locale)); //$NON-NLS-1$
        return info;
    }

    @Override
    public Collection getUsers() throws ConnectionException {
        final List result = new ArrayList<>();
        mapper.map(appUserManager.getUsers(), result);
        return result;
    }

    @Override
    public long countUsers() {
        return appUserManager.countUsers();
    }

    @Override
    public Collection getUserIds() throws ConnectionException {
        final List result = new LinkedList<>();
        mapper.map(appUserManager.getUsers(), result);
        return result;
    }

    @Override
    public IUser getUser(@Nonnull final String userId) {
        if (IUmiUserManager.ANONYMOUS_USER_NAME.equals(userId)) {
            return new User(ANONYMOUS_USER_NAME);
        }
        final org.jresearch.commons.base.manager.api.obj.IUser user = getApplicationUser(userId);
        return user == null ? null : mapper.map(user, User.class);
    }

    // @Cacheable(cacheName = "users")
    private org.jresearch.commons.base.manager.api.obj.IUser getApplicationUser(final String userId) {
        try {
            return appUserManager.getUser(Long.valueOf(userId));
        } catch (final NumberFormatException e) {
            logger.warn("Try to get user with incorrect id: {}", userId, e); //$NON-NLS-1$
            return null;
        }
    }

    @Override
    public  T getAttributeValue(final String userId, final Object attributeId) throws UnknownUserException, ConnectionException {
        return get(getUserProfile(userId).getUserAttributes(), attributeId);
    }

    // TODO Stas String to  ?
    @SuppressWarnings({ "null", "unchecked" })
    private static  T get(final List userAttributes, final Object attributeId) {
        for (final IAttributeValue attribute : userAttributes) {
            if (attribute.getBusinessType().getId().equals(attributeId)) {
                return (T) attribute.getStringValue();
            }
        }
        return (T) null;
    }

    private IUserProfile getUserProfile(final String userId) throws UnknownUserException {
        try {
            return profileManager.getUserProfile(Long.valueOf(userId));
        } catch (final NumberFormatException e) {
            throw new UnknownUserException(userId);
        }
    }

    @Override
    public IUser authenticate(final IAuthenticationData authenticationData) throws UnsupportedAuthenticationMethodException, org.jresearch.flexess.umi.api.AuthenticationException {
        try {
            final org.jresearch.commons.base.manager.api.obj.IUser user = authenticateLocal(authenticationData);
            return user != null ? mapper.map(user, User.class) : null;
        } catch (final AuthenticationException e) {
            throw new org.jresearch.flexess.umi.api.AuthenticationException(e.getCause(), e.getLocalizedMessage());
        }
    }

    private org.jresearch.commons.base.manager.api.obj.IUser authenticateLocal(final IAuthenticationData data) throws UnsupportedAuthenticationMethodException, AuthenticationException {
        for (final IUserLocator locator : userLocators) {
            if (locator.canProcess(data)) {
                return locator.process(data);
            }
        }
        final String type = data.getAuthenticateObject() == null ? "null" : data.getAuthenticateObject().getClass().toString(); //$NON-NLS-1$
        throw new UnsupportedAuthenticationMethodException("Can''t autenticate user {0} against object of type {1}", data.getUserName(), type); //$NON-NLS-1$
    }

    public boolean checkPassword(final org.jresearch.commons.base.manager.api.obj.IUser user, final String password) throws UnsupportedAuthenticationMethodException {
        try {
            return appUserManager.checkPassword(user, password);
        } catch (final AuthenticationException e) {
            throw new UnsupportedAuthenticationMethodException(e);
        }
    }

    @Override
    public boolean supportsListing() throws ConnectionException {
        return true;
    }

    @Override
    public boolean supportsFiltering() throws ConnectionException {
        return false;
    }

    @Override
    public boolean supportsCounting() throws ConnectionException {
        return true;
    }

    @Override
    public Collection getUsers(final IListSettings settings) throws ConnectionException {
        final List result = new ArrayList<>();
        mapper.map(appUserManager.searchUsers(createFiler(settings)).getRecords(), result);
        return result;
    }

    private static UserFilter createFiler(final IListSettings settings) {
        final UserFilter filter = new UserFilter();
        filter.setFirstPosition(settings.getPosition().getFirst());
        filter.setPageSize(settings.getPosition().getPageSize());
        return filter;
    }

    @Override
    public long countUsers(final ISearchCriteria criteria) throws ConnectionException {
        throw new UnsupportedOperationException();
    }

    @Override
    public IConnectionStatus testConnection() {
        return initStatus;
    }

    @Override
    public boolean isResetEnable() {
        return true;
    }

    @Override
    public void reset(final IResetAuthenticationData resetAuthData) throws UmiException, UnsupportedAuthenticationMethodException, ResetAuthenticationException {
        final Long userId = getUser(resetAuthData);
        if (userId != null) {
            try {
                final String password = appUserManager.resetPassword(userId);
                final IMailTemplate template = mailTemplateManager.getMailTemplate(ISystemEvent.PASSWORD_RESET);
                if (template == null) {
                    logger.error("Can't reset a password. Mail template is not defined"); //$NON-NLS-1$
                } else {
                    final String subject = template.getSubject();
                    final String content = MessageFormat.format(template.getTemplate(), password);
                    mailService.sendMessage(getUserEmail(resetAuthData), subject, content);
                }
            } catch (final AuthenticationException e) {
                logger.error("Can't reset a password.", e); //$NON-NLS-1$
                throw new RuntimeException(e);
            } catch (final UserNotFoundException e) {
                logger.error("User if not found.", e); //$NON-NLS-1$
                throw new IllegalStateException(e);
            }
        }
    }

    private Long getUser(final IResetAuthenticationData resetAuthData) throws UmiException, ResetAuthenticationException {
        if (resetAuthData instanceof EmailResetAuthenticationData) {
            return getUserByEmail(((EmailResetAuthenticationData) resetAuthData).getEmail());
        }
        throw new UnsupportedAuthenticationMethodException("Can''t reset password for data of class {0}", resetAuthData.getClass()); //$NON-NLS-1$
    }

    private static String getUserEmail(final IResetAuthenticationData resetAuthData) throws UmiException {
        if (resetAuthData instanceof EmailResetAuthenticationData) {
            return ((EmailResetAuthenticationData) resetAuthData).getEmail();
        }
        throw new UnsupportedAuthenticationMethodException("Can''t reset password for data of class {0}", resetAuthData.getClass()); //$NON-NLS-1$
    }

    private Long getUserByEmail(final String email) throws ResetAuthenticationException {
        final org.jresearch.commons.base.manager.api.obj.IUser user = appUserManager.findUserByEmail(email);
        if (user == null) {
            throw new ResetAuthenticationException(MessageFormat.format("No user with email {0}", email)); //$NON-NLS-1$
        }
        return user.getId();
    }

    public void changeUserPassword(@Nonnull final Long userId, @Nonnull final String password) {
        try {
            appUserManager.setPassword(userId, password);
        } catch (final UserNotFoundException e) {
            logger.error("Some promblems with user manager: {}", e.getLocalizedMessage(), e); //$NON-NLS-1$
            throw new IllegalStateException(e);
        }
    }

    @Override
    public boolean isSignUpEnable() {
        return true;
    }

    @Override
    public void signUp(final ISignUpData signUpData) throws UmiException, UnsupportedAuthenticationMethodException {
        try {
            final org.jresearch.commons.base.manager.api.obj.IUser user = getUser(signUpData);
            final String password = appUserManager.resetPassword(user.getId());
            // FIXME (Stas): Update after BKN-165, BKN-166
            // IMailTemplate template =
            // mailTemplateManager.getMailTemplate(null,
            // IMailTemplate.PASSWORD_RESET);
            // String subject = template.getSubject();
            // String content = MessageFormat.format(template.getTemplate(),
            // password);
            final String subject = "Create user"; //$NON-NLS-1$
            final String content = MessageFormat.format("Create user with password {0}", password); //$NON-NLS-1$
            mailService.sendMessage(user.getEmail(), subject, content);
        } catch (final AuthenticationException e) {
            logger.error("Can't create user.", e); //$NON-NLS-1$
            throw new RuntimeException(e);
        } catch (final UserUpdateException e) {
            throw new UmiException(e);
        } catch (final UserNotFoundException e) {
            logger.error("User is not found.", e); //$NON-NLS-1$
            throw new IllegalStateException(e);
        }
    }

    private org.jresearch.commons.base.manager.api.obj.IUser getUser(final ISignUpData signUpData) throws UmiException, UserUpdateException {
        if (signUpData instanceof EmailSignUpData) {
            final String email = ((EmailSignUpData) signUpData).getEmail();
            return appUserManager.registerUser(email, email);
        }
        throw new UnsupportedAuthenticationMethodException("Can''t register new user with data of class {0}", signUpData.getClass()); //$NON-NLS-1$
    }

    //
    // ----------------- Spring setters ---------------------
    //

    /**
     * @param profileManager
     *            the profileManager to set
     */
    @Required
    public void setProfileManager(final IUserProfileManager profileManager) {
        this.profileManager = profileManager;
    }

    /**
     * @param mailTemplateManager
     *            the mailTemplateManager to set
     */
    @Required
    public void setMailTemplateManager(final IMailTemplateManager mailTemplateManager) {
        this.mailTemplateManager = mailTemplateManager;
    }

    /**
     * @param mailService
     *            the mailService to set
     */
    @Required
    public void setMailService(final IMailService mailService) {
        this.mailService = mailService;
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        userLocators = applicationContext.getBeansOfType(IUserLocator.class).values();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy