View Javadoc
1   /*
2    * Copyright (c) 2002-2016, Mairie de 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.avatarserver.web;
35  
36  import fr.paris.lutece.plugins.avatarserver.business.Avatar;
37  import fr.paris.lutece.plugins.avatarserver.business.AvatarHome;
38  import fr.paris.lutece.plugins.avatarserver.service.AvatarService;
39  import fr.paris.lutece.plugins.avatarserver.service.HashService;
40  import fr.paris.lutece.plugins.avatarserver.service.HttpUtils;
41  import fr.paris.lutece.portal.service.security.LuteceUser;
42  import fr.paris.lutece.portal.service.security.SecurityService;
43  import fr.paris.lutece.portal.service.security.UserNotSignedException;
44  import fr.paris.lutece.portal.service.util.AppLogService;
45  import fr.paris.lutece.portal.service.util.AppPropertiesService;
46  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
47  import fr.paris.lutece.util.http.MultipartUtil;
48  
49  import org.apache.commons.fileupload.FileItem;
50  import org.apache.commons.fileupload.FileUploadException;
51  import org.apache.commons.lang.StringUtils;
52  
53  import java.io.IOException;
54  
55  import javax.servlet.ServletException;
56  import javax.servlet.ServletOutputStream;
57  import javax.servlet.http.HttpServlet;
58  import javax.servlet.http.HttpServletRequest;
59  import javax.servlet.http.HttpServletResponse;
60  
61  /**
62   * PostAvatar Servlet.
63   * This servlet let upload an avatar for the current connected user
64   */
65  public class PostAvatarServlet extends HttpServlet
66  {
67      private static final String PARAMETER_IMAGE = "image";
68      private static final String PARAMETER_RETURN_URL = "return_url";
69      private static final String PROPERTY_AUTHORIZED_DOMAINS = "avatarserver.post_servlet.authorized_domains";
70      private static final String PROPERTY_ACCESS_CONTROL_METHODS = "avatarserver.post_servlet.access_control.methods";
71      private static final String PROPERTY_ACCESS_CONTROL_CREDENTIALS = "avatarserver.post_servlet.access_control.credentials";
72      private static final String PROPERTY_SIZE_MAX = "avatarserver.post_servlet.size.max";
73      private static final String PROPERTY_SIZE_THRESHOLD = "avatarserver.post_servlet.size.threshold";
74      private static final String ACCESS_CONTROL_METHODS = AppPropertiesService.getProperty( PROPERTY_ACCESS_CONTROL_METHODS );
75      private static final String ACCESS_CONTROL_CREDENTIALS = AppPropertiesService.getProperty( PROPERTY_ACCESS_CONTROL_CREDENTIALS );
76      private static int _nRequestSizeMax = AppPropertiesService.getPropertyInt( PROPERTY_SIZE_MAX, -1 );
77      private static int _nSizeThreshold = AppPropertiesService.getPropertyInt( PROPERTY_SIZE_THRESHOLD, -1 );
78      private static final long serialVersionUID = 1L;
79  
80      /**
81       * {@inheritDoc }
82       */
83      @Override
84      protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
85      {
86          ServletOutputStream out = resp.getOutputStream( );
87          out.println( "Only POST is allowed" );
88          out.flush( );
89          out.close( );
90      }
91  
92      /**
93       * {@inheritDoc }
94       */
95      @Override
96      protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
97      {
98          ServletOutputStream out = response.getOutputStream( );
99  
100         try
101         {
102             MultipartHttpServletRequest multiPartRequest = MultipartUtil.convert( _nSizeThreshold, _nRequestSizeMax, true, request );
103             FileItem imageSource = multiPartRequest.getFile( PARAMETER_IMAGE );
104             String strReturnUrl = multiPartRequest.getParameter( PARAMETER_RETURN_URL );
105 
106             LuteceUser user = null;
107             if ( SecurityService.isAuthenticationEnable() ) {
108                 user = SecurityService.getInstance( ).getRemoteUser( request );
109             }
110             if ( user != null )
111             {
112                 String strEmail = user.getEmail( );
113                 String strHash = HashService.getHash( strEmail );
114                 Avatar avatar = AvatarHome.findByHash( strHash );
115                 boolean bCreate = false;
116 
117                 String strAuthorizedDomains = AppPropertiesService.getProperty( PROPERTY_AUTHORIZED_DOMAINS );
118                 String strOriginDomain = HttpUtils.getHeaderOrigin( request );
119 
120                 if( StringUtils.isNotEmpty( strOriginDomain ) ) {
121                     HttpUtils.setAccessControlHeaders( response , ACCESS_CONTROL_METHODS , strOriginDomain , ACCESS_CONTROL_CREDENTIALS );
122                 }
123 
124                 if( StringUtils.isEmpty( strOriginDomain ) || HttpUtils.isValidDomain( strOriginDomain, strAuthorizedDomains ))
125                 {
126                     if ( avatar == null )
127                     {
128                         avatar = new Avatar( );
129                         bCreate = true;
130                     }
131                     avatar.setEmail( strEmail );
132                     avatar.setHash( strHash );
133                     avatar.setValue( imageSource.get( ) );
134                     avatar.setMimeType( imageSource.getContentType( ) );
135 
136                     if ( bCreate )
137                     {
138                         AvatarService.create( avatar );
139                     }
140                     else
141                     {
142                         AvatarService.update( avatar );
143                     }
144 
145                     out.println( "Avatar successfully posted!" );
146                     if( strReturnUrl != null )
147                     {
148                         response.sendRedirect( strReturnUrl );
149                     }
150                 }
151                 else
152                 {
153                     out.println( "Request sent from an unauthorized domain : " + strOriginDomain );
154                     AppLogService.info( "AvatarServer : request sent from an unauthorized domain : " + strOriginDomain );
155                     response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
156                 }
157             }
158             else
159             {
160                 out.println( "User not signed!" );
161                 response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
162             }
163         }
164         catch( FileUploadException ex )
165         {
166             out.println( "Error uploading avatar : " + ex.getMessage( ) );
167             AppLogService.error( "AvatarServer : Error uploading avatar : " + ex.getMessage( ), ex );
168             response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
169         }
170         catch( UserNotSignedException ex )
171         {
172             out.println( "Error uploading avatar : User not signed" );
173             response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
174         }
175         finally
176         {
177             out.flush( );
178             out.close( );
179         }
180     }
181 }