001/* 002 * Copyright 2020 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.workspaces.project.rights.accesscontroller; 017 018import java.util.List; 019import java.util.Map; 020import java.util.Set; 021import java.util.stream.Collectors; 022import java.util.stream.Stream; 023 024import org.apache.avalon.framework.context.Context; 025import org.apache.avalon.framework.context.ContextException; 026import org.apache.avalon.framework.context.Contextualizable; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.cocoon.components.ContextHelper; 031import org.apache.cocoon.environment.Request; 032import org.apache.commons.lang3.StringUtils; 033 034import org.ametys.core.group.GroupIdentity; 035import org.ametys.core.right.AccessController; 036import org.ametys.core.right.RightProfilesDAO; 037import org.ametys.core.user.UserIdentity; 038import org.ametys.plugins.workspaces.project.ProjectManager; 039import org.ametys.plugins.workspaces.project.objects.Project; 040import org.ametys.runtime.config.Config; 041import org.ametys.web.WebHelper; 042import org.ametys.web.repository.page.PagesContainer; 043import org.ametys.web.repository.site.Site; 044import org.ametys.web.repository.site.SiteManager; 045 046import com.google.common.collect.Iterables; 047 048/** 049 * Automatically grand access to CMS on site related to a project where the user is manager. 050 * Grants the right on general context and sitemap context with the default admin profjle 051 */ 052public class BackOfficeAccessController implements AccessController, Serviceable, Contextualizable 053{ 054 private String _adminProfileIdentifier; 055 private RightProfilesDAO _rightProfileDAO; 056 private Context _context; 057 private SiteManager _siteManager; 058 private ProjectManager _projectManager; 059 060 public void service(ServiceManager manager) throws ServiceException 061 { 062 _rightProfileDAO = (RightProfilesDAO) manager.lookup(RightProfilesDAO.ROLE); 063 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 064 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 065 } 066 067 public void contextualize(Context context) throws ContextException 068 { 069 _context = context; 070 } 071 072 public boolean isSupported(Object object) 073 { 074 return object instanceof String && ((String) object).startsWith("/cms") 075 || object instanceof PagesContainer; 076 } 077 078 private Project _getProject(Object object) 079 { 080 Site site = null; 081 082 if (object instanceof PagesContainer) 083 { 084 site = ((PagesContainer) object).getSite(); 085 } 086 else 087 { 088 Request request = ContextHelper.getRequest(_context); 089 String siteName = WebHelper.getSiteName(request); 090 if (StringUtils.isNotBlank(siteName)) 091 { 092 site = _siteManager.getSite(siteName); 093 } 094 } 095 096 if (site != null) 097 { 098 List<Project> projectsForSite = _projectManager.getProjectsForSite(site); 099 Project project = Iterables.getFirst(projectsForSite, null); 100 return project; 101 } 102 else 103 { 104 return null; 105 } 106 } 107 108 private boolean _isRightInAdminProfile(String rightId) 109 { 110 if (rightId == null) 111 { 112 return true; // READER profile 113 } 114 115 return _getRightsInAdminProfile().contains(rightId); 116 } 117 private synchronized List<String> _getRightsInAdminProfile() 118 { 119 if (_adminProfileIdentifier == null) 120 { 121 _adminProfileIdentifier = Config.getInstance().getValue("workspaces.profile.managerdefault"); 122 } 123 124 return _rightProfileDAO.getRights(_adminProfileIdentifier); 125 } 126 127 public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object) 128 { 129 if (_isRightInAdminProfile(rightId)) 130 { 131 Project project = _getProject(object); 132 if (project != null && _projectManager.isManager(project, user)) 133 { 134 return AccessResult.USER_ALLOWED; 135 } 136 } 137 138 return AccessResult.UNKNOWN; 139 } 140 141 public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 142 { 143 return getPermission(user, userGroups, null, object); 144 } 145 146 public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 147 { 148 Project project = _getProject(object); 149 if (project != null && _projectManager.isManager(project, user)) 150 { 151 return _getRightsInAdminProfile().stream().collect(Collectors.toMap(rightId -> rightId, rightId -> AccessResult.USER_ALLOWED)); 152 } 153 else 154 { 155 return Map.of(); 156 } 157 } 158 159 public AccessResult getPermissionForAnonymous(String rightId, Object object) 160 { 161 return AccessResult.UNKNOWN; 162 } 163 164 public AccessResult getReadAccessPermissionForAnonymous(Object object) 165 { 166 return AccessResult.UNKNOWN; 167 } 168 169 public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object) 170 { 171 return AccessResult.UNKNOWN; 172 } 173 174 public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object) 175 { 176 return AccessResult.UNKNOWN; 177 } 178 179 public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object) 180 { 181 if (_isRightInAdminProfile(rightId)) 182 { 183 Project project = _getProject(object); 184 if (project != null) 185 { 186 return Stream.of(project.getManagers()).distinct().collect(Collectors.toMap(user -> user, user -> AccessResult.USER_ALLOWED)); 187 } 188 } 189 190 return Map.of(); 191 } 192 193 public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object) 194 { 195 return getPermissionByUser(null, object); 196 } 197 198 public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object) 199 { 200 return Map.of(); 201 } 202 203 public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object) 204 { 205 return Map.of(); 206 } 207 208 public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId) 209 { 210 if (_isRightInAdminProfile(rightId) && workspacesContexts.contains("/cms")) 211 { 212 Project project = _getProject("/cms"); 213 if (project != null && _projectManager.isManager(project, user)) 214 { 215 return true; // Assume that admin profile is not empty 216 } 217 } 218 219 return false; 220 } 221 222 public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups) 223 { 224 return hasUserAnyPermissionOnWorkspace(workspacesContexts, user, userGroups, null); 225 } 226 227 public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 228 { 229 return false; 230 } 231 232 public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 233 { 234 return false; 235 } 236 237 public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 238 { 239 return false; 240 } 241 242 public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 243 { 244 return false; 245 } 246}