001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Arnaud Kervern
018 */
019
020package org.nuxeo.ecm.platform.shibboleth;
021
022import java.io.Serializable;
023import java.util.HashMap;
024import java.util.HashSet;
025import java.util.List;
026import java.util.Map;
027
028import org.nuxeo.ecm.core.api.CoreSession;
029import org.nuxeo.ecm.core.api.DocumentModel;
030import org.nuxeo.ecm.core.api.DocumentModelComparator;
031import org.nuxeo.ecm.core.api.DocumentModelList;
032import org.nuxeo.ecm.core.api.model.InvalidPropertyValueException;
033import org.nuxeo.ecm.directory.Directory;
034import org.nuxeo.ecm.directory.DirectoryException;
035import org.nuxeo.ecm.directory.Reference;
036import org.nuxeo.ecm.directory.Session;
037import org.nuxeo.ecm.directory.api.DirectoryService;
038import org.nuxeo.ecm.platform.shibboleth.computedgroups.ELGroupComputerHelper;
039import org.nuxeo.ecm.platform.usermanager.UserManager;
040import org.nuxeo.ecm.platform.usermanager.exceptions.GroupAlreadyExistsException;
041import org.nuxeo.runtime.api.Framework;
042
043public class ShibbolethGroupHelper {
044
045    private ShibbolethGroupHelper() {
046        // Helper class
047    }
048
049    protected static DirectoryService getDirectoryService() {
050        return Framework.getService(DirectoryService.class);
051    }
052
053    protected static UserManager getUserManager() {
054        return Framework.getService(UserManager.class);
055    }
056
057    public static DocumentModel getBareGroupModel(CoreSession core) {
058        return core.createDocumentModel(ShibbolethConstants.SHIBBOLETH_DOCTYPE);
059    }
060
061    public static DocumentModel createGroup(DocumentModel group) {
062        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
063            if (session.hasEntry(group.getPropertyValue(
064                    ShibbolethConstants.SHIBBOLETH_SCHEMA + ":" + ShibbolethConstants.GROUP_ID_PROPERTY).toString())) {
065                throw new GroupAlreadyExistsException();
066            }
067
068            checkExpressionLanguageValidity(group);
069
070            group = session.createEntry(group);
071            return group;
072        }
073    }
074
075    public static DocumentModel getGroup(String groupName) throws DirectoryException {
076        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
077            return session.getEntry(groupName);
078        }
079    }
080
081    public static void updateGroup(DocumentModel group) {
082        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
083            checkExpressionLanguageValidity(group);
084
085            session.updateEntry(group);
086        }
087    }
088
089    public static void deleteGroup(DocumentModel group) {
090        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
091            session.deleteEntry(group);
092        }
093    }
094
095    /**
096     * Query the group directory to find if shibbGroupName is used in a subGroup field.
097     *
098     * @param shibbGroupName name of the desired groupe
099     * @return a DocumentList representing the groups matching the query
100     */
101    public static List<String> getParentsGroups(String shibbGroupName) {
102        Directory dir = getDirectoryService().getDirectory(getUserManager().getGroupDirectoryName());
103
104        Reference subGroups = dir.getReference(getUserManager().getGroupSubGroupsField());
105        List<String> ret = subGroups.getSourceIdsForTarget(shibbGroupName);
106        return ret;
107    }
108
109    public static DocumentModelList getGroups() {
110        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
111            return session.getEntries();
112        }
113    }
114
115    public static DocumentModelList searchGroup(String fullText) {
116        try (Session session = getDirectoryService().open(ShibbolethConstants.SHIBBOLETH_DIRECTORY)) {
117            Map<String, Serializable> filters = new HashMap<String, Serializable>();
118            if (fullText != null && !"".equals(fullText)) {
119                filters.put(ShibbolethConstants.GROUP_ID_PROPERTY, fullText);
120            }
121
122            Map<String, String> orderBy = new HashMap<String, String>();
123            orderBy.put(ShibbolethConstants.GROUP_ID_PROPERTY, DocumentModelComparator.ORDER_ASC);
124            return session.query(filters, new HashSet<String>(filters.keySet()), orderBy);
125        }
126    }
127
128    protected static void checkExpressionLanguageValidity(DocumentModel group) {
129        String expressionLanguage = (String) group.getPropertyValue(ShibbolethConstants.SHIBBOLETH_SCHEMA + ":"
130                + ShibbolethConstants.GROUP_EL_PROPERTY);
131        if (!ELGroupComputerHelper.isValidEL(expressionLanguage)) {
132            throw new InvalidPropertyValueException(expressionLanguage + " : is not a valid expression language");
133        }
134    }
135
136}