61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
''' Exports Authenticator. '''
|
|
|
|
import base64
|
|
import falcon
|
|
from szurubooru.model.user import User
|
|
from szurubooru.services.errors import AuthError
|
|
|
|
class Authenticator(object):
|
|
'''
|
|
Authenticates every request and puts information on active user in the
|
|
request context.
|
|
'''
|
|
|
|
def __init__(self, auth_service, user_service):
|
|
self._auth_service = auth_service
|
|
self._user_service = user_service
|
|
|
|
def process_request(self, request, response):
|
|
''' Executed before passing the request to the API. '''
|
|
request.context.user = self._get_user(request)
|
|
|
|
def _get_user(self, request):
|
|
if not request.auth:
|
|
return self._create_anonymous_user()
|
|
|
|
try:
|
|
auth_type, user_and_password = request.auth.split(' ', 1)
|
|
|
|
if auth_type.lower() != 'basic':
|
|
raise falcon.HTTPBadRequest(
|
|
'Invalid authentication type',
|
|
'Only basic authorization is supported.')
|
|
|
|
username, password = base64.decodebytes(
|
|
user_and_password.encode('ascii')).decode('utf8').split(':')
|
|
|
|
session = request.context.session
|
|
return self._authenticate(session, username, password)
|
|
except ValueError as err:
|
|
msg = 'Basic authentication header value not properly formed. ' \
|
|
+ 'Supplied header {0}. Got error: {1}'
|
|
raise falcon.HTTPBadRequest(
|
|
'Malformed authentication request',
|
|
msg.format(request.auth, str(err)))
|
|
|
|
def _authenticate(self, session, username, password):
|
|
''' Tries to authenticate user. Throws AuthError for invalid users. '''
|
|
user = self._user_service.get_by_name(session, username)
|
|
if not user:
|
|
raise AuthError('No such user.')
|
|
if not self._auth_service.is_valid_password(user, password):
|
|
raise AuthError('Invalid password.')
|
|
return user
|
|
|
|
def _create_anonymous_user(self):
|
|
user = User()
|
|
user.name = None
|
|
user.access_rank = 'anonymous'
|
|
user.password = None
|
|
return user
|