Commit 565f65c7 authored by Pietro Albini's avatar Pietro Albini

Add creation date for sessions and don't delete them

parent 28ede21f
Pipeline #82 passed with stage
in 0 seconds
......@@ -43,18 +43,19 @@ class Sessions:
id = str(uuid.uuid4())
ip = flask.request.remote_addr
now = int(time.time())
self.db.update(
"INSERT INTO auth_sessions (id, nickname, teams, ip, expires_at) "
"VALUES (?, ?, ?, ?, ?)", id, nickname, ",".join(teams), ip,
int(time.time()) + SESSION_EXPIRES_AFTER,
"INSERT INTO auth_sessions (id, nickname, teams, ip, created_at, "
"expires_at) VALUES (?, ?, ?, ?, ?, ?)", id, nickname,
",".join(teams), ip, now, now + SESSION_EXPIRES_AFTER,
)
return id
def check(self, id):
"""Check if a session is valid and return its data"""
data = self.db.query(
"SELECT nickname, teams, ip, expires_at FROM auth_sessions "
"WHERE id = ?", id,
"SELECT nickname, teams, ip, expires_at, created_at "
"FROM auth_sessions WHERE id = ?", id,
)
if not data:
raise SessionError("La tua sessione è scaduta, accedi di nuovo.")
......@@ -65,7 +66,6 @@ class Sessions:
expires_at = data[0][3]
if expires_at is None or expires_at < time.time():
self.delete(id)
raise SessionError("La tua sessione è scaduta, accedi di nuovo.")
else:
# Bump the session every time a new page is visited
......@@ -82,50 +82,58 @@ class Sessions:
"teams": data[0][1].split(","),
}
def delete(self, id):
"""Delete a session"""
self.db.update("DELETE FROM auth_sessions WHERE id = ?;", id)
def disable(self, id):
"""Disable a session"""
self.db.update(
"UPDATE auth_sessions SET expires_at = ? WHERE id = ?;",
int(time.time()), id,
)
def delete_all(self, except_id):
"""Delete every session except this one"""
self.db.update("DELETE FROM auth_sessions WHERE id != ?;", except_id)
def disable_all(self, except_id):
"""Disable every active session except this one"""
now = int(time.time())
self.db.update(
"UPDATE auth_sessions SET expires_at = ? WHERE id != ? AND "
"expires_at IS NOT NULL AND expires_at >= ?;",
now, id, now,
)
def all(self):
"""Return all the sessions"""
rows = self.db.query("SELECT id, nickname, teams, ip, expires_at FROM auth_sessions;")
now = time.time()
rows = self.db.query(
"SELECT id, nickname, teams, ip, expires_at, created_at "
"FROM auth_sessions WHERE expires_at IS NOT NULL "
"AND expires_at >= ?;", now,
)
result = []
for row in rows:
# Delete expired sessions
if row[0] is None or row[4] < now:
self.delete(row[0])
continue
result.append({
"id": row[0],
"nickname": row[1],
"teams": row[2].split(","),
"ip": row[3],
"expires_at": row[4],
"created_at": row[5],
})
return result
def get(self, id):
"""Return details about a session"""
row = self.db.query("SELECT nickname, teams, ip, expires_at FROM auth_sessions WHERE id = ?;", id)
row = self.db.query(
"SELECT nickname, teams, ip, expires_at, created_at "
"FROM auth_sessions WHERE id = ?;", id,
)
if row:
# Delete expired sessions
if row[0][3] is None or row[0][3] < time.time():
self.delete(id)
return
return {
"id": id,
"nickname": row[0][0],
"teams": row[0][1].split(","),
"ip": row[0][2],
"expires_at": row[0][3],
"created_at": row[0][4],
"active": row[0][3] >= time.time(),
}
def count(self):
......@@ -258,7 +266,7 @@ def prepare_blueprint(app):
@bp.route("/logout")
@permission("auth.logout")
def logout():
sessions.delete(flask.session["auth"])
sessions.disable(flask.session["auth"])
del flask.session["auth"]
flask.flash("La sessione è stata terminata correttamente.", "success")
......@@ -276,7 +284,7 @@ def prepare_blueprint(app):
@bp.route("/sessions/+all/revoke")
@permission("auth.sessions.manage")
def sessions_revoke_all():
sessions.delete_all(flask.g.auth_id)
sessions.disable_all(flask.g.auth_id)
return flask.redirect(flask.url_for(".sessions_list"))
@bp.route("/sessions/<id>")
......@@ -308,7 +316,7 @@ def prepare_blueprint(app):
"auth.sessions.own": lambda id: flask.g.auth_id == id,
})
def sessions_revoke(id):
sessions.delete(id)
sessions.disable(id)
return flask.redirect(flask.url_for(".sessions_list"))
return bp
......@@ -85,4 +85,8 @@ MIGRATIONS = [
("add_auth_sessions_expires_at_column", """
ALTER TABLE auth_sessions ADD COLUMN expires_at INTEGER;
"""),
("add_auth_sessions_created_at_column", """
ALTER TABLE auth_sessions ADD COLUMN created_at INTEGER;
"""),
]
......@@ -31,12 +31,24 @@
<td>Nome utente</td>
<td><b>{{ session.nickname }}</b></td>
</tr>
<tr>
<td>Stato</td>
<td>{% if session.active -%}
<span class="text-green">Attiva</span>
{%- else -%}
<span class="text-red">Scaduta</span>
{%- endif %}</td>
</tr>
<tr>
<td>Indirizzo IP</td>
<td>{{ session.ip }}</td>
</tr>
<tr>
<td>Scadenza</td>
<td>Inizio</td>
<td>{{ session.created_at|format_timestamp }}</td>
</tr>
<tr>
<td>{% if session.active %}Scadenza{% else %}Fine{% endif %}</td>
<td>{{ session.expires_at|format_timestamp }}</td>
</tr>
<tr>
......@@ -53,7 +65,7 @@
</table>
</div>
{% if g.auth_id != session.id %}
{% if g.auth_id != session.id and session.active %}
<a class="btn" href="{{ url_for(".sessions_revoke", id=session.id) }}">
Disabilita sessione
</a>
......@@ -63,11 +75,16 @@
{% if others %}
<div class="row">
<div class="col">
{% if session.active %}
<h2>Altre sessioni dell'utente</h2>
{% else %}
<h2>Sessioni correnti dell'utente</h2>
{% endif %}
<div class="table">
<table>
<tr>
<th>Indirizzo IP</th>
<th>Inizio</th>
<th>Scadenza</th>
<th></th>
<th></th>
......@@ -75,6 +92,7 @@
{% for session in others %}
<tr>
<td>{{ session.ip }}</td>
<td>{{ session.created_at|format_timestamp }}
<td>{{ session.expires_at|format_timestamp }}
<td>
<a href="{{ url_for(".sessions_show", id=session.id) }}">
......
......@@ -40,6 +40,7 @@
<tr>
<th>Nome utente</th>
<th>Indirizzo IP</th>
<th>Inizio</th>
<th>Scadenza</th>
<th></th>
<th></th>
......@@ -48,6 +49,7 @@
<tr>
<td>{{ session.nickname }}</td>
<td>{{ session.ip }}</td>
<td>{{ session.created_at|format_timestamp }}</td>
<td>{{ session.expires_at|format_timestamp }}</td>
<td>
<a href="{{ url_for(".sessions_show", id=session.id) }}">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment