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.collections.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 no 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    @SuppressWarnings("unchecked")
135    public Set<UserIdentity> resolveAllowedUsers (boolean returnAll)
136    {
137        if (_anonymousAllowed || (_anyConnectedUserAllowed && !returnAll))
138        {
139            return Collections.EMPTY_SET;
140        }
141        else if (_anyConnectedUserAllowed)
142        {
143            // Retrieve all users from the user manager, and remove just the denied ones
144            Set<UserIdentity> allowedUsers = _userManager.getUsersByContext(_populationContexts).stream().map(User::getIdentity).collect(Collectors.toSet());
145            
146            Set<UserIdentity> resolvedDeniedUsers = new HashSet<>();
147            resolvedDeniedUsers.addAll(_deniedUsers);
148            
149            // Remove the users of the denied groups to the resolvedDeniedUsers
150            // The users to remove are only those which are in deniedGroups and not in allAllowedUsers
151            for (GroupIdentity deniedGroup : _deniedGroups)
152            {
153                Set<UserIdentity> groupUsers = _groupManager.getGroup(deniedGroup).getUsers();
154                for (UserIdentity groupUser : groupUsers)
155                {
156                    if (!_allowedUsers.contains(groupUser))
157                    {
158                        resolvedDeniedUsers.add(groupUser);
159                    }
160                }
161            }
162            
163            return new HashSet<>(CollectionUtils.removeAll(allowedUsers, resolvedDeniedUsers));
164        }
165        else
166        {
167            Set<UserIdentity> resolvedAllowedUsers = new HashSet<>();
168            
169            // Retrieve the users from the allowed groups
170            for (GroupIdentity allowedGroup : _allowedGroups)
171            {
172                Group group = _groupManager.getGroup(allowedGroup);
173                if (group != null)
174                {
175                    Set<UserIdentity> groupUsers = group.getUsers();
176                    resolvedAllowedUsers.addAll(groupUsers);
177                }
178            }
179            
180            // Remove the users of the denied groups
181            for (GroupIdentity deniedGroup : _deniedGroups)
182            {
183                Group group = _groupManager.getGroup(deniedGroup);
184                if (group != null)
185                {
186                    Set<UserIdentity> groupUsers = group.getUsers();
187                    resolvedAllowedUsers.removeAll(groupUsers);
188                }
189            }
190            
191            // Add the allowed users
192            resolvedAllowedUsers.addAll(_allowedUsers);
193            
194            // Remove the denied users
195            resolvedAllowedUsers.removeAll(_deniedUsers);
196            
197            return resolvedAllowedUsers;
198        }
199    }
200}