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.captcha.modules.recaptcha.service;
35  
36  import fr.paris.lutece.portal.service.datastore.DatastoreService;
37  import fr.paris.lutece.portal.service.plugin.PluginService;
38  import fr.paris.lutece.portal.service.util.AppLogService;
39  import fr.paris.lutece.util.httpaccess.HttpAccess;
40  
41  import org.apache.commons.lang.StringUtils;
42  
43  import java.io.IOException;
44  import java.io.StringReader;
45  
46  import java.util.Map;
47  import java.util.concurrent.ConcurrentHashMap;
48  
49  import javax.json.Json;
50  import javax.json.JsonObject;
51  import javax.json.JsonReader;
52  
53  import javax.servlet.http.HttpServletRequest;
54  
55  
56  public class ReCaptchaService implements IReCaptchaService
57  {
58      private static boolean _bActive;
59      private static final String PARAM_SECRET = "secret";
60      private static final String PARAM_RESPONSE = "response";
61      private static final String PARAM_SUCCESS = "success";
62      private static final String PARAM_REMOTEIP = "remoteip";
63      private static final String PARAM_RECAPTCHA_RESPONSE = "g-recaptcha-response";
64      private static final String DSKEY_SITE_KEY = "module.captcha.recaptcha.site_property.siteKey";
65      private static final String DSKEY_SECRET_KEY = "module.captcha.recaptcha.site_property.sercretKey";
66      private static final String DSKEY_URL_VERIFY = "module.captcha.recaptcha.site_property.urlVerify";
67  
68      /**
69       * Default constructor.
70       *
71       * Gets the ReCaptchaValidator from the ReCaptcha module.
72       * If the validator is missing, sets available to false;
73       */
74      public ReCaptchaService(  )
75      {
76          _bActive = PluginService.isPluginEnable( "recaptcha" );
77      }
78  
79      /**
80       * {@inheritDoc}
81       */
82      @Override
83      public String getHtmlCode(  )
84      {
85          String strKeySite = DatastoreService.getDataValue( DSKEY_SITE_KEY, "" );
86  
87          if ( isActive(  ) && StringUtils.isNotBlank( strKeySite ) )
88          {
89              return "<div class=\"g-recaptcha\" data-sitekey=\"" + strKeySite + "\"></div>";
90          }
91          else
92          {
93              return StringUtils.EMPTY;
94          }
95      }
96  
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public boolean validate( HttpServletRequest request )
102     {
103         String gRecaptchaResponse = request.getParameter( PARAM_RECAPTCHA_RESPONSE );
104         AppLogService.info( gRecaptchaResponse );
105 
106         boolean verify = false;
107 
108         try
109         {
110             verify = verify( gRecaptchaResponse, request );
111         }
112         catch ( IOException e )
113         {
114             AppLogService.error( e.getMessage(  ) );
115         }
116 
117         if ( isActive(  ) && verify )
118         {
119             return true;
120         }
121         else
122         {
123             return false;
124         }
125     }
126 
127     private boolean verify( String gRecaptchaResponse, HttpServletRequest request )
128         throws IOException
129     {
130         String strSecretKey = DatastoreService.getDataValue( DSKEY_SECRET_KEY, "" );
131         String strUrl = DatastoreService.getDataValue( DSKEY_URL_VERIFY,
132                 "https://www.google.com/recaptcha/api/siteverify" );
133 
134         if ( ( gRecaptchaResponse == null ) || "".equals( gRecaptchaResponse ) || "".equals( strSecretKey ) ||
135                 "".equals( strUrl ) )
136         {
137             AppLogService.error( "Vérifier les paramètres du sites (clé du site, clé secrete, url recaptcha" );
138 
139             return false;
140         }
141 
142         try
143         {
144             HttpAccess httpAccess = new HttpAccess(  );
145             Map<String, String> mapParameters = new ConcurrentHashMap<String, String>(  );
146 
147             mapParameters.put( PARAM_SECRET, strSecretKey );
148             mapParameters.put( PARAM_RESPONSE, gRecaptchaResponse );
149             mapParameters.put( PARAM_REMOTEIP, request.getRemoteAddr(  ) );
150 
151             String strJson = httpAccess.doPost( strUrl, mapParameters );
152 
153             JsonReader jsonReader = Json.createReader( new StringReader( strJson ) );
154             JsonObject jsonObject = jsonReader.readObject(  );
155             jsonReader.close(  );
156 
157             return jsonObject.getBoolean( PARAM_SUCCESS );
158         }
159         catch ( Exception e )
160         {
161             AppLogService.error( e.getMessage(  ) );
162 
163             return false;
164         }
165     }
166 
167     /**
168      * {@inheritDoc}
169      */
170     @Override
171     public boolean isActive(  )
172     {
173         return _bActive;
174     }
175 
176     /**
177      * {@inheritDoc}
178      */
179     @Override
180     public void setActive( boolean isActive )
181     {
182         _bActive = isActive;
183     }
184 }