001/*
002 * (C) Copyright 2006-2007 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 *     Thierry Delprat
018 * *
019 */
020
021package org.nuxeo.ecm.platform.computedgroups;
022
023import java.io.Serializable;
024import java.util.ArrayList;
025import java.util.Collections;
026import java.util.HashMap;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031
032import org.apache.commons.logging.Log;
033import org.apache.commons.logging.LogFactory;
034import org.nuxeo.ecm.core.api.NuxeoGroup;
035import org.nuxeo.ecm.core.query.sql.model.QueryBuilder;
036import org.nuxeo.ecm.platform.usermanager.GroupConfig;
037import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl;
038import org.nuxeo.runtime.model.ComponentContext;
039import org.nuxeo.runtime.model.ComponentInstance;
040import org.nuxeo.runtime.model.DefaultComponent;
041
042/**
043 * {@link ComputedGroupsService} implementation
044 *
045 * @author Thierry Delprat
046 */
047public class ComputedGroupsServiceImpl extends DefaultComponent implements ComputedGroupsService {
048
049    public static final String COMPUTER_EP = "computer";
050
051    public static final String CHAIN_EP = "computerChain";
052
053    protected Map<String, GroupComputerDescriptor> computers = new HashMap<>();
054
055    protected List<String> computerNames = new ArrayList<>();
056
057    protected boolean allowOverride = true;
058
059    protected static Log log = LogFactory.getLog(ComputedGroupsServiceImpl.class);
060
061    @Override
062    public void activate(ComponentContext context) {
063        super.activate(context);
064        computers.clear();
065        computerNames.clear();
066    }
067
068    @Override
069    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
070
071        if (COMPUTER_EP.equals(extensionPoint)) {
072            if (contribution instanceof GroupComputerDescriptor) {
073                GroupComputerDescriptor desc = (GroupComputerDescriptor) contribution;
074
075                if (desc.isEnabled()) {
076                    log.debug("Add " + desc.getName() + " from component " + contributor.getName());
077                    computers.put(desc.getName(), desc);
078                } else {
079                    if (computers.containsKey(desc.getName())) {
080                        log.debug("Remove " + desc.getName() + " from component " + contributor.getName());
081                        computers.remove(desc.getName());
082                    } else {
083                        log.warn("Can't remove " + desc.getName() + " as not found, from component "
084                                + contributor.getName());
085                    }
086                }
087                return;
088            } else {
089                throw new RuntimeException("Waiting GroupComputerDescriptor contribution kind, please look component "
090                        + contributor.getName());
091            }
092        }
093
094        if (CHAIN_EP.equals(extensionPoint)) {
095            GroupComputerChainDescriptor desc = (GroupComputerChainDescriptor) contribution;
096            if (desc.isAppend()) {
097                computerNames.addAll(desc.getComputerNames());
098            } else {
099                computerNames = desc.getComputerNames();
100            }
101            return;
102        }
103
104        log.warn("Unkown contribution, please check the component " + contributor.getName());
105    }
106
107    @Override
108    public List<String> computeGroupsForUser(NuxeoPrincipalImpl nuxeoPrincipal) {
109        List<String> userGroups = new ArrayList<>();
110        for (String computerName : computerNames) {
111            userGroups.addAll(computers.get(computerName).getComputer().getGroupsForUser(nuxeoPrincipal));
112        }
113        return userGroups;
114    }
115
116    @Override
117    public void updateGroupsForUser(NuxeoPrincipalImpl nuxeoPrincipal) {
118        List<String> computedGroups = computeGroupsForUser(nuxeoPrincipal);
119        Set<String> virtualGroups = new HashSet<>(nuxeoPrincipal.getVirtualGroups());
120        virtualGroups.addAll(computedGroups);
121        nuxeoPrincipal.setVirtualGroups(new ArrayList<>(virtualGroups));
122    }
123
124    @Override
125    public boolean allowGroupOverride() {
126        return allowOverride;
127    }
128
129    @Override
130    @Deprecated
131    public NuxeoGroup getComputedGroup(String groupName) {
132        return getComputedGroup(groupName, GroupConfig.DEFAULT);
133    }
134
135    @Override
136    public NuxeoGroup getComputedGroup(String groupName, GroupConfig groupConfig) {
137        for (String name : computerNames) {
138            GroupComputer computer = computers.get(name).getComputer();
139            if (computer.hasGroup(groupName)) {
140                if (computer instanceof GroupComputerLabelled) {
141                    String groupLabel = ((GroupComputerLabelled) computer).getLabel(groupName);
142                    return new NuxeoComputedGroup(groupName, groupLabel, groupConfig);
143                }
144                return new NuxeoComputedGroup(groupName, groupConfig);
145            }
146        }
147        return null;
148    }
149
150    @Override
151    public List<String> computeGroupIds() {
152        List<String> groupIds = new ArrayList<>();
153        for (String name : computerNames) {
154            GroupComputerDescriptor desc = computers.get(name);
155            List<String> foundGroupIds = desc.getComputer().getAllGroupIds();
156            if (foundGroupIds != null) {
157                groupIds.addAll(foundGroupIds);
158            }
159        }
160        return groupIds;
161    }
162
163    @Override
164    public List<String> getComputedGroupMembers(String groupName) {
165        List<String> members = new ArrayList<>();
166        for (String name : computerNames) {
167            GroupComputerDescriptor desc = computers.get(name);
168            List<String> foundMembers = desc.getComputer().getGroupMembers(groupName);
169            if (foundMembers != null) {
170                members.addAll(foundMembers);
171            }
172        }
173        return members;
174    }
175
176    @Override
177    public List<String> getComputedGroupParent(String groupName) {
178        List<String> parents = new ArrayList<>();
179        for (String name : computerNames) {
180            GroupComputerDescriptor desc = computers.get(name);
181            List<String> foundParents = desc.getComputer().getParentsGroupNames(groupName);
182            if (foundParents != null) {
183                parents.addAll(foundParents);
184            }
185        }
186        return parents;
187    }
188
189    @Override
190    public List<String> getComputedGroupSubGroups(String groupName) {
191        List<String> subGroups = new ArrayList<>();
192        for (String name : computerNames) {
193            GroupComputerDescriptor desc = computers.get(name);
194            List<String> foundSubGroups = desc.getComputer().getSubGroupsNames(groupName);
195            if (foundSubGroups != null) {
196                subGroups.addAll(foundSubGroups);
197            }
198        }
199        return subGroups;
200    }
201
202    public List<GroupComputerDescriptor> getComputerDescriptors() {
203        List<GroupComputerDescriptor> result = new ArrayList<>();
204        for (String name : computerNames) {
205            result.add(computers.get(name));
206        }
207        return result;
208    }
209
210    @Override
211    public boolean activateComputedGroups() {
212        return computerNames.size() > 0;
213    }
214
215    @Override
216    public List<String> searchComputedGroups(Map<String, Serializable> filter, Set<String> fulltext) {
217        List<String> foundGroups = new ArrayList<>();
218        for (String name : computerNames) {
219            GroupComputerDescriptor desc = computers.get(name);
220            foundGroups.addAll(desc.getComputer().searchGroups(filter, fulltext));
221        }
222        Collections.sort(foundGroups);
223        return foundGroups;
224    }
225
226    @Override
227    public List<String> searchComputedGroups(QueryBuilder queryBuilder) {
228        List<String> groups = new ArrayList<>();
229        for (String name : computerNames) {
230            GroupComputerDescriptor desc = computers.get(name);
231            groups.addAll(desc.getComputer().searchGroups(queryBuilder));
232        }
233        Collections.sort(groups);
234        return groups;
235    }
236
237    @Override
238    public void deactivate(ComponentContext context) {
239        super.deactivate(context);
240
241    }
242}