001/* 002 * Copyright 2010 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.explorer.resources.readers; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.io.Serializable; 021import java.util.Map; 022 023import org.apache.avalon.framework.parameters.Parameters; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.avalon.framework.service.Serviceable; 027import org.apache.cocoon.ProcessingException; 028import org.apache.cocoon.ResourceNotFoundException; 029import org.apache.cocoon.caching.CacheableProcessingComponent; 030import org.apache.cocoon.environment.SourceResolver; 031import org.apache.commons.lang.StringUtils; 032import org.apache.excalibur.source.SourceValidity; 033import org.apache.excalibur.source.impl.validity.TimeStampValidity; 034 035import org.ametys.core.right.RightManager; 036import org.ametys.core.user.CurrentUserProvider; 037import org.ametys.core.user.UserIdentity; 038import org.ametys.core.util.FilenameUtils; 039import org.ametys.core.util.cocoon.AbstractResourceReader; 040import org.ametys.plugins.explorer.resources.Resource; 041import org.ametys.plugins.repository.AmetysObjectResolver; 042import org.ametys.plugins.repository.UnknownAmetysObjectException; 043import org.ametys.plugins.repository.version.VersionableAmetysObject; 044import org.ametys.runtime.authentication.AccessDeniedException; 045import org.ametys.runtime.authentication.AuthorizationRequiredException; 046 047/** 048 * Reader for {@link Resource} 049 */ 050public class AmetysResourceReader extends AbstractResourceReader implements Serviceable, CacheableProcessingComponent 051{ 052 /** The Ametys object resolver */ 053 protected AmetysObjectResolver _resolver; 054 /** The resource */ 055 protected Resource _object; 056 /** The right manager */ 057 protected RightManager _rightManager; 058 /** The current user provider */ 059 protected CurrentUserProvider _currentUserProvider; 060 061 @Override 062 public void service(ServiceManager sManager) throws ServiceException 063 { 064 _resolver = (AmetysObjectResolver) sManager.lookup(AmetysObjectResolver.ROLE); 065 _rightManager = (RightManager) sManager.lookup(RightManager.ROLE); 066 _currentUserProvider = (CurrentUserProvider) sManager.lookup(CurrentUserProvider.ROLE); 067 } 068 069 @Override 070 protected void doSetup(SourceResolver res, Map objModel, String src, Parameters par) throws ProcessingException, IOException 071 { 072 String id = par.getParameter("id", null); 073 String path = par.getParameter("path", null); 074 String version = par.getParameter("version", null); 075 076 try 077 { 078 if (id != null) 079 { 080 _object = _resolver.resolveById(id); 081 } 082 else 083 { 084 _object = _resolver.resolveByPath(FilenameUtils.decode(path.substring(1))); 085 } 086 087 // Check user access 088 checkUserAccess(); 089 090 if (!StringUtils.isEmpty(version) && _object instanceof VersionableAmetysObject) 091 { 092 ((VersionableAmetysObject) _object).switchToRevision(version); 093 } 094 } 095 catch (UnknownAmetysObjectException e) 096 { 097 if (id != null) 098 { 099 throw new ResourceNotFoundException(String.format("The resource with id '%s' does not exist", id)); 100 } 101 else 102 { 103 throw new ResourceNotFoundException(String.format("The resource at path '%s' does not exist", path)); 104 } 105 } 106 } 107 108 @Override 109 protected InputStream getInputStream() 110 { 111 return _object.getInputStream(); 112 } 113 114 @Override 115 protected String getFilename() 116 { 117 return _object.getName(); 118 } 119 120 @Override 121 protected String getEncodedFilename() 122 { 123 String name = _object.getName(); 124 return FilenameUtils.encodeName(name); 125 } 126 127 @Override 128 protected long getLength() 129 { 130 return _object.getLength(); 131 } 132 133 /** 134 * Check the user access 135 * @throws AuthorizationRequiredException if authorization is required 136 * @throws AccessDeniedException if user has no access 137 */ 138 protected void checkUserAccess() throws AuthorizationRequiredException, AccessDeniedException 139 { 140 UserIdentity user = _currentUserProvider.getUser(); 141 142 if (user == null) 143 { 144 // Check anonymous access 145 if (!_rightManager.hasAnonymousReadAccess(_object.getParent())) 146 { 147 throw new AuthorizationRequiredException(null); 148 } 149 } 150 else if (!_rightManager.hasReadAccess(user, _object.getParent())) 151 { 152 throw new AccessDeniedException("User " + user + " has no right to access the resource " + _object.getId()); 153 } 154 } 155 156 @Override 157 public Serializable getKey() 158 { 159 return _object.getId() + getKeySuffix(); 160 } 161 162 @Override 163 public SourceValidity getValidity() 164 { 165 return new TimeStampValidity(getLastModified()); 166 } 167 168 @Override 169 public long getLastModified() 170 { 171 return _object.getLastModified().getTime(); 172 } 173 174 @Override 175 public String getMimeType() 176 { 177 return _object.getMimeType(); 178 } 179 180 @Override 181 public void recycle() 182 { 183 super.recycle(); 184 _object = null; 185 } 186}