Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

106 wiersze
3.6KB

  1. import web
  2. from views.forms import login_form
  3. import models.user
  4. from views.utils import get_nav_bar
  5. import os, hmac, base64, pickle
  6. import hashlib
  7. # Get html templates
  8. render = web.template.render('templates/')
  9. class Login():
  10. # Get the server secret to perform signatures
  11. secret = web.config.get('session_parameters')['secret_key']
  12. def GET(self):
  13. """
  14. Show the login page
  15. :return: The login page showing other users if logged in
  16. """
  17. session = web.ctx.session
  18. nav = get_nav_bar(session)
  19. # Log the user in if the rememberme cookie is set and valid
  20. self.check_rememberme()
  21. return render.login(nav, login_form, "")
  22. def POST(self):
  23. """
  24. Log in to the web application and register the session
  25. :return: The login page showing other users if logged in
  26. """
  27. session = web.ctx.session
  28. nav = get_nav_bar(session)
  29. data = web.input(username="", password="", remember=False)
  30. # Validate login credential with database query
  31. password_hash = hashlib.md5(b'TDT4237' + data.password.encode('utf-8')).hexdigest()
  32. user = models.user.match_user(data.username, password_hash)
  33. # If there is a matching user/password in the database the user is logged in
  34. if user:
  35. self.login(user[1], user[0], data.remember)
  36. raise web.seeother("/")
  37. else:
  38. return render.login(nav, login_form, "- User authentication failed")
  39. def login(self, username, userid, remember):
  40. """
  41. Log in to the application
  42. """
  43. session = web.ctx.session
  44. session.username = username
  45. session.userid = userid
  46. if remember:
  47. rememberme = self.rememberme()
  48. web.setcookie('remember', rememberme , 300000000)
  49. def check_rememberme(self):
  50. """
  51. Validate the rememberme cookie and log in
  52. """
  53. username = ""
  54. sign = ""
  55. # If the user selected 'remember me' they log in automatically
  56. try:
  57. # Fetch the users cookies if it exists
  58. cookies = web.cookies()
  59. # Fetch the remember cookie and convert from string to bytes
  60. remember_hash = bytes(cookies.remember[2:][:-1], 'ascii')
  61. # Decode the hash
  62. decode = base64.b64decode(remember_hash)
  63. # Load the decoded hash to receive the host signature and the username
  64. username, sign = pickle.loads(decode)
  65. except AttributeError as e:
  66. # The user did not have the stored remember me cookie
  67. pass
  68. # If the users signed cookie matches the host signature then log in
  69. if self.sign_username(username) == sign:
  70. userid = models.user.get_user_id_by_name(username)
  71. self.login(username, userid, False)
  72. def rememberme(self):
  73. """
  74. Encode a base64 object consisting of the username signed with the
  75. host secret key and the username. Can be reassembled with the
  76. hosts secret key to validate user.
  77. :return: base64 object consisting of signed username and username
  78. """
  79. session = web.ctx.session
  80. creds = [ session.username, self.sign_username(session.username) ]
  81. return base64.b64encode(pickle.dumps(creds))
  82. @classmethod
  83. def sign_username(self, username):
  84. """
  85. Sign the current users name with the hosts secret key
  86. :return: The users signed name
  87. """
  88. secret = base64.b64decode(self.secret)
  89. return hmac.HMAC(secret, username.encode('ascii')).hexdigest()