<commit_before>package gov.nih.nci.cabig.caaers.domain.repository;

import gov.nih.nci.cabig.caaers.CaaersNoSuchUserException;
import gov.nih.nci.cabig.caaers.CaaersSystemException;
import gov.nih.nci.cabig.caaers.dao.UserDao;
import gov.nih.nci.cabig.caaers.domain.Investigator;
import gov.nih.nci.cabig.caaers.domain.Organization;
import gov.nih.nci.cabig.caaers.domain.ResearchStaff;
import gov.nih.nci.cabig.caaers.domain.SiteInvestigator;
import gov.nih.nci.cabig.caaers.domain.User;
import gov.nih.nci.cabig.caaers.domain.UserGroupType;
import gov.nih.nci.security.UserProvisioningManager;
import gov.nih.nci.security.acegi.csm.authorization.CSMObjectIdGenerator;
import gov.nih.nci.security.authorization.domainobjects.Group;
import gov.nih.nci.security.dao.GroupSearchCriteria;
import gov.nih.nci.security.exceptions.CSObjectNotFoundException;
import gov.nih.nci.security.exceptions.CSTransactionException;
import gov.nih.nci.security.util.StringEncrypter;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class CSMUserRepositoryImpl implements CSMUserRepository {

    private UserProvisioningManager userProvisioningManager;
    private CSMObjectIdGenerator siteObjectIdGenerator;
    private MailSender mailSender;
    private SimpleMailMessage accountCreatedTemplateMessage;
    private String authenticationMode;
    private UserDao userDao;
    
    //private ResearchStaffDao researchStaffDao;
    //private InvestigatorDao investigatorDao;
    
    private Logger log = Logger.getLogger(CSMUserRepositoryImpl.class);

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, noRollbackFor = MailException.class)
    public void createOrUpdateCSMUserAndGroupsForResearchStaff(final ResearchStaff researchStaff, String changeURL) {
        gov.nih.nci.security.authorization.domainobjects.User csmUser = null;
        MailException mailException = null;
        
        try {
			if (researchStaff.getId() == null) {
			    csmUser = createCSMUser(researchStaff);
			    sendCreateAccountEmail(researchStaff, changeURL);
			} else {
			    csmUser = updateCSMUser(researchStaff);
			    sendUpdateAccountEmail(researchStaff);
			}
		} catch (MailException e) {
			mailException = e;
		}
        List<Organization> associatedOrgList = new ArrayList<Organization>();
        associatedOrgList.add(researchStaff.getOrganization());
        createCSMUserGroups(csmUser, researchStaff, associatedOrgList);
        if(mailException != null) throw mailException;
    }

    public void createOrUpdateCSMUserAndGroupsForInvestigator(Investigator investigator, String changeURL) {
    	gov.nih.nci.security.authorization.domainobjects.User csmUser = null;
    	MailException mailException = null;
    	
    	try {
			if(investigator.getId() == null){
				csmUser = createCSMUser(investigator);
				sendCreateAccountEmail(investigator, changeURL);
			}else{
				csmUser = updateCSMUser(investigator);
				sendUpdateAccountEmail(investigator);
			}
		} catch (MailException e) {
			mailException = e;
		}
    	List<Organization> associatedOrgList = new ArrayList<Organization>();
    	for(SiteInvestigator siteInv : investigator.getSiteInvestigatorsInternal()){
    		associatedOrgList.add(siteInv.getOrganization());
    	}
        createCSMUserGroups(csmUser, investigator, associatedOrgList);
        if(mailException != null) throw mailException;
    }
    
    private void createCSMUserGroups(final gov.nih.nci.security.authorization.domainobjects.User csmUser, final User user, List<Organization> allowedOrgs) {
        try {
            List<String> groupIds = new ArrayList<String>();
            for (UserGroupType group : user.getUserGroupTypes()) {
                groupIds.add(group.getCode().toString());
            }
            for(Organization org :  allowedOrgs){
            	String organizationGroupId = getGroupIdByName(siteObjectIdGenerator.generateId(org.getNciInstituteCode()));
                groupIds.add(organizationGroupId);
            }
            
            if (csmUser.getUserId() == null) {
                throw new CaaersSystemException("ID has not been assigned to CSM user.");
            }
            assignUserToGroup(String.valueOf(csmUser.getUserId()), groupIds.toArray(new String[groupIds.size()]));
        } catch (CSObjectNotFoundException e) {
            throw new CaaersSystemException("Could not assign user to organization group.", e);
        }
        log.debug("Successfully assigned user to organization");
    }

    private void copyUserToCSMUser(User user, gov.nih.nci.security.authorization.domainobjects.User csmUser) {
        String emailId = user.getEmailAddress();
        if (user.getLoginId() == null || user.getLoginId().trim().length() == 0) {
            csmUser.setLoginName(emailId);
        } else {
            csmUser.setLoginName(user.getLoginId());
        }
        csmUser.setEmailId(emailId);
        csmUser.setPhoneNumber(user.getPhoneNumber());
        csmUser.setFirstName(user.getFirstName());
        csmUser.setLastName(user.getLastName());
        // psc does not use these
        // do we really need this? csmUser.setOrganization(researchStaff.getOrganization().getName());
        // or this? csmUser.setOrganization(researchStaff.getOrganization().getNciInstituteCode());
    }

    private gov.nih.nci.security.authorization.domainobjects.User createCSMUser(final User user) {
        // assumes research staff id is null
        String loginId = user.getLoginId();
        gov.nih.nci.security.authorization.domainobjects.User csmUser;
        
    	csmUser = getCSMUserByName(loginId);
    	if(csmUser != null)  throw new CaaersSystemException("Couldn't add user: " + loginId + ": already exists.");
    	
    	//we can create a new user
    	csmUser = new gov.nih.nci.security.authorization.domainobjects.User();
        copyUserToCSMUser(user, csmUser);
        csmUser.setPassword(encryptString(user.getSalt() + "obscurity"));
        userCreateToken(user);
        //create a csm user
        try {
            userProvisioningManager.createUser(csmUser);
        } catch (CSTransactionException e2) {
        	log.error("Error creating csm user",e2);
            throw new CaaersSystemException("Could not create user", e2);
        }
        <commit_msg>CAAERS-2177<commit_after>package gov.nih.nci.cabig.caaers.domain.repository;

import gov.nih.nci.cabig.caaers.CaaersNoSuchUserException;
import gov.nih.nci.cabig.caaers.CaaersSystemException;
import gov.nih.nci.cabig.caaers.dao.UserDao;
import gov.nih.nci.cabig.caaers.domain.Investigator;
import gov.nih.nci.cabig.caaers.domain.Organization;
import gov.nih.nci.cabig.caaers.domain.ResearchStaff;
import gov.nih.nci.cabig.caaers.domain.SiteInvestigator;
import gov.nih.nci.cabig.caaers.domain.User;
import gov.nih.nci.cabig.caaers.domain.UserGroupType;
import gov.nih.nci.security.UserProvisioningManager;
import gov.nih.nci.security.acegi.csm.authorization.CSMObjectIdGenerator;
import gov.nih.nci.security.authorization.domainobjects.Group;
import gov.nih.nci.security.dao.GroupSearchCriteria;
import gov.nih.nci.security.exceptions.CSObjectNotFoundException;
import gov.nih.nci.security.exceptions.CSTransactionException;
import gov.nih.nci.security.util.StringEncrypter;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class CSMUserRepositoryImpl implements CSMUserRepository {

    private UserProvisioningManager userProvisioningManager;
    private CSMObjectIdGenerator siteObjectIdGenerator;
    private MailSender mailSender;
    private SimpleMailMessage accountCreatedTemplateMessage;
    private String authenticationMode;
    private UserDao userDao;
    
    //private ResearchStaffDao researchStaffDao;
    //private InvestigatorDao investigatorDao;
    
    private Logger log = Logger.getLogger(CSMUserRepositoryImpl.class);

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, noRollbackFor = MailException.class)
    public void createOrUpdateCSMUserAndGroupsForResearchStaff(final ResearchStaff researchStaff, String changeURL) {
        gov.nih.nci.security.authorization.domainobjects.User csmUser = null;
        MailException mailException = null;
        
        try {
			if (researchStaff.getId() == null) {
			    csmUser = createCSMUser(researchStaff);
			    sendCreateAccountEmail(researchStaff, changeURL);
			} else {
			    csmUser = updateCSMUser(researchStaff);
			    sendUpdateAccountEmail(researchStaff);
			}
		} catch (MailException e) {
			mailException = e;
		}
        List<Organization> associatedOrgList = new ArrayList<Organization>();
        associatedOrgList.add(researchStaff.getOrganization());
        createCSMUserGroups(csmUser, researchStaff, associatedOrgList);
        if(mailException != null) throw mailException;
    }

    public void createOrUpdateCSMUserAndGroupsForInvestigator(Investigator investigator, String changeURL) {
    	gov.nih.nci.security.authorization.domainobjects.User csmUser = null;
    	MailException mailException = null;
    	
    	try {
			if(investigator.getId() == null){
				csmUser = createCSMUser(investigator);
				sendCreateAccountEmail(investigator, changeURL);
			}else{
				csmUser = updateCSMUser(investigator);
				sendUpdateAccountEmail(investigator);
			}
		} catch (MailException e) {
			mailException = e;
		}
    	List<Organization> associatedOrgList = new ArrayList<Organization>();
    	for(SiteInvestigator siteInv : investigator.getSiteInvestigatorsInternal()){
    		associatedOrgList.add(siteInv.getOrganization());
    	}
        createCSMUserGroups(csmUser, investigator, associatedOrgList);
        if(mailException != null) throw mailException;
    }
    
    private void createCSMUserGroups(final gov.nih.nci.security.authorization.domainobjects.User csmUser, final User user, List<Organization> allowedOrgs) {
        try {
            List<String> groupIds = new ArrayList<String>();
            for (UserGroupType group : user.getUserGroupTypes()) {
                groupIds.add(group.getCode().toString());
            }
            for(Organization org :  allowedOrgs){
            	String organizationGroupId = getGroupIdByName(siteObjectIdGenerator.generateId(org.getNciInstituteCode()));
                groupIds.add(organizationGroupId);
            }
            
            if (csmUser.getUserId() == null) {
                throw new CaaersSystemException("ID has not been assigned to CSM user.");
            }
            assignUserToGroup(String.valueOf(csmUser.getUserId()), groupIds.toArray(new String[groupIds.size()]));
        } catch (CSObjectNotFoundException e) {
            throw new CaaersSystemException("Could not assign user to organization group.", e);
        }
        log.debug("Successfully assigned user to organization");
    }

    private void copyUserToCSMUser(User user, gov.nih.nci.security.authorization.domainobjects.User csmUser) {
        String emailId = user.getEmailAddress();
        if (user.getLoginId() == null || user.getLoginId().trim().length() == 0) {
            csmUser.setLoginName(emailId);
        } else {
            csmUser.setLoginName(user.getLoginId());
        }
        csmUser.setEmailId(emailId);
// this line is causing issues, the CSM_USER table has the phone length as 15 chars, and the phone can be wider, as it can have spaces and extension        
//        csmUser.setPhoneNumber(user.getPhoneNumber());
        csmUser.setFirstName(user.getFirstName());
        csmUser.setLastName(user.getLastName());
        // psc does not use these
        // do we really need this? csmUser.setOrganization(researchStaff.getOrganization().getName());
        // or this? csmUser.setOrganization(researchStaff.getOrganization().getNciInstituteCode());
    }

    private gov.nih.nci.security.authorization.domainobjects.User createCSMUser(final User user) {
        // assumes research staff id is null
        String loginId = user.getLoginId();
        gov.nih.nci.security.authorization.domainobjects.User csmUser;
        
    	csmUser = getCSMUserByName(loginId);
    	if(csmUser != null)  throw new CaaersSystemException("Couldn't add user: " + loginId + ": already exists.");
    	
    	//we can create a new user
    	csmUser = new gov.nih.nci.security.authorization.domainobjects.User();
        copyUserToCSMUser(user, csmUser);
        csmUser.setPassword(encryptString(user.getSalt() + "obscurity"));
        userCreateToken(user);
        //create a csm user
        try {
            userProvisioningManager.createUser(csmUser);
        } catch (CSTransactionException e2) {
        	log.error("Error creating csm user",e2);
            throw new CaaersSystemException("Could not create user", e2);
        }
        
{'fraction_non_alphanumeric': 0.09796335498941529, 'fraction_numerical': 0.001167968464851449, 'mean_word_length': 3.6424940698068453, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6992677', 'n_tokens_mistral': 4197, 'n_tokens_neox': 4011, 'n_words': 712}