001/*
002 *  Copyright 2016 Anyware Services
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 */
016package org.ametys.core.right;
017
018import java.util.Collections;
019import java.util.HashSet;
020import java.util.Set;
021import java.util.stream.Collectors;
022
023import org.apache.commons.collections4.CollectionUtils;
024
025import org.ametys.core.group.Group;
026import org.ametys.core.group.GroupIdentity;
027import org.ametys.core.group.GroupManager;
028import org.ametys.core.user.User;
029import org.ametys.core.user.UserIdentity;
030import org.ametys.core.user.UserManager;
031
032/**
033 * Wrapper class to represent a set of allowed users, which can eventually be anonymous or any connected user.
034 */
035public class AllowedUsers
036{
037    private boolean _anonymousAllowed;
038    private boolean _anyConnectedUserAllowed;
039    private Set<UserIdentity> _allowedUsers;
040    private Set<UserIdentity> _deniedUsers;
041    private Set<GroupIdentity> _allowedGroups;
042    private Set<GroupIdentity> _deniedGroups;
043    
044    private UserManager _userManager;
045    private Set<String> _populationContexts;
046    private GroupManager _groupManager;
047
048    /**
049     * Creates an object representing allowed users.
050     * @param anonymousAllowed true to indicate any anonymous user is allowed
051     * @param anyConnectedUserAllowed if anonymous is false, true to indicate any connected user is allowed  
052     * @param allowedUsers the allowed users, not taking into account the denied users. Must be null if anonymous or anyConnectedUser is true, must not otherwise.
053     * @param deniedUsers the denied users. Must be null if anonymous is true, must not otherwise.
054     * @param allowedGroups the allowed groups, not taking into account the denied groups. Must be null if anonymous or anyConnectedUser is true, must not otherwise.
055     * @param deniedGroups the denied groups. Must be null if anonymous is true, must not otherwise.
056     * @param userManager The user manager
057     * @param groupManager The group manager
058     * @param populationContexts The population contexts for retrieving users from user manager. Can be null if anyConnectedUser is false
059     */
060    AllowedUsers(boolean anonymousAllowed, boolean anyConnectedUserAllowed, Set<UserIdentity> allowedUsers, Set<UserIdentity> deniedUsers, Set<GroupIdentity> allowedGroups, Set<GroupIdentity> deniedGroups, UserManager userManager, GroupManager groupManager, Set<String> populationContexts)
061    {
062        _anonymousAllowed = anonymousAllowed;
063        _anyConnectedUserAllowed = anyConnectedUserAllowed;
064        _allowedUsers = allowedUsers;
065        _deniedUsers = deniedUsers;
066        _allowedGroups = allowedGroups;
067        _deniedGroups = deniedGroups;
068        
069        _userManager = userManager;
070        _groupManager = groupManager;
071        _populationContexts = populationContexts;
072    }
073    
074    /**
075     * Returns true if any anonymous user is allowed
076     * @return true if any anonymous user is allowed
077     */
078    public boolean isAnonymousAllowed()
079    {
080        return _anonymousAllowed;
081    }
082    
083    /**
084     * Returns true if any connected user is allowed
085     * @return true if any connected user is allowed
086     */
087    public boolean isAnyConnectedUserAllowed()
088    {
089        return !_anonymousAllowed && _anyConnectedUserAllowed;
090    }
091    
092    /**
093     * Get the allowed users
094     * @return The allowed users
095     */
096    public Set<UserIdentity> getAllowedUsers()
097    {
098        return _allowedUsers;
099    }
100    
101    /**
102     * Get the denied users
103     * @return The denied users
104     */
105    public Set<UserIdentity> getDeniedUsers()
106    {
107        return _deniedUsers;
108    }
109    
110    /**
111     * Get the allowed groups
112     * @return The allowed groups
113     */
114    public Set<GroupIdentity> getAllowedGroups()
115    {
116        return _allowedGroups;
117    }
118    
119    /**
120     * Get the allowed groups
121     * @return The allowed groups
122     */
123    public Set<GroupIdentity> getDeniedGroups()
124    {
125        return _deniedGroups;
126    }
127    
128    /**
129     * Resolve the actual allowed users, taking into account the anyconnected, allowed and denied users and groups.
130     * If anonymous is allowed, it will return an empty list.
131     * @param returnAll Set to <code>true</code> to resolve all users if any connected user is allowed. If <code>false</code>, returns an empty Set if any connected user is allowed.
132     * @return the computed actual allowed users
133     */
134    public Set<UserIdentity> resolveAllowedUsers (boolean returnAll)
135    {
136        if (_anonymousAllowed || (_anyConnectedUserAllowed && !returnAll))
137        {
138            return Collections.EMPTY_SET;
139        }
140        else if (_anyConnectedUserAllowed)
141        {
142            // Retrieve all users from the user manager, and remove just the denied ones
143            Set<UserIdentity> allowedUsers = _userManager.getUsersByContext(_populationContexts, false).stream().map(User::getIdentity).collect(Collectors.toSet());
144            
145            Set<UserIdentity> resolvedDeniedUsers = new HashSet<>();
146            resolvedDeniedUsers.addAll(_deniedUsers);
147            
148            // Remove the users of the denied groups to the resolvedDeniedUsers
149            // The users to remove are only those which are in deniedGroups and not in allAllowedUsers
150            for (GroupIdentity deniedGroup : _deniedGroups)
151            {
152                Set<UserIdentity> groupUsers = _groupManager.getGroup(deniedGroup).getUsers();
153                for (UserIdentity groupUser : groupUsers)
154                {
155                    if (!_allowedUsers.contains(groupUser))
156                    {
157                        resolvedDeniedUsers.add(groupUser);
158                    }
159                }
160            }
161            
162            return new HashSet<>(CollectionUtils.removeAll(allowedUsers, resolvedDeniedUsers));
163        }
164        else
165        {
166            Set<UserIdentity> resolvedAllowedUsers = new HashSet<>();
167            
168            // Retrieve the users from the allowed groups
169            for (GroupIdentity allowedGroup : _allowedGroups)
170            {
171                Group group = _groupManager.getGroup(allowedGroup);
172                if (group != null)
173                {
174                    Set<UserIdentity> groupUsers = group.getUsers();
175                    resolvedAllowedUsers.addAll(groupUsers);
176                }
177            }
178            
179            // Remove the users of the denied groups
180            for (GroupIdentity deniedGroup : _deniedGroups)
181            {
182                Group group = _groupManager.getGroup(deniedGroup);
183                if (group != null)
184                {
185                    Set<UserIdentity> groupUsers = group.getUsers();
186                    resolvedAllowedUsers.removeAll(groupUsers);
187                }
188            }
189            
190            // Add the allowed users
191            resolvedAllowedUsers.addAll(_allowedUsers);
192            
193            // Remove the denied users
194            resolvedAllowedUsers.removeAll(_deniedUsers);
195            
196            return resolvedAllowedUsers;
197        }
198    }
199}