Name | Register | XP | Inn. | +Newsletter | |
---|---|---|---|---|---|
{{ user.name }} | +{{ user.email }} | +{{ user.register_date }} | {{ user.xp }} | +{{ user.innovation }} | +{{ "Yes" if user.newsletter else "No" }} |
Group | Members | Privileges |
---|---|---|
{{ group.name }} | + {% for user in group.members %} + {{ user.name }} + {% endfor %} + |
+ {% for priv in group.privs %}
+ {{ priv }}
+ {% endfor %}
+ |
- Erreur {{ error_code }}
-
- {% if error_code == 400 %}
- Bad Request : Votre requête semble mal formée.
- {% elif error_code == 401 %}
- Unauthorized : Une authentification est nécessaire pour accéder à la ressource.
-
- Veuillez vous connecter à l'aide du panneau sur la gauche.
- {% elif error_code == 403 %}
- Forbidden : Cette page vous est interdite. Désolé, si vous pensez que c'est une erreur ou que vous voulez avoir accès à cette page malgré tout veuillez contacter un administrateur.
- {% elif error_code == 404 %}
- Not Found : La page n'existe pas ou plus, si vous avez rentré l'url à la main vérifiez de ne pas vous être trompé.
-
/| /‾‾‾‾‾‾‾\ /| |\ | /‾‾‾‾‾\ ––––––––– - / | / \ / | | \ | / \ | - / | | | / | | \ | / \ | - / | | | / | | \ | | | | - / | | | / | | \ | | | | - / | | | / | | \ | | | | -/______|_ | | /______|_ | \ | | | | - | | | | | \ | \ / | - | \ / | | \ | \ / | - | \_______/ | | \| \_____/ | - -|‾‾‾‾‾‾‾‾‾‾ /‾‾‾‾‾\ | | |\ | |‾‾‾‾‾‾‾\ -| / \ | | | \ | | \ -| / \ | | | \ | | \ -| | | | | | \ | | | -|––––––– | | | | | \ | | | -| | | | | | \ | | | -| | | | | | \ | | | -| \ / \ / | \ | | / -| \ / \ / | \ | | / -| \_____/ \_____/ | \| |_______/- {% elif error_code == 418 %} - Oups! Il semblerai que vous m'ayez demandé du café mais je suis une théière. -
- {{ form.username.label }}
- {{ form.username(size=32) }}
- {% for error in form.username.errors %}
- [{{ error }}]
- {% endfor %}
-
- {{ form.password.label }}
- {{ form.password(size=32) }}
- {% for error in form.password.errors %}
- [{{ error }}]
- {% endfor %}
-
{{ form.remember_me() }} {{ form.remember_me.label }}
-{{ form.submit() }}
-New User? Click to Register!
-{% endblock %} diff --git a/app/templates/register.html b/app/templates/register.html new file mode 100644 index 0000000..fd5088f --- /dev/null +++ b/app/templates/register.html @@ -0,0 +1,56 @@ +{% extends "base/container.html" %} + +{% block content %} +
- {{ form2.username.label }}
- {{ form2.username(size=32) }}
- {% for error in form2.username.errors %}
- [{{ error }}]
- {% endfor %}
-
- {{ form2.email.label }}
- {{ form2.email(size=64) }}
- {% for error in form2.email.errors %}
- [{{ error }}]
- {% endfor %}
-
- {{ form2.password.label }}
- {{ form2.password(size=32) }}
- {% for error in form2.password.errors %}
- [{{ error }}]
- {% endfor %}
-
- {{ form2.password2.label }}
- {{ form2.password2(size=32) }}
- {% for error in form2.password2.errors %}
- [{{ error }}]
- {% endfor %}
-
{{ form2.submit() }}
-ici il y aura la page qui demande de checker les mails pour valider
ici il y aura la page qui demande de checker les mails pour valider
{priv}'+
+ '
', 'error')
+ return redirect(url_for('index'))
+ else:
+ f()
+ return wrapper
+ return privilege_decorator
diff --git a/app/utils/priv_required.py b/app/utils/priv_required.py
new file mode 100644
index 0000000..7a5fd21
--- /dev/null
+++ b/app/utils/priv_required.py
@@ -0,0 +1,38 @@
+from functools import wraps
+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
+
+def priv_required(*perms):
+ """
+ If you decorate a view with this, it will ensure that the current user is
+ authenticated and has required permissions before calling the actual view.
+ (If they are not, it calls the :attr:`LoginManager.unauthorized` callback.)
+ For example::
+
+ @app.route('/admin')
+ @priv_required('access-admin-board')
+ def admin_board():
+ pass
+
+ It can be convenient to globally turn off authentication when unit testing.
+ To enable this, if the application configuration variable `LOGIN_DISABLED`
+ is set to `True`, this decorator will be ignored.
+ """
+ def decorated_view(func):
+ @wraps(func)
+ def wrapped(*args, **kwargs):
+ if request.method in EXEMPT_METHODS:
+ return func(*args, **kwargs)
+ elif 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):
+ abort(403)
+ return func(*args, **kwargs)
+ return wrapped
+ return decorated_view
diff --git a/app/utils/render.py b/app/utils/render.py
new file mode 100644
index 0000000..b7b918f
--- /dev/null
+++ b/app/utils/render.py
@@ -0,0 +1,14 @@
+from flask import render_template
+from app.forms.login import LoginForm
+from app.forms.search import SearchForm
+
+def render(*args, **kwargs):
+ # TODO: debugguer cette merde : au logout, ça foire
+ # if current_user.is_authenticated:
+ # login_form = LoginForm()
+ # return render_template(*args, **kwargs, login_form=login_form)
+ # return render_template(*args, **kwargs)
+ login_form = LoginForm()
+ search_form = SearchForm()
+ return render_template(*args, **kwargs,
+ login_form=login_form, search_form=search_form)
\ No newline at end of file
diff --git a/app/utils/validators.py b/app/utils/validators.py
new file mode 100644
index 0000000..3f58c3b
--- /dev/null
+++ b/app/utils/validators.py
@@ -0,0 +1,30 @@
+from flask_login import current_user
+from wtforms.validators import ValidationError
+from app.models.users import User, Member
+
+def name(form, name):
+ member = Member.query.filter_by(name=name.data).first()
+ if member is not None:
+ raise ValidationError('Pseudo indisponible.')
+ if not User.valid_name(name.data):
+ raise ValidationError("Nom d'utilisateur invalide.")
+
+def email(form, email):
+ member = Member.query.filter_by(email=email.data).first()
+ if member is not None:
+ raise ValidationError('Adresse email déjà utilisée.')
+
+def password(form, password):
+ if len(password.data) != 0 and len(password.data) < 10:
+ raise ValidationError('Mot de passe est trop court (10 caractères minimum).')
+ # TODO: add more rules >:]
+
+def avatar(form, avatar):
+ pass
+
+def old_password(form, field):
+ if field.data:
+ if not form.old_password.data:
+ raise ValidationError('Votre ancien mot de passe est requis pour cette modification.')
+ if not current_user.check_password(form.old_password.data):
+ raise ValidationError('Mot de passe actuel erroné.')
diff --git a/assets/diagramme_1.dia b/assets/diagramme_1.dia
new file mode 100644
index 0000000..4e72781
Binary files /dev/null and b/assets/diagramme_1.dia differ
diff --git a/assets/diagramme_1.dia~ b/assets/diagramme_1.dia~
new file mode 100644
index 0000000..e4d1e75
Binary files /dev/null and b/assets/diagramme_1.dia~ differ
diff --git a/assets/diagramme_1.png b/assets/diagramme_1.png
new file mode 100644
index 0000000..34e114d
Binary files /dev/null and b/assets/diagramme_1.png differ
diff --git a/assets/privs.txt b/assets/privs.txt
new file mode 100644
index 0000000..6a1d5ac
--- /dev/null
+++ b/assets/privs.txt
@@ -0,0 +1,38 @@
+# Privileges
+
+Read/write access to forum boards:
+ access-admin-board Administration board of the forum
+ access-assoc-board CreativeCalc discussion board
+ write-news Post articles on the news board
+
+Shared file upload (like /Fr/adpc/img.php for any file):
+ upload-shared-files Upload files and images on the website server
+ delete-shared-files Delete files uploaded with upload-shared-files
+
+Post management:
+ edit-posts Edit any post on the website
+ delete-posts Remove any post from the website
+ scheduled-posting Schedule a post or content creation in the future
+
+Content (topic, progs, tutos, etc) management:
+ delete-content Delete whole topics, program pages, or tutorials
+ move-public-content Change the section of a page in a public section
+ move-private-content Change the section of a page in a private section
+ showcase-content Manage stocky content (post-its)
+ edit-static-content Edit static content pages
+
+Program evaluation:
+ delete-notes Delete program notes
+ delete-tests Delete program tests
+
+Shoutbox:
+ shoutbox-post Write messages in the shoutbox
+ shoutbox-kick Kick people using the shoutbox
+ shoutbox-ban Ban people using the shoutbox
+
+Miscellaenous:
+ unlimited-pms Removes the limit on the number of private messages
+ footer-statistics View performance statistics in the page footer
+ community-login Automatically login as a community account
+
+Administration panel...
diff --git a/assets/users.txt b/assets/users.txt
new file mode 100644
index 0000000..ba432c1
--- /dev/null
+++ b/assets/users.txt
@@ -0,0 +1,73 @@
+# User management
+
+User information:
+
+ Name Unique, no space, at least one letter
+ Avatar Stored in a server folder. Size limit?
+ Password Hashed, of course
+ Email Mail address, used to send newsletters
+
+ Points Participation measure (mainly number of posts)
+ Innovation points A different kind of participation measure
+
+ Biography Description of the user
+ Signature Short signature added at the end of every post
+ Birthday Birthday date
+
+ Newsletter Subscription to newsletter
+ Settings...
+
+Relations:
+
+ Notifications 1 to many
+ Groups 1 to many
+ Sent PMs 1 to many
+ Received PMs 1 to many
+ Trophies/Titles 1 to many
+
+ All posts many to many (tutorials can have several authors)
+ Privileges many to many
+
+Rest API for users:
+ Requests where "Search" is set to "Yes" accept search patterns. The syntax
+ needs to be chosen, it could be something like "/users[name~=/*storm*/i]".
+
+ Method URL Search Description
+ -----------------------------------------------------------------------------
+ GET /users Yes Query users
+ POST /users - Create new user
+ -----------------------------------------------------------------------------
+ GET /users/