Package org.openengsb.core.services.internal.security.ldap

Source Code of org.openengsb.core.services.internal.security.ldap.UserDataManagerLdap

/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.openengsb.core.services.internal.security.ldap;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.name.Dn;
import org.openengsb.core.api.security.model.Permission;
import org.openengsb.core.api.security.service.NoSuchAttributeException;
import org.openengsb.core.api.security.service.NoSuchCredentialsException;
import org.openengsb.core.api.security.service.PermissionSetAlreadyExistsException;
import org.openengsb.core.api.security.service.PermissionSetNotFoundException;
import org.openengsb.core.api.security.service.UserDataManager;
import org.openengsb.core.api.security.service.UserExistsException;
import org.openengsb.core.api.security.service.UserNotFoundException;
import org.openengsb.core.services.internal.security.EntryUtils;
import org.openengsb.core.services.internal.security.PermissionUtils;
import org.openengsb.core.services.internal.security.model.EntryElement;
import org.openengsb.core.services.internal.security.model.EntryValue;
import org.openengsb.core.services.internal.security.model.PermissionData;
import org.openengsb.core.util.CollectionUtilsExtended;
import org.openengsb.infrastructure.ldap.EntryAlreadyExistsException;
import org.openengsb.infrastructure.ldap.InconsistentDITException;
import org.openengsb.infrastructure.ldap.LdapDao;
import org.openengsb.infrastructure.ldap.MissingParentException;
import org.openengsb.infrastructure.ldap.NoSuchNodeException;
import org.openengsb.infrastructure.ldap.model.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;

public class UserDataManagerLdap implements UserDataManager {

    private LdapDao dao;

    private static final Logger LOGGER = LoggerFactory.getLogger(UserDataManagerLdap.class);

    public void setLdapDao(LdapDao dao) {
        this.dao = dao;
    }

    public LdapDao getDao() {
        return dao;
    }

    @Override
    public String getPermissionSetAttribute(String permissionSet, String attributename)
        throws PermissionSetNotFoundException, NoSuchAttributeException {
        Dn dn = SchemaConstants.globalPermissionSetAttribute(permissionSet, attributename);
        Entry entry;
        try {
            entry = dao.lookup(dn);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        } catch (NoSuchNodeException e) {
            throw new NoSuchAttributeException(attributename);
        }
        return LdapUtils.extractAttributeEmptyCheck(entry, SchemaConstants.STRING_ATTRIBUTE);
    }

    @Override
    public void setPermissionSetAttribute(String permissionSet, String attributename, String value)
        throws PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouGlobalPermissionSetAttributes(permissionSet);
        Entry entry = EntryFactory.namedDescriptiveObject(attributename, value, parent);
        try {
            dao.storeOverwriteExisting(entry);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        }
    }

    @Override
    public Collection<String> getPermissionSetList() {
        Dn parent = SchemaConstants.ouGlobalPermissionSets();
        List<Entry> entries;
        try {
            entries = dao.getDirectChildren(parent);
        } catch (InconsistentDITException e) {
            throw new LdapRuntimeException(e);
        }
        return LdapUtils.extractAttributeEmptyCheck(entries, SchemaConstants.CN_ATTRIBUTE);
    }

    @Override
    public Collection<String> getPermissionSetsFromPermissionSet(String permissionSet)
        throws PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouGlobalPermissionSetChildren(permissionSet);
        List<Entry> entries;
        try {
            entries = dao.getDirectChildren(parent);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
        TimebasedOrderFilter.sortById(entries);
        return LdapUtils.extractAttributeEmptyCheck(entries, SchemaConstants.CN_ATTRIBUTE);
    }

    @Override
    public Collection<String> getPermissionSetsFromUser(String username) throws UserNotFoundException {
        Dn parent = SchemaConstants.ouUserPermissionSets(username);
        List<Entry> entries;
        try {
            entries = dao.getDirectChildren(parent);
        } catch (MissingParentException e) {
            throw new UserNotFoundException(username);
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
        TimebasedOrderFilter.sortById(entries);
        return LdapUtils.extractAttributeEmptyCheck(entries, SchemaConstants.CN_ATTRIBUTE);
    }

    @Override
    public void addPermissionSetToUser(String username, String... permissionSet) throws UserNotFoundException,
            PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouUserPermissionSets(username);
        try {
            storePermissionSets(parent, permissionSet);
        } catch (MissingParentException e) {
            throw new UserNotFoundException(username);
        }
    }

    @Override
    public void addPermissionSetToPermissionSet(String permissionSetParent, String... permissionSet)
        throws PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouGlobalPermissionSetChildren(permissionSetParent);
        try {
            storePermissionSets(parent, permissionSet);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSetParent);
        }
    }

    private void storePermissionSets(Dn parent, String... permissionSet) throws MissingParentException {
        for (String s : permissionSet) {
            if (!dao.exists(SchemaConstants.globalPermissionSet(s))) {
                throw new PermissionSetNotFoundException(s);
            }
        }
        List<Entry> entries = new LinkedList<Entry>();
        for (String s : permissionSet) { // done in separate loop to provide
            // some atomicity
            Entry entry = EntryFactory.namedObject(s, parent);
            TimebasedOrderFilter.addId(entry, false);
            entries.add(entry);
        }
        dao.storeSkipExisting(entries);
    }

    @Override
    public void addPermissionToUser(String username, Permission... permissions) throws UserNotFoundException {
        Dn parent = SchemaConstants.ouUserPermissionsDirect(username);
        try {
            storePermissions(parent, permissions);
        } catch (MissingParentException e) {
            throw new UserNotFoundException(username);
        } catch (EntryAlreadyExistsException e) {
            throw new LdapRuntimeException(e); //TODO also here duplicates should be allowed but this looks like not
        }
    }

    @Override
    public void addPermissionToSet(String permissionSet, Permission... permissions)
        throws PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouGlobalPermissionsDirect(permissionSet);
        try {
            storePermissions(parent, permissions);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        } catch (EntryAlreadyExistsException e) {
            throw new LdapRuntimeException(e); //TODO here is it possible to store duplicates? think not..
        }
    }

    @Override
    public void createPermissionSet(String permissionSet, Permission... permission)
        throws PermissionSetAlreadyExistsException {
        List<Entry> permissionSetStructure = EntryFactory.globalPermissionSetStructure(permissionSet);
        try {
            dao.store(permissionSetStructure);
            storePermissions(SchemaConstants.ouGlobalPermissionsDirect(permissionSet), permission);
        } catch (EntryAlreadyExistsException e) {
            throw new PermissionSetAlreadyExistsException();
        } catch (MissingParentException e) {
            throw new LdapRuntimeException(e);
        }
    }

    private void storePermissions(Dn parent, Permission... permission) throws EntryAlreadyExistsException,
            MissingParentException {
        if (permission == null) {
            return;
        }
        Collection<PermissionData> pd = new LinkedList<PermissionData>();
        for (Permission p : permission) {
            PermissionData data = PermissionUtils.convertPermissionToPermissionData(p);
            pd.add(data);
        }
        List<Entry> permissionStructure = EntryFactory.permissionStructureFromPermissionData(pd, parent);
        dao.store(permissionStructure);
    }

    @Override
    public void removePermissionFromSet(String permissionSet, Permission... permission)
        throws PermissionSetNotFoundException {
        Dn parent = SchemaConstants.ouGlobalPermissionsDirect(permissionSet);
        try {
            deletePermission(parent, permission);
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
    }

    @Override
    public void removePermissionFromUser(String username, Permission... permission) throws UserNotFoundException {
        Dn parent = SchemaConstants.ouUserPermissionsDirect(username);
        try {
            deletePermission(parent, permission);
        } catch (MissingParentException e) {
            throw new UserNotFoundException(username);
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
    }

    private void deletePermission(Dn parent, Permission... permission) throws MissingParentException,
            NoSuchNodeException {
        List<Node> nodes = dao.searchSubtree(parent);
        Collection<Permission> permissions = extractPermissionsFromNodes(nodes);
        boolean b = permissions.removeAll(Arrays.asList(permission));
        if (b) {
            dao.deleteSubtreeExcludingRoot(parent);
            try {
                storePermissions(parent, permissions.toArray(new Permission[0]));
            } catch (EntryAlreadyExistsException e) {
                LOGGER.debug("should never reach here");
                throw new LdapRuntimeException(e);
            }
        }
    }

    @Override
    public void removePermissionSetFromPermissionSet(String permissionSetParent, String... permissionSet)
        throws PermissionSetNotFoundException {
        for (String child : permissionSet) {
            Dn parent = SchemaConstants.globalPermissionChild(permissionSetParent, child);
            try {
                dao.deleteSubtreeIncludingRoot(parent);
            } catch (MissingParentException e) {
                throw new PermissionSetNotFoundException(permissionSetParent);
            } catch (NoSuchNodeException e) {
                LOGGER.warn("permissionSet {} was to be deleted, but not found", child);
            }
        }
    }

    @Override
    public void removePermissionSetFromUser(String username, String... permissionSet) throws UserNotFoundException {
        for (String child : permissionSet) {
            Dn baseDn = SchemaConstants.userPermissionSet(username, child);
            try {
                dao.deleteSubtreeIncludingRoot(baseDn);
            } catch (MissingParentException e) {
                throw new UserNotFoundException(username);
            } catch (NoSuchNodeException e) {
                LOGGER.warn("permissionSet {} was to be deleted, but not found", child);
            }
        }
    }

    @Override
    public Collection<Permission> getPermissionsForUser(String username) throws UserNotFoundException {
        List<Node> nodes;
        try {
            nodes = dao.searchSubtree(SchemaConstants.ouUserPermissionsDirect(username));
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
        return extractPermissionsFromNodes(nodes);
    }

    private Collection<Permission> extractPermissionsFromNodes(List<Node> nodes) {
        Collection<PermissionData> permissionData = new LinkedList<PermissionData>();
        TimebasedOrderFilter.sortByIdNode(nodes);
        for (Node permission : nodes) {
            Map<String, EntryValue> attributes = Maps.newHashMap();
            for (Node property : permission.getChildren()) {

                List<EntryElement> entryElements = new LinkedList<EntryElement>();
                TimebasedOrderFilter.sortByIdNode(property.getChildren());
                for (Node propertyValue : property.getChildren()) {
                    EntryElement entryElement = new EntryElement();
                    entryElement.setType(LdapUtils.extractAttributeEmptyCheck(propertyValue.getEntry(),
                            SchemaConstants.JAVA_CLASS_NAME_ATTRIBUTE));
                    entryElement.setValue(LdapUtils.extractAttributeEmptyCheck(propertyValue.getEntry(),
                            SchemaConstants.STRING_ATTRIBUTE));
                    entryElements.add(entryElement);
                }
                String key = LdapUtils.extractAttributeEmptyCheck(property.getEntry(), SchemaConstants.CN_ATTRIBUTE);
                EntryValue entryValue = new EntryValue(key, entryElements);
                attributes.put(key, entryValue); // TODO why need key 2x?
            }
            String type = LdapUtils.extractAttributeEmptyCheck(permission.getEntry(),
                    SchemaConstants.JAVA_CLASS_NAME_ATTRIBUTE);
            PermissionData data = new PermissionData();
            data.setType(type);
            data.setAttributes(attributes);
            permissionData.add(data);
        }
        return EntryUtils.convertAllBeanDataToObjects(permissionData);
    }

    @Override
    public <T extends Permission> Collection<T> getPermissionsForUser(String username, Class<T> type)
        throws UserNotFoundException {
        // TODO improve performance by better query
        return CollectionUtilsExtended.filterCollectionByClass(getPermissionsForUser(username), type);
    }

    @Override
    public Collection<Permission> getPermissionsFromPermissionSet(String permissionSet)
        throws PermissionSetNotFoundException {
        List<Node> nodes;
        try {
            nodes = dao.searchSubtree(SchemaConstants.ouGlobalPermissionsDirect(permissionSet));
        } catch (MissingParentException e) {
            throw new PermissionSetNotFoundException(permissionSet);
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        }
        return extractPermissionsFromNodes(nodes);
    }

    @Override
    public Collection<Permission> getAllPermissionsForUser(String username) throws UserNotFoundException {
        Collection<Permission> result = new HashSet<Permission>();
        result.addAll(getPermissionsForUser(username));
        for (String s : getPermissionSetsFromUser(username)) {
            result.addAll(getAllPermissionsFromPermissionSet(s));
        }
        return result;
    }

    @Override
    public <T extends Permission> Collection<T> getAllPermissionsForUser(String username, Class<T> type)
        throws UserNotFoundException {
        // TODO improve performance by better query
        return CollectionUtilsExtended.filterCollectionByClass(getPermissionsForUser(username), type);
    }

    // TODO note: this does not reflect insertion order because HashSet is used

    @Override
    public Collection<Permission> getAllPermissionsFromPermissionSet(String permissionSet)
        throws PermissionSetNotFoundException {
        Collection<Permission> result = new HashSet<Permission>();
        for (String s : getAllPermissionSetsFromPermissionSet(permissionSet)) {
            result.addAll(getPermissionsFromPermissionSet(s));
        }
        return result;
    }

    private Collection<String> getAllPermissionSetsFromPermissionSet(String permissionSet) {
        Collection<String> result = new HashSet<String>();
        for (String s : getPermissionSetsFromPermissionSet(permissionSet)) {
            boolean b = result.addAll(getAllPermissionSetsFromPermissionSet(s));
            if (!b) { // prevents circles
                break;
            }
        }
        return result;
    }

    @Override
    public Collection<String> getUserList() {
        List<Entry> entries;
        try {
            entries = dao.getDirectChildren(SchemaConstants.ouUsers());
        } catch (NoSuchNodeException e) {
            throw new LdapRuntimeException(e);
        } catch (MissingParentException e) {
            throw new LdapRuntimeException(e);
        }
        return LdapUtils.extractAttributeEmptyCheck(entries, SchemaConstants.CN_ATTRIBUTE);
    }

    @Override
    public void createUser(String username) throws UserExistsException {
        List<Entry> userStructure = userStructure(username);
        try {
            dao.store(userStructure);
        } catch (EntryAlreadyExistsException e) {
            throw new UserExistsException();
        } catch (MissingParentException e) {
            throw new LdapRuntimeException(e);
        }
    }

    @Override
    public void deleteUser(String username) {
        try {
            dao.deleteSubtreeIncludingRoot(SchemaConstants.user(username));
        } catch (NoSuchNodeException e) {
            LOGGER.warn("user {} was to be deleted, but not found", username);
        } catch (MissingParentException e) {
            throw new LdapRuntimeException(e);
        }
    }

    @Override
    public List<Object> getUserAttribute(String username, String attributename) throws UserNotFoundException,
            NoSuchAttributeException {
        List<Entry> entries;
        try {
            entries = dao.getDirectChildren(SchemaConstants.userAttribute(username, attributename));
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        } catch (NoSuchNodeException e) {
            throw new NoSuchAttributeException();
        }
        TimebasedOrderFilter.sortById(entries);
        return extractUserAttributeValues(entries);
    }

    private List<Object> extractUserAttributeValues(List<Entry> entries) {
        List<EntryElement> entryElements = new LinkedList<EntryElement>();
        for (Entry entry : entries) {
            String type = LdapUtils.extractAttributeEmptyCheck(entry, SchemaConstants.JAVA_CLASS_NAME_ATTRIBUTE);
            String value = LdapUtils.extractAttributeEmptyCheck(entry, SchemaConstants.STRING_ATTRIBUTE);
            entryElements.add(new EntryElement(type, value));
        }
        return EntryUtils.convertAllEntryElementsToObject(entryElements);
    }

    @Override
    public void setUserAttribute(String username, String attributename, Object... value) throws UserNotFoundException {

        Entry attribute = EntryFactory.namedObject(attributename, SchemaConstants.ouUserAttributes(username));
        List<Entry> attributeValues = new LinkedList<Entry>();

        for (EntryElement e : EntryUtils.makeEntryElementList(value)) {
            Entry entry = EntryFactory.javaObject(e.getType(), e.getValue(), attribute.getDn());
            attributeValues.add(entry);
        }
        TimebasedOrderFilter.addIds(attributeValues, true);

        try {
            dao.storeOverwriteExisting(attribute);
            for (Entry entry : attributeValues) {
                dao.storeSkipExisting(entry);
            }
        } catch (MissingParentException e) {
            throw new UserNotFoundException(username);
        }
    }

    @Override
    public void removeUserAttribute(String username, String attributename) throws UserNotFoundException {
        try {
            dao.deleteSubtreeIncludingRoot(SchemaConstants.userAttribute(username, attributename));
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        } catch (NoSuchNodeException e) {
            LOGGER.warn("attribute {} was to be deleted, but not found", attributename);
        }
    }

    @Override
    public void removeUserCredentials(String username, String credentials) throws UserNotFoundException {
        try {
            dao.deleteSubtreeIncludingRoot(SchemaConstants.userCredentials(username, credentials));
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        } catch (NoSuchNodeException e) {
            LOGGER.warn("credentials {} was to be deleted, but not found", credentials);
        }
    }

    @Override
    public void setUserCredentials(String username, String credentialsType, String credentialsValue)
        throws UserNotFoundException {
        Dn parent = SchemaConstants.ouUserCredentials(username);
        Entry entry = EntryFactory.namedDescriptiveObject(credentialsType, credentialsValue, parent);
        try {
            dao.storeOverwriteExisting(entry);
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        }
    }

    @Override
    public String getUserCredentials(String username, String credentials) throws UserNotFoundException,
            NoSuchCredentialsException {
        try {
            Entry entry = dao.lookup(SchemaConstants.userCredentials(username, credentials));
            return LdapUtils.extractAttributeEmptyCheck(entry, SchemaConstants.STRING_ATTRIBUTE);
        } catch (MissingParentException e) {
            throw new UserNotFoundException();
        } catch (NoSuchNodeException e) {
            throw new NoSuchCredentialsException();
        }
    }

    private List<Entry> userStructure(String username) {
        Entry entry = EntryFactory.namedObject(username, SchemaConstants.ouUsers());
        Entry ouPermissions = EntryFactory.organizationalUnit("permissions", entry.getDn());
        Entry ouDirectPermissions = EntryFactory.organizationalUnit("direct", ouPermissions.getDn());
        Entry ouPermissionSets = EntryFactory.organizationalUnit("permissionSets", ouPermissions.getDn());
        Entry ouCredentials = EntryFactory.organizationalUnit("credentials", entry.getDn());
        Entry ouAttributes = EntryFactory.organizationalUnit("attributes", entry.getDn());
        return Arrays.asList(entry, ouPermissions, ouDirectPermissions, ouPermissionSets, ouCredentials, ouAttributes);
    }

}
TOP

Related Classes of org.openengsb.core.services.internal.security.ldap.UserDataManagerLdap

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.