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.

193 lines
5.3KB

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. """Endpoints for admin functions."""
  4. from flask import g, Blueprint, request, redirect, url_for, session, flash
  5. import rophako.model.user as User
  6. import rophako.model.tracking as Tracking
  7. from rophako.modules.account import validate_create_form
  8. from rophako.utils import template, admin_required
  9. mod = Blueprint("admin", __name__, url_prefix="/admin")
  10. @mod.route("/")
  11. @admin_required
  12. def index():
  13. return template("admin/index.html")
  14. @mod.route("/users")
  15. @admin_required
  16. def users():
  17. # Get the list of existing users.
  18. users = User.list_users()
  19. return template("admin/users.html",
  20. users=users,
  21. )
  22. @mod.route("/users/create", methods=["POST"])
  23. @admin_required
  24. def create_user():
  25. # Submitting the form.
  26. username = request.form.get("username", "")
  27. name = request.form.get("name", "")
  28. pw1 = request.form.get("password1", "")
  29. pw2 = request.form.get("password2", "")
  30. role = request.form.get("role", "")
  31. # Default name = username.
  32. if name == "":
  33. name = username
  34. # Lowercase the user.
  35. username = username.lower()
  36. if User.exists(username=username):
  37. flash("That username already exists.")
  38. return redirect(url_for(".users"))
  39. # Validate the form.
  40. errors = validate_create_form(username, pw1, pw2)
  41. if errors:
  42. for error in errors:
  43. flash(error)
  44. return redirect(url_for(".users"))
  45. # Create the account.
  46. uid = User.create(
  47. username=username,
  48. password=pw1,
  49. name=name,
  50. role=role,
  51. )
  52. flash("User created!")
  53. return redirect(url_for(".users"))
  54. @mod.route("/users/edit/<uid>", methods=["GET", "POST"])
  55. @admin_required
  56. def edit_user(uid):
  57. uid = int(uid)
  58. user = User.get_user(uid=uid)
  59. # Submitting?
  60. if request.method == "POST":
  61. action = request.form.get("action", "")
  62. username = request.form.get("username", "")
  63. name = request.form.get("name", "")
  64. pw1 = request.form.get("password1", "")
  65. pw2 = request.form.get("password2", "")
  66. role = request.form.get("role", "")
  67. username = username.lower()
  68. if action == "save":
  69. # Validate...
  70. errors = None
  71. # Don't allow them to change the username to one that exists.
  72. if username != user["username"]:
  73. if User.exists(username=username):
  74. flash("That username already exists.")
  75. return redirect(url_for(".edit_user", uid=uid))
  76. # Password provided?
  77. if len(pw1) > 0:
  78. errors = validate_create_form(username, pw1, pw2)
  79. elif username != user["username"]:
  80. # Just validate the username, then.
  81. errors = validate_create_form(username, skip_passwd=True)
  82. if errors:
  83. for error in errors:
  84. flash(error)
  85. return redirect(url_for(".edit_user", uid=uid))
  86. # Update the user.
  87. user["username"] = username
  88. user["name"] = name or username
  89. user["role"] = role
  90. if len(pw1) > 0:
  91. user["password"] = User.hash_password(pw1)
  92. User.update_user(uid, user)
  93. flash("User account updated!")
  94. return redirect(url_for(".users"))
  95. elif action == "delete":
  96. # Don't let them delete themself!
  97. if uid == g.info["session"]["uid"]:
  98. flash("You shouldn't delete yourself!")
  99. return redirect(url_for(".edit_user", uid=uid))
  100. User.delete_user(uid)
  101. flash("User deleted!")
  102. return redirect(url_for(".users"))
  103. return template("admin/edit_user.html",
  104. info=user,
  105. )
  106. @mod.route("/impersonate/<int:uid>")
  107. @admin_required
  108. def impersonate(uid):
  109. """Impersonate a user."""
  110. # Check that they exist.
  111. if not User.exists(uid=uid):
  112. flash("That user ID wasn't found.")
  113. return redirect(url_for(".users"))
  114. db = User.get_user(uid=uid)
  115. if db["role"] == "deleted":
  116. flash("That user was deleted!")
  117. return redirect(url_for(".users"))
  118. # Log them in!
  119. orig_uid = session["uid"]
  120. session.update(
  121. login=True,
  122. uid=uid,
  123. username=db["username"],
  124. name=db["name"],
  125. role=db["role"],
  126. impersonator=orig_uid,
  127. )
  128. flash("Now logged in as {}".format(db["name"]))
  129. return redirect(url_for("index"))
  130. @mod.route("/unimpersonate")
  131. def unimpersonate():
  132. """Unimpersonate a user."""
  133. # Must be impersonating, first!
  134. if not "impersonator" in session:
  135. flash("Stop messing around.")
  136. return redirect(url_for("index"))
  137. uid = session.pop("impersonator")
  138. db = User.get_user(uid=uid)
  139. session.update(
  140. login=True,
  141. uid=uid,
  142. username=db["username"],
  143. name=db["name"],
  144. role=db["role"],
  145. )
  146. flash("No longer impersonating.")
  147. return redirect(url_for("index"))
  148. @mod.route("/maint/rebuild_visitor_counts")
  149. @admin_required
  150. def rebuild_visitor_counts():
  151. """Rebuild visitor counts."""
  152. Tracking.rebuild_visitor_stats()
  153. flash("Visitor counts recalculated.")
  154. return redirect(url_for(".index"))