Hide keyboard shortcuts

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 

8 

9 

10class AuthMiddleware: 

11 """ 

12 Authentification. The name and secret comes from 

13 a file. The file must store encrypted password. 

14 """ 

15 

16 help_url = "http://www.xavierdupre.fr/app/lightmlrestapi/helpsphinx/tutorial/first_rest_api.html" 

17 

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' 

28 

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 """ 

34 

35 if not auth_header: 

36 raise falcon.HTTPUnauthorized( 

37 title='401 Unauthorized', description='Missing Authorization Header') 

38 

39 parts = auth_header.split() 

40 

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)) 

45 

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') 

54 

55 return parts[1] 

56 

57 def process_request(self, req, resp): 

58 """ 

59 Processes an authentification request. 

60 

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.')) 

68 

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)') 

76 

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)') 

83 

84 if not self._token_is_valid(username, password): 

85 raise falcon.HTTPUnauthorized( 

86 "Authentication failed for '{0}'".format(username)) 

87 

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