mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/ConfirmEdit
synced 2024-09-23 18:30:21 +00:00
New "Asirra" module, from the Asirra extension by Bachsau
This commit is contained in:
parent
44cfaed7ce
commit
44d03e206a
Notes:
Yaron Koren
2011-07-12 17:26:26 +00:00
118
Asirra.class.php
Normal file
118
Asirra.class.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Bachsau
|
||||
*/
|
||||
|
||||
class Asirra extends SimpleCaptcha
|
||||
{
|
||||
// Asirra URLs
|
||||
public $asirra_localpath = '';
|
||||
public $asirra_clientscript = 'http://challenge.asirra.com/js/AsirraClientSide.js';
|
||||
public $asirra_apiscript = 'http://challenge.asirra.com/cgi/Asirra';
|
||||
|
||||
// As we don't have to store anything but some other things to do,
|
||||
// we're going to replace that constructor completely.
|
||||
function __construct()
|
||||
{
|
||||
global $wgScriptPath, $wgAsirraScriptPath;
|
||||
|
||||
// WTF isn't this in ConfirmEdit_body.php?
|
||||
wfLoadExtensionMessages('ConfirmEdit');
|
||||
wfLoadExtensionMessages('Asirra');
|
||||
|
||||
// Try to find $asirra_localpath if not set
|
||||
if (!$this -> asirra_localpath = $wgAsirraScriptPath)
|
||||
{
|
||||
if (strpos(__FILE__, $_SERVER['DOCUMENT_ROOT']) === 0)
|
||||
{
|
||||
$this -> asirra_localpath = preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '(\\/*)/s', '/', dirname(__FILE__));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this -> asirra_localpath = $wgScriptPath . '/extensions/ConfirmEdit';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getForm()
|
||||
{
|
||||
global $wgAsirraEnlargedPosition, $wgAsirraCellsPerRow, $wgOut;
|
||||
|
||||
return '
|
||||
<script type="text/javascript" src="' . $this -> asirra_clientscript . '"></script>
|
||||
<script type="text/javascript" src="' . $this -> asirra_localpath . '/asirra_contentloaded.js"></script>
|
||||
<script type="text/javascript" src="' . $this -> asirra_localpath . '/asirra_humanverify.js"></script>
|
||||
<script type="text/javascript">
|
||||
asirraState.SetEnlargedPosition("' . $wgAsirraEnlargedPosition . '");
|
||||
asirraState.SetCellsPerRow(' . $wgAsirraCellsPerRow . ');
|
||||
var asirra_js_failed = "' . $this -> getMessage('createaccount-fail') . '"
|
||||
</script>
|
||||
<noscript>' . $wgOut -> parse($this -> getMessage('nojs')) . '</noscript>
|
||||
';
|
||||
}
|
||||
|
||||
function getMessage( $action )
|
||||
{
|
||||
$name = 'asirra-' . $action;
|
||||
$text = wfMsg($name);
|
||||
// Obtain a more tailored message, if possible, otherwise, fall back to
|
||||
// the default for edits
|
||||
return wfEmptyMsg($name, $text) ? wfMsg('asirra-edit') : $text;
|
||||
}
|
||||
|
||||
// This is where the party goes on...
|
||||
function passCaptcha()
|
||||
{
|
||||
global $wgRequest, $wgAsirra;
|
||||
|
||||
$ticket = $wgRequest -> getVal('Asirra_Ticket');
|
||||
$url = $this -> asirra_apiscript . '?action=ValidateTicket&ticket=' . $ticket;
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
$resultXml = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$xml_parser = xml_parser_create();
|
||||
xml_set_element_handler($xml_parser, 'AsirraXmlParser::startElement', 'AsirraXmlParser::endElement');
|
||||
xml_set_character_data_handler($xml_parser, 'AsirraXmlParser::characterData');
|
||||
xml_parse($xml_parser, $resultXml, 1);
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
if ($wgAsirra['passed'])
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class AsirraXmlParser
|
||||
{
|
||||
static function startElement($parser, $name, $attrs)
|
||||
{
|
||||
global $wgAsirra;
|
||||
|
||||
$wgAsirra['inResult'] = ($name=="RESULT");
|
||||
}
|
||||
|
||||
static function endElement($name)
|
||||
{
|
||||
global $wgAsirra;
|
||||
|
||||
$wgAsirra['inResult'] = 0;
|
||||
}
|
||||
|
||||
static function characterData($parer, $data)
|
||||
{
|
||||
global $wgAsirra;
|
||||
|
||||
if ($wgAsirra['inResult'] && $data == "Pass")
|
||||
{
|
||||
$wgAsirra['passed'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
35
Asirra.i18n.php
Normal file
35
Asirra.i18n.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalisation file for the Asirra module of the ConfirmEdit
|
||||
* extension.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
/* English */
|
||||
$messages['en'] = array(
|
||||
'asirra-desc' => 'Asirra module for ConfirmEdit',
|
||||
'asirra-edit' => 'To help protect against automated edit spam, please select just the cat photos in the box below:',
|
||||
'asirra-addurl' => 'Your edit includes new external links. To help protect against automated spam, please select just the cat photos in the box below:',
|
||||
'asirra-badpass' => 'To help protect against automated password cracking, please select just the cat photos in the box below:',
|
||||
'asirra-createaccount' => 'To help protect against automated account creation, please select just the cat photos in the box below:',
|
||||
'asirra-createaccount-fail' => "Please correctly identify the cats.",
|
||||
'asirra-create' => 'To help protect against automated page creation, please select just the cat photos in the box below:',
|
||||
'asirra-nojs' => '\'\'\'Please enable JavaScript and resubmit the page.\'\'\''
|
||||
);
|
||||
|
||||
|
||||
/** German (Deutsch) */
|
||||
$messages['de'] = array(
|
||||
'asirra-desc' => 'Asirra-Modul für ConfirmEdit',
|
||||
'asirra-edit' => 'Zum Schutz vor automatisiertem Spam, wähle bitte nur die Katzen im untenstehenden Feld aus:',
|
||||
'asirra-addurl' => 'Deine Bearbeitung enthält neue externe Links. Zum Schutz vor automatisiertem Spam wähle bitte nur die Katzen im untenstehenden Feld aus:',
|
||||
'asirra-badpass' => 'Zum Schutz gegen automatisiertes Knacken von Passwörtern, wähle bitte nur die Katzen im untenstehenden Feld aus:',
|
||||
'asirra-createaccount' => 'Zum Schutz gegen automatisierte Erstellung von Benutzerkonten wähle bitte nur die Katzen im untenstehenden Feld aus:',
|
||||
'asirra-createaccount-fail' => 'Bitte wähle nur Katzen aus.',
|
||||
'asirra-create' => 'Zum Schutz gegen automatisierte Erstellung von Seiten, wähle bitte nur die Katzen im untenstehenden Feld aus:',
|
||||
'asirra-nojs' => '\'\'\'Bitte aktiviere JavaScript und sende die Seite noch einmal ab.\'\'\''
|
||||
);
|
43
Asirra.php
Normal file
43
Asirra.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* Asirra CAPTCHA module for the ConfirmEdit MediaWiki extension.
|
||||
* @author Bachsau
|
||||
*
|
||||
* Makes use of the Asirra (Animal Species Image Recognition for
|
||||
* Restricting Access) CAPTCHA service, developed by John Douceur, Jeremy
|
||||
* Elson and Jon Howell at Microsoft Research.
|
||||
*
|
||||
* Asirra uses a large set of images from http://petfinder.com.
|
||||
*
|
||||
* For more information about Asirra, see:
|
||||
* http://research.microsoft.com/en-us/um/redmond/projects/asirra/
|
||||
*
|
||||
* This MediaWiki code is released into the public domain, without any
|
||||
* warranty. YOU CAN DO WITH IT WHATEVER YOU LIKE!
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once dirname( __FILE__ ) . '/ConfirmEdit.php';
|
||||
$wgCaptchaClass = 'Asirra';
|
||||
|
||||
// Default Asirra options.
|
||||
// Use LocalSettings.php for any changes
|
||||
$wgAsirraEnlargedPosition = 'bottom';
|
||||
$wgAsirraCellsPerRow = '6';
|
||||
$wgAsirraScriptPath = '';
|
||||
|
||||
// AsirraXmlParser initial values
|
||||
$wgAsirra = array
|
||||
(
|
||||
'inResult' => 0,
|
||||
'passed' => 0
|
||||
);
|
||||
|
||||
$wgExtensionMessagesFiles['Asirra'] = dirname( __FILE__ ) . '/Asirra.i18n.php';
|
||||
$wgAutoloadClasses['Asirra'] = dirname( __FILE__ ) . '/Asirra.class.php';
|
50
asirra_contentloaded.js
Normal file
50
asirra_contentloaded.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*!
|
||||
* contentloaded.js
|
||||
*
|
||||
* Author: Diego Perini (diego.perini at gmail.com)
|
||||
* Summary: cross-browser wrapper for DOMContentLoaded
|
||||
* Updated: 20101020
|
||||
* License: MIT
|
||||
* Version: 1.2
|
||||
*
|
||||
* URL:
|
||||
* http://javascript.nwbox.com/ContentLoaded/
|
||||
* http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
// @win window reference
|
||||
// @fn function reference
|
||||
function contentLoaded(win, fn) {
|
||||
|
||||
var done = false, top = true,
|
||||
|
||||
doc = win.document, root = doc.documentElement,
|
||||
|
||||
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
||||
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
||||
pre = doc.addEventListener ? '' : 'on',
|
||||
|
||||
init = function(e) {
|
||||
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
||||
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
||||
if (!done && (done = true)) fn.call(win, e.type || e);
|
||||
},
|
||||
|
||||
poll = function() {
|
||||
try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
|
||||
init('poll');
|
||||
};
|
||||
|
||||
if (doc.readyState == 'complete') fn.call(win, 'lazy');
|
||||
else {
|
||||
if (doc.createEventObject && root.doScroll) {
|
||||
try { top = !win.frameElement; } catch(e) { }
|
||||
if (top) poll();
|
||||
}
|
||||
doc[add](pre + 'DOMContentLoaded', init, false);
|
||||
doc[add](pre + 'readystatechange', init, false);
|
||||
win[add](pre + 'load', init, false);
|
||||
}
|
||||
|
||||
}
|
62
asirra_humanverify.js
Normal file
62
asirra_humanverify.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*======================================================================*\
|
||||
|| #################################################################### ||
|
||||
|| # Asirra module for ConfirmEdit by Bachsau # ||
|
||||
|| # ---------------------------------------------------------------- # ||
|
||||
|| # This code is released into public domain, in the hope that it # ||
|
||||
|| # will be useful, but without any warranty. # ||
|
||||
|| # ------------ YOU CAN DO WITH IT WHATEVER YOU LIKE! ------------- # ||
|
||||
|| #################################################################### ||
|
||||
\*======================================================================*/
|
||||
|
||||
var asirra_js_failed = "Please correctly identify the cats.";
|
||||
var asirraform = document.forms[document.forms.length - 1];
|
||||
var submitButtonClicked = document.createElement("input");
|
||||
var passThroughFormSubmit = false;
|
||||
|
||||
function PrepareSubmit()
|
||||
{
|
||||
submitButtonClicked.type = "hidden";
|
||||
var inputFields = asirraform.getElementsByTagName("input");
|
||||
for (var i=0; i<inputFields.length; i++)
|
||||
{
|
||||
if (inputFields[i].type == "submit")
|
||||
{
|
||||
inputFields[i].onclick = function(event)
|
||||
{
|
||||
submitButtonClicked.name = this.name;
|
||||
submitButtonClicked.value = this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asirraform.onsubmit = function(event)
|
||||
{
|
||||
return MySubmitForm();
|
||||
}
|
||||
}
|
||||
|
||||
function MySubmitForm()
|
||||
{
|
||||
if (passThroughFormSubmit)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Asirra_CheckIfHuman(HumanCheckComplete);
|
||||
return false;
|
||||
}
|
||||
|
||||
function HumanCheckComplete(isHuman)
|
||||
{
|
||||
if (!isHuman)
|
||||
{
|
||||
alert(asirra_js_failed);
|
||||
}
|
||||
else
|
||||
{
|
||||
asirraform.appendChild(submitButtonClicked);
|
||||
passThroughFormSubmit = true;
|
||||
asirraform.submit();
|
||||
}
|
||||
}
|
||||
|
||||
contentLoaded(window,PrepareSubmit);
|
Loading…
Reference in a new issue