<commit_before>package imcode.server.user;

import imcode.server.ImcmsConstants;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;

import java.util.Arrays;
import java.util.HashSet;

public class ExternalizedImcmsAuthenticatorAndUserRegistry implements UserAndRoleRegistry, Authenticator {

    private ImcmsAuthenticatorAndUserAndRoleMapper imcmsAuthenticatorAndUserMapperAndRole;
    private Authenticator externalAuthenticator;
    private UserAndRoleRegistry externalUserRegistry;
    private String defaultLanguage;

    private Logger log = Logger.getLogger( ExternalizedImcmsAuthenticatorAndUserRegistry.class );

    public ExternalizedImcmsAuthenticatorAndUserRegistry( ImcmsAuthenticatorAndUserAndRoleMapper imcmsAndRole,
                                                          Authenticator externalAuthenticator,
                                                          UserAndRoleRegistry externalUserRegistry,
                                                          String defaultLanguage ) throws IllegalArgumentException {
        if ( ( null == externalAuthenticator ) != ( null == externalUserRegistry ) ) {
            throw new IllegalArgumentException( "External authenticator and external usermapper should both be either set or not set." );
        }

        this.imcmsAuthenticatorAndUserMapperAndRole = imcmsAndRole;
        this.externalAuthenticator = externalAuthenticator;
        this.externalUserRegistry = externalUserRegistry;
        this.defaultLanguage = defaultLanguage;
    }

    public void synchRolesWithExternal() {
        if ( null != externalUserRegistry ) {
            String[] externalRoleNames = externalUserRegistry.getAllRoleNames();
            imcmsAuthenticatorAndUserMapperAndRole.addRoleNames( externalRoleNames );
        }
    }

    public boolean authenticate( String loginName, String password ) {
        NDC.push( "authenticate" );
        boolean userAuthenticatesInImcms = false;
        if ( password.length() >= ImcmsConstants.PASSWORD_MINIMUM_LENGTH ) {
            userAuthenticatesInImcms = imcmsAuthenticatorAndUserMapperAndRole.authenticate( loginName, password );
        }
        boolean userAuthenticatesInExternal = false;
        if ( !userAuthenticatesInImcms && null != externalAuthenticator && password.length() > 0 ) {
            userAuthenticatesInExternal = externalAuthenticator.authenticate( loginName, password );
        }
        NDC.pop();
        return userAuthenticatesInImcms || userAuthenticatesInExternal;
    }

    public UserDomainObject getUser( String loginName ) {
        NDC.push( "getUser" );
        UserDomainObject imcmsUser = imcmsAuthenticatorAndUserMapperAndRole.getUser( loginName );
        boolean imcmsUserExists = null != imcmsUser;
        boolean imcmsUserIsInternal = imcmsUserExists && !imcmsUser.isImcmsExternal();
        UserDomainObject result;

        if ( imcmsUserIsInternal ) {
            result = imcmsUser;
        } else {
            result = getExternalUser( loginName, imcmsUserExists, imcmsUser );
        }
        NDC.pop();
        return result;
    }

    private UserDomainObject getExternalUser( String loginName, boolean imcmsUserExists, UserDomainObject imcmsUser ) {
        UserDomainObject result;
        UserDomainObject externalUser = getUserFromOtherUserMapper( loginName );
        boolean externalUserExists = null != externalUser;

        if ( externalUserExists ) {
            result = synchExternalUserInImcms( loginName, externalUser, imcmsUserExists );
        } else {
            if ( imcmsUserExists ) {
                deactivateExternalUserInImcms( loginName, imcmsUser );
            }
            result = null;
        }
        return result;
    }

    private UserDomainObject getUserFromOtherUserMapper( String loginName ) {
        UserDomainObject result = null;
        if ( null != externalUserRegistry ) {
            result = externalUserRegistry.getUser( loginName );
        }
        if ( null != result && null == result.getLanguageIso639_2() ) {
            result.setLanguageIso639_2( defaultLanguage );
        }
        return result;
    }

    private UserDomainObject synchExternalUserInImcms( String loginName, UserDomainObject externalUser,
                                                       boolean imcmsUserExists ) {
        externalUser.setImcmsExternal( true );

        if ( imcmsUserExists ) {
            imcmsAuthenticatorAndUserMapperAndRole.saveUser( loginName, externalUser, null );
        } else {
            imcmsAuthenticatorAndUserMapperAndRole.addUser( externalUser, null );
        }
        addExternalRolesToUser( externalUser );
        imcmsAuthenticatorAndUserMapperAndRole.sqlUpdateUserRoles( externalUser );

        return imcmsAuthenticatorAndUserMapperAndRole.getUser( loginName );
    }

    private void addExternalRolesToUser( UserDomainObject user ) {
        String[] externalRoleNames = externalUserRegistry.getRoleNames( user );
        for ( int i = 0; i < externalRoleNames.length; i++ ) {
            String externalRoleName = externalRoleNames[i];
            RoleDomainObject externalRole = imcmsAuthenticatorAndUserMapperAndRole.getRoleByName( externalRoleName );
            if ( null == externalRole ) {
                externalRole = imcmsAuthenticatorAndUserMapperAndRole.addRole( externalRoleName );
            }
            if ( !externalRole.isAdminRole() ) {
                user.addRole( externalRole );
            }
        }
    }

    private void deactivateExternalUserInImcms( String loginName, UserDomainObject imcmsUser ) {
        imcmsUser.setActive( false );
        imcmsAuthenticatorAndUserMapperAndRole.saveUser( loginName, imcmsUser, null );
    }

    public String[] getRoleNames( UserDomainObject user ) {
        String[] imcmsRoleNames = imcmsAuthenticatorAndUserMapperAndRole.getRoleNames( user );
        String[] externalRoleNames = externalUserRegistry.getRoleNames( user );

        String[] result = mergeAndDeleteDuplicates( imcmsRoleNames, externalRoleNames );
        log.debug( "Roles from imcms and external: " + Arrays.asList( result ) );<commit_msg>Bug 2870: Fixed synch of roles for external users.<commit_after>package imcode.server.user;

import imcode.server.ImcmsConstants;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;

import java.util.Arrays;
import java.util.HashSet;

public class ExternalizedImcmsAuthenticatorAndUserRegistry implements UserAndRoleRegistry, Authenticator {

    private ImcmsAuthenticatorAndUserAndRoleMapper imcmsAuthenticatorAndUserMapperAndRole;
    private Authenticator externalAuthenticator;
    private UserAndRoleRegistry externalUserRegistry;
    private String defaultLanguage;

    private Logger log = Logger.getLogger( ExternalizedImcmsAuthenticatorAndUserRegistry.class );

    public ExternalizedImcmsAuthenticatorAndUserRegistry( ImcmsAuthenticatorAndUserAndRoleMapper imcmsAndRole,
                                                          Authenticator externalAuthenticator,
                                                          UserAndRoleRegistry externalUserRegistry,
                                                          String defaultLanguage ) throws IllegalArgumentException {
        if ( ( null == externalAuthenticator ) != ( null == externalUserRegistry ) ) {
            throw new IllegalArgumentException( "External authenticator and external usermapper should both be either set or not set." );
        }

        this.imcmsAuthenticatorAndUserMapperAndRole = imcmsAndRole;
        this.externalAuthenticator = externalAuthenticator;
        this.externalUserRegistry = externalUserRegistry;
        this.defaultLanguage = defaultLanguage;
    }

    public void synchRolesWithExternal() {
        if ( null != externalUserRegistry ) {
            String[] externalRoleNames = externalUserRegistry.getAllRoleNames();
            imcmsAuthenticatorAndUserMapperAndRole.addRoleNames( externalRoleNames );
        }
    }

    public boolean authenticate( String loginName, String password ) {
        NDC.push( "authenticate" );
        boolean userAuthenticatesInImcms = false;
        if ( password.length() >= ImcmsConstants.PASSWORD_MINIMUM_LENGTH ) {
            userAuthenticatesInImcms = imcmsAuthenticatorAndUserMapperAndRole.authenticate( loginName, password );
        }
        boolean userAuthenticatesInExternal = false;
        if ( !userAuthenticatesInImcms && null != externalAuthenticator && password.length() > 0 ) {
            userAuthenticatesInExternal = externalAuthenticator.authenticate( loginName, password );
        }
        NDC.pop();
        return userAuthenticatesInImcms || userAuthenticatesInExternal;
    }

    public UserDomainObject getUser( String loginName ) {
        NDC.push( "getUser" );
        UserDomainObject imcmsUser = imcmsAuthenticatorAndUserMapperAndRole.getUser( loginName );
        boolean imcmsUserExists = null != imcmsUser;
        boolean imcmsUserIsInternal = imcmsUserExists && !imcmsUser.isImcmsExternal();
        UserDomainObject result;

        if ( imcmsUserIsInternal ) {
            result = imcmsUser;
        } else {
            result = getExternalUser( loginName, imcmsUser );
        }
        NDC.pop();
        return result;
    }

    private UserDomainObject getExternalUser( String loginName, UserDomainObject imcmsUser ) {
        UserDomainObject result;
        UserDomainObject externalUser = getUserFromOtherUserMapper( loginName );
        boolean externalUserExists = null != externalUser;

        if ( externalUserExists ) {
            result = synchExternalUserInImcms( loginName, externalUser, imcmsUser );
        } else {
            if ( null != imcmsUser ) {
                deactivateExternalUserInImcms( loginName, imcmsUser );
            }
            result = null;
        }
        return result;
    }

    private UserDomainObject getUserFromOtherUserMapper( String loginName ) {
        UserDomainObject result = null;
        if ( null != externalUserRegistry ) {
            result = externalUserRegistry.getUser( loginName );
        }
        if ( null != result && null == result.getLanguageIso639_2() ) {
            result.setLanguageIso639_2( defaultLanguage );
        }
        return result;
    }

    private UserDomainObject synchExternalUserInImcms( String loginName, UserDomainObject externalUser,
                                                       UserDomainObject imcmsUser ) {
        externalUser.setImcmsExternal( true );
        addExternalRolesToUser( externalUser );

        if ( null != imcmsUser ) {
            externalUser.setRoles( imcmsUser.getRoles() );
            imcmsAuthenticatorAndUserMapperAndRole.saveUser( loginName, externalUser, null );
        } else {
            imcmsAuthenticatorAndUserMapperAndRole.addUser( externalUser, null );
        }

        return imcmsAuthenticatorAndUserMapperAndRole.getUser( loginName );
    }

    private void addExternalRolesToUser( UserDomainObject user ) {
        String[] externalRoleNames = externalUserRegistry.getRoleNames( user );
        for ( int i = 0; i < externalRoleNames.length; i++ ) {
            String externalRoleName = externalRoleNames[i];
            RoleDomainObject externalRole = imcmsAuthenticatorAndUserMapperAndRole.getRoleByName( externalRoleName );
            if ( null == externalRole ) {
                externalRole = imcmsAuthenticatorAndUserMapperAndRole.addRole( externalRoleName );
            }
            if ( !externalRole.isAdminRole() ) {
                user.addRole( externalRole );
            }
        }
    }

    private void deactivateExternalUserInImcms( String loginName, UserDomainObject imcmsUser ) {
        imcmsUser.setActive( false );
        imcmsAuthenticatorAndUserMapperAndRole.saveUser( loginName, imcmsUser, null );
    }

    public String[] getRoleNames( UserDomainObject user ) {
        String[] imcmsRoleNames = imcmsAuthenticatorAndUserMapperAndRole.getRoleNames( user );
        String[] externalRoleNames = externalUserRegistry.getRoleNames( user );

        String[] result = mergeAndDeleteDuplicates( imcmsRoleNames, externalRoleNames );
        log.debug( "Roles from imcms and external: " + Arrays.asList( result ) );
{'fraction_non_alphanumeric': 0.068681766335343, 'fraction_numerical': 0.0022812449079354733, 'mean_word_length': 2.735544735240414, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3144012', 'n_tokens_mistral': 3186, 'n_tokens_neox': 3008, 'n_words': 639}