Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bwinf
medal
Commits
b8718f46
Commit
b8718f46
authored
Mar 23, 2021
by
Robert Czechowski
Browse files
Add cleanup function that deletes temporary sessions (session without login credentials)
parent
46f94141
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/core.rs
View file @
b8718f46
...
...
@@ -1587,9 +1587,37 @@ pub fn admin_do_cleanup<T: MedalConnection>(conn: &T, session_token: &str, csrf_
let
result
=
conn
.remove_old_users_and_groups
(
maxstudentage
,
Some
(
maxteacherage
),
Some
(
maxage
));
let
mut
data
=
json_val
::
Map
::
new
();
if
let
Ok
((
n_users
,
n_groups
,
n_teachers
,
n_other
))
=
result
{
let
infodata
=
format!
(
",
\"
n_users
\"
:{},
\"
n_groups
\"
:{},
\"
n_teachers
\"
:{},
\"
n_other
\"
:{}"
,
n_users
,
n_groups
,
n_teachers
,
n_other
);
if
let
Ok
((
n_user
,
n_group
,
n_teacher
,
n_other
))
=
result
{
let
infodata
=
format!
(
",
\"
n_user
\"
:{},
\"
n_group
\"
:{},
\"
n_teacher
\"
:{},
\"
n_other
\"
:{}"
,
n_user
,
n_group
,
n_teacher
,
n_other
);
data
.insert
(
"data"
.to_string
(),
to_json
(
&
infodata
));
Ok
((
"delete_ok"
.to_string
(),
data
))
}
else
{
data
.insert
(
"reason"
.to_string
(),
to_json
(
&
"Fehler."
));
Ok
((
"delete_fail"
.to_string
(),
data
))
}
}
pub
fn
admin_do_session_cleanup
<
T
:
MedalConnection
>
(
conn
:
&
T
,
session_token
:
&
str
,
csrf_token
:
&
str
)
->
MedalValueResult
{
let
session
=
conn
.get_session
(
&
session_token
)
.ensure_logged_in
()
.ok_or
(
MedalError
::
NotLoggedIn
)
?
.ensure_admin
()
.ok_or
(
MedalError
::
AccessDenied
)
?
;
if
session
.csrf_token
!=
csrf_token
{
return
Err
(
MedalError
::
CsrfCheckFailed
);
}
let
now
=
time
::
get_time
();
let
maxage
=
now
-
time
::
Duration
::
days
(
30
);
// Delete all temporary sessions after 30 days
let
result
=
conn
.remove_temporary_sessions
(
maxage
);
let
mut
data
=
json_val
::
Map
::
new
();
if
let
Ok
((
n_session
,))
=
result
{
let
infodata
=
format!
(
",
\"
n_session
\"
:{}"
,
n_session
);
data
.insert
(
"data"
.to_string
(),
to_json
(
&
infodata
));
Ok
((
"delete_ok"
.to_string
(),
data
))
}
else
{
...
...
@@ -1612,7 +1640,10 @@ pub fn admin_do_soft_cleanup<T: MedalConnection>(conn: &T, session_token: &str,
let
result
=
conn
.remove_unreferenced_participation_data
();
let
mut
data
=
json_val
::
Map
::
new
();
if
let
Ok
(())
=
result
{
if
let
Ok
((
n_submission
,
n_grade
,
n_participation
))
=
result
{
let
infodata
=
format!
(
",
\"
n_submission
\"
:{},
\"
n_grade
\"
:{},
\"
n_participation
\"
:{}"
,
n_submission
,
n_grade
,
n_participation
);
data
.insert
(
"data"
.to_string
(),
to_json
(
&
infodata
));
Ok
((
"delete_ok"
.to_string
(),
data
))
}
else
{
data
.insert
(
"reason"
.to_string
(),
to_json
(
&
"Fehler."
));
...
...
src/db_conn.base.rs
View file @
b8718f46
...
...
@@ -1620,7 +1620,31 @@ impl MedalConnection for Connection {
Ok
((
n_users
,
n_groups
,
n_teachers
,
n_other
))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(),
()
>
{
fn
remove_temporary_sessions
(
&
self
,
maxage
:
time
::
Timespec
)
->
Result
<
(
i32
,),
()
>
{
// WARNING: This function could possibly be dangerous if the login possibilities change in a way
// that not every possibility is covered her …
// TODO: How can we make sure, this function is always safe, even in cases of changes elsewhere?
let
query
=
"SELECT count(*)
FROM session
WHERE (last_activity < $1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
let
n_session
=
self
.query_map_one
(
query
,
&
[
&
maxage
],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM session
WHERE (last_activity < $1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
self
.execute
(
query
,
&
[
&
maxage
])
.unwrap
();
Ok
((
n_session
,))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(
i32
,
i32
,
i32
),
()
>
{
// We use
// DELETE FROM submission WHERE session NOT IN (SELECT id FROM session);
// which works on Postgres as well es on Sqlite
...
...
@@ -1628,6 +1652,24 @@ impl MedalConnection for Connection {
// DELETE FROM submission WHERE NOT EXISTS (SELECT FROM session WHERE session.id = submission.session);
// and the latter might be faster on Postgres, so if we ever feel the need to speed up this function,
// it should be split up in database specific code
let
query
=
"SELECT count(*)
FROM submission
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_submission
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM grade
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_grade
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM participation
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_participation
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM submission
...
...
@@ -1636,18 +1678,18 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
participation
FROM
grade
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
grade
FROM
participation
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
Ok
(())
Ok
((
n_submission
,
n_grade
,
n_participation
))
}
fn
get_debug_information
(
&
self
)
->
String
{
...
...
src/db_conn.rs
View file @
b8718f46
...
...
@@ -149,7 +149,8 @@ pub trait MedalConnection {
fn
remove_old_users_and_groups
(
&
self
,
maxstudentage
:
time
::
Timespec
,
maxteacherage
:
Option
<
time
::
Timespec
>
,
maxage
:
Option
<
time
::
Timespec
>
)
->
Result
<
(
i32
,
i32
,
i32
,
i32
),
()
>
;
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(),
()
>
;
fn
remove_temporary_sessions
(
&
self
,
maxage
:
time
::
Timespec
)
->
Result
<
(
i32
,),
()
>
;
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(
i32
,
i32
,
i32
),
()
>
;
fn
get_search_users
(
&
self
,
_
:
(
Option
<
i32
>
,
Option
<
String
>
,
Option
<
String
>
,
Option
<
String
>
,
Option
<
String
>
,
Option
<
String
>
))
...
...
src/db_conn_postgres.rs
View file @
b8718f46
...
...
@@ -1739,7 +1739,31 @@ impl MedalConnection for Connection {
Ok
((
n_users
,
n_groups
,
n_teachers
,
n_other
))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(),
()
>
{
fn
remove_temporary_sessions
(
&
self
,
maxage
:
time
::
Timespec
)
->
Result
<
(
i32
,),
()
>
{
// WARNING: This function could possibly be dangerous if the login possibilities change in a way
// that not every possibility is covered her …
// TODO: How can we make sure, this function is always safe, even in cases of changes elsewhere?
let
query
=
"SELECT count(*)
FROM session
WHERE (last_activity < $1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
let
n_session
=
self
.query_map_one
(
query
,
&
[
&
maxage
],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM session
WHERE (last_activity < $1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
self
.execute
(
query
,
&
[
&
maxage
])
.unwrap
();
Ok
((
n_session
,))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(
i32
,
i32
,
i32
),
()
>
{
// We use
// DELETE FROM submission WHERE session NOT IN (SELECT id FROM session);
// which works on Postgres as well es on Sqlite
...
...
@@ -1748,6 +1772,24 @@ impl MedalConnection for Connection {
// and the latter might be faster on Postgres, so if we ever feel the need to speed up this function,
// it should be split up in database specific code
let
query
=
"SELECT count(*)
FROM submission
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_submission
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM grade
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_grade
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM participation
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_participation
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM submission
WHERE session NOT IN (SELECT id
...
...
@@ -1755,18 +1797,18 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
participation
FROM
grade
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
grade
FROM
participation
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
Ok
(())
Ok
((
n_submission
,
n_grade
,
n_participation
))
}
fn
get_debug_information
(
&
self
)
->
String
{
...
...
src/db_conn_sqlite_new.rs
View file @
b8718f46
...
...
@@ -1739,7 +1739,31 @@ impl MedalConnection for Connection {
Ok
((
n_users
,
n_groups
,
n_teachers
,
n_other
))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(),
()
>
{
fn
remove_temporary_sessions
(
&
self
,
maxage
:
time
::
Timespec
)
->
Result
<
(
i32
,),
()
>
{
// WARNING: This function could possibly be dangerous if the login possibilities change in a way
// that not every possibility is covered her …
// TODO: How can we make sure, this function is always safe, even in cases of changes elsewhere?
let
query
=
"SELECT count(*)
FROM session
WHERE (last_activity < ?1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
let
n_session
=
self
.query_map_one
(
query
,
&
[
&
maxage
],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM session
WHERE (last_activity < ?1 OR last_activity IS NULL)
AND logincode IS NULL
AND password IS NULL
AND oauth_foreign_id IS NULL"
;
self
.execute
(
query
,
&
[
&
maxage
])
.unwrap
();
Ok
((
n_session
,))
}
fn
remove_unreferenced_participation_data
(
&
self
)
->
Result
<
(
i32
,
i32
,
i32
),
()
>
{
// We use
// DELETE FROM submission WHERE session NOT IN (SELECT id FROM session);
// which works on Postgres as well es on Sqlite
...
...
@@ -1748,6 +1772,24 @@ impl MedalConnection for Connection {
// and the latter might be faster on Postgres, so if we ever feel the need to speed up this function,
// it should be split up in database specific code
let
query
=
"SELECT count(*)
FROM submission
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_submission
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM grade
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_grade
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"SELECT count(*)
FROM participation
WHERE session NOT IN (SELECT id
FROM session)"
;
let
n_participation
=
self
.query_map_one
(
query
,
&
[],
|
row
|
row
.get
(
0
))
.unwrap
()
.unwrap
();
let
query
=
"DELETE
FROM submission
WHERE session NOT IN (SELECT id
...
...
@@ -1755,18 +1797,18 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
participation
FROM
grade
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
let
query
=
"DELETE
FROM
grade
FROM
participation
WHERE session NOT IN (SELECT id
FROM session)"
;
self
.execute
(
query
,
&
[])
.unwrap
();
Ok
(())
Ok
((
n_submission
,
n_grade
,
n_participation
))
}
fn
get_debug_information
(
&
self
)
->
String
{
...
...
src/webfw_iron.rs
View file @
b8718f46
...
...
@@ -1129,6 +1129,9 @@ fn admin_cleanup<C>(req: &mut Request) -> IronResult<Response>
match
cleanup_type
.as_deref
()
{
Some
(
"soft"
)
=>
with_conn!
[
core
::
admin_do_soft_cleanup
,
C
,
req
,
&
session_token
,
&
csrf_token
]
.aug
(
req
)
?
,
Some
(
"session"
)
=>
{
with_conn!
[
core
::
admin_do_session_cleanup
,
C
,
req
,
&
session_token
,
&
csrf_token
]
.aug
(
req
)
?
}
_
=>
with_conn!
[
core
::
admin_do_cleanup
,
C
,
req
,
&
session_token
,
&
csrf_token
]
.aug
(
req
)
?
,
}
}
else
{
...
...
templates/default/admin_cleanup.hbs
View file @
b8718f46
...
...
@@ -9,13 +9,22 @@
</form>
</p>
<h2>
Temporäre Sitzungen löschen
</h2>
<p>
Löscht Sitzungen von Benutzern, die sich nicht eingeloggt haben, wenn diese älter als 30 Tage sind.
</p>
<p>
Kann jederzeit gefahrlos ausgeführt werden.
</p>
<p>
<form
action=
"cleanup/session"
method=
"post"
>
<input
type=
"hidden"
name=
"csrf_token"
value=
"
{{
csrf_token
}}
"
>
<input
type=
"submit"
value=
"Temporäre Sitzungen löschen!"
>
</form>
</p>
<h2>
Verwaiste Teilnahmen löschen
</h2>
<p>
Löscht Teilnahmen, deren Accounts gelöscht wurden.
</p>
<p>
Kann jederzeit gefahrlos ausgeführt werden
</p>
<p>
Kann jederzeit gefahrlos ausgeführt werden
.
</p>
<p>
<form
action=
"cleanup/soft"
method=
"post"
>
<input
type=
"hidden"
name=
"csrf_token"
value=
"
{{
csrf_token
}}
"
>
<input
type=
"submit"
value=
"
Alte Dat
en löschen!"
>
<input
type=
"submit"
value=
"
Verwaiste Teilnahm
en löschen!"
>
</form>
</p>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment