package cz.muni.fi.rtc.teacherWorkbench.importer;
import java.util.Collection;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
import com.ibm.team.repository.client.IContributorManager;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.internal.TeamRepository;
import com.ibm.team.repository.common.IContributor;
import com.ibm.team.repository.common.IDefaultLicenseProviderService;
import com.ibm.team.repository.common.ILicenseAdminService;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.novell.ldap.LDAPAttribute;
import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPModification;
import cz.muni.fi.rtc.teacherWorkbench.importer.exceptions.ConfigurationException;
import cz.muni.fi.rtc.teacherWorkbench.importer.exceptions.ImporterException;
import cz.muni.fi.rtc.teacherWorkbench.model.ImportedPerson;
/**
* Class for importing people into LDAP and RTC
* @author Jan Stastny
*/
public class PeopleImporter {
private ImporterConfiguration configuration;
/**
* Connection established by getLdapConnection called by init()
*/
private LDAPConnection connection = null;
/**
* Connection established by getRepositoryConnection called by init()
*/
private ITeamRepository repo = null;
private Log log = LogFactory
.getLog(cz.muni.fi.rtc.teacherWorkbench.importer.PeopleImporter.class);
private IProgressMonitor monitor = LogProgressMonitor.getInstance();
/**
* Constructs new Importer using the configuration passed as argument
*
* @param conf
* Configuration of the importer
* @throws ImporterException If the configuration values are not correct or connection to some services fails
*/
public PeopleImporter(ImporterConfiguration conf) throws ImporterException {
this.configuration = conf;
init();
}
/**
* Initialize the instance
* @throws ImporterException rethrown from called methods.
*/
private void init() throws ImporterException {
this.connection = Utils.establishLdapConnection(configuration);
this.repo = Utils.establishRepositoryConnection(configuration);
}
/**
* Inserts the users to the LDAP database and creates their account in RTC
* assigning them default licence. LDAP exceptions are not thrown but logger
* as ERROR instead.
*
* Mandatory configuration fields: ldapGroupPeople, ldapGroupJazzUsers
*
* Mandatory user fields:
*
* - UID
*
- email
*
- firstName (can be empty but not null)
*
- lastName
*
- description (can be empty but not null)
*
*
* @param users
* @throws ImporterException
* Thrown when: - Class not configured correctly - Mandatory
* fields of some users are not filled (checked before writting
* to LDAP -- atomic fail)
*/
public void importUsers(Collection users) throws ImporterException {
if (configuration.getLdapGroupPeople() == null) {
throw new ConfigurationException("ldapGroupPeople not configured");
}
if (configuration.getLdapGroupJazzUsers() == null) {
throw new ConfigurationException("LdapGroupJazzUsers not configured");
}
for (ImportedPerson person : users) {
if (person.getUID() == null || person.getUID().equals("")) {
throw new ImporterException("Person " + person
+ " is missing UID", new IllegalArgumentException(person.toString()));
}
if (person.getRawPassword() == null || person.getRawPassword().equals("")) {
throw new ImporterException("Person " + person
+ " is missing rawPassword", new IllegalArgumentException(person.toString()));
}
if (person.getEmailAddress() == null
|| person.getEmailAddress().equals("")) {
throw new ImporterException("Person " + person
+ " is missing email address", new IllegalArgumentException(person.toString()));
}
if (person.getFirstName() == null) {
throw new ImporterException("Person " + person
+ " is missing first name", new IllegalArgumentException(person.toString()));
}
if (person.getLastName() == null || person.getLastName().equals("")) {
throw new ImporterException("Person " + person
+ " is missing last name", new IllegalArgumentException(person.toString()));
}
if (person.getDescription() == null) {
throw new ImporterException("Person " + person
+ " is missing description", new IllegalArgumentException(person.toString()));
}
}
Random random = new Random();
for (ImportedPerson person : users) {
try {
// Import into LDAP
LDAPAttributeSet attributeSet = new LDAPAttributeSet();
attributeSet.add(new LDAPAttribute("uid", person.getUID()));
attributeSet.add(new LDAPAttribute("sn", person.getLastName()));
attributeSet.add(new LDAPAttribute("cn", person.getFirstName()
+ " " + person.getLastName()));
PasswordEncoder passEncoder = new LdapShaPasswordEncoder();
byte[] salt = {};
random.nextBytes(salt);
String saltedPassword = passEncoder.encodePassword(person
.getRawPassword(), salt);
attributeSet.add(new LDAPAttribute("userPassword",
saltedPassword));
attributeSet.add(new LDAPAttribute("description", person
.getDescription()));
attributeSet.add(new LDAPAttribute("mail", person
.getEmailAddress()));
attributeSet.add(new LDAPAttribute("objectClass",
"inetOrgPerson"));
String dn = "uid=" + person.getUID() + ","
+ configuration.getLdapGroupPeople();
connection.add(new LDAPEntry(dn, attributeSet));
LDAPModification mod = new LDAPModification(
LDAPModification.ADD, new LDAPAttribute("member", dn));
connection.modify(
configuration.getLdapGroupJazzUsers(), mod);
log.info("Created LDAP user " + person.getUID());
// Import into RTC
IContributorManager conManager = repo.contributorManager();
IContributor contributor = (IContributor) IContributor.ITEM_TYPE.createItem();
contributor.setUserId(person.getUID());
contributor.setName(person.getFirstName() + " " + person.getLastName());
contributor.setEmailAddress(person.getEmailAddress());
IContributor newContributor = conManager.saveContributor(contributor, monitor);
// assign license to the newly created contributor
assignDefaultLicense(newContributor, getDefaultLicenseId());
log.info("Created RTC user " + person.getUID());
} catch (LDAPException e) {
log.error("Error executing LDAP", e);
} catch (TeamRepositoryException e) {
log.error("Error adding user to RTC", e);
}
}
}
private void assignDefaultLicense(IContributor contributor, String licenseId) {
if (licenseId == null) {
// default license id not specified.
log.error("Licence id is null");
return;
}
try {
ILicenseAdminService adminService = (ILicenseAdminService) ((TeamRepository)repo).getServiceInterface(ILicenseAdminService.class);
adminService.assignLicense(contributor, licenseId);
} catch (TeamRepositoryException e) {
//logErrorAssigningLicense(contributor, licenseId, e);
log.error("Failed assigning licence to contributor "+contributor, e);
}
}
private String getDefaultLicenseId() {
try {
IDefaultLicenseProviderService defaultLicenseProviderService = (IDefaultLicenseProviderService) ((TeamRepository)repo).getServiceInterface(IDefaultLicenseProviderService.class);
String licenseId = defaultLicenseProviderService.getDefaultLicenseId();
return licenseId;
} catch (Exception e) {
// log error
log.error("Error fetching default licence", e);
return null;
}
}
}