159 lines
6.1 KiB
Python
159 lines
6.1 KiB
Python
from datetime import datetime
|
|
|
|
import flask_admin as admin
|
|
from flask import flash
|
|
from flask import redirect
|
|
from flask import request
|
|
from flask import url_for
|
|
from flask_admin import expose
|
|
from flask_admin import helpers
|
|
from flask_admin.contrib.fileadmin import FileAdmin
|
|
from flask_login import current_user
|
|
from flask_login import login_user
|
|
from flask_login import logout_user
|
|
from peewee import DoesNotExist
|
|
from werkzeug.security import check_password_hash
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
from afpy.forms.auth import ChangePasswordForm
|
|
from afpy.forms.auth import LoginForm
|
|
from afpy.forms.auth import RegistrationForm
|
|
from afpy.models.AdminUser import AdminUser
|
|
from afpy.models.JobPost import JobPost
|
|
from afpy.models.NewsEntry import NewsEntry
|
|
|
|
|
|
# Create customized index view class that handles login & registration
|
|
class AdminIndexView(admin.AdminIndexView):
|
|
@expose("/")
|
|
def index(self):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for(".login_view"))
|
|
return super(AdminIndexView, self).index()
|
|
|
|
@expose("/login/", methods=("GET", "POST"))
|
|
def login_view(self):
|
|
# handle user login
|
|
form = LoginForm(request.form)
|
|
if helpers.validate_form_on_submit(form):
|
|
try:
|
|
user = AdminUser.get(AdminUser.email == form.email_or_username.data)
|
|
except DoesNotExist:
|
|
user = AdminUser.get(AdminUser.username == form.email_or_username.data)
|
|
if check_password_hash(user.password, form.password.data):
|
|
login_user(user)
|
|
else:
|
|
flash("Incorrect username or password")
|
|
|
|
if current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
self._template_args["form"] = form
|
|
return super(AdminIndexView, self).index()
|
|
|
|
@expose("/logout/")
|
|
def logout_view(self):
|
|
logout_user()
|
|
return redirect(url_for("admin.index"))
|
|
|
|
|
|
class NewAdminView(admin.BaseView):
|
|
@expose("/", methods=("GET", "POST"))
|
|
def register_view(self):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
form = RegistrationForm(request.form)
|
|
if helpers.validate_form_on_submit(form):
|
|
AdminUser.create(
|
|
email=form.email.data,
|
|
username=form.username.data,
|
|
password=generate_password_hash(form.password.data),
|
|
dt_added=datetime.now(),
|
|
).save()
|
|
return redirect(url_for("admin.index"))
|
|
return self.render("admin/create_user.html", form=form)
|
|
|
|
|
|
class ChangePasswordView(admin.BaseView):
|
|
@expose("/", methods=("GET", "POST"))
|
|
def change_password_view(self):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
form = ChangePasswordForm(request.form)
|
|
if helpers.validate_form_on_submit(form):
|
|
if not check_password_hash(current_user.password, form.old_password.data):
|
|
flash("Incorrect old password.")
|
|
return self.render("admin/change_password.html", form=form)
|
|
if not form.new_password.data == form.new_password_confirmation.data:
|
|
flash("Passwords don't match.")
|
|
return self.render("admin/change_password.html", form=form)
|
|
current_user.password = generate_password_hash(form.new_password.data)
|
|
current_user.save()
|
|
return redirect(url_for("admin.index"))
|
|
return self.render("admin/change_password.html", form=form)
|
|
|
|
|
|
class ModerateView(admin.BaseView):
|
|
@expose("/", methods=["GET"])
|
|
def home_moderation(self):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
return self.render("admin/moderation_home.html")
|
|
|
|
@expose("/<type>", methods=["GET"])
|
|
def moderate_view(self, type):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
if type == "jobs":
|
|
jobs = JobPost.select().where(JobPost.state == "waiting").order_by(JobPost.dt_submitted.desc())
|
|
return self.render("admin/moderate_view.html", items=jobs, type=type)
|
|
elif type == "news":
|
|
news = NewsEntry.select().where(NewsEntry.state == "waiting").order_by(NewsEntry.dt_submitted.desc())
|
|
return self.render("admin/moderate_view.html", items=news, type=type)
|
|
else:
|
|
flash("Wrong type")
|
|
return redirect(url_for("admin.index"))
|
|
|
|
@expose("/preview/<type>/<id>", methods=["GET"])
|
|
def preview_item(self, type, id):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
if type == "jobs":
|
|
job = JobPost.get_by_id(id)
|
|
return self.render("pages/job.html", job=job, preview=True)
|
|
elif type == "news":
|
|
news = NewsEntry.get_by_id(id)
|
|
return self.render("pages/post.html", post=news, preview=True)
|
|
else:
|
|
flash("Wrong type")
|
|
return redirect(url_for("admin.index"))
|
|
|
|
@expose("/moderate/action/<id>/<type>/<action>", methods=["GET"])
|
|
def moderate_action(self, id, type, action):
|
|
if not current_user.is_authenticated:
|
|
return redirect(url_for("admin.index"))
|
|
if type == "jobs":
|
|
item = JobPost.get_by_id(id)
|
|
elif type == "news":
|
|
item = NewsEntry.get_by_id(id)
|
|
else:
|
|
flash("Wrong type")
|
|
return redirect(url_for("admin.index"))
|
|
if action == "approve":
|
|
item.state = "published"
|
|
item.approved_by = current_user.id
|
|
item.dt_published = datetime.now()
|
|
item.save()
|
|
elif action == "reject":
|
|
item.state = "rejected"
|
|
item.approved_by = current_user.id
|
|
item.save()
|
|
else:
|
|
flash("Wrong action type")
|
|
return redirect(url_for("admin.index"))
|
|
return redirect(url_for(".moderate_view", type=type))
|
|
|
|
|
|
class CustomFileAdmin(FileAdmin):
|
|
def is_accessible(self):
|
|
return current_user.is_authenticated
|