A Python content management system designed for kirsle.net featuring a blog, comments and photo albums. https://rophako.kirsle.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.6KB

  1. # -*- coding: utf-8 -*-
  2. """Endpoints for user login and out."""
  3. from flask import Blueprint, request, redirect, url_for, session, flash
  4. import re
  5. import rophako.model.user as User
  6. from rophako.utils import template
  7. mod = Blueprint("account", __name__, url_prefix="/account")
  8. @mod.route("/")
  9. def index():
  10. return redirect(url_for(".login"))
  11. @mod.route("/login", methods=["GET", "POST"])
  12. def login():
  13. """Log into an account."""
  14. if request.method == "POST":
  15. username = request.form.get("username", "")
  16. password = request.form.get("password", "")
  17. # Lowercase the username.
  18. username = username.lower()
  19. if User.check_auth(username, password):
  20. # OK!
  21. db = User.get_user(username=username)
  22. session["login"] = True
  23. session["username"] = username
  24. session["uid"] = db["uid"]
  25. session["name"] = db["name"]
  26. session["role"] = db["role"]
  27. return redirect(url_for("index"))
  28. else:
  29. flash("Authentication failed.")
  30. return redirect(url_for(".login"))
  31. return template("account/login.html")
  32. @mod.route("/logout")
  33. def logout():
  34. """Log out the user."""
  35. session["login"] = False
  36. session["username"] = "guest"
  37. session["uid"] = 0
  38. session["name"] = "Guest"
  39. session["role"] = "user"
  40. flash("You have been signed out.")
  41. return redirect(url_for(".login"))
  42. @mod.route("/setup", methods=["GET", "POST"])
  43. def setup():
  44. """Initial setup to create the Admin user account."""
  45. # This can't be done if users already exist on the CMS!
  46. if User.exists(uid=1):
  47. flash("This website has already been configured (users already created).")
  48. return redirect(url_for("index"))
  49. if request.method == "POST":
  50. # Submitting the form.
  51. username = request.form.get("username", "")
  52. name = request.form.get("name", "")
  53. pw1 = request.form.get("password1", "")
  54. pw2 = request.form.get("password2", "")
  55. # Default name = username.
  56. if name == "":
  57. name = username
  58. # Lowercase the user.
  59. username = username.lower()
  60. if User.exists(username=username):
  61. flash("That username already exists.")
  62. return redirect(url_for(".setup"))
  63. # Validate the form.
  64. errors = validate_create_form(username, pw1, pw2)
  65. if errors:
  66. for error in errors:
  67. flash(error)
  68. return redirect(url_for(".setup"))
  69. # Create the account.
  70. uid = User.create(
  71. username=username,
  72. password=pw1,
  73. name=name,
  74. role="admin",
  75. )
  76. flash("Admin user created! Please log in now.".format(uid))
  77. return redirect(url_for(".login"))
  78. return template("account/setup.html")
  79. def validate_create_form(username, pw1=None, pw2=None, skip_passwd=False):
  80. """Validate the submission of a create-user form.
  81. Returns a list of error messages if there were errors, otherwise
  82. it returns None."""
  83. errors = list()
  84. if len(username) == 0:
  85. errors.append("You must provide a username.")
  86. if re.search(r'[^A-Za-z0-9-_]', username):
  87. errors.append("Usernames can only contain letters, numbers, dashes or underscores.")
  88. if not skip_passwd:
  89. if len(pw1) < 3:
  90. errors.append("You should use at least 3 characters in your password.")
  91. if pw1 != pw2:
  92. errors.append("Your passwords don't match.")
  93. if len(errors):
  94. return errors
  95. else:
  96. return None