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.odf.rights;
017
018import java.util.Collections;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028
029import org.ametys.cms.repository.Content;
030import org.ametys.core.group.GroupIdentity;
031import org.ametys.core.right.AccessController;
032import org.ametys.core.user.UserIdentity;
033import org.ametys.odf.ODFHelper;
034import org.ametys.odf.ProgramItem;
035import org.ametys.odf.course.Course;
036import org.ametys.odf.coursepart.CoursePart;
037import org.ametys.odf.orgunit.OrgUnit;
038import org.ametys.odf.program.AbstractProgram;
039import org.ametys.runtime.plugin.component.AbstractLogEnabled;
040
041/**
042 * This access controller give access the content's creator, regardless of the required right, if and only if the ODF content is still orphan (during creation process for example)
043 *
044 */
045public class ODFOrphanContentAccessController extends AbstractLogEnabled implements AccessController, Component, Serviceable
046{
047    private ODFHelper _odfHelper;
048
049    public void service(ServiceManager manager) throws ServiceException
050    {
051        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
052    }
053    
054    @Override
055    public boolean isSupported(Object object)
056    {
057        return object instanceof ProgramItem || object instanceof OrgUnit || object instanceof CoursePart;
058    }
059    
060    /**
061     * Determines if the object is a orphan program item (without parent)
062     * @param object the object
063     * @return true if the object is a orphan program item 
064     */
065    protected boolean _isOrphan(Object object)
066    {
067        if (object instanceof ProgramItem)
068        {
069            List<ProgramItem> parentProgramItems = _odfHelper.getParentProgramItems((ProgramItem) object);
070            return parentProgramItems.isEmpty();
071        }
072        else if (object instanceof OrgUnit)
073        {
074            return ((OrgUnit) object).getParentOrgUnit() == null;
075        }
076        else if (object instanceof CoursePart)
077        {
078            return ((CoursePart) object).getCourses().isEmpty();
079        }
080        
081        return false;
082    }
083    
084    /**
085     * Get the user permission on object
086     * @param user the user
087     * @param object the object
088     * @return The access result
089     */
090    protected AccessResult _getUserPermission(UserIdentity user, Object object)
091    {
092        if (_isOrphan(object) && !_hasOrgUnit(object))
093        {
094            if (user.equals(((Content) object).getCreator()))
095            {
096                return AccessResult.USER_ALLOWED;
097            }
098        }
099        return AccessResult.UNKNOWN;
100    }
101    
102    /**
103     * Determines if the object has a orgunit
104     * @param object the object
105     * @return true if the object is attach to a orgunit
106     */
107    protected boolean _hasOrgUnit(Object object)
108    {
109        if (object instanceof AbstractProgram)
110        {
111            return !((AbstractProgram) object).getOrgUnits().isEmpty();
112        }
113        else if (object instanceof Course)
114        {
115            return !((Course) object).getOrgUnits().isEmpty();
116        }
117        return false;
118    }
119    
120    /**
121     * Get the permission by users
122     * @param object the object
123     * @return the permission by users
124     */
125    protected Map<UserIdentity, AccessResult> _getPermissionByUser(Object object)
126    {
127        Map<UserIdentity, AccessResult> permissions = new HashMap<>();
128        if (_isOrphan(object) && !_hasOrgUnit(object))
129        {
130            permissions.put(((Content) object).getCreator(), AccessResult.USER_ALLOWED);
131        }
132        return permissions;
133    }
134
135    @Override
136    public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object)
137    {
138        return _getUserPermission(user, object);
139    }
140
141    @Override
142    public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
143    {
144        return _getUserPermission(user, object);
145    }
146
147    @Override
148    public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
149    {
150        return Collections.EMPTY_MAP;
151    }
152
153    @Override
154    public AccessResult getPermissionForAnonymous(String rightId, Object object)
155    {
156        return AccessResult.UNKNOWN;
157    }
158
159    public AccessResult getReadAccessPermissionForAnonymous(Object object)
160    {
161        return AccessResult.UNKNOWN;
162    }
163
164    @Override
165    public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object)
166    {
167        return AccessResult.UNKNOWN;
168    }
169
170    @Override
171    public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object)
172    {
173        return AccessResult.UNKNOWN;
174    }
175
176    @Override
177    public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object)
178    {
179        return _getPermissionByUser(object);
180    }
181
182    @Override
183    public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object)
184    {
185        return _getPermissionByUser(object);
186    }
187
188    @Override
189    public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object)
190    {
191        return Collections.EMPTY_MAP;
192    }
193
194    @Override
195    public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object)
196    {
197        return Collections.EMPTY_MAP;
198    }
199
200    @Override
201    public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId)
202    {
203        return false;
204    }
205
206    @Override
207    public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups)
208    {
209        return false;
210    }
211
212    @Override
213    public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
214    {
215        return false;
216    }
217
218    @Override
219    public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
220    {
221        return false;
222    }
223
224    @Override
225    public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
226    {
227        return false;
228    }
229
230    @Override
231    public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
232    {
233        return false;
234    }
235}