001/*
002 *  Copyright 2021 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.plugins.joboffer.right;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021import java.util.Set;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.commons.collections.MapUtils;
027import org.apache.commons.lang3.ArrayUtils;
028
029import org.ametys.cms.contenttype.ContentTypesHelper;
030import org.ametys.cms.repository.Content;
031import org.ametys.core.group.GroupIdentity;
032import org.ametys.core.right.AccessController;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.plugins.joboffer.JobOfferConstants;
035
036/**
037 * {@link AccessController} so responsible of a job offer can access and handle the applications
038 *
039 */
040public class ApplicationAccessController implements AccessController, Serviceable
041{
042    /** ContentTypes Helper */
043    protected ContentTypesHelper _cTypeHelper;
044    
045    public void service(ServiceManager smanager) throws ServiceException
046    {
047        _cTypeHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
048    }
049    
050    /**
051     * Get the rights for person in charge of a application content
052     * @return the list of allowed rights
053     */
054    protected List<String> getApplicationRights()
055    {
056        return List.of(
057                "Workflow_Right_Application_Edit",
058                "Workflow_Right_Application_Shortlist", 
059                "Workflow_Right_Application_Disapprove");
060    }
061    
062    /**
063     * Determines if the current user is in charge of the current application
064     * @param user the user
065     * @param content the application content
066     * @return true if the current user is in charge
067     */
068    protected boolean isInCharge(UserIdentity user, Content content)
069    {
070        UserIdentity[] personsInCharge = getPersonInCharge(content);
071        return personsInCharge != null && ArrayUtils.contains(personsInCharge, user);
072    }   
073    
074    /**
075     * Get the persons in charge of a application
076     * @param content the application content
077     * @return the persons in charge or null if not found or empty
078     */
079    protected UserIdentity[] getPersonInCharge(Content content)
080    {
081        if (content.hasDefinition(JobOfferConstants.JOB_APPLICATION_ATTRIBUTE_PATH_PERSON_IN_CHARGE))
082        {
083            return content.getValue(JobOfferConstants.JOB_APPLICATION_ATTRIBUTE_PATH_PERSON_IN_CHARGE);
084        }
085        
086        return null;
087    }
088    
089    public boolean isSupported(Object object)
090    {
091        return object instanceof Content && _cTypeHelper.isInstanceOf((Content) object, JobOfferConstants.JOB_APPLICATION_CONTENT_TYPE);
092    }
093    
094    public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object)
095    {
096        if (object instanceof Content && isInCharge(user, (Content) object))
097        {
098            return getApplicationRights().contains(rightId) ? AccessResult.USER_ALLOWED : AccessResult.UNKNOWN;
099        }
100        
101        return AccessResult.UNKNOWN;
102    }
103
104    public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
105    {
106        if (object instanceof Content && isInCharge(user, (Content) object))
107        {
108            return AccessResult.USER_ALLOWED;
109        }
110        
111        return AccessResult.UNKNOWN;
112    }
113
114    /**
115     * If creator, access to a list of rights
116     */
117    public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
118    {
119        Map<String, AccessResult> permissionByRight = new HashMap<>();
120        
121        if (isInCharge(user, (Content) object))
122        {
123            for (String rightId : getApplicationRights())
124            {
125                permissionByRight.put(rightId, AccessResult.USER_ALLOWED);
126            }
127        }
128        
129        return permissionByRight;
130    }
131
132    public AccessResult getPermissionForAnonymous(String rightId, Object object)
133    {
134        return AccessResult.UNKNOWN;
135    }
136
137    public AccessResult getReadAccessPermissionForAnonymous(Object object)
138    {
139        return AccessResult.UNKNOWN;
140    }
141
142    public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object)
143    {
144        return AccessResult.UNKNOWN;
145    }
146
147    public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object)
148    {
149        return AccessResult.UNKNOWN;
150    }
151
152    /**
153     * If right requested is in the list, the creator is added the list of USER_ALLOWED
154     */
155    public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object)
156    {
157        Map<UserIdentity, AccessResult> permissionByUser = new HashMap<>();
158        
159        if (getApplicationRights().contains(rightId))
160        {
161            UserIdentity[] personInCharge = getPersonInCharge((Content) object);
162            if (personInCharge != null)
163            {
164                for (UserIdentity userIdentity : personInCharge)
165                {
166                    permissionByUser.put(userIdentity, AccessResult.USER_ALLOWED);
167                }
168            }
169        }
170            
171        return permissionByUser;
172    }
173
174    public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object)
175    {
176        Map<UserIdentity, AccessResult> readPermissionByUser = new HashMap<>();
177        
178        UserIdentity[] personInCharge = getPersonInCharge((Content) object);
179        if (personInCharge != null)
180        {
181            for (UserIdentity userIdentity : personInCharge)
182            {
183                readPermissionByUser.put(userIdentity, AccessResult.USER_ALLOWED);
184            }
185        }
186            
187        return readPermissionByUser;
188    }
189
190    public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object)
191    {
192        return MapUtils.EMPTY_MAP;
193    }
194
195    public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object)
196    {
197        return MapUtils.EMPTY_MAP;
198    }
199
200    public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId)
201    {
202        return false;
203    }
204
205    public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups)
206    {
207        return false;
208    }
209
210    public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
211    {
212        return false;
213    }
214
215    public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
216    {
217        return false;
218    }
219
220    public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
221    {
222        return false;
223    }
224
225    public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
226    {
227        return false;
228    }
229
230}