Update cherrpy to 17.4.2
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# This file is part of CherryPy <http://www.cherrypy.org/>
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim:ts=4:sw=4:expandtab:fileencoding=utf-8
|
||||
"""HTTP Basic Authentication tool.
|
||||
|
||||
__doc__ = """This module provides a CherryPy 3.x tool which implements
|
||||
This module provides a CherryPy 3.x tool which implements
|
||||
the server-side of HTTP Basic Access Authentication, as described in
|
||||
:rfc:`2617`.
|
||||
|
||||
@@ -14,18 +15,23 @@ as the credentials store::
|
||||
basic_auth = {'tools.auth_basic.on': True,
|
||||
'tools.auth_basic.realm': 'earth',
|
||||
'tools.auth_basic.checkpassword': checkpassword,
|
||||
'tools.auth_basic.accept_charset': 'UTF-8',
|
||||
}
|
||||
app_config = { '/' : basic_auth }
|
||||
|
||||
"""
|
||||
|
||||
import binascii
|
||||
import unicodedata
|
||||
import base64
|
||||
|
||||
import cherrypy
|
||||
from cherrypy._cpcompat import ntou, tonative
|
||||
|
||||
|
||||
__author__ = 'visteya'
|
||||
__date__ = 'April 2009'
|
||||
|
||||
import binascii
|
||||
from cherrypy._cpcompat import base64_decode
|
||||
import cherrypy
|
||||
|
||||
|
||||
def checkpassword_dict(user_password_dict):
|
||||
"""Returns a checkpassword function which checks credentials
|
||||
@@ -42,9 +48,10 @@ def checkpassword_dict(user_password_dict):
|
||||
return checkpassword
|
||||
|
||||
|
||||
def basic_auth(realm, checkpassword, debug=False):
|
||||
def basic_auth(realm, checkpassword, debug=False, accept_charset='utf-8'):
|
||||
"""A CherryPy tool which hooks at before_handler to perform
|
||||
HTTP Basic Access Authentication, as specified in :rfc:`2617`.
|
||||
HTTP Basic Access Authentication, as specified in :rfc:`2617`
|
||||
and :rfc:`7617`.
|
||||
|
||||
If the request has an 'authorization' header with a 'Basic' scheme, this
|
||||
tool attempts to authenticate the credentials supplied in that header. If
|
||||
@@ -64,27 +71,50 @@ def basic_auth(realm, checkpassword, debug=False):
|
||||
|
||||
"""
|
||||
|
||||
fallback_charset = 'ISO-8859-1'
|
||||
|
||||
if '"' in realm:
|
||||
raise ValueError('Realm cannot contain the " (quote) character.')
|
||||
request = cherrypy.serving.request
|
||||
|
||||
auth_header = request.headers.get('authorization')
|
||||
if auth_header is not None:
|
||||
try:
|
||||
# split() error, base64.decodestring() error
|
||||
msg = 'Bad Request'
|
||||
with cherrypy.HTTPError.handle((ValueError, binascii.Error), 400, msg):
|
||||
scheme, params = auth_header.split(' ', 1)
|
||||
if scheme.lower() == 'basic':
|
||||
username, password = base64_decode(params).split(':', 1)
|
||||
charsets = accept_charset, fallback_charset
|
||||
decoded_params = base64.b64decode(params.encode('ascii'))
|
||||
decoded_params = _try_decode(decoded_params, charsets)
|
||||
decoded_params = ntou(decoded_params)
|
||||
decoded_params = unicodedata.normalize('NFC', decoded_params)
|
||||
decoded_params = tonative(decoded_params)
|
||||
username, password = decoded_params.split(':', 1)
|
||||
if checkpassword(realm, username, password):
|
||||
if debug:
|
||||
cherrypy.log('Auth succeeded', 'TOOLS.AUTH_BASIC')
|
||||
request.login = username
|
||||
return # successful authentication
|
||||
# split() error, base64.decodestring() error
|
||||
except (ValueError, binascii.Error):
|
||||
raise cherrypy.HTTPError(400, 'Bad Request')
|
||||
|
||||
charset = accept_charset.upper()
|
||||
charset_declaration = (
|
||||
(', charset="%s"' % charset)
|
||||
if charset != fallback_charset
|
||||
else ''
|
||||
)
|
||||
# Respond with 401 status and a WWW-Authenticate header
|
||||
cherrypy.serving.response.headers[
|
||||
'www-authenticate'] = 'Basic realm="%s"' % realm
|
||||
cherrypy.serving.response.headers['www-authenticate'] = (
|
||||
'Basic realm="%s"%s' % (realm, charset_declaration)
|
||||
)
|
||||
raise cherrypy.HTTPError(
|
||||
401, "You are not authorized to access that resource")
|
||||
401, 'You are not authorized to access that resource')
|
||||
|
||||
|
||||
def _try_decode(subject, charsets):
|
||||
for charset in charsets[:-1]:
|
||||
try:
|
||||
return tonative(subject, charset)
|
||||
except ValueError:
|
||||
pass
|
||||
return tonative(subject, charsets[-1])
|
||||
|
||||
Reference in New Issue
Block a user