blob: d0d2e666e0c5a599fef778d41e17570bb8d66540 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
******************************************************************************/
package org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport;
import java.util.ArrayList;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.eclipse.emf.emfstore.client.model.util.WorkspaceUtil;
import org.eclipse.emf.emfstore.server.model.accesscontrol.ACOrgUnit;
import org.eclipse.emf.emfstore.server.model.accesscontrol.AccesscontrolFactory;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Shell;
/**
* @author deser
*/
public class LdapImportSource extends ImportSource {
private static final String DEFAULT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
/**
* A constant for setting the LDAP base property.
*/
public static final String LDAP_BASE = "ldapbase";
private DirContext dirContext;
private String[] attrSet = new String[] { "objectclass", "cn", "uid" };
// This strings decide whether an ldap-entry is a person, a group or none of
// both.
// Maybe we should change the access to public and implement a setter,
// because in this way
// one could easily let the user define what has to be considered as a
// person and what as a group.
private String personObjectClass = "inetOrgPerson";
private String groupObjectClass = "posixGroup";
private Properties properties;
/**
* Simple class for a LDAP-connection to import users and groups.
*/
public LdapImportSource() {
}
/**
* @see org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport.ImportSource#init(org.eclipse.swt.widgets.Shell)
* @param shell
* the shell
* @return whether the initialization was successful or not (e.g. pressing
* cancel on choosing the source)
*/
@Override
public boolean init(Shell shell) {
LdapSourceDialog dialog = new LdapSourceDialog(shell, this);
dialog.setBlockOnOpen(true);
dialog.create();
dialog.open();
return dialog.getIsInitFinished();
}
/**
* @see org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport.ImportSource#getLabel()
* @return a small label which indicates that this is an import from an LDAP
* server.
*/
@Override
public String getLabel() {
return "LDAP Import";
}
/**
* Returns the children of a given object (which is of the type
* ImportItemWrapper in this case). One special thing about this method is,
* that it does not only return the children objects, but also sets the
* correct reference (the children) of the given object. This is important
* as otherwise displaying the items on a TreeViewer correctly would fail,
* as the getParent()-method wouldn't return the right result.
*
* @see org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport.ImportSource#getChildren(java.lang.Object)
* @param arg0
* the object to get the children from.
* @return the children, which have the correct references to their parent
* (the given object).
*/
@Override
public Object[] getChildren(Object arg0) {
// This method-chaining is necessary! Why? Otherwise the reference to
// the given object (arg0) wouldn't be
// available when the ContentProvider (ImportSource in our case) calls
// his getParent()-method.
return setChildOrgUnits(arg0).getChildOrgUnits().toArray();
}
private ImportItemWrapper setChildOrgUnits(Object arg0) {
try {
ImportItemWrapper wrappedObject = (ImportItemWrapper) arg0;
String str = (String) wrappedObject.getSourceObj();
NamingEnumeration<NameClassPair> list = dirContext.list(str);
ArrayList<ImportItemWrapper> arrayList = new ArrayList<ImportItemWrapper>();
while (list.hasMore()) {
String nameInNamespace = list.next().getNameInNamespace();
Attributes attr = new BasicAttributes();
try {
attr = this.dirContext.getAttributes(nameInNamespace, attrSet);
} catch (NamingException exc) {
// do nothing at all, attributes couldn't be fetched
}
ACOrgUnit orgUnit;
Attribute objectclasses = attr.get("objectclass");
if (isGroup(objectclasses)) {
orgUnit = AccesscontrolFactory.eINSTANCE.createACGroup();
orgUnit.setName((String) attr.get("cn").get());
} else if (isPerson(objectclasses)) {
orgUnit = AccesscontrolFactory.eINSTANCE.createACUser();
// if we can't get "uid", we take "cn" instead.
String username = attr.get("uid") != null ? (String) attr.get("uid").get() : (String) attr
.get("cn").get();
orgUnit.setName(username);
} else {
orgUnit = AccesscontrolFactory.eINSTANCE.createACOrgUnit();
if (attr.get("cn") != null) {
orgUnit.setName((String) attr.get("cn").get());
} else {
orgUnit.setName(nameInNamespace);
}
}
// Here we set the parent object of every child we add. We
// couldn't do this in the getChildren-method,
// because in this case we would lose the wrappedObject - it
// would vanish, as it is just a parameter!
arrayList.add(new ImportItemWrapper(nameInNamespace, orgUnit, wrappedObject));
}
wrappedObject.setChildOrgUnits(arrayList);
// As we return the wrapped object, it still exists, when
// getParent() of ImportSource is called.
return wrappedObject;
} catch (NamingException e) {
WorkspaceUtil.logException(e.getMessage(), e);
}
return null;
}
/**
* @see org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport.ImportSource#getElements(java.lang.Object)
* @param arg0
* object to get the basic elements from.
* @return the root elements.
*/
@Override
public Object[] getElements(Object arg0) {
try {
NamingEnumeration<NameClassPair> list = dirContext.list(properties.getProperty(LdapImportSource.LDAP_BASE));
ArrayList<ImportItemWrapper> arrayList = new ArrayList<ImportItemWrapper>();
while (list.hasMore()) {
String nameInNamespace = list.next().getNameInNamespace();
Attributes attr = this.dirContext.getAttributes(nameInNamespace, attrSet);
ACOrgUnit orgUnit;
Attribute objectclasses = attr.get("objectclass");
if (isGroup(objectclasses)) {
orgUnit = AccesscontrolFactory.eINSTANCE.createACGroup();
orgUnit.setName((String) attr.get("cn").get());
} else if (isPerson(objectclasses)) { // if we got a user
orgUnit = AccesscontrolFactory.eINSTANCE.createACUser();
// if we can't get "uid", we take "cn" instead.
String username = attr.get("uid") != null ? (String) attr.get("uid").get() : (String) attr
.get("cn").get();
orgUnit.setName(username);
} else {
orgUnit = AccesscontrolFactory.eINSTANCE.createACOrgUnit();
if (attr.get("cn") != null) {
orgUnit.setName((String) attr.get("cn").get());
} else {
orgUnit.setName(nameInNamespace);
}
}
arrayList.add(new ImportItemWrapper(nameInNamespace, orgUnit));
}
return arrayList.toArray();
} catch (NamingException e) {
WorkspaceUtil.logException(e.getMessage(), e);
}
return null;
}
private boolean isGroup(Attribute objectclasses) throws NamingException {
if (objectclasses == null) {
return false;
}
for (int i = 0; i < objectclasses.size(); i++) {
if (((String) objectclasses.get(i)).equals(this.groupObjectClass)) {
return true;
}
}
return false;
}
private boolean isPerson(Attribute objectclasses) throws NamingException {
if (objectclasses == null) {
return false;
}
for (int i = 0; i < objectclasses.size(); i++) {
if (((String) objectclasses.get(i)).equals(this.personObjectClass)) {
return true;
}
}
return false;
}
/**
* @param list
* a NamingEnumeration, that should be converted into an
* ArrayList
* @return an ArrayList of the given NamingEnumeration
* @throws NamingException
* throws an exception
*/
public ArrayList<NameClassPair> namingEnumerationToArrayList(NamingEnumeration<NameClassPair> list)
throws NamingException {
ArrayList<NameClassPair> arrayList = new ArrayList<NameClassPair>();
while (list.hasMore()) {
arrayList.add(list.next());
}
return arrayList;
}
/**
* @param serverProperties
* The properties of the LDAP server.
*/
public void setProperties(Properties serverProperties) {
this.properties = serverProperties;
}
/**
* Initializes the connection to the LDAP server, using the properties
* field.
*
* @throws CorruptedSourceException
* if no connection could be established to the given server.
*/
public void connect() throws CorruptedSourceException {
properties.put("java.naming.ldap.version", "3");
properties.put(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_CTX);
// Create the connection to the LDAP-server
// (Each time an initial context is created, a new LDAP connection is
// created)
try {
dirContext = new InitialDirContext(properties);
} catch (NamingException e) {
WorkspaceUtil.logWarning(e.getMessage(), e);
throw new CorruptedSourceException("Couldn't connect to server!");
}
}
/**
* @return a small description of the LDAP import source (server, base)
* @see org.eclipse.emf.emfstore.client.ui.views.emfstorebrowser.dialogs.admin.acimport.ImportSource#getMessage()
*/
@Override
public String getMessage() {
return "Import from " + properties.getProperty(Context.PROVIDER_URL) + " with base: "
+ properties.getProperty(LDAP_BASE);
}
/**
* Disposes any created resources.
*/
public void dispose() {
// Nothing to dispose
}
/**
* Called when the input changes.
*
* @param arg0
* the viewer
* @param arg1
* the old input
* @param arg2
* the new input
*/
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
// Nothing to change
}
}