This module includes support for challenge-response tests posed to users registering for new Sage notebook accounts. These Completely Automated Public Turing tests to tell Computers and Humans Apart, or CAPTCHAs, may be simple math questions, requests for special registration codes, or reCAPTCHAs.
AUTHORS:
Bases: object
An abstract class with a suggested common interface for specific challenge-response schemes.
Returns HTML for the challenge, e.g., to insert into a new account registration page.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import AbstractChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = AbstractChallenge(nb.conf())
sage: chal.html()
...
NotImplementedError
Returns the status of a challenge response.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import AbstractChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = AbstractChallenge(nb.conf())
sage: chal.is_valid_response()
...
NotImplementedError
Bases: object
A simple dispatcher class that provides access to a specific challenge.
Bases: object
A simple challenge response class that indicates whether a response is empty, correct, or incorrect, and, if it’s incorrect, includes an optional error code.
Bases: sagenb.notebook.challenge.AbstractChallenge
A fallback challenge used when an administrator has not configured a specific method.
Returns a suggestion to inform the Notebook server’s administrator about the misconfigured challenge.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import NotConfiguredChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = NotConfiguredChallenge(nb.conf())
sage: chal.html()
'Please ask the server administrator to configure a challenge!'
Always reports a failed response, for the sake of security.
INPUT:
- kwargs - a dictionary of keyword arguments
OUTPUT:
- a ChallengeResponse instance
TESTS:
sage: from sagenb.notebook.challenge import NotConfiguredChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = NotConfiguredChallenge(nb.conf())
sage: chal.is_valid_response().is_valid
False
sage: chal.is_valid_response().error_code
''
Bases: sagenb.notebook.challenge.AbstractChallenge
A simple question and answer challenge.
Returns a HTML form posing a randomly chosen question.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import SimpleChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = SimpleChallenge(nb.conf())
sage: chal.html() # random
'...What is the largest prime factor of 1001?...'
Returns the status of a user’s answer to the challenge question.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import SimpleChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = SimpleChallenge(nb.conf())
sage: req = {}
sage: chal.is_valid_response(req).is_valid
sage: chal.is_valid_response(req).error_code
''
sage: from sagenb.notebook.challenge import QUESTIONS
sage: ques, ans = QUESTIONS.items()[0]
sage: ans = ans.split('|')[0]
sage: print ques
What is 3 times 8?
sage: print ans
24
sage: req['simple_response_field'] = [ans]
sage: chal.is_valid_response(req).is_valid
False
sage: chal.is_valid_response(req).error_code
''
sage: req['simple_challenge_field'] = [ques]
sage: chal.is_valid_response(req).is_valid
True
sage: chal.is_valid_response(req).error_code
''
Returns whether a challenge response agrees with the answer.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import agree
sage: agree('0', r'0|zero')
True
sage: agree('eighty', r'8|eight')
False
Wraps an instance of ChallengeDispatcher and returns an instance of a specific challenge.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import challenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: nb.conf()['challenge_type'] = 'simple'
sage: chal = challenge(nb.conf())
sage: chal.html() # random
'<p>...'
Bases: sagenb.notebook.challenge.AbstractChallenge
A reCAPTCHA challenge adapted from this Python API, also hosted here, written by Ben Maurer and maintained by Josh Bronson.
Returns HTML and JavaScript for a reCAPTCHA challenge and response field.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import reCAPTCHAChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = reCAPTCHAChallenge(nb.conf(), remote_ip = 'localhost')
sage: chal.html()
u'...recaptcha...'
sage: chal.html('incorrect-captcha-sol')
u'...incorrect-captcha-sol...'
Submits a reCAPTCHA request for verification and returns its status.
INPUT:
OUTPUT:
TESTS:
sage: from sagenb.notebook.challenge import reCAPTCHAChallenge
sage: tmp = tmp_dir() + '.sagenb'
sage: import sagenb.notebook.notebook as n
sage: nb = n.Notebook(tmp)
sage: chal = reCAPTCHAChallenge(nb.conf(), remote_ip = 'localhost')
sage: req = {}
sage: chal.is_valid_response(req).is_valid
sage: chal.is_valid_response(req).error_code
''
sage: req['recaptcha_response_field'] = ['subplotTimes']
sage: chal.is_valid_response(req).is_valid
False
sage: chal.is_valid_response(req).error_code
'incorrect-captcha-sol'
sage: req['simple_challenge_field'] = ['VBORw0KGgoANSUhEUgAAAB']
sage: chal.is_valid_response(req).is_valid # random
False
sage: chal.is_valid_response(req).error_code # random
'incorrect-captcha-sol'