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