Merge branch 'main' into gamelimit
This commit is contained in:
		
						commit
						c9541ae89e
					
				| @ -10,3 +10,4 @@ DB_PORT=3306 | ||||
| DB_USER="" | ||||
| DB_PASSWORD="" | ||||
| DB_DBNAME="" | ||||
| ADMIN_PASSWORD="s0meV3ryL0ngP@sswOrd" | ||||
| @ -1,3 +1,5 @@ | ||||
| import uuid | ||||
| 
 | ||||
| from sqlalchemy import Column, Integer, VARCHAR, Text, LargeBinary, ForeignKey | ||||
| from sqlalchemy.orm import relationship, declarative_base | ||||
| 
 | ||||
| @ -50,6 +52,27 @@ class Locale(Base): | ||||
|     def __repr__(self) -> str: | ||||
|         return self.__str__() | ||||
| 
 | ||||
|     def get_texts(self, lang): | ||||
|         texts = [] | ||||
|         for text in self.TEXTS: | ||||
|             if text.LANG == lang: | ||||
|                 texts.append(text) | ||||
|         return texts | ||||
| 
 | ||||
|     def get_text(self, lang, auto_create=False): | ||||
|         for text in self.TEXTS: | ||||
|             if text.LANG == lang: | ||||
|                 return text | ||||
|          | ||||
|         if auto_create: | ||||
|             text = Text(None, None, lang, None) | ||||
|             self.TEXTS.append(text) | ||||
|             return text | ||||
|         else: | ||||
|             return None | ||||
| 
 | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
| class Place(Base): | ||||
|     """ | ||||
| @ -59,7 +82,7 @@ class Place(Base): | ||||
|     __tablename__ = 'T_PLACE' | ||||
|     PLACE_ID = Column(Integer, primary_key=True, autoincrement=True, comment="ID of this place") | ||||
|     NAME_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Place name") | ||||
|     LOCALE = relationship("Locale") | ||||
|     NAME_LOCALE = relationship("Locale") | ||||
| 
 | ||||
|     def __init__(self, PLACE_ID, NAME_LID): | ||||
|         self.PLACE_ID = PLACE_ID | ||||
| @ -80,7 +103,7 @@ class QuestionType(Base): | ||||
|     __tablename__ = "T_QUESTION_TYPE" | ||||
|     QUESTION_TYPE_ID = Column(Integer, default=0, primary_key=True, comment="ID of this question type.") | ||||
|     TEXT_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Question text") | ||||
|     LOCALE = relationship("Locale") | ||||
|     TEXT_LOCALE = relationship("Locale") | ||||
| 
 | ||||
|     def __init__(self, QUESTION_TYPE_ID, TEXT_LID): | ||||
|         self.QUESTION_TYPE_ID = QUESTION_TYPE_ID | ||||
| @ -103,7 +126,7 @@ class Answer(Base): | ||||
|     QUESTION_TYPE_ID = Column(Integer, ForeignKey("T_QUESTION_TYPE.QUESTION_TYPE_ID"), primary_key=True, comment="Question type ID") | ||||
|     NPC_ID = Column(Integer, ForeignKey("T_NPC.NPC_ID"), primary_key=True, comment="ID of the NPC that will say this answer") | ||||
|     TEXT_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Text of the answer") | ||||
|     LOCALE = relationship("Locale") | ||||
|     TEXT_LOCALE = relationship("Locale") | ||||
|     NPC = relationship("Npc", backref="ANSWERS") | ||||
| 
 | ||||
|     def __init__(self, QUESTION_TYPE_ID, NPC_ID, TEXT_LID): | ||||
| @ -128,7 +151,7 @@ class Npc(Base): | ||||
|     NPC_ID = Column(Integer, autoincrement=True, primary_key=True, comment="ID of this Npc") | ||||
|     NAME_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Name of this Npc") | ||||
|     DEFAULT_IMG = Column(LargeBinary(length=2**24), comment="Binary data of the default image of this Npc") | ||||
|     LOCALE = relationship("Locale") | ||||
|     NAME_LOCALE = relationship("Locale") | ||||
| 
 | ||||
|     def __init__(self, NPC_ID, NAME_LID): | ||||
|         self.NPC_ID = NPC_ID | ||||
| @ -150,8 +173,8 @@ class Trait(Base): | ||||
|     NAME_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Name of this trait") | ||||
|     DESC_LID = Column(Integer, ForeignKey("T_LOCALE.LID"), comment="Description of this trait") | ||||
| 
 | ||||
|     Name = relationship("Locale",foreign_keys=[NAME_LID]) | ||||
|     Desc = relationship("Locale",foreign_keys=[DESC_LID]) | ||||
|     NAME_LOCALE = relationship("Locale",foreign_keys=[NAME_LID]) | ||||
|     DESC_LOCALE = relationship("Locale",foreign_keys=[DESC_LID]) | ||||
| 
 | ||||
| 
 | ||||
|     def __init__(self, TRAIT_ID, NAME_LID, DESC_LID): | ||||
| @ -177,14 +200,16 @@ class Reaction(Base): | ||||
|     IMG = Column(LargeBinary(length=2**24), comment="Binary data of the image associated to this npc and trait") | ||||
|     NPC = relationship("Npc") | ||||
|     TRAIT = relationship("Trait") | ||||
|     REACTION_UUID = Column(VARCHAR(255), unique=True, comment="ID of this reaction") | ||||
| 
 | ||||
|     def __init__(self, REACTION_ID, NPC_ID, TRAIT_ID): | ||||
|         self.REACTION_ID = REACTION_ID | ||||
|         self.NPC_ID = NPC_ID | ||||
|         self.TRAIT_ID = TRAIT_ID | ||||
|         self.REACTION_UUID = uuid.uuid4() | ||||
| 
 | ||||
|     def __str__(self) -> str: | ||||
|         return f"Reaction(REACTION_ID={self.REACTION_ID}, NPC_ID={self.NPC_ID}, TRAIT_ID={self.TRAIT_ID})" | ||||
|         return f"Reaction(REACTION_ID={self.REACTION_ID}, NPC_ID={self.NPC_ID}, TRAIT_ID={self.TRAIT_ID}, REACTION_UUID={self.REACTION_UUID})" | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         return self.__str__() | ||||
| @ -132,7 +132,6 @@ class Game: | ||||
|         :param npc_id: the id of the npc, to get the reactions from, must be in the current game | ||||
|         :return: the reaction image as bytes | ||||
|         """ | ||||
|         print(self.reaction_table) | ||||
|         if npc_id not in self.reaction_table: | ||||
|             return None | ||||
|         trait_id = self.reaction_table[npc_id] | ||||
|  | ||||
| @ -3,16 +3,27 @@ from sqlalchemy import select, or_ | ||||
| 
 | ||||
| from truthinquiry.ext.database.models import * | ||||
| from truthinquiry.ext.database.fsa import db | ||||
| from truthinquiry.utils import require_admin | ||||
| 
 | ||||
| 
 | ||||
| routes_admin = flask.Blueprint("admin", __name__) | ||||
| 
 | ||||
| DEFAULT_LANG = "FR" | ||||
| 
 | ||||
| @routes_admin.route("/") | ||||
| @require_admin(ui=True) | ||||
| def index(): | ||||
|     npcs_objs = db.session.query(Npc).all() | ||||
|     npcs_dicts = [{"id": npc_obj.NPC_ID, "name": npc_obj.LOCALE.TEXTS[0].TEXT} for npc_obj in npcs_objs] | ||||
|     npcs_dicts = [{"id": npc_obj.NPC_ID, "name": npc_obj.NAME_LOCALE.get_text(DEFAULT_LANG).TEXT} for npc_obj in npcs_objs] | ||||
|     return flask.render_template("admin/index.html", npcs=npcs_dicts) | ||||
| 
 | ||||
| @routes_admin.route("/auth") | ||||
| def auth(): | ||||
|     input_failed = bool(flask.request.values.get("failed")) | ||||
|     return flask.render_template("admin/auth.html", failed=input_failed) | ||||
| 
 | ||||
| @routes_admin.route("/npc/<npc_id>") | ||||
| @require_admin(ui=True) | ||||
| def npc(npc_id): | ||||
|     if npc_id == "new": | ||||
|         return flask.render_template("admin/npc.html", npc={}) | ||||
| @ -21,11 +32,12 @@ def npc(npc_id): | ||||
| 
 | ||||
|         npc_answers = [] | ||||
|         for answer_type in npc_obj.ANSWERS: | ||||
|             answer_list = [answer.TEXT for answer in answer_type.LOCALE.TEXTS] | ||||
|             answer_list = [answer.TEXT for answer in answer_type.TEXT_LOCALE.TEXTS] | ||||
|             npc_answers.append(answer_list) | ||||
|          | ||||
|         npc_dict = { | ||||
|             "name": npc_obj.LOCALE.TEXTS[0].TEXT, | ||||
|             "id": npc_obj.NPC_ID, | ||||
|             "name": npc_obj.NAME_LOCALE.get_text(DEFAULT_LANG).TEXT, | ||||
|             "img": npc_obj.NPC_ID, | ||||
|             "answers": npc_answers, | ||||
|         } | ||||
| @ -33,8 +45,9 @@ def npc(npc_id): | ||||
|         return flask.render_template("admin/npc.html", npc=npc_dict) | ||||
| 
 | ||||
| @routes_admin.route("/questions") | ||||
| @require_admin(ui=True) | ||||
| def questions(): | ||||
|     lang = "FR" | ||||
|     lang = DEFAULT_LANG | ||||
| 
 | ||||
|     results = db.session.execute( | ||||
|         select(QuestionType, Text) | ||||
| @ -59,13 +72,19 @@ def questions(): | ||||
|     return flask.render_template("admin/questions.html", questions=data, langs=["FR", "EN"]) | ||||
| 
 | ||||
| @routes_admin.route("/places") | ||||
| @require_admin(ui=True) | ||||
| def places(): | ||||
|     lang = DEFAULT_LANG | ||||
| 
 | ||||
|     places_objs = db.session.query(Place).all() | ||||
|     places_dicts = [{"id": place_obj.PLACE_ID, "name": place_obj.LOCALE.TEXTS[0].TEXT} for place_obj in places_objs] | ||||
|     places_dicts = [{"id": place_obj.PLACE_ID, "name": place_obj.NAME_LOCALE.get_text(lang).TEXT} for place_obj in places_objs] | ||||
|     return flask.render_template("admin/places.html", places=places_dicts) | ||||
| 
 | ||||
| @routes_admin.route("/traits") | ||||
| @require_admin(ui=True) | ||||
| def traits(): | ||||
|     lang = DEFAULT_LANG | ||||
| 
 | ||||
|     traits_objs = db.session.query(Trait).all() | ||||
|     traits_dicts = [{"id": trait_obj.TRAIT_ID, "name": trait_obj.Name.TEXTS[0].TEXT, "desc": trait_obj.Desc.TEXTS[0].TEXT} for trait_obj in traits_objs] | ||||
|     traits_dicts = [{"id": trait_obj.TRAIT_ID, "name": trait_obj.NAME_LOCALE.get_text(lang).TEXT, "desc": trait_obj.DESC_LOCALE.get_text(lang).TEXT} for trait_obj in traits_objs] | ||||
|     return flask.render_template("admin/traits.html", traits=traits_dicts) | ||||
|  | ||||
| @ -1,8 +1,12 @@ | ||||
| import json | ||||
| import json | ||||
| import io | ||||
| 
 | ||||
| import flask | ||||
| import os | ||||
| from sqlalchemy import select | ||||
| 
 | ||||
| from truthinquiry.ext.database.models import * | ||||
| from truthinquiry.ext.database.fsa import db | ||||
| from truthinquiry.ext.discord_bot import discord_bot | ||||
| from truthinquiry.ext.socketio import socket_io | ||||
| from truthinquiry.logic import game_logic | ||||
| @ -157,6 +161,20 @@ def get_npc_reaction(): | ||||
|         'Content-Disposition', 'attachment', filename='reaction.png') | ||||
|     return response | ||||
| 
 | ||||
| @routes_api.route("/getReaction", methods=["GET", "POST"]) | ||||
| def get_reaction(): | ||||
|     input_uuid = flask.request.values.get("uuid") | ||||
|     results = db.session.execute(select(Reaction).where(Reaction.REACTION_UUID==input_uuid)) | ||||
|      | ||||
|     row = results.first() | ||||
|     if row == None: | ||||
|         return {"error": 1, "msg": "No such reaction"} | ||||
|     reaction_obj = row[0] | ||||
| 
 | ||||
|     return flask.send_file(io.BytesIO(reaction_obj.IMG), mimetype='image/png') | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @routes_api.route("/gameProgress", methods=["GET", "POST"]) | ||||
| def game_progress(): | ||||
|  | ||||
| @ -1,13 +1,26 @@ | ||||
| import os | ||||
| 
 | ||||
| import flask | ||||
| from sqlalchemy import select, delete, or_ | ||||
| 
 | ||||
| from truthinquiry.ext.database.models import * | ||||
| from truthinquiry.ext.database.fsa import db | ||||
| from truthinquiry.utils import require_admin | ||||
| 
 | ||||
| 
 | ||||
| routes_api_admin = flask.Blueprint("api_admin", __name__) | ||||
| 
 | ||||
| @routes_api_admin.route("/auth", methods=["GET", "POST"]) | ||||
| def auth(): | ||||
|     password = flask.request.values.get("password") | ||||
|     if password == os.getenv("ADMIN_PASSWORD"): | ||||
|         flask.session["admin"] = True | ||||
|         return flask.redirect("/admin") | ||||
|     else: | ||||
|         return flask.redirect("/admin/auth?failed=1") | ||||
| 
 | ||||
| @routes_api_admin.route("/setQuestions", methods=["GET", "POST"]) | ||||
| @require_admin(api=True) | ||||
| def set_questions(): | ||||
|     if not flask.request.json: | ||||
|         return {"error": 1, "msg": "no json set"} | ||||
| @ -44,6 +57,7 @@ def set_questions(): | ||||
|     return {"error": 0} | ||||
| 
 | ||||
| @routes_api_admin.route("/setTraits", methods=["GET", "POST"]) | ||||
| @require_admin(api=True) | ||||
| def set_traits(): | ||||
|     input_lang = flask.request.json["lang"] | ||||
|     input_traits = flask.request.json["traits"] | ||||
| @ -57,10 +71,10 @@ def set_traits(): | ||||
|             # modify | ||||
|             db_trait = list(filter(lambda db_trait: db_trait.TRAIT_ID == int(input_trait["id"]), db_traits))[0] | ||||
|              | ||||
|             db.session.delete(db_trait.Name.TEXTS[0]) | ||||
|             db.session.delete(db_trait.Desc.TEXTS[0]) | ||||
|             db_trait.Name.TEXTS = [Text(None, None, input_lang, input_trait["name"])] | ||||
|             db_trait.Desc.TEXTS = [Text(None, None, input_lang, input_trait["desc"])] | ||||
|             db.session.delete(db_trait.NAME_LOCALE.get_text(input_lang)) | ||||
|             db.session.delete(db_trait.DESC_LOCALE.get_text(input_lang)) | ||||
|             db_trait.NAME_LOCALE.TEXTS = [Text(None, None, input_lang, input_trait["name"])] | ||||
|             db_trait.DESC_LOCALE.TEXTS = [Text(None, None, input_lang, input_trait["desc"])] | ||||
|              | ||||
|             db.session.add(db_trait) | ||||
|             modified_db_traits.append(db_trait) | ||||
| @ -68,11 +82,11 @@ def set_traits(): | ||||
|             # add | ||||
|             new_trait = Trait(None, None, None) | ||||
|              | ||||
|             new_trait.Name = Locale(None) | ||||
|             new_trait.Desc = Locale(None) | ||||
|             new_trait.NAME_LOCALE = Locale(None) | ||||
|             new_trait.DESC_LOCALE = Locale(None) | ||||
| 
 | ||||
|             new_trait.Name.TEXTS.append(Text(None, None, input_lang, input_trait["name"])) | ||||
|             new_trait.Desc.TEXTS.append(Text(None, None, input_lang, input_trait["desc"])) | ||||
|             new_trait.NAME_LOCALE.TEXTS.append(Text(None, None, input_lang, input_trait["name"])) | ||||
|             new_trait.DESC_LOCALE.TEXTS.append(Text(None, None, input_lang, input_trait["desc"])) | ||||
|              | ||||
|             db.session.add(new_trait) | ||||
| 
 | ||||
| @ -86,6 +100,7 @@ def set_traits(): | ||||
|     return {"error": 0} | ||||
| 
 | ||||
| @routes_api_admin.route("/setPlaces", methods=["GET", "POST"]) | ||||
| @require_admin(api=True) | ||||
| def set_places(): | ||||
|     input_lang = flask.request.json["lang"] | ||||
|     input_places = flask.request.json["places"] | ||||
| @ -99,9 +114,9 @@ def set_places(): | ||||
|             # modify | ||||
|             db_place = list(filter(lambda db_place: db_place.PLACE_ID == int(input_place["id"]), db_places))[0] | ||||
|              | ||||
|             db.session.delete(db_place.LOCALE.TEXTS[0]) | ||||
|             db.session.delete(db_place.NAME_LOCALE.get_text(input_lang)) | ||||
|              | ||||
|             db_place.LOCALE.TEXTS = [Text(None, None, input_lang, input_place["name"])] | ||||
|             db_place.NAME_LOCALE.TEXTS = [Text(None, None, input_lang, input_place["name"])] | ||||
|              | ||||
|             db.session.add(db_place) | ||||
|             modified_db_places.append(db_place) | ||||
| @ -109,8 +124,8 @@ def set_places(): | ||||
|             # add | ||||
|             new_place = Place(None, None) | ||||
|              | ||||
|             new_place.LOCALE = Locale(None) | ||||
|             new_place.LOCALE.TEXTS = [Text(None, None, input_lang, input_place["name"])] | ||||
|             new_place.NAME_LOCALE = Locale(None) | ||||
|             new_place.NAME_LOCALE.TEXTS = [Text(None, None, input_lang, input_place["name"])] | ||||
|              | ||||
|             db.session.add(new_place) | ||||
| 
 | ||||
| @ -121,4 +136,29 @@ def set_places(): | ||||
| 
 | ||||
|     db.session.commit() | ||||
| 
 | ||||
|     return {"error": 0} | ||||
| 
 | ||||
| @routes_api_admin.route("/setNpc", methods=["GET", "POST"]) | ||||
| @require_admin(api=True) | ||||
| def set_npc(): | ||||
|     input_lang = flask.request.json["lang"] | ||||
|     input_npc = flask.request.json["npc"] | ||||
| 
 | ||||
|     if input_npc["id"] == None: | ||||
|         npc_obj = Npc(None, None) | ||||
|         db.session.add(npc_obj) | ||||
|     else: | ||||
|         npc_obj = db.session.get(Npc, input_npc["id"]) | ||||
| 
 | ||||
|     npc_obj.NAME_LOCALE.get_text(input_lang, True).TEXT = input_npc["name"] | ||||
| 
 | ||||
|     for answer_type, input_answer_type in zip(npc_obj.ANSWERS, input_npc["allAnswers"]): | ||||
|         for text in answer_type.TEXT_LOCALE.get_texts(input_lang): | ||||
|             db.session.delete(text) | ||||
|         for input_answer in input_answer_type["answers"]: | ||||
|             answer_type.TEXT_LOCALE.TEXTS.append(Text(None, None, input_lang, input_answer["text"])) | ||||
| 
 | ||||
| 
 | ||||
|     db.session.commit() | ||||
| 
 | ||||
|     return {"error": 0} | ||||
| @ -34,7 +34,6 @@ def lobbyRedirect(): | ||||
| @routes_ui.route("/lobby/<game_id>") | ||||
| def lobby(game_id): | ||||
|     # rendered by the javascript client-side | ||||
|     print(game_id) | ||||
|     if game_id is None: | ||||
|         return flask.redirect("") | ||||
|     return flask.render_template("lobby.html", gameid=game_id) | ||||
|  | ||||
| @ -92,3 +92,27 @@ function changeLang(){ | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| //functions for npc.html
 | ||||
| 
 | ||||
| function saveFormNpc(){ | ||||
|     let data = {} | ||||
|      | ||||
|     data["id"] = npc.querySelector("#npc_id").value; | ||||
|     data["name"] = npc.querySelector("#npc_name").value; | ||||
|      | ||||
|     let allAnswersJson = []; | ||||
|     data["allAnswers"] = allAnswersJson; | ||||
|      | ||||
|     for(let answerTypeNode of npc.querySelectorAll(".answerType")){ | ||||
|         let answersJson = []; | ||||
|         let answerTypeJson = {"answers": answersJson}; | ||||
|         allAnswersJson.push(answerTypeJson); | ||||
| 
 | ||||
|         for(let answerNode of answerTypeNode.querySelectorAll("input")){ | ||||
|             answersJson.push({"text": answerNode.value}) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     makeAPIRequest("admin/setNpc", {"npc": data, "lang": "FR"}, {"content": "json"}) | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										9
									
								
								truthinquiry/templates/admin/auth.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								truthinquiry/templates/admin/auth.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| {% if failed %} | ||||
| <p style="color: red"> Invalid password !</p> | ||||
| {% endif %} | ||||
| 
 | ||||
| <form action="/api/v1/admin/auth" method="POST"> | ||||
|     <p>Password :</p> | ||||
|     <input name="password"> | ||||
|     <input type="submit" value="Submit"> | ||||
| </form> | ||||
| @ -3,27 +3,33 @@ | ||||
|     <head> | ||||
|         <title>NPC</title> | ||||
|         <meta charset="UTF-8"> | ||||
|         <link rel="stylesheet" href="admin_ui.css"> | ||||
|         <link rel="stylesheet" href="/static/css/admin_ui.css"> | ||||
|         <script src="/static/js/api.js"></script> | ||||
|         <script src="/static/js/admin.js"></script> | ||||
|     </head> | ||||
|     <body> | ||||
|         <a href="/admin"> go Back </a> <br> | ||||
| 
 | ||||
|         <section> | ||||
|             <span>Npc name: </span> | ||||
|             <input value="{{ npc.get('name') or ''}}"> | ||||
|             <img href="{{npc.get('img')}}"> | ||||
|         </section> | ||||
|          | ||||
|         <section> | ||||
|             <p>Answers:</p> | ||||
|             {%for answer_type in npc.get("answers") or []%} | ||||
|             <section>     | ||||
|                 {%for answer in answer_type%} | ||||
|                 <input value="{{answer}}"> | ||||
|         <section id="npc"> | ||||
|             <section> | ||||
|                 <span>Npc name: </span> | ||||
|                 <input id="npc_id" value="{{ npc.get('id') or ''}}" hidden> | ||||
|                 <input id="npc_name" value="{{ npc.get('name') or ''}}"> | ||||
|                 <img href="{{npc.get('img')}}"> | ||||
|             </section> | ||||
|              | ||||
|             <section> | ||||
|                 <p>Answers:</p> | ||||
|                 {%for answer_type in npc.get("answers") or []%} | ||||
|                 <section class="answerType"> | ||||
|                     {%for answer in answer_type%} | ||||
|                     <input value="{{answer}}"> | ||||
|                     {%endfor%} | ||||
|                 </section> | ||||
|                 {%endfor%} | ||||
|             </section> | ||||
|             {%endfor%} | ||||
|         </section> | ||||
| 
 | ||||
|         <button onclick="saveFormNpc()">Save changes</button> | ||||
|     </body> | ||||
| </html> | ||||
|  | ||||
							
								
								
									
										20
									
								
								truthinquiry/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								truthinquiry/utils.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| from functools import wraps | ||||
| 
 | ||||
| import flask | ||||
| 
 | ||||
| def require_admin(*args, **kwargs): | ||||
|     def decorator(route): | ||||
|         @wraps(route) | ||||
|         def decorated_function(*route_args, **route_kwargs): | ||||
| 
 | ||||
|             if flask.session.get("admin"): | ||||
|                 return route(*route_args, **route_kwargs) | ||||
|             elif kwargs.get("api"): | ||||
|                 return {"error": 1, "msg": "Invalid authentication"} | ||||
|             elif kwargs.get("ui"): | ||||
|                 return flask.redirect("/admin/auth") | ||||
|             else: | ||||
|                 raise ValueError("Can't determine request type") | ||||
|              | ||||
|         return decorated_function | ||||
|     return decorator | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user