diff --git a/app/models/privs.py b/app/models/privs.py index 426f755..692b3ae 100644 --- a/app/models/privs.py +++ b/app/models/privs.py @@ -2,7 +2,6 @@ # models.privs: Database models for groups and privilege management from app import db -from config import V5Config # Privileges are represented by strings (slugs), for instance "post-news" or # "delete-own-posts". Belonging to a group automatically grants a user the @@ -19,7 +18,7 @@ class SpecialPrivilege(db.Model): # Member that is granted the privilege mid = db.Column(db.Integer, db.ForeignKey('member.id'), index=True) # Privilege name - priv = db.Column(db.String(V5Config.PRIVS_MAXLEN)) + priv = db.Column(db.String(64)) def __init__(self, member, priv): self.mid = member.id @@ -85,7 +84,7 @@ class GroupPrivilege(db.Model): id = db.Column(db.Integer, primary_key=True) gid = db.Column(db.Integer, db.ForeignKey('group.id')) - priv = db.Column(db.String(V5Config.PRIVS_MAXLEN)) + priv = db.Column(db.String(64)) def __init__(self, group, priv): self.gid = group.id diff --git a/app/models/thread.py b/app/models/thread.py index bd1236b..1f69f3c 100644 --- a/app/models/thread.py +++ b/app/models/thread.py @@ -15,6 +15,8 @@ class Thread(db.Model): # Other fields populated automatically through relations: # The list of comments (of type Comment) + COMMENTS_PER_PAGE = 20 + def __init__(self): """ Create a empty Thread. Normally threads are not meant to be empty, so diff --git a/app/models/topic.py b/app/models/topic.py index fe18b9d..414d7ca 100644 --- a/app/models/topic.py +++ b/app/models/topic.py @@ -1,6 +1,5 @@ from app import db from app.models.post import Post -from config import V5Config class Topic(Post): __tablename__ = 'topic' @@ -10,7 +9,7 @@ class Topic(Post): id = db.Column(db.Integer, db.ForeignKey('post.id'), primary_key=True) # Topic title - title = db.Column(db.Unicode(V5Config.THREAD_NAME_MAXLEN)) + title = db.Column(db.Unicode(32)) # Parent forum forum_id = db.Column(db.Integer, db.ForeignKey('forum.id'), nullable=False) diff --git a/app/models/users.py b/app/models/users.py index e01567e..2e626e1 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -213,7 +213,7 @@ class Member(User): def set_avatar(self, avatar): # Save old avatar filepath - old_avatar = V5Config.AVATARS_FOLDER + self.avatar + old_avatar = os.path.join(V5Config.DATA_FOLDER, "avatars", self.avatar) # Resize & convert image size = 128, 128 im = Image.open(avatar) @@ -225,7 +225,8 @@ class Member(User): db.session.merge(self) db.session.commit() # Save the new avatar - im.save(V5Config.AVATARS_FOLDER + self.avatar, 'PNG') + im.save(os.path.join(V5Config.DATA_FOLDER, "avatars", self.avatar), + 'PNG') # If nothing has failed, remove old one (allow failure to regularize # exceptional situations like missing avatar or folder migration) try: @@ -458,7 +459,7 @@ class Member(User): # TODO: Trophy "actif" if context in ["on-profile-update", None]: - if isfile(V5Config.AVATARS_FOLDER + self.avatar): + if isfile(os.path.join(V5Config.DATA_FOLDED, "avatar", self.avatar)): self.add_trophy("Artiste") else: self.del_trophy("Artiste") diff --git a/app/routes/account/login.py b/app/routes/account/login.py index 37d1f03..2c4238e 100644 --- a/app/routes/account/login.py +++ b/app/routes/account/login.py @@ -7,7 +7,7 @@ from app.models.users import Member from app.models.privs import Group from app.utils.render import render from app.utils.send_mail import send_validation_mail -from config import V5Config +import datetime @app.route('/connexion', methods=['GET', 'POST']) @@ -46,7 +46,7 @@ def login(): # Login & update time-based trophies login_user(member, remember=form.remember_me.data, - duration=V5Config.REMEMBER_COOKIE_DURATION) + duration=datetime.timedelta(days=7)) member.update_trophies("on-login") # Redirect safely (https://huit.re/open-redirect) diff --git a/app/routes/forum/index.py b/app/routes/forum/index.py index 6c46298..f87910d 100644 --- a/app/routes/forum/index.py +++ b/app/routes/forum/index.py @@ -58,7 +58,7 @@ def forum_page(f): # Update member's xp and trophies if current_user.is_authenticated: - current_user.add_xp(V5Config.XP_POINTS['topic']) + current_user.add_xp(2) # 2 points for a topic current_user.update_trophies('new-post') flash('Le sujet a bien été créé', 'ok') diff --git a/app/routes/forum/topic.py b/app/routes/forum/topic.py index ac264be..bdd4ab6 100644 --- a/app/routes/forum/topic.py +++ b/app/routes/forum/topic.py @@ -39,7 +39,7 @@ def forum_topic(f, page): # Update member's xp and trophies if current_user.is_authenticated: - current_user.add_xp(V5Config.XP_POINTS['comment']) + current_user.add_xp(1) # 1 point for a comment current_user.update_trophies('new-post') flash('Message envoyé', 'ok') @@ -54,9 +54,9 @@ def forum_topic(f, page): if page == -1: page = (t.thread.comments.count() - 1) \ - // V5Config.COMMENTS_PER_PAGE + 1 + // Thread.COMMENTS_PER_PAGE + 1 comments = t.thread.comments.paginate(page, - V5Config.COMMENTS_PER_PAGE, True) + Thread.COMMENTS_PER_PAGE, True) return render('/forum/topic.html', t=t, form=form, comments=comments) diff --git a/app/routes/users.py b/app/routes/users.py index 72a57b0..5f8a91c 100644 --- a/app/routes/users.py +++ b/app/routes/users.py @@ -1,4 +1,4 @@ -from flask import redirect, url_for, send_from_directory +from flask import redirect, url_for, send_file from werkzeug.utils import secure_filename import os.path from app import app @@ -25,6 +25,7 @@ def user_by_id(user_id): @app.route('/avatar/') def avatar(filename): filename = secure_filename(filename) # No h4ckers allowed - if os.path.isfile(V5Config.AVATARS_FOLDER + filename): - return send_from_directory(V5Config.AVATARS_FOLDER, filename) + filepath = os.path.join(V5Config.DATA_FOLDER, "avatars", filename) + if os.path.isfile(filepath): + return send_file(filepath) return redirect(url_for('static', filename='images/default_avatar.png')) diff --git a/app/utils/valid_name.py b/app/utils/valid_name.py index f3d6642..158cc40 100644 --- a/app/utils/valid_name.py +++ b/app/utils/valid_name.py @@ -1,5 +1,5 @@ -from config import V5Config from app.utils.unicode_names import normalize +from app.models.users import User import re def valid_name(name, msg=False): @@ -18,11 +18,13 @@ def valid_name(name, msg=False): errors = [] + FORBIDDEN_USERNAMES = ["admin", "root", "webmaster", "contact"] + # Rule 1 - if len(name) < V5Config.USER_NAME_MINLEN: + if len(name) < User.NAME_MINLEN: errors.append("too-short") - if len(name) > V5Config.USER_NAME_MAXLEN: + if len(name) > User.NAME_MAXLEN: errors.append("too-long") # Rule 2 @@ -37,7 +39,7 @@ def valid_name(name, msg=False): errors.append("no-letter") # Rule 4 - if normalized_name in V5Config.FORBIDDEN_USERNAMES: + if normalized_name in FORBIDDEN_USERNAMES: errors.append("forbidden") return True if errors == [] else errors diff --git a/app/utils/validators.py b/app/utils/validators.py index f805537..73f2c2f 100644 --- a/app/utils/validators.py +++ b/app/utils/validators.py @@ -15,10 +15,10 @@ def name_valid(form, name): msg = { "too-short": "Le nom d'utilisateur doit faire au moins " - f"{User.USER_NAME_MINLEN} caractères.", + f"{User.NAME_MINLEN} caractères.", "too-long": "Le nom d'utilisateur doit faire au plus " - f"{User.USER_NAME_MAXLEN} caractères.", + f"{User.NAME_MAXLEN} caractères.", "cant-normalize": "Ce nom d'utilisateur contient des caractères interdits. Les " "caractères autorisés sont les lettres, lettres accentuées, " diff --git a/config.py b/config.py index 490ee76..ae5df4d 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,4 @@ import os -import datetime try: from local_config import LocalConfig @@ -24,26 +23,6 @@ class DefaultConfig(object): """Every value here can be overrided in the local_config.py class""" # Domain DOMAIN = "v5.planet-casio.com" - # Length allocated to privilege names (slugs) - PRIVS_MAXLEN = 64 - # Forbidden user names - FORBIDDEN_USERNAMES = ["admin", "root", "webmaster", "contact"] - # Unauthorized message (@priv_required) - UNAUTHORIZED_MSG = "Vous n'avez pas l'autorisation d'effectuer cette action !" - # Maximum thread name length - THREAD_NAME_MAXLEN = 32 - # Amount of comments per thread page - COMMENTS_PER_PAGE = 20 - # Remember-me cookie duration time - REMEMBER_COOKIE_DURATION = datetime.timedelta(days=7) - # XP points for content posting (and deletion) - XP_POINTS = { - 'topic': 2, - 'program': 5, - 'tutorial': 5, - 'comment': 1, - 'contest': 10, - } # Database name DB_NAME = "pcv5" # LDAP usage @@ -53,8 +32,8 @@ class DefaultConfig(object): LDAP_ORGANIZATION = "o=planet-casio" # Secret key used to authenticate tokens. **USE YOURS!** SECRET_KEY = "a-random-secret-key" - # Avatars folder - AVATARS_FOLDER = '/avatar/folder/' + # Uploaded data folder + DATA_FOLDER = '/var/www/uploads' # Enable guest post ENABLE_GUEST_POST = True # Disable email confimation