001/*
002 * (C) Copyright 2006-2016 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 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.ecm.platform.usermanager;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.LinkedHashMap;
025import java.util.List;
026import java.util.Map;
027import java.util.regex.Pattern;
028
029import org.nuxeo.common.xmap.annotation.XNode;
030import org.nuxeo.common.xmap.annotation.XNodeList;
031import org.nuxeo.common.xmap.annotation.XNodeMap;
032import org.nuxeo.common.xmap.annotation.XObject;
033import org.nuxeo.ecm.platform.usermanager.UserManager.MatchType;
034
035/**
036 * APG-240 All attributes are defined public because the user manager service do not get access to the fields. OSGI
037 * don't allow splitted packages having access to public members defined from an another package provider.
038 *
039 * @author matic
040 */
041@XObject(value = "userManager")
042public class UserManagerDescriptor implements Serializable {
043
044    private static final long serialVersionUID = 1L;
045
046    @XNode("@class")
047    public Class<?> userManagerClass;
048
049    @XNode("defaultGroup")
050    public String defaultGroup;
051
052    @XNodeList(value = "defaultAdministratorId", type = ArrayList.class, componentType = String.class)
053    public List<String> defaultAdministratorIds;
054
055    @XNodeList(value = "administratorsGroup", type = ArrayList.class, componentType = String.class)
056    public List<String> administratorsGroups;
057
058    @XNode("disableDefaultAdministratorsGroup")
059    public Boolean disableDefaultAdministratorsGroup;
060
061    @XNode("userSortField")
062    public String userSortField;
063
064    @XNode("groupSortField")
065    public String groupSortField;
066
067    @XNode("users/directory")
068    public String userDirectoryName;
069
070    @XNode("users/emailField")
071    public String userEmailField;
072
073    @XNode("users/listingMode")
074    public String userListingMode;
075
076    // BBB old syntax
077    @XNode("userListingMode")
078    public void setUserListingMode(String userListingMode) {
079        this.userListingMode = userListingMode;
080    }
081
082    public boolean userSearchFieldsPresent = false;
083
084    @XNode("users/searchFields")
085    public void setUserSearchFieldsPresent(@SuppressWarnings("unused") String text) {
086        userSearchFieldsPresent = true;
087    }
088
089    @XNode("users/searchFields@append")
090    public boolean userSearchFieldsAppend;
091
092    public Map<String, MatchType> userSearchFields = new LinkedHashMap<String, MatchType>();
093
094    @XNodeList(value = "users/searchFields/exactMatchSearchField", componentType = String.class, type = String[].class)
095    public void setExactMatchUserSearchFields(String[] fields) {
096        for (String field : fields) {
097            userSearchFields.put(field, MatchType.EXACT);
098        }
099    }
100
101    @XNodeList(value = "users/searchFields/substringMatchSearchField", componentType = String.class, type = String[].class)
102    public void setSubstringMatchUserSearchFields(String[] fields) {
103        for (String field : fields) {
104            userSearchFields.put(field, MatchType.SUBSTRING);
105        }
106    }
107
108    public Pattern userPasswordPattern;
109
110    @XNode("userPasswordPattern")
111    public void setUserPasswordPattern(String pattern) {
112        userPasswordPattern = Pattern.compile(pattern);
113    }
114
115    @XNode("users/anonymousUser")
116    public VirtualUserDescriptor anonymousUser;
117
118    @XNodeMap(value = "users/virtualUser", key = "@id", type = HashMap.class, componentType = VirtualUserDescriptor.class)
119    public Map<String, VirtualUserDescriptor> virtualUsers;
120
121    @XNode("groups/directory")
122    public String groupDirectoryName;
123
124    @XNode("groups/groupLabelField")
125    public String groupLabelField;
126
127    @XNode("groups/membersField")
128    public String groupMembersField;
129
130    @XNode("groups/subGroupsField")
131    public String groupSubGroupsField;
132
133    @XNode("groups/parentGroupsField")
134    public String groupParentGroupsField;
135
136    @XNode("groups/listingMode")
137    public String groupListingMode;
138
139    public boolean groupSearchFieldsPresent = false;
140
141    @XNode("groups/searchFields")
142    public void setGroupSearchFieldsPresent(@SuppressWarnings("unused") String text) {
143        groupSearchFieldsPresent = true;
144    }
145
146    @XNode("groups/searchFields@append")
147    public boolean groupSearchFieldsAppend;
148
149    public Map<String, MatchType> groupSearchFields = new LinkedHashMap<String, MatchType>();
150
151    @XNodeList(value = "groups/searchFields/exactMatchSearchField", componentType = String.class, type = String[].class)
152    public void setExactMatchGroupSearchFields(String[] fields) {
153        for (String field : fields) {
154            groupSearchFields.put(field, MatchType.EXACT);
155        }
156    }
157
158    @XNodeList(value = "groups/searchFields/substringMatchSearchField", componentType = String.class, type = String[].class)
159    public void setSubstringMatchGroupSearchFields(String[] fields) {
160        for (String field : fields) {
161            groupSearchFields.put(field, MatchType.SUBSTRING);
162        }
163    }
164
165    @XNode("digestAuthDirectory")
166    public String digestAuthDirectory;
167
168    @XNode("digestAuthRealm")
169    public String digestAuthRealm;
170
171    @XNode("userCacheName")
172    public String userCacheName;
173
174    /**
175     * Merge with data from another descriptor.
176     */
177    public void merge(UserManagerDescriptor other) {
178        if (other.userManagerClass != null) {
179            userManagerClass = other.userManagerClass;
180        }
181        if (other.userCacheName != null) {
182            userCacheName = other.userCacheName;
183        }
184        if (other.userListingMode != null) {
185            userListingMode = other.userListingMode;
186        }
187        if (other.groupListingMode != null) {
188            groupListingMode = other.groupListingMode;
189        }
190        if (other.defaultGroup != null) {
191            defaultGroup = other.defaultGroup;
192        }
193        if (other.defaultAdministratorIds != null) {
194            if (defaultAdministratorIds == null) {
195                defaultAdministratorIds = new ArrayList<>();
196            }
197            defaultAdministratorIds.addAll(other.defaultAdministratorIds);
198        }
199        if (other.administratorsGroups != null) {
200            if (administratorsGroups == null) {
201                administratorsGroups = new ArrayList<>();
202            }
203            administratorsGroups.addAll(other.administratorsGroups);
204        }
205        if (other.disableDefaultAdministratorsGroup != null) {
206            disableDefaultAdministratorsGroup = other.disableDefaultAdministratorsGroup;
207        }
208        if (other.userSearchFieldsPresent) {
209            if (other.userSearchFieldsAppend) {
210                userSearchFields.putAll(other.userSearchFields);
211            } else {
212                userSearchFields = other.userSearchFields;
213            }
214        }
215
216        if (other.userSortField != null) {
217            userSortField = other.userSortField;
218        }
219        if (other.groupSortField != null) {
220            groupSortField = other.groupSortField;
221        }
222        if (other.userDirectoryName != null) {
223            userDirectoryName = other.userDirectoryName;
224        }
225        if (other.userEmailField != null) {
226            userEmailField = other.userEmailField;
227        }
228        if (other.userSearchFieldsPresent) {
229            if (other.userSearchFieldsAppend) {
230                userSearchFields.putAll(other.userSearchFields);
231            } else {
232                userSearchFields = other.userSearchFields;
233            }
234        }
235        if (other.userPasswordPattern != null) {
236            userPasswordPattern = other.userPasswordPattern;
237        }
238        if (other.groupDirectoryName != null) {
239            groupDirectoryName = other.groupDirectoryName;
240        }
241        if (other.groupLabelField != null) {
242            groupLabelField = other.groupLabelField;
243        }
244        if (other.groupMembersField != null) {
245            groupMembersField = other.groupMembersField;
246        }
247        if (other.groupSubGroupsField != null) {
248            groupSubGroupsField = other.groupSubGroupsField;
249        }
250        if (other.groupParentGroupsField != null) {
251            groupParentGroupsField = other.groupParentGroupsField;
252        }
253        if (other.groupSearchFieldsPresent) {
254            if (other.groupSearchFieldsAppend) {
255                groupSearchFields.putAll(other.groupSearchFields);
256            } else {
257                groupSearchFields = other.groupSearchFields;
258            }
259        }
260        if (other.anonymousUser != null) {
261            if (other.anonymousUser.remove) {
262                anonymousUser = null;
263            } else {
264                anonymousUser = other.anonymousUser;
265            }
266        }
267        if (other.virtualUsers != null) {
268            if (virtualUsers == null) {
269                virtualUsers = other.virtualUsers;
270            } else {
271                for (VirtualUserDescriptor otherVirtualUser : other.virtualUsers.values()) {
272                    if (virtualUsers.containsKey(otherVirtualUser.id) && otherVirtualUser.remove) {
273                        virtualUsers.remove(otherVirtualUser.id);
274                    } else {
275                        virtualUsers.put(otherVirtualUser.id, otherVirtualUser);
276                    }
277                }
278            }
279        }
280        if (other.digestAuthDirectory != null) {
281            digestAuthDirectory = other.digestAuthDirectory;
282        }
283        if (other.digestAuthRealm != null) {
284            digestAuthRealm = other.digestAuthRealm;
285        }
286    }
287
288}