diff --git a/.gitignore b/.gitignore index 88cb029..ecd218d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ app.db __pycache__/ app/__pycache__/ +app/static/avatars/ venv/ diff --git a/app/__init__.py b/app/__init__.py index 3543c48..44d965e 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -14,4 +14,4 @@ login.login_view = 'login' login.login_message = "Veuillez vous authentifier avant de continuer." from app import models -from app.routes import index, login, search, account, admin +from app.routes import index, login, search, account, admin, users diff --git a/app/models/privs.py b/app/models/privs.py index a8f0d96..6e0ed2f 100644 --- a/app/models/privs.py +++ b/app/models/privs.py @@ -28,8 +28,10 @@ class SpecialPrivilege(db.Model): return f'' # TODO: clean this. filter does not work ootb + # This ensure that refresh the page should sometime fail with a 403 def filter(*args, **kwargs): - return False + from random import randint + return not not randint(0, 2) # Group: User group, corresponds to a community role and a set of privileges class Group(db.Model): diff --git a/app/routes/admin.py b/app/routes/admin.py index bea040e..a64b586 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -4,12 +4,12 @@ from wtforms import SubmitField from app.models.users import Member, Group, GroupPrivilege from app.models.privs import SpecialPrivilege from app.utils.render import render +from app.utils.priv_required import priv_required from app import app, db @app.route('/admin', methods=['GET', 'POST']) -@login_required +@priv_required('panel-admin') def admin(): - class AdminForm(FlaskForm): submit = SubmitField('Régénérer les groupes, les privilèges, et les ' + 'membres de test "PlanèteCasio" et "GLaDOS" (mdp "v5-forever")') diff --git a/app/routes/index.py b/app/routes/index.py index 692a11a..6c0f038 100644 --- a/app/routes/index.py +++ b/app/routes/index.py @@ -4,4 +4,12 @@ from app.utils.render import render @app.route('/') def index(): - return render('index.html') \ No newline at end of file + return render('index.html') + +@app.errorhandler(404) +def file_not_found(e): + return render('errors/404.html'), 404 + +@app.errorhandler(403) +def unauthorized_access(e): + return render('errors/403.html'), 403 \ No newline at end of file diff --git a/app/routes/search.py b/app/routes/search.py index 78c442d..ef3fb41 100644 --- a/app/routes/search.py +++ b/app/routes/search.py @@ -2,8 +2,6 @@ from app import app from app.forms.search import AdvancedSearchForm from app.utils.render import render -from app.utils.priv_required import priv_required - @app.route('/search') def search(): form = AdvancedSearchForm() diff --git a/app/routes/users.py b/app/routes/users.py index 86b71df..e3299a4 100644 --- a/app/routes/users.py +++ b/app/routes/users.py @@ -1,30 +1,20 @@ -from flask import redirect, url_for, request, flash +from flask import redirect, url_for, abort from flask_login import login_required, current_user, logout_user from app import app, db from app.forms.account import UpdateAccountForm, RegistrationForm, DeleteAccountForm from app.models.users import Member from app.utils.render import render -@app.route('/users/') -def user(): - form = UpdateAccountForm() - if request.method == "POST": - if form.validate_on_submit(): - if form.avatar.data: - f = form.avatar.data - f.save("./app/static/"+current_user.avatar) - current_user.update( - email = form.email.data or None, - password = form.password.data or None, - birthday = form.birthday.data, - signature = form.signature.data, - biography = form.biography.data, - newsletter = form.newsletter.data - ) - db.session.merge(current_user) - db.session.commit() - flash('Modifications effectuées', 'ok') - else: - flash('Erreur lors de la modification', 'error') +@app.route('/user/') +def user(username): + user = Member.query.filter_by(name=username).first() + if not user: + abort(404) + return render('user.html', user=user) - return render('account.html', form=form) \ No newline at end of file +@app.route('/user/id/') +def user_by_id(user_id): + user = Member.query.filter_by(id=user_id).first() + if not user: + abort(404) + return redirect(url_for('user', username=user.name)) \ No newline at end of file diff --git a/app/static/css/container.css b/app/static/css/container.css index b742cd9..4ba38df 100644 --- a/app/static/css/container.css +++ b/app/static/css/container.css @@ -3,7 +3,7 @@ } section { - min-width: 350px; + min-width: 350px; width: 90%; margin: 20px auto 0; padding: 20px; background: #ffffff; border: 1px solid #dddddd; border-radius: 5px; @@ -23,6 +23,12 @@ section h2 { font-weight: 300; color: #242424; } +section .avatar { + display: block; + border-radius: 100%; + width: 150px; height: 150px; +} + /* #container h1 { margin-left: 5%; font-family: Raleway; font-size: 24px; diff --git a/app/static/css/form.css b/app/static/css/form.css index 4706af7..1915d99 100644 --- a/app/static/css/form.css +++ b/app/static/css/form.css @@ -3,6 +3,7 @@ border-radius: 100%; width: 150px; height: 150px; } + .form .avatar + input[type="file"] { display: inline-block; margin-left: 20px; vertical-align: middle; diff --git a/app/static/images/403.webp b/app/static/images/403.webp new file mode 100644 index 0000000..6c5ff47 Binary files /dev/null and b/app/static/images/403.webp differ diff --git a/app/static/images/404.webp b/app/static/images/404.webp new file mode 100644 index 0000000..3e125e4 Binary files /dev/null and b/app/static/images/404.webp differ diff --git a/app/templates/account.html b/app/templates/account.html index 0933334..7c4aa88 100644 --- a/app/templates/account.html +++ b/app/templates/account.html @@ -1,7 +1,7 @@ {% extends "base/container.html" %} {% block content %} -
+

Gestion du compte

diff --git a/app/templates/admin.html b/app/templates/admin.html index 76ea1ca..d0498e6 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -1,42 +1,43 @@ {% extends "base/container.html" %} {% block content %} +
+ + {{ form.hidden_tag() }} + {{ form.submit }} + -
- {{ form.hidden_tag() }} - {{ form.submit }} -
+

List of members

-

List of members

+ + + -
NameEmailRegisterXPInn.Newsletter
- - + {% for user in users %} + + + + + + {% endfor %} +
NameEmailRegisterXPInn.Newsletter
{{ user.name }}{{ user.email }}{{ user.register_date }}{{ user.xp }}{{ user.innovation }}{{ "Yes" if user.newsletter else "No" }}
- {% for user in users %} - {{ user.name }}{{ user.email }} - {{ user.register_date }}{{ user.xp }} - {{ user.innovation }} - {{ "Yes" if user.newsletter else "No" }} - {% endfor %} - +

List of groups

-

List of groups

- - - - - {% for group in groups %} - - {% endfor %} -
GroupMembersPrivileges
{{ group.name }} - {% for user in group.members %} - {{ user.name }} - {% endfor %} - - {% for priv in group.privs %} - {{ priv }} - {% endfor %} -
+ + + {% for group in groups %} + + {% endfor %} +
GroupMembersPrivileges
{{ group.name }} + {% for user in group.members %} + {{ user.name }} + {% endfor %} + + {% for priv in group.privs %} + {{ priv }} + {% endfor %} +
+
{% endblock %} diff --git a/app/templates/base/navbar/account.html b/app/templates/base/navbar/account.html index a2c67f3..f00fa42 100644 --- a/app/templates/base/navbar/account.html +++ b/app/templates/base/navbar/account.html @@ -22,7 +22,7 @@ Topics favoris - + diff --git a/app/templates/delete_account.html b/app/templates/delete_account.html index 70abe34..447edef 100644 --- a/app/templates/delete_account.html +++ b/app/templates/delete_account.html @@ -1,7 +1,7 @@ {% extends "base/container.html" %} {% block content %} -
+

Suppression du compte

{{ del_form.hidden_tag() }} diff --git a/app/templates/errors/403.html b/app/templates/errors/403.html new file mode 100644 index 0000000..ad49def --- /dev/null +++ b/app/templates/errors/403.html @@ -0,0 +1,9 @@ +{% extends "base/container.html" %} + +{% block content %} +
+

403 - Accès non autorisé

+ + +
+{% endblock %} diff --git a/app/templates/errors/404.html b/app/templates/errors/404.html new file mode 100644 index 0000000..6282c07 --- /dev/null +++ b/app/templates/errors/404.html @@ -0,0 +1,9 @@ +{% extends "base/container.html" %} + +{% block content %} +
+

404 - Page non trouvée

+ + +
+{% endblock %} diff --git a/app/templates/search.html b/app/templates/search.html index a48675e..aefa203 100644 --- a/app/templates/search.html +++ b/app/templates/search.html @@ -1,7 +1,7 @@ {% extends "base/container.html" %} {% block content %} -
+

Recherche avancée

diff --git a/app/templates/user.html b/app/templates/user.html new file mode 100644 index 0000000..861dabf --- /dev/null +++ b/app/templates/user.html @@ -0,0 +1,9 @@ +{% extends "base/container.html" %} + +{% block content %} +
+

+ {{ user.name }} + Profil de {{ user.name }}

+
+{% endblock %} diff --git a/app/templates/validation.html b/app/templates/validation.html index 0b5ffa0..bfba28f 100644 --- a/app/templates/validation.html +++ b/app/templates/validation.html @@ -1,10 +1,10 @@ {% extends "base/container.html" %} {% block content %} -
- +
+
+

ici il y aura la page qui demande de checker les mails pour valider


+ Retour à la page d'accueil +
{% endblock content %} diff --git a/app/utils/priv_required.py b/app/utils/priv_required.py index 5a689cf..7a5fd21 100644 --- a/app/utils/priv_required.py +++ b/app/utils/priv_required.py @@ -1,9 +1,8 @@ from functools import wraps -from flask import redirect, url_for, request, flash +from flask import redirect, url_for, request, flash, abort from flask_login import current_user from flask_login.config import EXEMPT_METHODS from app import app -from config import V5Config def priv_required(*perms): """ @@ -27,15 +26,13 @@ def priv_required(*perms): if request.method in EXEMPT_METHODS: return func(*args, **kwargs) elif app.config.get('LOGIN_DISABLED'): - #if app.config.get('LOGIN_DISABLED'): return func(*args, **kwargs) elif not current_user.is_authenticated: return app.login_manager.unauthorized() else: for p in perms: if not current_user.priv(p): - flash(V5Config.UNAUTHORIZED_MSG, 'error') - return redirect(url_for('index')) + abort(403) return func(*args, **kwargs) return wrapped - return decorated_view \ No newline at end of file + return decorated_view