Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Authentification part.
4"""
5import base64
6import falcon
7from ..args import encrypt_password, load_passwords
10class AuthMiddleware:
11 """
12 Authentification. The name and secret comes from
13 a file. The file must store encrypted password.
14 """
16 help_url = "http://www.xavierdupre.fr/app/lightmlrestapi/helpsphinx/tutorial/first_rest_api.html"
18 def __init__(self, source, algo="sha224"):
19 """
20 @param source filename or dataframe for encrypted password
21 @param algo algorithm used to hash the passwords
22 """
23 if source is None:
24 raise ValueError("source cannot be empty")
25 self.allowed = load_passwords(source)
26 self.algo = algo
27 self.auth_header_prefix = 'Basic'
29 def parse_auth_token_from_request(self, auth_header):
30 """
31 Parses and returns Auth token from the request header. Raises
32 `falcon.HTTPUnauthoried exception` with proper error message
33 """
35 if not auth_header:
36 raise falcon.HTTPUnauthorized(
37 title='401 Unauthorized', description='Missing Authorization Header')
39 parts = auth_header.split()
41 if parts[0].lower() != self.auth_header_prefix.lower():
42 raise falcon.HTTPUnauthorized(title='401 Unauthorized',
43 description='Invalid Authorization Header: '
44 'Must start with {0}'.format(self.auth_header_prefix))
46 if len(parts) == 1:
47 raise falcon.HTTPUnauthorized(
48 title='401 Unauthorized',
49 description='Invalid Authorization Header: Token Missing')
50 if len(parts) > 2:
51 raise falcon.HTTPUnauthorized(
52 title='401 Unauthorized',
53 description='Invalid Authorization Header: Contains extra content')
55 return parts[1]
57 def process_request(self, req, resp):
58 """
59 Processes an authentification request.
61 @param req request
62 @param resp unused
63 """
64 if req.scheme.lower() != 'https':
65 raise falcon.HTTPBadRequest(title='HTTPS Required',
66 description=('All requests must be performed via the HTTPS protocol. '
67 'Please switch to HTTPS and try again.'))
69 auth = req.get_header('Authorization')
70 token = self.parse_auth_token_from_request(auth_header=auth)
71 try:
72 token = base64.b64decode(token).decode('utf-8')
73 except Exception:
74 raise falcon.HTTPUnauthorized(title='401 Unauthorized',
75 description='Invalid Authorization Header: Unable to decode credentials (1)')
77 try:
78 username, password = token.split(':', 1)
79 except ValueError:
80 raise falcon.HTTPUnauthorized(
81 title='401 Unauthorized',
82 description='Invalid Authorization: Unable to decode credentials (2)')
84 if not self._token_is_valid(username, password):
85 raise falcon.HTTPUnauthorized(
86 "Authentication failed for '{0}'".format(username))
88 def _token_is_valid(self, username, password):
89 """
90 Decides if it is valid or not.
91 """
92 if username not in self.allowed:
93 return False
94 enc = encrypt_password(password, algo=self.algo)
95 return self.allowed[username] == enc