Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Q
question2answer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
outils
question2answer
Commits
4405b33e
Commit
4405b33e
authored
Oct 22, 2015
by
Amiya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed #300
updated the ReCaptcha and fixed the issue with allow_url_fopen dependency
parent
c6a3629c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
250 additions
and
40 deletions
+250
-40
qa-recaptcha-captcha.php
qa-plugin/recaptcha-captcha/qa-recaptcha-captcha.php
+5
-1
recaptchalib.php
qa-plugin/recaptcha-captcha/recaptchalib.php
+245
-39
No files found.
qa-plugin/recaptcha-captcha/qa-recaptcha-captcha.php
View file @
4405b33e
...
...
@@ -133,7 +133,11 @@ class qa_recaptcha_captcha
{
require_once
$this
->
directory
.
'recaptchalib.php'
;
$recaptcha
=
new
ReCaptcha
(
qa_opt
(
'recaptcha_private_key'
));
if
(
ini_get
(
'allow_url_fopen'
))
$recaptcha
=
new
ReCaptcha
(
qa_opt
(
'recaptcha_private_key'
));
else
$recaptcha
=
new
ReCaptcha
(
qa_opt
(
'recaptcha_private_key'
)
,
new
ReCaptchaSocketPostRequestMethod
());
$remoteIp
=
qa_remote_ip_address
();
$userResponse
=
qa_post_text
(
'g-recaptcha-response'
);
...
...
qa-plugin/recaptcha-captcha/recaptchalib.php
View file @
4405b33e
...
...
@@ -39,58 +39,269 @@ class ReCaptchaResponse
public
$errorCodes
=
array
();
}
class
ReCaptcha
/**
* Stores and formats the parameters for the request to the reCAPTCHA service.
*/
class
ReCaptchaRequestParameters
{
private
static
$_signupUrl
=
'https://www.google.com/recaptcha/admin'
;
private
static
$_siteVerifyUrl
=
'https://www.google.com/recaptcha/api/siteverify?'
;
private
$
_secret
;
private
static
$_version
=
'php_1.0'
;
private
$secret
;
private
$response
;
private
$
remoteIp
;
private
$version
;
/**
*
Constructor
.
*
Initialise parameters
.
*
* @param string $secret shared secret between site and ReCAPTCHA server.
* @param string $secret Site secret.
* @param string $response Value from g-captcha-response form field.
* @param string $remoteIp User's IP address.
* @param string $version Version of this client library.
*/
public
function
__construct
(
$secret
)
public
function
__construct
(
$secret
,
$response
,
$remoteIp
=
null
,
$version
=
null
)
{
if
(
$secret
==
null
||
$secret
==
''
)
{
die
(
'To use reCAPTCHA you must get an API key from <a href="'
.
self
::
$_signupUrl
.
'">'
.
self
::
$_signupUrl
.
'</a>'
);
$this
->
secret
=
$secret
;
$this
->
response
=
$response
;
$this
->
remoteIp
=
$remoteIp
;
$this
->
version
=
$version
;
}
/**
* Array representation.
*
* @return array Array formatted parameters.
*/
public
function
toArray
()
{
$params
=
array
(
'secret'
=>
$this
->
secret
,
'response'
=>
$this
->
response
);
if
(
!
is_null
(
$this
->
remoteIp
))
{
$params
[
'remoteip'
]
=
$this
->
remoteIp
;
}
$this
->
_secret
=
$secret
;
if
(
!
is_null
(
$this
->
version
))
{
$params
[
'version'
]
=
$this
->
version
;
}
return
$params
;
}
/**
*
Encodes the given data into a query string forma
t.
*
Query string representation for HTTP reques
t.
*
* @param array $data array of string elements to be encoded.
* @return string Query string formatted parameters.
*/
public
function
toQueryString
()
{
return
http_build_query
(
$this
->
toArray
(),
''
,
'&'
);
}
}
/**
* Defines certain rules for a RequestMethod
* Interface ReCaptchaRequestMethod
*/
interface
ReCaptchaRequestMethod
{
/**
* Submit the request with the specified parameters.
*
* @return string - encoded request.
* @param ReCaptchaRequestParameters $params Request parameters
* @return string Body of the reCAPTCHA response
*/
private
function
_encodeQS
(
$data
)
public
function
submit
(
ReCaptchaRequestParameters
$params
);
}
/**
* Sends GET requests to the reCAPTCHA service.
*/
class
ReCaptchaGetRequestMethod
implements
ReCaptchaRequestMethod
{
const
SITE_VERIFY_URL
=
'https://www.google.com/recaptcha/api/siteverify?'
;
/**
* Submit the request with the specified parameters.
*
* @param ReCaptchaRequestParameters $params Request parameters
* @return string Body of the reCAPTCHA response
*/
public
function
submit
(
ReCaptchaRequestParameters
$params
){
return
file_get_contents
(
self
::
SITE_VERIFY_URL
.
$params
->
toQueryString
());
}
}
/**
* Convenience wrapper around native socket and file functions to allow for
* mocking.
*/
class
ReCaptchaSocket
{
private
$handle
=
null
;
/**
* fsockopen
*
* @see http://php.net/fsockopen
* @param string $hostname
* @param int $port
* @param int $errno
* @param string $errstr
* @param float $timeout
* @return resource
*/
public
function
fsockopen
(
$hostname
,
$port
=
-
1
,
&
$errno
=
0
,
&
$errstr
=
''
,
$timeout
=
null
)
{
$req
=
""
;
foreach
(
$data
as
$key
=>
$value
)
{
$req
.=
$key
.
'='
.
urlencode
(
stripslashes
(
$value
))
.
'&'
;
$this
->
handle
=
fsockopen
(
$hostname
,
$port
,
$errno
,
$errstr
,
(
is_null
(
$timeout
)
?
ini_get
(
"default_socket_timeout"
)
:
$timeout
));
if
(
$this
->
handle
!=
false
&&
$errno
===
0
&&
$errstr
===
''
)
{
return
$this
->
handle
;
}
// Cut the last '&'
$req
=
substr
(
$req
,
0
,
strlen
(
$req
)
-
1
);
return
$req
;
return
false
;
}
/**
* fwrite
*
* @see http://php.net/fwrite
* @param string $string
* @param int $length
* @return int | bool
*/
public
function
fwrite
(
$string
,
$length
=
null
)
{
return
fwrite
(
$this
->
handle
,
$string
,
(
is_null
(
$length
)
?
strlen
(
$string
)
:
$length
));
}
/**
*
Submits an HTTP GET to a reCAPTCHA server.
*
fgets
*
* @param string $path url path to recaptcha server.
* @param array $data array of parameters to be sent.
* @see http://php.net/fgets
* @param int $length
* @return string
*/
public
function
fgets
(
$length
=
null
)
{
return
fgets
(
$this
->
handle
,
$length
);
}
/**
* feof
*
* @return array response
* @see http://php.net/feof
* @return bool
*/
p
rivate
function
_submitHTTPGet
(
$path
,
$data
)
p
ublic
function
feof
(
)
{
$req
=
$this
->
_encodeQS
(
$data
);
$response
=
file_get_contents
(
$path
.
$req
);
return
$response
;
return
feof
(
$this
->
handle
);
}
/**
* fclose
*
* @see http://php.net/fclose
* @return bool
*/
public
function
fclose
()
{
return
fclose
(
$this
->
handle
);
}
}
/**
* Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
* instead of get_file_contents(). This is to account for people who may be on
* servers where allow_furl_open is disabled.
*/
class
ReCaptchaSocketPostRequestMethod
implements
ReCaptchaRequestMethod
{
const
RECAPTCHA_HOST
=
'www.google.com'
;
const
SITE_VERIFY_PATH
=
'/recaptcha/api/siteverify'
;
const
BAD_REQUEST
=
'{"success": false, "error-codes": ["invalid-request"]}'
;
const
BAD_RESPONSE
=
'{"success": false, "error-codes": ["invalid-response"]}'
;
private
$socket
;
public
function
__construct
(
ReCaptchaSocket
$socket
=
null
)
{
if
(
!
is_null
(
$socket
))
{
$this
->
socket
=
$socket
;
}
else
{
$this
->
socket
=
new
ReCaptchaSocket
();
}
}
/**
* Submit the POST request with the specified parameters.
*
* @param ReCaptchaRequestParameters $params Request parameters
* @return string Body of the reCAPTCHA response
*/
public
function
submit
(
ReCaptchaRequestParameters
$params
)
{
$errno
=
0
;
$errstr
=
''
;
if
(
false
===
$this
->
socket
->
fsockopen
(
'ssl://'
.
self
::
RECAPTCHA_HOST
,
443
,
$errno
,
$errstr
,
30
))
{
return
self
::
BAD_REQUEST
;
}
$content
=
$params
->
toQueryString
();
$request
=
"POST "
.
self
::
SITE_VERIFY_PATH
.
" HTTP/1.1
\r\n
"
;
$request
.=
"Host: "
.
self
::
RECAPTCHA_HOST
.
"
\r\n
"
;
$request
.=
"Content-Type: application/x-www-form-urlencoded
\r\n
"
;
$request
.=
"Content-length: "
.
strlen
(
$content
)
.
"
\r\n
"
;
$request
.=
"Connection: close
\r\n\r\n
"
;
$request
.=
$content
.
"
\r\n\r\n
"
;
$this
->
socket
->
fwrite
(
$request
);
$response
=
''
;
while
(
!
$this
->
socket
->
feof
())
{
$response
.=
$this
->
socket
->
fgets
(
4096
);
}
$this
->
socket
->
fclose
();
if
(
0
!==
strpos
(
$response
,
'HTTP/1.1 200 OK'
))
{
return
self
::
BAD_RESPONSE
;
}
$parts
=
preg_split
(
"#
\n
\s*
\n
#Uis"
,
$response
);
return
$parts
[
1
];
}
}
class
ReCaptcha
{
private
static
$_signupUrl
=
'https://www.google.com/recaptcha/admin'
;
const
VERSION
=
'php_1.1.2'
;
private
$secret
;
private
$requestMethod
;
/**
* Constructor.
*
* @param string $secret shared secret between site and ReCAPTCHA server.
*/
public
function
__construct
(
$secret
,
ReCaptchaRequestMethod
$requestMethod
=
null
)
{
if
(
$secret
==
null
||
$secret
==
''
)
{
die
(
'To use reCAPTCHA you must get an API key from <a href="'
.
self
::
$_signupUrl
.
'">'
.
self
::
$_signupUrl
.
'</a>'
);
}
if
(
!
is_string
(
$secret
))
{
die
(
'The provided secret must be a string'
);
}
$this
->
secret
=
$secret
;
if
(
!
is_null
(
$requestMethod
))
{
$this
->
requestMethod
=
$requestMethod
;
}
else
{
$this
->
requestMethod
=
new
ReCaptchaGetRequestMethod
();
}
}
/**
...
...
@@ -112,16 +323,11 @@ class ReCaptcha
return
$recaptchaResponse
;
}
$getResponse
=
$this
->
_submitHttpGet
(
self
::
$_siteVerifyUrl
,
array
(
'secret'
=>
$this
->
_secret
,
'remoteip'
=>
$remoteIp
,
'v'
=>
self
::
$_version
,
'response'
=>
$response
)
);
$answers
=
json_decode
(
$getResponse
,
true
);
$params
=
new
ReCaptchaRequestParameters
(
$this
->
secret
,
$response
,
$remoteIp
,
self
::
VERSION
);
$rawResponse
=
$this
->
requestMethod
->
submit
(
$params
);
$answers
=
json_decode
(
$rawResponse
,
true
);
$recaptchaResponse
=
new
ReCaptchaResponse
();
if
(
trim
(
$answers
[
'success'
])
==
true
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment