simbha

webapp2_extras implementation

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