##// END OF EJS Templates
Set secure cookie by default if login handler is hit....
Matthias Bussonnier -
Show More
@@ -1,95 +1,101 b''
1 1 """Tornado handlers for logging into the notebook."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 import uuid
7 7
8 8 from tornado.escape import url_escape
9 9
10 10 from IPython.lib.security import passwd_check
11 11
12 12 from ..base.handlers import IPythonHandler
13 13
14 14
15 15 class LoginHandler(IPythonHandler):
16 16 """The basic tornado login handler
17 17
18 18 authenticates with a hashed password from the configuration.
19 19 """
20 20 def _render(self, message=None):
21 21 self.write(self.render_template('login.html',
22 22 next=url_escape(self.get_argument('next', default=self.base_url)),
23 23 message=message,
24 24 ))
25 25
26 26 def get(self):
27 27 if self.current_user:
28 28 self.redirect(self.get_argument('next', default=self.base_url))
29 29 else:
30 30 self._render()
31 31
32 32 @property
33 33 def hashed_password(self):
34 34 return self.password_from_settings(self.settings)
35 35
36 36 def post(self):
37 37 typed_password = self.get_argument('password', default=u'')
38 38 if self.login_available(self.settings):
39 39 if passwd_check(self.hashed_password, typed_password):
40 self.set_secure_cookie(self.cookie_name, str(uuid.uuid4()))
40 # tornado <4.2 have a bug that consider secure==True as soon as
41 # 'secure' kwarg is passed to set_secure_cookie
42 if self.settings.get('secure_cookie', self.request.protocol == 'https'):
43 kwargs = {'secure':True}
44 else:
45 kwargs = {}
46 self.set_secure_cookie(self.cookie_name, str(uuid.uuid4()), **kwargs)
41 47 else:
42 48 self._render(message={'error': 'Invalid password'})
43 49 return
44 50
45 51 self.redirect(self.get_argument('next', default=self.base_url))
46 52
47 53 @classmethod
48 54 def get_user(cls, handler):
49 55 """Called by handlers.get_current_user for identifying the current user.
50 56
51 57 See tornado.web.RequestHandler.get_current_user for details.
52 58 """
53 59 # Can't call this get_current_user because it will collide when
54 60 # called on LoginHandler itself.
55 61
56 62 user_id = handler.get_secure_cookie(handler.cookie_name)
57 63 # For now the user_id should not return empty, but it could, eventually.
58 64 if user_id == '':
59 65 user_id = 'anonymous'
60 66 if user_id is None:
61 67 # prevent extra Invalid cookie sig warnings:
62 68 handler.clear_login_cookie()
63 69 if not handler.login_available:
64 70 user_id = 'anonymous'
65 71 return user_id
66 72
67 73
68 74 @classmethod
69 75 def validate_security(cls, app, ssl_options=None):
70 76 """Check the notebook application's security.
71 77
72 78 Show messages, or abort if necessary, based on the security configuration.
73 79 """
74 80 if not app.ip:
75 81 warning = "WARNING: The notebook server is listening on all IP addresses"
76 82 if ssl_options is None:
77 83 app.log.warning(warning + " and not using encryption. This "
78 84 "is not recommended.")
79 85 if not app.password:
80 86 app.log.warning(warning + " and not using authentication. "
81 87 "This is highly insecure and not recommended.")
82 88
83 89 @classmethod
84 90 def password_from_settings(cls, settings):
85 91 """Return the hashed password from the tornado settings.
86 92
87 93 If there is no configured password, an empty string will be returned.
88 94 """
89 95 return settings.get('password', u'')
90 96
91 97 @classmethod
92 98 def login_available(cls, settings):
93 99 """Whether this LoginHandler is needed - and therefore whether the login page should be displayed."""
94 100 return bool(cls.password_from_settings(settings))
95 101
General Comments 0
You need to be logged in to leave comments. Login now