config: refactor configuration values

- System/host config values stay in `config.py`
- Application config values moves in corresponding models
- BREAK: AVATAR_FOLDER becomes DATA_FOLDER. Edit your local config if 
needed
This commit is contained in:
Darks 2020-07-26 16:50:07 +02:00
parent 0896a6b163
commit e35910ee76
Signed by: Darks
GPG Key ID: F61F10FA138E797C
11 changed files with 29 additions and 46 deletions

View File

@ -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

View File

@ -15,6 +15,8 @@ class Thread(db.Model):
# Other fields populated automatically through relations:
# <comments> 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

View File

@ -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)

View File

@ -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")

View File

@ -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)

View File

@ -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')

View File

@ -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)

View File

@ -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/<filename>')
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'))

View File

@ -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

View File

@ -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, "

View File

@ -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