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