Guest User

Untitled

a guest
Dec 16th, 2018
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.76 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. """
  4. A real simple app for using webapp2 with auth and session.
  5.  
  6. It just covers the basics. Creating a user, login, logout and a decorator for protecting certain handlers.
  7.  
  8. PRE-REQUIREMENTS:
  9.  
  10. Set at secret_key in webapp2 config:
  11. webapp2_config = {}
  12. webapp2_config['webapp2_extras.sessions'] = {
  13. 'secret_key': 'Im_an_alien',
  14. }
  15.  
  16. You need to either set upp the following routes:
  17.  
  18. app = webapp2.WSGIApplication([
  19. webapp2.Route(r'/login/', handler=LoginHandler, name='login'),
  20. webapp2.Route(r'/logout/', handler=LogoutHandler, name='logout'),
  21. webapp2.Route(r'/login/', handler=SecureRequestHandler, name='secure'),
  22. webapp2.Route(r'/secure/', handler=CreateUserHandler, name='create-user'),
  23.  
  24. ])
  25.  
  26. OR:
  27.  
  28. Change the urls in BaseHandler.auth_config to match LoginHandler/LogoutHandler
  29. And also change the url in the post method of the LoginHandler to redirect to to a page requiring a user session
  30. """
  31.  
  32. import webapp2
  33. from webapp2_extras import auth
  34. from webapp2_extras import sessions
  35. from webapp2_extras.auth import InvalidAuthIdError
  36. from webapp2_extras.auth import InvalidPasswordError
  37.  
  38. def user_required(handler):
  39. """
  40. Decorator for checking if there's a user associated with the current session.
  41. Will also fail if there's no session present.
  42. """
  43. def check_login(self, *args, **kwargs):
  44. auth = self.auth
  45. if not auth.get_user_by_session():
  46. # If handler has no login_url specified invoke a 403 error
  47. try:
  48. self.redirect(self.auth_config['login_url'], abort=True)
  49. except (AttributeError, KeyError), e:
  50. self.abort(403)
  51. else:
  52. return handler(self, *args, **kwargs)
  53.  
  54. return check_login
  55.  
  56. class BaseHandler(webapp2.RequestHandler):
  57. """
  58. BaseHandler for all requests
  59.  
  60. Holds the auth and session properties so they are reachable for all requests
  61. """
  62. def dispatch(self):
  63. """
  64. Save the sessions for preservation across requests
  65. """
  66. try:
  67. response = super(BaseHandler, self).dispatch()
  68. self.response.write(response)
  69. finally:
  70. self.session_store.save_sessions(self.response)
  71.  
  72. @webapp2.cached_property
  73. def auth(self):
  74. return auth.get_auth()
  75.  
  76. @webapp2.cached_property
  77. def session_store(self):
  78. return sessions.get_store(request=self.request)
  79.  
  80. @webapp2.cached_property
  81. def auth_config(self):
  82. """
  83. Dict to hold urls for login/logout
  84. """
  85. return {
  86. 'login_url': self.uri_for('login'),
  87. 'logout_url': self.uri_for('logout')
  88. }
  89.  
  90.  
  91. class LoginHandler(BaseHandler):
  92. def get(self):
  93. """
  94. Returns a simple HTML form for login
  95. """
  96. return """
  97. <!DOCTYPE hml>
  98. <html>
  99. <head>
  100. <title>webapp2 auth example</title>
  101. </head>
  102. <body>
  103. <form action="%s" method="post">
  104. <fieldset>
  105. <legend>Login form</legend>
  106. <label>Username <input type="text" name="username" placeholder="Your username" /></label>
  107. <label>Password <input type="password" name="password" placeholder="Your password" /></label>
  108. </fieldset>
  109. <button>Login</button>
  110. </form>
  111. </html>
  112. """ % self.request.url
  113.  
  114. def post(self):
  115. """
  116. username: Get the username from POST dict
  117. password: Get the password from POST dict
  118. """
  119. username = self.request.POST.get('username')
  120. password = self.request.POST.get('password')
  121. # Try to login user with password
  122. # Raises InvalidAuthIdError if user is not found
  123. # Raises InvalidPasswordError if provided password doesn't match with specified user
  124. try:
  125. self.auth.get_user_by_password(username, password)
  126. self.redirect('/secure')
  127. except (InvalidAuthIdError, InvalidPasswordError), e:
  128. # Returns error message to self.response.write in the BaseHandler.dispatcher
  129. # Currently no message is attached to the exceptions
  130. return e
  131.  
  132. class CreateUserHandler(BaseHandler):
  133. def get(self):
  134. """
  135. Returns a simple HTML form for create a new user
  136. """
  137. return """
  138. <!DOCTYPE hml>
  139. <html>
  140. <head>
  141. <title>webapp2 auth example</title>
  142. </head>
  143. <body>
  144. <form action="%s" method="post">
  145. <fieldset>
  146. <legend>Create user form</legend>
  147. <label>Username <input type="text" name="username" placeholder="Your username" /></label>
  148. <label>Password <input type="password" name="password" placeholder="Your password" /></label>
  149. </fieldset>
  150. <button>Create user</button>
  151. </form>
  152. </html>
  153. """ % self.request.url
  154.  
  155. def post(self):
  156. """
  157. username: Get the username from POST dict
  158. password: Get the password from POST dict
  159. """
  160. username = self.request.POST.get('username')
  161. password = self.request.POST.get('password')
  162. # Passing password_raw=password so password will be hashed
  163. # Returns a tuple, where first value is BOOL. If True ok, If False no new user is created
  164. user = self.auth.store.user_model.create_user(username, password_raw=password)
  165. if not user[0]: #user is a tuple
  166. return user[1] # Error message
  167. else:
  168. # User is created, let's try redirecting to login page
  169. try:
  170. self.redirect(self.auth_config['login_url'], abort=True)
  171. except (AttributeError, KeyError), e:
  172. self.abort(403)
  173.  
  174.  
  175. class LogoutHandler(BaseHandler):
  176. """
  177. Destroy user session and redirect to login
  178. """
  179. def get(self):
  180. self.auth.unset_session()
  181. # User is logged out, let's try redirecting to login page
  182. try:
  183. self.redirect(self.auth_config['login_url'])
  184. except (AttributeError, KeyError), e:
  185. return "User is logged out"
  186.  
  187.  
  188. class SecureRequestHandler(BaseHandler):
  189. """
  190. Only accessible to users that are logged in
  191. """
  192. @user_required
  193. def get(self, **kwargs):
  194. a = self.app.config.get('foo')
  195. try:
  196. return "Secure zone %s <a href='%s'>Logout</a>" % (a, self.auth_config['logout_url'])
  197. except (AttributeError, KeyError), e:
  198. return "Secure zone"
Add Comment
Please, Sign In to add comment