Ajout support serveur MAIL et XMPP

This commit is contained in:
kitoy 2022-08-06 18:22:24 +02:00
parent beb1e65ca7
commit d923a5eb97
44 changed files with 2177 additions and 701 deletions

BIN
base.db.bkp Normal file

Binary file not shown.

View File

@ -4,6 +4,9 @@ SECRET_KEY="fksmlfkljklknfzqlknfzqlkezq"
# Dossier où seront stocker les fichiers
DOSSIER_APP = "users/"
# Fichiers sqlite
DATABASE = "./base.db"
# Extension des images accepter
EXT_IMG= {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
@ -16,3 +19,8 @@ XMPP_SERVER = True
# MAIL_SERVER = True => Le service est installé et lancer
# MAIL_SERVER = False => Le service est désactivé
MAIL_SERVER = True
# Possibilté de s'inscrire sur le serveur
SIGNIN_ENABLE = True
SETUID='doas'

View File

@ -14,8 +14,9 @@ from views.inscription import inscription
from views.profil import profil
from views.logs import logs
from views.loginlogout import loginlogout
from views.gallery import mygallery
from tools.databaseinit import init_db, init_dir
from tools.databaseinit import init_db, init_dir, db_migrate
import glob, os, sys, time
@ -23,13 +24,10 @@ app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
if init_db():
print ("La base de données a été créer")
exit()
init_db()
db_migrate()
if init_dir():
print ("Le repertoire des utilisateurs a été créer")
exit()
@ -52,85 +50,39 @@ app.register_blueprint(filesupload)
app.register_blueprint(profil)
app.register_blueprint(logs)
app.register_blueprint(loginlogout)
@app.route( '/gallery/')
def gallery():
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
THUMBNAILS=DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/'
fichiers = [fich for fich in os.listdir(THUMBNAILS)]
return render_template('gallery.html',
section='Gallery',
THUMBNAILS=THUMBNAILS,
fichiers=fichiers)
else :
return redirect(url_for('loginlogout.login'))
@app.route( '/parametres/', methods=['GET','POST'] )
def parametres() :
if 'username' in session :
return render_template('parametres.html', section='profil')
else:
return redirect(url_for('loginlogout.login'))
@app.route('/remove/<nom>')
def remove(nom):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
nom = secure_filename(nom)
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom): # si le fichier existe
os.remove(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom) # on le supprime
return redirect(url_for('filesupload.list', _external=True))
else:
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom): # si le fichier existe
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom) # on le supprime
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/' + nom) # on le supprime
return redirect(url_for('gallery'))
else:
flash(u'Fichier {nom} inexistant.'.format(nom=nom), 'error')
return redirect(url_for('filesupload.list', _external=True)) # sinon on redirige vers la liste, avec un message d'erreur
else :
return redirect(url_for('loginlogout.login'))
@app.route('/myfiles/<filename>')
def myfiles(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'files'), filename )
else :
return redirect(url_for('loginlogout.login'))
@app.route('/myfiles/images/<filename>')
def myimg(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images'), filename )
else :
return redirect(url_for('loginlogout.login'))
@app.route('/myfiles/images/thumbnails/<filename>')
def mythumbnails(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images/thumbnails'), filename )
else :
return redirect(url_for('loginlogout.login'))
@app.route( '/' )
def index():
if 'username' in session :
return redirect(url_for('profil.profile'))
else :
return redirect(url_for('loginlogout.login', _external=True))
app.register_blueprint(mygallery)
def create_app():
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
init_db()
db_migrate()
if init_dir():
print ("Le repertoire des utilisateurs a été créer")
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
app.register_blueprint(inscription)
app.register_blueprint(postit)
app.register_blueprint(filesupload)
app.register_blueprint(profil)
app.register_blueprint(logs)
app.register_blueprint(loginlogout)
return app
if __name__ == '__main__' :
app.run(host='127.0.0.1', port=8080, debug=True)
hostname=gethostname()
app.run(host='127.0.0.1', port=8080, debug=False)

9
scripts/etc/mailconfig Normal file
View File

@ -0,0 +1,9 @@
# Password file
PASSWD_FILE="/etc/mail/passwd"
# Alias File
ALIAS_FILE="/etc/mail/virtuals"
# APPLICATIONS MAIL ADDRESS
APP_MAIL="/etc/mail/reserved"

9
scripts/mailconfig Normal file
View File

@ -0,0 +1,9 @@
# Password file
PASSWD_FILE="/home/kitoy/prog/shell/passwd"
# Alias File
ALIAS_FILE="/home/kitoy/prog/shell/virtuals"
#App mail list
APP_MAIL=/home/kitoy/prog/shell/app_mail

109
scripts/set_mail_alias Executable file
View File

@ -0,0 +1,109 @@
#!/bin/sh
. /etc/mailconfig
check_mail()
{
mail=$1
domain=`echo $mail | awk -F '@' '{ print $2 }'`
if [ "$domain" != `hostname` ]; then
echo "bad domain"
exit 1
fi;
mail_exist=`egrep "$mail" $PASSWD_FILE`
if [ -z $mail_exist ]; then
print "This address doesn't exist"
exit 1
fi
}
check_alias()
{
mail=$1
while read line; do
alias=`echo $line | awk -F ':' '{ print $1 }'`
isvmail=`echo $line | awk -F ':' '{ print $2 }'`
if [ "$mail" = "$alias" ] && [ "$isvmail" != " vmail" ]; then
echo "Address already exist in alias!"
exit 2;
fi;
done < $ALIAS_FILE
}
check_app_mail()
{
mail=$1
while read line; do
if ["mail" == "line"]; then
echo "Adress already exist"
exit 2;
fi;
done < $APP_MAIL
}
add_alias()
{
print "$2":" $1" >> "$alias_file"
}
del_alias()
{
while read line; do
if [ "$1: $2" = "$line" ]; then
cat alias | grep -w -v -e "$1" > /tmp/alias.tmp
mv /tmp/alias.tmp "$alias_file"
isremove=1
fi
done < "$ALIAS_FILE"
}
usage(){
print "This program ask 3 arguments : \n"
print "First is email with domain name of this host second is add or del for \n"
print "add or delete an alias "
print "\t$0 email-adresse del alias@`hostname`\n"
print "Other example:\n\t $0 test@`hostname` add myalias@`hostname` "
print "This script require root privilèges"
}
if [ `id -u` -ne 0 ]; then
usage
exit 4;
fi
if [ -z $1 ];
then
usage
exit 3;
fi
if [ -z $2 ];
then
usage
exit 3;
fi
check_mail $1
case $2 in
"add")
check_alias $3
check_app_mail $3
add_alias $1 $3
;;
"del")
del_alias $3 $1
;;
*)
usage
exit 4;
;;
esac

112
scripts/set_mail_passwd Executable file
View File

@ -0,0 +1,112 @@
#!/bin/sh
. /etc/mailconfig
check_domain()
{
mail=$1
domain=`echo $mail | awk -F '@' '{ print $2 }'`
if [ "$domain" != `hostname` ]; then
echo "bad domain"
exit 1
fi;
}
check_alias()
{
mail=$1
while read line; do
alias=`echo $line | awk -F ':' '{ print $1 }'`
isvmail=`echo $line | awk -F ':' '{ print $2 }'`
if [ "$mail" = "$ALIAS_FILE" ] && [ "$isvmail" != " vmail" ]; then
echo "Address already exist in alias!"
exit 2;
fi;
done < $ALIAS_FILE
}
check_app_mail()
{
mail=$1
while read line; do
if ["mail" == "line"]; then
echo "Adress already exist"
exit 2;
fi;
done < $APP_MAIL
}
change_password()
{
cat $PASSWD_FILE | grep -w -v -e "$1" > /tmp/passwd.tmp
print "$1":`encrypt "$2"` >> /tmp/passwd.tmp
mv /tmp/passwd.tmp $PASSWD_FILE
}
add_mailbox()
{
mailbox="$1"': vmail'
egrep "$mailbox" "$ALIAS_FILE";
if [ "$?" -eq "1" ]; then
print "$mailbox" >> $ALIAS_FILE
fi
}
delete_mail_account()
{
mail_account=$1
cat $PASSWD_FILE | grep -w -v -e "$mail_account" > /tmp/passwd.tmp
mv /tmp/passwd.tmp $PASSWD_FILE
cat $ALIAS_FILE | grep -w -v -e "$mail_account" >> /tmp/virtuals.tmp
mv /tmp/virtuals.tmp $ALIAS_FILE
# rm -fr repertoir mail.
}
usage(){
print "This program ask 2 arguments : \n"
print "For add or change password of mail account :\: "
print "First is email with domain name of this host second is password \n:"
print "\t$0 email-adresse 'password'\n"
print "Example:\n\t $0 test@`hostname` 'yourverysecurepassword' "
print "For delete a mail account:\n"
print "$0 del test@`hostname`"
print "This script require root privilèges"
}
if [ `id -u` -ne 0 ]; then
usage
exit 4;
fi
if [ -z "$1" ]; then
usage
exit 3;
fi
if [ -z "$2" ]; then
usage
exit 3;
fi
case $1 in
"del")
check_domain "$2"
delete_mail_account "$2"
;;
*)
check_domain "$1"
check_alias "$1"
check_app_mail "$1"
add_mailbox "$1"
change_password "$1" "$2"
;;
esac

1243
static/bootstrap.css vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -9,11 +9,13 @@ a:hover {
color: #fff;
}*/
/* Custom default button */
.btn-default,
.btn-default:hover,
.btn-default:focus {
color: #333;
color: #fff;
text-shadow: none; /* Prevent inheritence from `body` */
/*background-color: #fff;*/
border: 1px solid #fff;
@ -35,6 +37,8 @@ body {
text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* Extra markup and styles for table-esque vertical and horizontal centering */
.site-wrapper {
display: table;
@ -58,6 +62,29 @@ body {
padding: 30px;
}
.panel-body {
background-color: #444;
}
.row {
margin-top: 5vw;
}
.container a {
color #00abff;
}
.panel-body a {
color: #00abff;
}
.well {
margin-top : 7em;
}
.well a {
color: #00abff;
}
/*
* Header

View File

@ -1,11 +1,11 @@
function divhider() {
var x = document.getElementsByClassName("msginfo");
var x = document.getElementsByClassName("flashed");
x[0].style.visibility = "hidden";
}
function animation() {
var x = document.getElementsByClassName("msginfo");
var x = document.getElementsByClassName("flashed");
x[0].style.animation = "disparition 0.2s 1";
}

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Binary file not shown.

View File

@ -37,7 +37,7 @@
margin: auto;
margin-top: 5%;
width: 50%;
background-color: #333;
}
.flashed p {
@ -48,7 +48,7 @@
}
.succes p {
background-color: #CDCBD0;
background-color: #CDCBD0;
color: #00A310;
}
@ -182,6 +182,7 @@
#gallery img:hover {
filter:none;
transform: scale(1.2);
}
@media (max-width: 1200px) {

View File

@ -18,22 +18,31 @@
Post-it !
</a>
</li>
<li {% if section == "Upload" %} class="active" {% endif %}>
<a href="/filesupload/">
<span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span>
Envoyer des fichiers
</a>
</li>
<li{% if section == "Files" %} class="active" {% endif %} >
<a href="/view/">
<span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span>
Mes Fichiers</a>
</li>
<li {% if section == "Gallery" %} class="active" {% endif %} >
<a href="/gallery/">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
Gallerie d'images
</a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-folder-open" aria-hidden="true"></span> Mes Fichiers</a>
<ul class="dropdown-menu" role="menu">
<li><a href="/view/"> <span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span>
Fichiers envoyés </a></li>
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span>
Envoyer des fichiers</a></li>
<li><a href="/gallery/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
Gallerie d'images
</a></li>
</ul>
<li{% if section == "mailbox" %} class="active" {% endif %} >
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-comment" aria-hidden="true"></span> Ma Messagerie </a>
<ul class="dropdown-menu" role="menu">
<li><a href="/mymailbox/"> <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
Changer mon mot de passe </a></li>
<li><a href="/mymailbox/alias"><span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span>
Gerer mes alias</a></li>
</ul>
</li>
<li{% if section == "Logs" %} class="active" {% endif %}>
<a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
@ -46,6 +55,7 @@
<li><a href="/profil/"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
<li class="divider"></li>
<li><a href="/invitation/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Inviter une personne</a></li>
<!--<li class="dropdown-header">Nav header</li>-->
</ul>
</li>

View File

@ -17,7 +17,6 @@
<h3 class="masthead-brand">Pywallter</h3>
<ul class="nav masthead-nav">
<li class="active"><a href="/filesupload/"></a></li>
<li><a href="/inscription/">Inscription</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>

View File

@ -1,6 +1,5 @@
{% extends 'up_squelette.html' %}
{% include '_nav_userlogin.html' %}
{% block main %}
@ -18,7 +17,7 @@
Bienvenue sur le tableau de post-it communautaire.
Il vous est possible de laisser des post-its en tout genre sur cette page.
Vous disposez pour cela d'un éditeur de type Markdown.
Une page <a href="/postit/publicblog"><span class="glyphicon glyphicon-star" aria-hidden="true"></span>
Une page <a href="/postit/board"><span class="glyphicon glyphicon-star" aria-hidden="true"></span>
est là pour consulter le tableau public du serveur</a>.
Celui-ci regroupe tout les post-it public des utilisateurs inscrits sur le serveur.<br>
Vous pouvez aussi écrire des post-its privé que vous seul pourrait consulter.</div>
@ -49,7 +48,7 @@
<div class="col-sm-2">
<img src="/static/usersprofil/{{ post.avatar }}" class="img-rounded" alt=""/><br><br>
<p>{{ post.nom }}<br>{{ post.prenom }}<br>{{ post.age }} ans<br></p>
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
</div>
<div class="col-sm-9">
@ -80,5 +79,3 @@
{% endfor %}
{% endblock %}
</div>

43
templates/board.html Normal file
View File

@ -0,0 +1,43 @@
{% extends 'up_squelette.html' %}
{% block main %}
{% for post in posts %}
<div class="well">
<div class="row">
<div class="col-sm-2">
<img src="/static/usersprofil/{{ post.avatar }}" class="img-rounded" alt=""/><br><br>
<p>{% if post.author != None %}{{ post.author }} {%endif%} <br />{% if post.prenom != None %}{{ post.prenom }}{%endif%} <br/>{% if post.age != None %}{{ post.age }} ans {%endif%}<br /></p>
</div>
<div class="col-sm-9">
<h6>{{ post.time }}</h6>
<h2>{{ post.title }}</h2>
{{ post.content|safe }}
</div>
<div class="col-sm-1">
{% if post.author == session['username'] %}
{% if post.status == 'prive' %}
<h4><span class="label label-danger">Privé</span></h4>
{% else %}
<h4><span class="label label-success">Public</span></h4>
{% endif %}
<br /><br>
<a href="{{ url_for('post-it.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
<a href="{{ url_for('post-it.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a><br /><br>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endblock %}

View File

@ -1,43 +1,5 @@
{% extends 'up_squelette.html' %}
{% block navbar %}
<!-- Fixed navbar -->
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!--<a class="navbar-brand" href="/blog/">Blog</a>-->
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/post-it/"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Blog</a></li>
<li><a href="/filesupload/"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload</a></li>
<li><a href="/view/"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Fichiers</a></li>
<li class="active"><a href="/gallery/"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> Gallerie</a></li>
<li><a href="/logs/"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Logs</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> <span id="majuscule">{{ session['username'] }} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/profil/"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Profil</a></li>
<li><a href="/parametres/"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Paramètres</a></li>
<li class="divider"></li>
<!--<li class="dropdown-header">Nav header</li>-->
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Déconnexion</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="/logout/"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Exit</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
{% endblock %}
{% block main %}

View File

@ -12,9 +12,12 @@
<div class="inner">
<h3 class="masthead-brand">Pywallter</h3>
<ul class="nav masthead-nav">
<li><a href="/login/">Login</a></li>
<li class="active"><a href="/inscription/">Inscription</a></li>
<li><a href="#">Contact</a></li>
<li><a href="/login/">Login</a></li>
{% if signin_enable %}
<li class="active"><a href="/inscription/">Inscription</a></li>
{% endif %}
<li><a href="#">Contact</a></li>
</ul>
</div>
</div>
@ -22,19 +25,28 @@
<div class="inner cover">
<h1 class="cover-heading">Inscription</h1>
<br>
<p class="lead">
<form method="POST" action="{{ url_for('inscription.signin') }}">
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
<input type="mail" name="mail" id="mail" placeholder="Adresse mail" class="form-control"><br />
{% if signin_enable %}
<form method="POST" action="{{ base_url }}">
<input type="text" name="user" id="user" placeholder="Pseudo" class="form-control"><br />
<div class="col-sm-7">
<input type="text" name="mail" id="mail" placeholder="Adresse mail" class="form-control" size="2"> <br/>
</div>
<h4>@{{hostname}}</h4>
<br/>
<input type="password" name="passwd" id="passwd" placeholder="Mot de passe" class="form-control"><br />
<input type="password" name="passwdconfirm" id="passwdconfirm" placeholder="Confirmation du mot de passe" class="form-control"><br />
<br>
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
</form>
</p>
{% for i in users %}
</form>
{% else %}
<p class="lead">
Désolé les inscriptions ne sont pas activés sur le serveur
</p>
{%endif%}
{% for i in users %}
<p>{{i}}</p>
{% endfor %}
{% endfor %}
</div>
<div class="msginfo">

53
templates/invitation.html Normal file
View File

@ -0,0 +1,53 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div class="row">
<div class="well">
Si vous voulez vous pouvez inviter une personne à se crée un compte sur ce serveur
pour cela vous devez crée un lien d'inscription. Ce lien restera valable tant
que la personne ne s'est pas inscrite ou tant que vous ne créez pas un autre lien.
Les invitations se font une par une et sont limité à 20 personnes pour ne pas surcharger notre petit serveur :).
Une fois que la personne s'est incrite votre nombre d'invitations sera mis à jour
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Création du lien d'inscription</h3>
</div>
<div class="panel-body">
{% if token %}
<h3> Votre lien d'inscription en cours: </h3>
<a href="{{ base_url }}/{{ token }}">
{{base_url }}/{{ token }}
</a>
{% else %}
<h3> Pas d'invitation en attente </h3>
{% endif %}
<p> Il vous reste : {{ nb_invitation }} invitations à envoyer </p>
<a href="/gen_token/">
<button type="submit" id="tada" class="btn btn btn-success"> Créer un nouveau lien </button></a>
<div class="msginfo">
{# on affiche les messages d'erreur puis les messages de succes #}
{% for categorie in ['error', 'succes'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,12 +1,11 @@
{% extends 'up_squelette.html' %}
{% include '_nav_userlogin.html' %}
{% block main %}
<!--<div class="page-header">
<div class="page-header">
<p class="text-center"><h1>Logs</h1></p>
</div>-->
</div>
<br />

61
templates/mailbox.html Normal file
View File

@ -0,0 +1,61 @@
{% extends 'up_squelette.html' %}
{% block main %}
<!--<div class="page-header">
<h1>Profil</h1>
</div>-->
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<div class="well">
<p>En créant une adresse e-mail sur ce serveur vous pouvez utiliser cette adresse à la fois
avec un client mail et avec client XMPP
</p>
<p>Voici un exemple de <a href="https://www.thunderbird.net/fr/"> client mail </a>
et <a href="https://gajim.org/">client XMPP </a> pour un ordinateur </p>
<p> Voici un exemple de <a href="https://k9mail.app/"> client mail </a> et <a href="https://conversations.im/">client XMPP</a>
pour un téléphone sous Android </p>
<p> Voici un exemple de<a href="https://support.apple.com/fr-fr/mail"> client mail</a> et <a href="https://monal.im/"> client XMPP </a>sous iOS </p>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"> Changer mon mot de passe </h3>
</div>
<div class="panel-body">
<form method="POST" action="" enctype="multipart/form-data">
<p> Votre Adresse e-mail sur ce serveur : {{ address }} </p>
<label> Mot de passe </label>
<input type="password" name="password" id="password" placeholder="Votre mot de passe" class="form-control"><br />
<input type="password" name="passwd_confirm" id="passwd_confirm" placeholder="Confirmation du mot de passe" class="form-control"><br />
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
</form>
{# on affiche les messages d'erreur puis les messages de succes #}
{% for categorie in ['error', 'succes'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

67
templates/myalias.html Normal file
View File

@ -0,0 +1,67 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th>Mes Alias <span class="badge">{{ i }}</span></th>
<th></th>
</tr>
</thead>
<tbody>
{% if aliases %}
{% for alias in aliases %}
<tr>
<td>{{ alias }}</td>
<td><a href="{{ url_for('profil.remove_alias', aliasrm=alias) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"> Mes identités </h3>
</div>
<div class="panel-body">
<form method="POST" action="" enctype="multipart/form-data">
<p> Votre Adresse e-mail sur ce serveur : {{ email }} </p>
<label> Nouvelles identité </label>
<br/>
<div class="col-sm-7">
<input type="text" name="alias" id="alias" placeholder="Nouvel_identité" class="form-control"><br />
</div>
<h4>@{{ hostname }}</h4>
<br/>
<br/>
<button id="tada" class="btn btn-default btn-primary" type="submit">Ajouter</button>
</form>
</div>
</div>
{# on affiche les messages d'erreur puis les messages de succes #}
{% for categorie in ['error', 'succes'] %}
{% with msgs = get_flashed_messages(category_filter=[categorie]) %}
{% if msgs %}
<div class="flashed {{ categorie }}">
{% for m in msgs %}
<p>{{ m|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endfor %}
{% endblock %}

View File

@ -1,7 +1,5 @@
{% extends 'up_squelette.html' %}
{% include '_nav_userlogin.html' %}
{% block main %}
<div class="page-header">

View File

@ -1,57 +0,0 @@
{% extends 'up_squelette.html' %}
{% block main %}
<div class="jumbotron">
<div class="row">
<div class="col-sm-4">
<p id="majuscule" class="text-center"><h3>Articles privés de <span id="majuscule">{{ UTILISATEUR }}</span></h3>
<br />
<h5> Articles visibles par vous uniquement </h5></p>
</div>
<div class="col-sm-6">
</div>
<div class="col-sm-2">
<img src="/static/usersprofil/{{ usersinfos[0] }}" class="img-rounded" alt=""/>
</div>
</div>
</div>
<br>
{% for post in posts %}
<div class="row">
<div class="col-sm-2">
</div>
<div class="col-sm-8">
<div class="well">
<div class="row">
<div class="col-sm-10">
<div class="well">
<h6>{{ post.time }}</h6>
<h2>{{ post.title }}</h2>
{{ post.content|safe }}
<h6>Auteur : {{ post.author }}</h6>
</div>
</div>
<div class="col-sm-1">
{% if post.author == session['username'] %}
{% if post.status == 'prive' %}
<h4><span class="label label-danger">Privé</span></h4>
{% else %}
<h4><span class="label label-success">Public</span></h4>
{% endif %}
<br /><br>
<a href="{{ url_for('blog.edit', post=post.title) }}"><button type="button" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></button></a><br /><br>
<a href="{{ url_for('blog.delete', post=post.title) }}"><button type="button" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button></a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
</div>

View File

@ -1,6 +1,5 @@
{% extends 'up_squelette.html' %}
b{% include '_nav_userlogin.html' %}
{% block main %}
@ -14,7 +13,7 @@ b{% include '_nav_userlogin.html' %}
<div class="col-sm-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Informations personnelles</h3>
<h3 class="panel-title">Mon profil</h3>
</div>
<div class="panel-body">
<form method="POST" action="" enctype="multipart/form-data">
@ -25,13 +24,13 @@ b{% include '_nav_userlogin.html' %}
</div>
<br>
<label>Nom </label>
<input type="text" name="nom" id="nom" value="{{ profil['nom'] }}" class="form-control"><br />
<input type="text" name="nom" id="nom" value="{% if profil['nom'] != None %}{{ profil['nom'] }}{%endif%}" class="form-control"><br />
<label>Prenom </label>
<input type="text" name="prenom" id="prenom" value="{{ profil['prenom'] }}" class="form-control"><br />
<input type="text" name="prenom" id="prenom" value="{% if profil['nom'] != None %}{{ profil['prenom'] }}{%endif%}" class="form-control"><br />
<label> Age </label>
<input type="text" name="age" value="{{ profil['age'] }}" class="form-control"><br />
<input type="text" name="age" value="{% if profil['age'] != None %}{{ profil['age'] }}{%endif%}" class="form-control"><br />
<label> Mail de secours </label>
<input type="text" name="mail_rescue" id="mail_rescue" value="{{ profil['mail_rescue'] }}" class="form-control"><br />
<input type="text" name="mail_rescue" id="mail_rescue" value="{% if profil['nom'] != None %}{{ profil['mail_rescue'] }}{%endif%}" class="form-control"><br />
<button id="tada" class="btn btn-default btn-primary" type="submit">Envoyer</button>
</form>
{# on affiche les messages d'erreur puis les messages de succes #}

30
templates/rmalias.html Normal file
View File

@ -0,0 +1,30 @@
{% extends 'up_squelette.html' %}
az
{% block main %}
<br>
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th>Alias <span class="badge">{{ i }}</span></th>
<th></th>
</tr>
</thead>
<tbody>
{% if aliases %}
{% for alias in aliases %}
<tr>
<td>{{ alias }}</td>
<td><a href="{{ url_for('rmalias', alias=alias) }}"><button type="button" class="btn btn-sm btn-danger">Supprimer</button></a></td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -3,7 +3,7 @@
{% include '_head.html' %}
<body role="document">
{% include '_nav_userlogin.html'%}
{% include '_nav_userlogin.html'%}

View File

@ -1,50 +1,72 @@
#!venv/bin/python
from flask import Flask
import sqlite3
import os.path
import os
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
DATABASE = app.config['DATABASE']
DOSSIER_PERSO = app.config['DOSSIER_APP']
DATABASE = app.config['DATABASE']
def init_db():
if os.path.isfile('base.db'):
return False
else:
conn = sqlite3.connect('base.db')
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users(
Mail CHAR(80) PRIMARY KEY UNIQUE NOT NULL,
name TEXT,
alias TEXT,
xmpp TEXT,
passwd TEXT,
avatar TEXT,
nom TEXT,
prenom TEXT,
age TEXT,
website TEXT,
Token CHAR(30),
Mail_rescue TEXT )
""")
conn.commit()
print ('table users OK')
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users(
Mail CHAR(80) PRIMARY KEY UNIQUE NOT NULL,
name TEXT,
alias TEXT,
xmpp TEXT,
passwd TEXT,
avatar TEXT,
nom TEXT,
prenom TEXT,
age TEXT,
website TEXT,
Token CHAR(30),
invitations INTEGER DEFAULT (20),
Mail_rescue TEXT )
""")
conn.commit()
print ('table users Ok')
cursor.execute("""
CREATE TABLE IF NOT EXISTS posts(
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
title TEXT,
content TEXT,
time TEXT,
category TEXT,
author TEXT,
status TEXT
)
""")
conn.commit()
conn.close()
print ('table posts OK')
return True
cursor.execute("""
CREATE TABLE IF NOT EXISTS posts(
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
title TEXT,
content TEXT,
time TEXT,
category TEXT,
author TEXT,
status TEXT
)
""")
conn.commit()
conn.close()
print ('table posts OK')
def init_dir():
if os.path.isdir('users'):
return False
else:
os.makedirs('./users/')
def db_migrate():
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""SELECT name FROM PRAGMA_TABLE_INFO('users');""")
db_columns = cursor.fetchall()
present = False
for col in db_columns:
if "invitations" == col[0]:
present = True
if not(present):
cursor.execute("""ALTER TABLE users ADD COLUMN invitations INTEGER DEFAULT (20);""")
conn.commit()
print ("Ajout du champ invitations")

75
tools/utils.py Normal file
View File

@ -0,0 +1,75 @@
from flask import Flask
import sqlite3
import os
import string
import random
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
DATABASE = app.config['DATABASE']
DOSSIER_PERSO = app.config['DOSSIER_APP']
DATABASE = app.config['DATABASE']
def append_to_log(log_line, user):
log_file=os.path.join(DOSSIER_PERSO, user, "log.txt")
logs=open(log_file, "r")
tmp=logs.read()
logs.close()
log=open(log_file, "w")
log.write(log_line)
log.write(tmp)
log.close()
def email_disp(email):
disp = True
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT mail FROM users WHERE mail=?""", (email,))
testmail = cursor.fetchall()
if testmail:
print ("on passe ici")
disp = False
if disp:
cursor.execute("""SELECT alias FROM users""")
aliases = cursor.fetchall()
for alist in aliases:
for alias in alist:
if alias:
if email in alias:
disp=False
return disp
def valid_token_register(token):
valid = True
print(token)
if len(token) != 30:
valid = False
if valid:
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
tmp = cursor.fetchone()
conn.close()
print (tmp)
if tmp:
valid = True
else:
valid = False
print(valid)
return valid
#Génère un token de 30 caratères aléatoires
def gen_token():
letters = random.choices(string.ascii_letters, k=20)
digits = random.choices(string.digits, k=10)
sample = ''.join(random.sample(digits + letters, 30))
return sample

View File

@ -1,12 +1,28 @@
# -*- coding: utf-8 -*-
from flask import Blueprint, escape, render_template, session, redirect, url_for, request, flash, abort
from flask import Blueprint, escape, render_template, session, redirect, url_for, request, flash, abort, Flask
import time
import sqlite3
from markdown import markdown
postit = Blueprint('post-it', __name__, template_folder='templates')
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
#### Variables ####################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
##################################################################################################
@postit.route('/post-it/', methods=['GET', 'POST'])
def racine_blog():
@ -18,7 +34,7 @@ def racine_blog():
#category = request.form['category']
status = request.form['status']
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
conn = sqlite3.connect('base.db') # Connexion la base de donne
conn = sqlite3.connect(DATABASE) # Connexion la base de donne
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""INSERT INTO posts(title, content, time, author, status) VALUES(?, ?, ?, ?, ?)""",
(title, content, TIME, UTILISATEUR, status)) # Insérer des valeurs
@ -30,7 +46,7 @@ def racine_blog():
conn.close()
return render_template('blog.html', posts=posts)
else:
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""")
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3],
@ -39,21 +55,21 @@ def racine_blog():
conn.close()
return render_template('blog.html', section='Post-it', posts=posts)
else:
return redirect(url_for('loginlogout.login', _external=True))
return redirect(url_for('loginlogout.login', _external=True), code=401)
@postit.route('/delete/<post>')
def delete(post):
if 'username' in session :
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""DELETE FROM posts WHERE title=?""", (post,))
conn.commit()
conn.close()
return redirect(url_for('post-it.racine_blog'))
else:
return redirect(url_for('loginlogout.login', _external=True)) # sinon on redirige vers login
return redirect(url_for('loginlogout.login', _external=True), code=401) # sinon on redirige vers login
@postit.route('/edit/<post>', methods=['GET', 'POST'])
def edit(post):
@ -62,7 +78,7 @@ def edit(post):
newtitle = request.form['title']
newcontent = markdown(request.form['content'])
newstatus = request.form['status']
conn = sqlite3.connect('base.db')
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""UPDATE posts SET title=?, content=?, status=? WHERE title=?""",
(newtitle, newcontent, newstatus, post,))
@ -70,13 +86,28 @@ def edit(post):
conn.close()
return redirect(url_for('post-it.racine_blog'))
else:
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content FROM posts WHERE title=?""", (post,))
oldpost = (cursor.fetchone())
oldpost = cursor.fetchone()
conn.close()
return render_template('postedit.html',
section='Post-it',
oldpost=oldpost)
else:
return redirect(url_for('loginlogout.login', _external=True)) # sinon on redirige vers login)
return redirect(url_for('loginlogout.login', _external=True), code=401) # sinon on redirige vers login)
@postit.route('/postit/board', methods=['GET'])
def viewsheet():
if 'username' in session:
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT title, content, time, author, status, avatar, nom, prenom, age FROM posts INNER JOIN users ON author = name""")
posts = [dict(title=row[0], content=row[1], time=row[2], author=row[3],
status=row[4], avatar=row[5], nom=row[6], prenom=row[7], age=row[8])
for row in reversed(cursor.fetchall())]
conn.close()
return render_template('board.html', section='Post-it', posts=posts)
else:
return redirect(url_for('loginlogout.login', _external=True), code=401)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, escape, flash, abort, send_file, escape, send_from_directory
from werkzeug.utils import secure_filename
from PIL import Image
import time
@ -8,15 +8,21 @@ import sqlite3
import os
filesupload = Blueprint('filesupload', __name__, template_folder='templates')
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
filesupload = Blueprint('filesupload', __name__, template_folder='templates')
#### Variables ####################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
##################################################################################################
@filesupload.route( '/filesupload/', methods=['GET', 'POST'])
def uploadfiles():
if 'username' in session :
@ -44,7 +50,8 @@ def uploadfiles():
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
IP=request.environ['REMOTE_ADDR']
CLIENT_PLATFORM=request.headers.get('User-Agent')
LOG=open("log.txt", "a")
log_file=os.path.join(DOSSIER_PERSO, UTILISATEUR, "log.txt")
LOG=open(log_file, "a")
LOG.write (TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + nom + '\n')
LOG.close()
flash(u'Image envoyée et traitée avec succés', 'succes')
@ -74,7 +81,7 @@ def uploadfiles():
resp.set_cookie('username', session['username'])
return resp
else :
return redirect(url_for('loginlogout.login', _external=True))
return redirect(url_for('loginlogout.login', _external=True), code=401)
@filesupload.route('/view/')
@ -98,4 +105,33 @@ def list():
flash(u'Aucun fichier uploadé ! Redirection vers Upload', 'error')
return redirect(url_for('filesupload.uploadfiles', external=True))
else :
return redirect(url_for('loginlogout.login', _external=True))
return redirect(url_for('loginlogout.login', _external=True), code=401)
@filesupload.route('/myfiles/<filename>')
def myfiles(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'files'), filename )
else :
return redirect(url_for('loginlogout.login'), code=401)
@filesupload.route('/remove/<nom>')
def remove(nom):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
nom = secure_filename(nom)
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom): # si le fichier existe
os.remove(DOSSIER_PERSO + UTILISATEUR + '/files/' + nom) # on le supprime
return redirect(url_for('filesupload.list', _external=True))
else:
if os.path.isfile(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom): # si le fichier existe
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/' + nom) # on le supprime
os.remove(DOSSIER_PERSO + UTILISATEUR + '/images/' + nom) # on le supprime
return redirect(url_for('gallery'))
else:
flash(u'Fichier {nom} inexistant.'.format(nom=nom), 'error')
return redirect(url_for('filesupload.list', _external=True)) # sinon on redirige vers la liste, avec un message d'erreur
else :
return redirect(url_for('loginlogout.login'), code=401)

55
views/gallery.py Normal file
View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
from flask import Blueprint, Flask, request, flash, render_template, url_for, session, redirect, abort, make_response, send_file, escape, flash, abort, send_file, send_from_directory
from werkzeug.utils import secure_filename
from PIL import Image
import time
import sqlite3
import os
mygallery = Blueprint('mygallery', __name__, template_folder='templates')
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
#### Variables ####################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
##################################################################################################
@mygallery.route( '/gallery/')
def gallery():
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
THUMBNAILS=DOSSIER_PERSO + UTILISATEUR + '/images/thumbnails/'
fichiers = [fich for fich in os.listdir(THUMBNAILS)]
return render_template('gallery.html',
section='Gallery',
THUMBNAILS=THUMBNAILS,
fichiers=fichiers)
else :
return redirect(url_for('loginlogout.login'), code=401)
@mygallery.route('/myfiles/images/<filename>')
def myimg(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images'), filename )
else :
return redirect(url_for('loginlogout.login'), code=401)
@mygallery.route('/myfiles/images/thumbnails/<filename>')
def mythumbnails(filename):
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
return send_from_directory(
os.path.join(DOSSIER_PERSO, UTILISATEUR, 'images/thumbnails'), filename )
else :
return redirect(url_for('loginlogout.login'), code=401)

View File

@ -2,71 +2,118 @@ from flask import Blueprint, Flask, request, flash, render_template, url_for, se
from flask_bcrypt import Bcrypt
import sqlite3
import glob, os, sys, time
from tools.utils import email_disp, valid_token_register
from socket import gethostname
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
#### Variables ####################################################################################
#### Variables ##################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
##################################################################################################
DATABASE = app.config['DATABASE']
MAIL_SERVER = app.config['MAIL_SERVER']
XMMP_SERVER = app.config['XMPP_SERVER']
SETUID = app.config['SETUID']
#################################################################################################
inscription = Blueprint('inscription', __name__, template_folder='templates')
@inscription.route( '/inscription/', methods=['GET','POST'] )
def signin() :
if 'username' in session :
return redirect(url_for('filesupload'))
else :
if request.method == 'POST' :
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
user = request.form['user']
mail = request.form['mail']
passwd = bcrypt.generate_password_hash(request.form['passwd'])
passwdconfirm = request.form['passwdconfirm']
cursor.execute("""SELECT name FROM users WHERE name=?""", (user,))
testuser=cursor.fetchone()
cursor.execute("""SELECT mail FROM users WHERE mail=?""", (mail,))
testmail=cursor.fetchone()
conn.close()
if testuser or testmail:
flash(u'Non d\'utilisateur ou email déjà utilisé, merci d\'en choisir un autre', 'error')
return render_template('inscription.html')
else:
confirmation = bcrypt.check_password_hash(passwd, passwdconfirm)
if confirmation is True:
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""INSERT INTO users(name, mail, passwd) VALUES(?, ?, ?)""", (user, mail, passwd)) # Insérer des valeurs
conn.commit() # Sauvegarder valeurs dans la bdd
cursor.execute("""SELECT name, mail, passwd FROM users""")
users = cursor.fetchall()
for i in users:
i = print('{0} - {1} - {2}'.format(i[0], i[1], i[2]))
conn.close()
userracine = DOSSIER_PERSO + user
userfiles = userracine + '/files'
userimages = userracine + '/images'
userthumbnails = userracine + '/images/thumbnails'
userprofile = userracine + '/profile'
if not os.path.exists(userracine):
os.makedirs(userracine)
os.makedirs(userfiles)
os.makedirs(userimages)
os.makedirs(userthumbnails)
os.makedirs(userprofile)
flash(u'Inscription réalisée avec succés !', 'succes')
return render_template('login.html')
else:
flash(u'Les mots de passe ne sont pas identiques !', 'error')
return render_template('inscription.html')
@inscription.route( '/inscription/<token>', methods=['GET','POST'] )
def signin(token) :
hostname = gethostname()
if app.config['SIGNIN_ENABLE'] and valid_token_register(token):
if 'username' in session :
resp = redirect(url_for('profil.profile', _external=True))
else :
return render_template('inscription.html')
if request.method == 'POST':
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
user = request.form['user']
mail = request.form['mail']+'@'+hostname
passwd = bcrypt.generate_password_hash(request.form['passwd'])
passwdconfirm = request.form['passwdconfirm']
cursor.execute("""SELECT name FROM users WHERE name=?""", (user,))
testuser = cursor.fetchone()
conn.close()
if MAIL_SERVER:
p = run( [ SETUID, 'set_mail_passwd', "'"+mailbox['Mail']+"'", "'"+passwd+"'" ] )
if testuser:
flash(u'Non d\'utilisateur déjà utilisé, merci d\'en choisir un autre', 'error')
resp = render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'],
hostname=hostname)
elif not(email_disp(mail)) or p.returncode != 0 :
flash(u'Adresse email déjà utilisé, merci d\'en choisir un autre', 'error')
resp = render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'],
hostname=hostname)
else:
confirmation = bcrypt.check_password_hash(passwd, passwdconfirm)
if confirmation is True:
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""INSERT INTO users(name, mail, passwd) VALUES(?, ?, ?)""", (user, mail, passwd)) # Insérer des valeurs
conn.commit() # Sauvegarder valeurs dans la bdd
if XMMP_SERVER:
tmp = mailbox['mail'].split('@')
p = run( [ SETUID, 'prosodyctl register ', "'"+tmp[0]+"'",
"'"+tmp[1]+"'", "'"+passwd+"'" ])
if p.returncode != 0:
flash(u'Il y a eu un problème lors de la création du compte XMPP !', 'error')
cursor.execute("""SELECT name, mail, passwd FROM users""")
users = cursor.fetchall()
for i in users:
i = print('{0} - {1} - {2}'.format(i[0], i[1], i[2]))
conn.close()
userracine = DOSSIER_PERSO + user
userfiles = userracine + '/files'
userimages = userracine + '/images'
userthumbnails = userracine + '/images/thumbnails'
userprofile = userracine + '/profile'
if not os.path.exists(userracine):
os.makedirs(userracine)
os.makedirs(userfiles)
os.makedirs(userimages)
os.makedirs(userthumbnails)
os.makedirs(userprofile)
fp = open('log.txt', 'x')
fp.close()
# Une fois que tout c'est bien passé pour l'inscription on détruit le jeton.
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
tmp = cursor.fetchone()
username =tmp[0]
invitations_count=tmp[1] - 1
cursor.execute("""UPDATE users set invitations=?, Token='' where name=?""", (invitations_count, username,))
conn.commit()
flash(u'Inscription réalisée avec succés !', 'succes')
resp = redirect(url_for('loginlogout.login', _external=True))
else:
flash(u'Les mots de passe ne sont pas identiques !', 'error')
resp = render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'],
hostname=hostname)
else :
resp = render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'],
token=token, hostname=hostname, base_url=request.base_url)
else:
resp = redirect(url_for('index', _external=True), code=401)
return resp

View File

@ -3,17 +3,30 @@ import sqlite3
from flask_bcrypt import Bcrypt
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
bcrypt = Bcrypt(app)
#### Variables ####################################################################################
bcrypt = Bcrypt(app)
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
##################################################################################################
loginlogout = Blueprint('loginlogout', __name__, template_folder='templates')
@loginlogout.route( '/login/', methods=['GET','POST'] )
def login() :
if 'username' in session :
return redirect(url_for('filesupload.uploadfiles', _external=True))
resp = redirect(url_for('filesupload.uploadfiles', _external=True))
else :
resp = redirect(url_for('loginlogout.login', _external=True))
if request.method == 'POST' :
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT name, passwd FROM users""")
users = cursor.fetchall()
@ -25,12 +38,21 @@ def login() :
print ( passwd[2:(len(passwd)-1 )] )
if user[0] == request.form['user'] and bcrypt.check_password_hash(user[1], password) is True:
session['username'] = request.form['user']
return redirect(url_for('profil.profile', _external=True))
return redirect(url_for('loginlogout.login', _external=True))
resp = redirect(url_for('profil.profile', _external=True))
else:
return render_template('accueil.html')
resp = render_template('accueil.html', signin_enable=app.config['SIGNIN_ENABLE'])
return resp
@loginlogout.route( '/logout/' )
def logout():
session.pop('username', None) # Supprimer username de la session s'il s'y trouve
return redirect(url_for('index'))
return redirect(url_for('loginlogout.index'))
@loginlogout.route( '/' )
def index():
if 'username' in session :
return redirect(url_for('profil.profile'))
else :
return redirect(url_for('loginlogout.login', _external=True))

View File

@ -3,13 +3,29 @@ import glob, os, sys
logs = Blueprint('logs', __name__, template_folder='templates')
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
#### Variables ####################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
##################################################################################################
@logs.route('/logs/')
def logfile():
if 'username' in session :
with open('log.txt', 'r') as log:
if 'username' in session:
UTILISATEUR='%s'% escape(session['username'])
log_file=os.path.join(DOSSIER_PERSO, UTILISATEUR, "log.txt")
with open(log_file, 'r') as log:
print("on passe ici")
logs=log.readlines()
log.close()
for line in logs:
return render_template('logs.html', section="Logs", logs=logs, line=line)
return render_template('logs.html', section="Logs", logs=logs)
else :
return redirect(url_for('loginlogout.login', _external=True))
return redirect(url_for('loginlogout.login', _external=True), code=401)

View File

@ -4,6 +4,10 @@ from PIL import Image
import time
import sqlite3
import os
from socket import gethostname
from subprocess import run
from flask_bcrypt import Bcrypt
from tools.utils import email_disp, append_to_log, gen_token
profil = Blueprint('profil', __name__, template_folder='templates')
@ -13,19 +17,32 @@ app.config.from_pyfile('config.py')
#### Variables ####################################################################################
DOSSIER_PERSO= app.config['DOSSIER_APP']
bcrypt = Bcrypt(app)
DOSSIER_PERSO = app.config['DOSSIER_APP']
extensionimg = app.config['EXT_IMG']
DATABASE = app.config['DATABASE']
MAIL_SERVER = app.config['MAIL_SERVER']
XMPP_SERVER = app.config['XMPP_SERVER']
SETUID = app.config['SETUID']
##################################################################################################
@profil.route( '/parametres/', methods=['GET','POST'] )
def parametres() :
if 'username' in session :
return render_template('parametres.html', section='profil')
else:
return redirect(url_for('loginlogout.login'))
@profil.route('/profil/', methods=['GET','POST'] )
def profile() :
if 'username' in session :
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT avatar, nom, prenom, age, mail_rescue FROM users WHERE name=?""", (UTILISATEUR,))
tmp = (cursor.fetchone())
@ -61,7 +78,7 @@ def profile() :
img.tumbnails(resize='80x80')
img.save(filename = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom)
imagelocation = DOSSIER_PERSO + UTILISATEUR + '/profile/' + nom
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("UPDATE users SET avatar=? WHERE name=?",
(imagelocation, UTILISATEUR))
@ -71,8 +88,8 @@ def profile() :
flash(u'Image de profil mise à jour', 'succes')
else:
conn = sqlite3.connect('base.db') # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l\'objet "curseur"
cursor.execute("UPDATE users SET nom=?, prenom=?, age=?, mail_rescue=? WHERE name=?",
(profil_user['nom'], profil_user['prenom'], profil_user['age'], profil_user['mail_rescue'],
UTILISATEUR))
@ -88,4 +105,198 @@ def profile() :
username=UTILISATEUR)
else :
return redirect(url_for('loginlogout.login', _external=True))
return redirect(url_for('loginlogout.login', _external=True), code=401)
@profil.route('/profil/change-password/', methods=['GET','POST'] )
def change_passwd() :
if 'username' in session:
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT Mail, alias, xmpp FROM users WHERE name=?""", (UTILISATEUR,))
tmp = cursor.fetchone()
mailbox = dict()
mailbox['Mail'] = tmp[0]
mailbox['alias'] = tmp[1]
mailbox['xmpp'] = tmp[2]
if request.method == 'POST' :
if request.form['password'] == request.form['passwd_confirm']:
mail_passwd_change = 0
xmmp_passwd_change = 0
passwd = request.form['password']
if MAIL_SERVER:
p = run( [ SETUID, 'set_mail_passwd', "'"+mailbox['Mail']+"'", "'"+passwd+"'" ] )
mail_passwd_change = p.returncode
if XMMP_SERVER:
tmp = mailbox['mail'].split('@')
p = run( [ SETUID, 'prosodyctl register', "'"+tmp[0]+"'",
"'"+tmp[1]+"'", "'"+passwd+"'" ])
if p.returncode != 0:
flash(u'Il y a eu un problème pour le changement du mot de passe du compte XMPP !', 'error')
if mail_passwd_change == 0:
passwd_bcrypt = bcrypt.generate_password_hash(passwd)
cursor.execute("UPDATE users SET passwd=? WHERE name=?",
(passwd_bcrypt, UTILISATEUR))
conn.commit()
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
IP=request.environ['REMOTE_ADDR']
CLIENT_PLATFORM=request.headers.get('User-Agent')
log=TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Changement du mot de passe" + '\n'
append_to_log(log, UTILISATEUR)
flash(u'Votre mot de passe a été changé', 'succes')
else:
flash(u'Il y eu un problème votre mot de passe n\'a pas été changé', 'error')
can_commit=False
conn.close()
return render_template('mailbox.html',
section="mailbox",
address=mailbox['Mail'],
alias=mailbox['alias'],
username=UTILISATEUR)
else :
return redirect(url_for('loginlogout.login', _external=True), code=401)
@profil.route('/mymailbox/alias', methods=['GET', 'POST'] )
def myalias():
hostname=gethostname()
if 'username' in session:
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
if request.method == 'POST' and MAIL_SERVER:
if request.form['alias']:
alias = request.form['alias']+'@'+hostname
else:
flash(u'Addresse invalide')
if email_disp(alias):
cursor.execute("""SELECT Mail, alias FROM users where name=?""", (UTILISATEUR,))
tmp = cursor.fetchone()
mail = tmp[0]
if tmp[1]:
alias_list = tmp[1]
aliases = alias_list + "," +alias
else:
aliases = alias
p = run( [ 'set_mail_alias', "'"+mail+"'", "add", "'"+alias+"'" ] )
if p.returncode == 0:
cursor.execute("UPDATE users SET alias=? WHERE name=?",
(aliases, UTILISATEUR))
conn.commit()
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
IP=request.environ['REMOTE_ADDR']
CLIENT_PLATFORM=request.headers.get('User-Agent')
log=TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Ajout de l'alias "+ alias + '\n'
append_to_log(log, UTILISATEUR)
flash(u'Votre alias a été ajouté', 'succes')
else:
flash(u'Adresse indisponible', 'error')
else:
flash(u'Adresse indisponible', 'error')
cursor.execute("""SELECT Mail, alias FROM users WHERE name=?""",
(UTILISATEUR,))
tmp = cursor.fetchone()
mailbox = dict()
mailbox['Mail'] = tmp[0]
if tmp[1]:
mailbox['alias'] = tmp[1].split(',')
else:
mailbox['alias'] = list()
conn.close()
return render_template('myalias.html',
section="mailbox",
email=mailbox['Mail'],
aliases=mailbox['alias'],
hostname=hostname,
Mail_active=MAIL_SERVER
username=UTILISATEUR )
else:
return redirect(url_for('loginlogout.login', _external=True), code=401)
@profil.route('/mymailbox/rmalias/<aliasrm>')
def remove_alias(aliasrm):
if 'username' in session:
if MAIL_SERVER:
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT Mail, alias FROM users WHERE name=?""", (UTILISATEUR,))
tmp = cursor.fetchone()
mail = tmp[0]
alias_list = tmp[1].split(',')
aliases = ""
for alias in alias_list:
if alias != aliasrm:
if aliases:
aliases = aliases + "," + alias
else:
aliases = alias
p = run( [ 'set_mail_alias', "'"+mail+"'", "del", "'"+alias+"'" ] )
if p.returncode == 0:
cursor.execute("UPDATE users SET alias=? WHERE name=?",
(aliases, UTILISATEUR))
conn.commit()
TIME=time.strftime("%A %d %B %Y %H:%M:%S")
IP=request.environ['REMOTE_ADDR']
CLIENT_PLATFORM=request.headers.get('User-Agent')
log = TIME + ' - ' + IP + ' - ' + UTILISATEUR + ' - ' + CLIENT_PLATFORM + '\n' + '---> ' + "Suppression de l'alias "+ alias + '\n'
append_to_log(log, UTILISATEUR)
flash(u'Votre alias a été supprimé', 'succes')
else:
flash(u'Il y a eu une erreur', 'error')
return redirect(url_for('profil.myalias', _external=True))
else:
return redirect(url_for('loginlogout.login', _external=True), code=401)
@profil.route('/invitation/', methods=['GET'])
def invitation():
if 'username' in session:
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT Token, invitations FROM users WHERE name=?""", (UTILISATEUR,))
tmp = cursor.fetchone()
print (tmp)
token = tmp[0]
invitations_count = tmp[1]
conn.close()
base_url = request.base_url
base_url = base_url.replace("/invitation/", "inscription")
return render_template('invitation.html',
section='Profil',
token=token,
nb_invitation=invitations_count,
base_url=base_url)
else:
return redirect(url_for('loginlogout.login', _external=True), code=401)
@profil.route('/gen_token/', methods=['GET'])
def generate_token():
if 'username' in session:
UTILISATEUR='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
token = gen_token()
cursor.execute("UPDATE users SET Token=? WHERE name=?",
(token, UTILISATEUR))
conn.commit()
conn.close()
return redirect(url_for('profil.invitation', _external=True))
else:
return redirect(url_for('loginlogout.login', _external=True), code=401)

7
wsgi.py Normal file
View File

@ -0,0 +1,7 @@
from gevent.pywsgi import WSGIServer
from pywallter import create_app
app = create_app()
http_server = WSGIServer(("127.0.0.1", 8000), app)
http_server.serve_forever()