001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Arnaud Kervern
016 */
017
018package org.nuxeo.ecm.platform.shibboleth;
019
020import java.io.Serializable;
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Map;
025
026import org.nuxeo.ecm.core.api.CoreSession;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.core.api.DocumentModelComparator;
029import org.nuxeo.ecm.core.api.DocumentModelList;
030import org.nuxeo.ecm.core.api.model.InvalidPropertyValueException;
031import org.nuxeo.ecm.directory.Directory;
032import org.nuxeo.ecm.directory.DirectoryException;
033import org.nuxeo.ecm.directory.Reference;
034import org.nuxeo.ecm.directory.Session;
035import org.nuxeo.ecm.directory.api.DirectoryService;
036import org.nuxeo.ecm.platform.shibboleth.computedgroups.ELGroupComputerHelper;
037import org.nuxeo.ecm.platform.usermanager.UserManager;
038import org.nuxeo.ecm.platform.usermanager.exceptions.GroupAlreadyExistsException;
039import org.nuxeo.runtime.api.Framework;
040
041public class ShibbolethGroupHelper {
042
043    private ShibbolethGroupHelper() {
044        // Helper class
045    }
046
047    protected static DirectoryService getDirectoryService() {
048        return Framework.getService(DirectoryService.class);
049    }
050
051    protected static UserManager getUserManager() {
052        return Framework.getService(UserManager.class);
053    }
054
055    public static DocumentModel getBareGroupModel(CoreSession core) {
056        return core.createDocumentModel(ShibbolethConstants.SHIBBOLETH_DOCTYPE);
057    }
058
059    public static DocumentModel createGroup(DocumentModel group) {
060        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
061            if (session.hasEntry(group.getPropertyValue(
062                    ShibbolethConstants.SHIBBOLETH_SCHEMA + ":" + ShibbolethConstants.GROUP_ID_PROPERTY).toString())) {
063                throw new GroupAlreadyExistsException();
064            }
065
066            checkExpressionLanguageValidity(group);
067
068            group = session.createEntry(group);
069            return group;
070        }
071    }
072
073    public static DocumentModel getGroup(String groupName) throws DirectoryException {
074        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
075            return session.getEntry(groupName);
076        }
077    }
078
079    public static void updateGroup(DocumentModel group) {
080        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
081            checkExpressionLanguageValidity(group);
082
083            session.updateEntry(group);
084        }
085    }
086
087    public static void deleteGroup(DocumentModel group) {
088        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
089            session.deleteEntry(group);
090        }
091    }
092
093    /**
094     * Query the group directory to find if shibbGroupName is used in a subGroup field.
095     *
096     * @param shibbGroupName name of the desired groupe
097     * @return a DocumentList representing the groups matching the query
098     */
099    public static List<String> getParentsGroups(String shibbGroupName) {
100        Directory dir = getDirectoryService().getDirectory(getUserManager().getGroupDirectoryName());
101
102        Reference subGroups = dir.getReference(getUserManager().getGroupSubGroupsField());
103        List<String> ret = subGroups.getSourceIdsForTarget(shibbGroupName);
104        return ret;
105    }
106
107    public static DocumentModelList getGroups() {
108        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
109            return session.getEntries();
110        }
111    }
112
113    public static DocumentModelList searchGroup(String fullText) {
114        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
115            Map<String, Serializable> filters = new HashMap<String, Serializable>();
116            if (fullText != null && !"".equals(fullText)) {
117                filters.put(ShibbolethConstants.GROUP_ID_PROPERTY, fullText);
118            }
119
120            Map<String, String> orderBy = new HashMap<String, String>();
121            orderBy.put(ShibbolethConstants.GROUP_ID_PROPERTY, DocumentModelComparator.ORDER_ASC);
122            return session.query(filters, new HashSet<String>(filters.keySet()), orderBy);
123        }
124    }
125
126    protected static void checkExpressionLanguageValidity(DocumentModel group) {
127        String expressionLanguage = (String) group.getPropertyValue(ShibbolethConstants.SHIBBOLETH_SCHEMA + ":"
128                + ShibbolethConstants.GROUP_EL_PROPERTY);
129        if (!ELGroupComputerHelper.isValidEL(expressionLanguage)) {
130            throw new InvalidPropertyValueException(expressionLanguage + " : is not a valid expression language");
131        }
132    }
133
134}