View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.announce.service;
35  
36  import javax.servlet.http.HttpServletRequest;
37  
38  import fr.paris.lutece.plugins.announce.business.Announce;
39  import fr.paris.lutece.plugins.announce.business.AnnounceHome;
40  import fr.paris.lutece.plugins.announce.web.AnnounceJspBean;
41  import fr.paris.lutece.plugins.genericattributes.business.Response;
42  import fr.paris.lutece.plugins.genericattributes.business.ResponseHome;
43  import fr.paris.lutece.portal.business.file.File;
44  import fr.paris.lutece.portal.business.file.FileHome;
45  import fr.paris.lutece.portal.business.physicalfile.PhysicalFile;
46  import fr.paris.lutece.portal.business.physicalfile.PhysicalFileHome;
47  import fr.paris.lutece.portal.business.user.AdminUser;
48  import fr.paris.lutece.portal.service.admin.AdminUserService;
49  import fr.paris.lutece.portal.service.image.ImageResource;
50  import fr.paris.lutece.portal.service.image.ImageResourceProvider;
51  import fr.paris.lutece.portal.service.security.LuteceUser;
52  import fr.paris.lutece.portal.service.security.SecurityService;
53  import fr.paris.lutece.portal.web.LocalVariables;
54  import fr.paris.lutece.util.file.FileUtil;
55  import fr.paris.lutece.util.url.UrlItem;
56  
57  /**
58   * Resource provider for Announce images
59   */
60  public class AnnounceResponseImageResourceProvider implements ImageResourceProvider
61  {
62  
63      private static final String RESOURCE_TYPE = "announce_img";
64  
65      /**
66       * {@inheritDoc}
67       */
68      @Override
69      public String getResourceTypeId( )
70      {
71          return RESOURCE_TYPE;
72      }
73  
74      /**
75       * Returns whether this image is authorized for this request
76       *
77       * @param nAnnounceId
78       *            The id of the announce
79       * @param request
80       *            The request
81       * @return true if this image is authorized for this request
82       */
83      private boolean isImageAuthorized( int nAnnounceId, HttpServletRequest request )
84      {
85  
86          Announce announce = AnnounceHome.findByPrimaryKey( nAnnounceId );
87  
88          boolean bAllowAccess = false;
89          boolean bUserIsAuthor = false;
90  
91          LuteceUser user = null;
92  
93          if ( SecurityService.isAuthenticationEnable( ) )
94          {
95              user = SecurityService.getInstance( ).getRegisteredUser( request );
96          }
97  
98          if ( ( ( user != null ) && user.getName( ).equals( announce.getUserName( ) ) ) )
99          {
100             bUserIsAuthor = true;
101         }
102 
103         if ( ( announce.getPublished( ) && !announce.getSuspended( ) && !announce.getSuspendedByUser( ) ) || bUserIsAuthor )
104         {
105             bAllowAccess = true;
106         }
107 
108         // Is the announce visible in the front office ?
109         if ( bAllowAccess )
110         {
111             return true;
112         }
113 
114         // Is the announce visible in the back office ?
115         AdminUser adminUser = AdminUserService.getAdminUser( request );
116         if ( adminUser != null )
117         {
118             return adminUser.checkRight( AnnounceJspBean.RIGHT_MANAGE_ANNOUNCE );
119         }
120 
121         return false;
122     }
123 
124     /**
125      * {@inheritDoc}
126      */
127     @Override
128     public ImageResource getImageResource( int nIdResource )
129     {
130         Integer nIdAnnounce = AnnounceHome.findIdByImageResponse( nIdResource );
131         if ( nIdAnnounce != null )
132         {
133             // When using an older core version (before 5.1.5), the local variables will not
134             // have been set by the image servlet. So we can get null or a request from another thread.
135             // We could try to detect this by checking request.getServletPath( ) (or maybe other things?)
136             // but it would break if we decide to expose this provider through another entrypoint.
137             // Also, on tomcat (tested 8.5.5), it seems like the request object is reused just like
138             // the thread, so that even if the local variables were set in another request,
139             // the object we get here is the correct one (with the corect LuteceUser or AdminUser etc).
140             // Also, Portal.jsp, the main entry point of the webapp, does clean up the local variables.
141             // Note that the other request could even have run code from another webapp (not even a lutece webapp)
142             // Also, we could log a warning here when request is null, but then it would prevent from using
143             // this function from code not associated with a request. So no warnings.
144             HttpServletRequest request = LocalVariables.getRequest( );
145 
146             if ( request == null || isImageAuthorized( nIdAnnounce, request ) )
147             {
148                 Response response = ResponseHome.findByPrimaryKey( nIdResource );
149 
150                 if ( response.getFile( ) != null )
151                 {
152                     File file = FileHome.findByPrimaryKey( response.getFile( ).getIdFile( ) );
153 
154                     if ( ( file.getPhysicalFile( ) != null ) && FileUtil.hasImageExtension( file.getTitle( ) ) )
155                     {
156                         PhysicalFile physicalFile = PhysicalFileHome.findByPrimaryKey( file.getPhysicalFile( ).getIdPhysicalFile( ) );
157                         ImageResource image = new ImageResource( );
158                         image.setImage( physicalFile.getValue( ) );
159                         image.setMimeType( file.getMimeType( ) );
160 
161                         return image;
162                     }
163                 }
164             }
165         }
166 
167         return null;
168     }
169 
170     /**
171      * Get the URL to download an image response
172      *
173      * @param nIdResponse
174      *            The id of the response
175      * @return The URl to download the image
176      */
177     public static String getUrlDownloadImageResponse( int nIdResponse )
178     {
179         UrlItem urlItem = new UrlItem( "image" );
180         urlItem.addParameter( "resource_type", RESOURCE_TYPE );
181         urlItem.addParameter( "id", nIdResponse );
182 
183         return urlItem.getUrl( );
184     }
185 }