001/* 002 * Copyright 2022 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.queriesdirectory.accesscontroller; 017 018import java.util.Collection; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.avalon.framework.service.Serviceable; 027import org.apache.commons.collections.MapUtils; 028 029import org.ametys.core.group.GroupIdentity; 030import org.ametys.core.right.AccessController; 031import org.ametys.core.right.AccessExplanation; 032import org.ametys.core.right.RightsException; 033import org.ametys.core.user.UserIdentity; 034import org.ametys.plugins.core.impl.right.AbstractRightBasedAccessController; 035import org.ametys.plugins.queriesdirectory.Query; 036import org.ametys.plugins.queriesdirectory.QueryDAO; 037import org.ametys.plugins.queriesdirectory.QueryFactory; 038import org.ametys.plugins.repository.AmetysObjectResolver; 039import org.ametys.plugins.repository.query.QueryHelper; 040import org.ametys.plugins.repository.query.expression.Expression.Operator; 041import org.ametys.plugins.repository.query.expression.UserExpression; 042import org.ametys.runtime.i18n.I18nizableText; 043 044/** 045 * {@link AccessController} to allow read access and handle for author of a query 046 * 047 */ 048public class QueryAuthorAccessController extends AbstractRightBasedAccessController implements Serviceable 049{ 050 private static final List<String> __CREATOR_RIGHTS = List.of(QueryDAO.QUERY_HANDLE_RIGHT_ID); 051 /** The ametys object resolver */ 052 protected AmetysObjectResolver _resolver; 053 054 public void service(ServiceManager manager) throws ServiceException 055 { 056 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 057 } 058 059 public boolean isSupported(Object object) 060 { 061 return object instanceof Query; 062 } 063 064 public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object) 065 { 066 if (((Query) object).getAuthor().equals(user)) 067 { 068 return __CREATOR_RIGHTS.contains(rightId) ? AccessResult.USER_ALLOWED : AccessResult.UNKNOWN; 069 } 070 071 return AccessResult.UNKNOWN; 072 } 073 074 public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 075 { 076 return ((Query) object).getAuthor().equals(user) ? AccessResult.USER_ALLOWED : AccessResult.UNKNOWN; 077 } 078 079 /** 080 * If creator, access to a list of rights 081 */ 082 public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 083 { 084 Map<String, AccessResult> permissionByRight = new HashMap<>(); 085 086 if (((Query) object).getAuthor().equals(user)) 087 { 088 for (String rightId : __CREATOR_RIGHTS) 089 { 090 permissionByRight.put(rightId, AccessResult.USER_ALLOWED); 091 } 092 } 093 094 return permissionByRight; 095 } 096 097 public AccessResult getPermissionForAnonymous(String rightId, Object object) 098 { 099 return AccessResult.UNKNOWN; 100 } 101 102 public AccessResult getReadAccessPermissionForAnonymous(Object object) 103 { 104 return AccessResult.UNKNOWN; 105 } 106 107 public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object) 108 { 109 return AccessResult.UNKNOWN; 110 } 111 112 public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object) 113 { 114 return AccessResult.UNKNOWN; 115 } 116 117 /** 118 * If right requested is in the list, the creator is added the list of USER_ALLOWED 119 */ 120 public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object) 121 { 122 Map<UserIdentity, AccessResult> permissionByUser = new HashMap<>(); 123 124 if (__CREATOR_RIGHTS.contains(rightId)) 125 { 126 permissionByUser.put(((Query) object).getAuthor(), AccessResult.USER_ALLOWED); 127 } 128 return permissionByUser; 129 } 130 131 public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object) 132 { 133 return MapUtils.EMPTY_MAP; 134 } 135 136 public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object) 137 { 138 return MapUtils.EMPTY_MAP; 139 } 140 141 public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object) 142 { 143 return MapUtils.EMPTY_MAP; 144 } 145 146 public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId) 147 { 148 return false; 149 } 150 151 public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups) 152 { 153 return false; 154 } 155 156 public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 157 { 158 return false; 159 } 160 161 public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 162 { 163 return false; 164 } 165 166 public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 167 { 168 return false; 169 } 170 171 public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 172 { 173 return false; 174 } 175 176 @Override 177 public AccessExplanation getStandardAccessExplanation(AccessResult permission, Object object) 178 { 179 switch (permission) 180 { 181 case USER_ALLOWED: 182 case UNKNOWN: 183 return new AccessExplanation( 184 getId(), 185 permission, 186 new I18nizableText("plugin.queries-directory", "PLUGINS_QUERIESDIRECTORY_QUERY_AUTHOR_ACCESS_CONTROLLER_" + permission.name() + "_EXPLANATION", 187 Map.of("title", getObjectLabel(object))) 188 ); 189 default: 190 return super.getStandardAccessExplanation(permission, object); 191 } 192 } 193 194 @Override 195 protected Iterable< ? extends Object> getHandledObjects(UserIdentity identity, Set<GroupIdentity> groups) 196 { 197 String xPathQuery = QueryHelper.getXPathQuery(null, QueryFactory.QUERY_NODETYPE, new UserExpression(Query.AUTHOR, Operator.EQ, identity), null); 198 return _resolver.query(xPathQuery); 199 } 200 201 @Override 202 protected Collection<String> getHandledRights(UserIdentity identity, Set<GroupIdentity> groups, Object object) 203 { 204 return __CREATOR_RIGHTS; 205 } 206 207 @Override 208 public I18nizableText getObjectLabel(Object object) 209 { 210 if (object instanceof Query query) 211 { 212 return new I18nizableText(QueryAccessController.getQueryContainerParentPathLabel(query.getParent()) + query.getTitle()); 213 } 214 throw new RightsException("Unsupported context: " + object.toString()); 215 } 216 217 @Override 218 public I18nizableText getObjectCategory(Object object) 219 { 220 return QueryAccessController.QUERIES_DIRECTORY_CONTEXT_CATEGORY; 221 } 222}