001/* 002 * Copyright 2025 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.restriction; 017 018import java.util.Arrays; 019import java.util.List; 020import java.util.Set; 021 022import org.apache.avalon.framework.activity.Initializable; 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.cocoon.components.ContextHelper; 029import org.apache.cocoon.environment.Request; 030import org.apache.commons.lang3.StringUtils; 031 032import org.ametys.cms.model.restrictions.RestrictedModelItem; 033import org.ametys.cms.repository.Content; 034import org.ametys.core.right.RightManager.RightResult; 035import org.ametys.odf.data.EducationalPath; 036import org.ametys.odf.rights.ODFRightHelper; 037import org.ametys.odf.rights.ODFRightHelper.ContextualizedContent; 038import org.ametys.runtime.config.Config; 039import org.ametys.runtime.model.ModelItem; 040 041/** 042 * Restrictions for a repeater with educational path or for data in a repeater with educational 043 */ 044public class RepeaterWithEducationalPathRestriction extends SharedOnlyRestriction implements Contextualizable, Initializable 045{ 046 /** The fields handled by this restriction */ 047 protected List<String> _fields; 048 049 private Context _context; 050 051 @Override 052 public void configure(Configuration configuration) throws ConfigurationException 053 { 054 super.configure(configuration); 055 056 _checkWriteRights(); 057 } 058 059 /** 060 * Ensure the configuration of write rights is correct 061 * @throws ConfigurationException If the configuration is incorrect 062 */ 063 protected void _checkWriteRights() throws ConfigurationException 064 { 065 if (_writeRightIds == null || _writeRightIds.isEmpty()) 066 { 067 throw new ConfigurationException("At least one write right ids must be set for the " + getClass().getName() + " restriction: you should at least set the classic edition right."); 068 } 069 } 070 071 public void contextualize(Context context) throws ContextException 072 { 073 _context = context; 074 } 075 076 public void initialize() throws Exception 077 { 078 String[] fields = StringUtils.split(Config.getInstance().getValue("odf.consumercaneditcoursedatabyeducationalpath", false, ""), ","); 079 _fields = Arrays.stream(fields).filter(StringUtils::isNotBlank).toList(); 080 } 081 082 @Override 083 public RestrictionResult canWrite(Content content, RestrictedModelItem modelItem) 084 { 085 if (canRead(content, modelItem) == RestrictionResult.FALSE) 086 { 087 return RestrictionResult.FALSE; 088 } 089 return super.canWrite(content, modelItem); 090 } 091 092 093 @Override 094 protected boolean _hasRights(Content content, RestrictedModelItem modelItem, Set<String> rightLimitations) 095 { 096 if (super._hasRights(content, modelItem, rightLimitations)) 097 { 098 // User is producer of content with needed rights for restrictions 099 return true; 100 } 101 102 if (_fields.contains(StringUtils.substringBefore(modelItem.getPath(), ModelItem.ITEM_PATH_SEPARATOR))) // will match exact fields or repeaters 103 { 104 Request request = ContextHelper.getRequest(_context); 105 @SuppressWarnings("unchecked") 106 List<EducationalPath> educationalPaths = (List<EducationalPath>) request.getAttribute(ODFRightHelper.REQUEST_ATTR_EDUCATIONAL_PATHS); 107 108 if (educationalPaths != null) 109 { 110 // Test rights as a consumer of the content (ie. allowed to edit repeater data for one of the given educational paths) 111 for (String rightId : rightLimitations) 112 { 113 for (EducationalPath educationalPath : educationalPaths) 114 { 115 if (_rightManager.currentUserHasRight(rightId, new ContextualizedContent(content, educationalPath)) == RightResult.RIGHT_ALLOW) 116 { 117 return true; 118 } 119 } 120 } 121 } 122 } 123 124 return false; 125 } 126}