DATABASE = '/tmp/cavote.db'
SECRET_KEY = '{J@uRKO,xO-PK7B,jF?>iHbxLasF9s#zjOoy=+:'
DEBUG = True
-USERNAME = 'admin'
-PASSWORD = 'admin'
app = Flask(__name__)
app.config.from_object(__name__)
# Login / Logout
def valid_login(username, password):
- return username == app.config['USERNAME'] and password == app.config['PASSWORD']
+ return query_db('select * from users where email = ? and password = ?', [username, password], one=True)
+
+def connect_user(user):
+ session['userid'] = user['id']
+ session['username'] = user['name']
+ session['email'] = user['email']
+ session['organization'] = user['organization']
+ if user['is_admin'] == 1:
+ session['is_admin'] = True
+
+def disconnect_user():
+ session.pop('username', None)
+ session.pop('is_admin', None)
@app.route('/login', methods=['GET', 'POST'])
def login():
- error = None
if request.method == 'POST':
- if valid_login(request.form['username'], request.form['password']):
- session['username'] = request.form['username']
- if session['username'] == 'admin':
- session['is_admin'] = True
- flash('You were logged in')
- return redirect(url_for('home'))
+ user = valid_login(request.form['username'], request.form['password'])
+ if user is None:
+ flash('Invalid username/password', 'error')
else:
- error = "Invalid username/password"
- return render_template('login.html', error=error)
+ connect_user(user)
+ flash('You were logged in', 'success')
+ return redirect(url_for('home'))
+ return render_template('login.html')
@app.route('/logout')
def logout():
- session.pop('username', None)
- session.pop('is_admin', None)
- flash('You were logged out')
+ disconnect_user()
+ flash('You were logged out', 'info')
return redirect(url_for('home'))
+#-----------------
+# Change password
+
+@app.route('/password/lost', methods=['GET', 'POST'])
+def password_lost():
+ info = None
+ if request.method == 'POST':
+ user = query_db('select * from users where email = ?', [request.form['email']], one=True)
+ if user is None:
+ flash('Cet utilisateur n\'existe pas !', 'error')
+ else:
+ # :TODO:maethor:120528: Générer la clé, la mettre dans la base de données et envoyer le mail
+ flash(u"Un mail a été envoyé à " + user['email'], 'info')
+ return render_template('password_lost.html')
+
+@app.route('/login/<username>/<key>')
+def login_key(username, key):
+ user = query_db('select * from users where email = ? and key = ?', [username, key], one=True)
+ if user is None:
+ abort(404)
+ else:
+ connect_user(user)
+ # :TODO:maethor:120528: Remplacer la clé pour qu'elle ne puisse plus être utilisée
+ return redirect(url_for('home'))
+
#---------------
# User settings
+
@app.route('/user/settings/<username>')
-def show_settings(username):
- if username != session['username']:
+def show_user(username):
+ if username != session.get('username'):
abort(401)
-
+ return render_template('user_settings.html')
#------------
# User admin
g.db.execute('insert into votes (title, description, date_begin, date_end, is_transparent, is_public, is_multiplechoice) values (?, ?, ?, ?, ?, ?, ?)',
[request.form['title'], request.form['description'], date_begin, date_end, transparent, public, multiplechoice])
g.db.commit()
- flash('New entry was successfully posted')
+ flash('New entry was successfully posted', 'info')
return redirect(url_for('home'))
#------
drop table if exists votes;
+drop table if exists users;
+
+create table users (
+ id INTEGER primary key autoincrement,
+ email TEXT unique not null,
+ password TEXT not null,
+ name TEXT,
+ organization TEXT,
+ is_admin INTEGER default 0 not null,
+ key TEXT
+);
+
create table votes (
id INTEGER primary key autoincrement,
title TEXT not null,
is_public INTEGER default 1 not null,
is_multiplechoice INTEGER default 1 not null,
is_weighted INTEGER default 0 not null,
- is_closed INTEGER default 0 not null
- --id_author INTEGER not null,
+ is_closed INTEGER default 0 not null,
+ id_author INTEGER, -- :COMMENT:maethor:120528: not null ?
--id_role INTEGER,
- --FOREIGN KEY(id_author) REFERENCES user(id),
+ FOREIGN KEY(id_author) REFERENCES users(id)
--FOREIGN KEY(id_role) REFERENCES role(id)
);
+-- Test data
+
+insert into users (email, password, name, organization, is_admin, key) values ("admin@admin.fr", "admin", "Toto (admin) Tata", "World corp", 1, "test");
</div>
<div class="btn-group pull-right">
{% if 'username' in session %}
- <a href="#" class="btn"><i class="icon-user"></i> {{ session.username }}</a>
+ <a href="{{ url_for('show_user', username=session.username) }}" class="btn"><i class="icon-user"></i> {{ session.username }}</a>
<a href="#" class="btn dropdown-toggle" data-toggle="dropdown"><b class="caret"></b></a>
<ul class="dropdown-menu pull-right">
<li><a href=""><i class="icon-comment"></i> Votes en attente</a></li>
- <li><a href=""><i class="icon-cog"></i> Paramètres</a></li>
+ <li><a href="{{ url_for('show_user', username=session.username) }}"><i class="icon-cog"></i> Paramètres</a></li>
<li class="divider"></li>
<li><a href="{{ url_for('logout') }}"><i class="icon-off"></i> Déconnexion</a></li>
</ul>
</header>
<h1 class="page-header">Outil de vote du CA FFDN</h1>
-{% with messages = get_flashed_messages() %}
+{% with messages = get_flashed_messages(with_categories="true") %}
{% if messages %}
- {% for message in messages %}
- <div class="alert alert-info fade in">
+ {% for category, message in messages %}
+ <div class="alert alert-{{ category }} fade in">
<button class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
+
{% block body %}{% endblock %}
</div> <!-- container -->