1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 21:22:40 +00:00

Invalidate sessions on password change; closes #170

This commit is contained in:
J. King 2019-07-25 22:34:58 -04:00
parent be92d2f052
commit 422eaf9605
4 changed files with 26 additions and 5 deletions

View file

@ -5,13 +5,14 @@ New features:
- Support for the Fever protocol (see README.md for details) - Support for the Fever protocol (see README.md for details)
- Command line functionality for clearing a password, disabling the account - Command line functionality for clearing a password, disabling the account
- Command line options for dealing with Fever passwords - Command line options for dealing with Fever passwords
- Command line functionality for exporting subscriptions to OPML - Command line functionality for importing and exporting OPML
- Command line functionality for cron-based feed updating - Command line functionality for cron-based feed updating
- Command line documentation of all commands and options - Command line documentation of all commands and options
Bug fixes: Bug fixes:
- Treat command line option -h the same as --help - Treat command line option -h the same as --help
- Sort Tiny Tiny RSS special feeds according to special ordering - Sort Tiny Tiny RSS special feeds according to special ordering
- Invalidate sessions when passwords are changed
Version 0.7.1 (2019-03-25) Version 0.7.1 (2019-03-25)
========================== ==========================

View file

@ -340,16 +340,22 @@ class Database {
* This function can be used to explicitly invalidate a session after a user logs out * This function can be used to explicitly invalidate a session after a user logs out
* *
* @param string $user The user who owns the session to be destroyed * @param string $user The user who owns the session to be destroyed
* @param string $id The identifier of the session to destroy * @param string|null $id The identifier of the session to destroy
*/ */
public function sessionDestroy(string $user, string $id): bool { public function sessionDestroy(string $user, string $id = null): bool {
// If the user isn't authorized to perform this action then throw an exception. // If the user isn't authorized to perform this action then throw an exception.
if (!Arsse::$user->authorize($user, __FUNCTION__)) { if (!Arsse::$user->authorize($user, __FUNCTION__)) {
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
} }
// delete the session and report success. if (is_null($id)) {
// delete all sessions and report success unconditionally if no identifier was specified
$this->db->prepare("DELETE FROM arsse_sessions where \"user\" = ?", "str")->run($user);
return true;
} else {
// otherwise delete only the specified session and report success.
return (bool) $this->db->prepare("DELETE FROM arsse_sessions where id = ? and \"user\" = ?", "str", "str")->run($id, $user)->changes(); return (bool) $this->db->prepare("DELETE FROM arsse_sessions where id = ? and \"user\" = ?", "str", "str")->run($id, $user)->changes();
} }
}
/** Resumes a session, returning available session data /** Resumes a session, returning available session data
* *

View file

@ -110,6 +110,8 @@ class User {
if (Arsse::$db->userExists($user)) { if (Arsse::$db->userExists($user)) {
// if the password change was successful and the user exists, set the internal password to the same value // if the password change was successful and the user exists, set the internal password to the same value
Arsse::$db->userPasswordSet($user, $out); Arsse::$db->userPasswordSet($user, $out);
// also invalidate any current sessions for the user
Arsse::$db->sessionDestroy($user);
} }
return $out; return $out;
} }
@ -123,6 +125,8 @@ class User {
if (Arsse::$db->userExists($user)) { if (Arsse::$db->userExists($user)) {
// if the password change was successful and the user exists, set the internal password to the same value // if the password change was successful and the user exists, set the internal password to the same value
Arsse::$db->userPasswordSet($user, null); Arsse::$db->userPasswordSet($user, null);
// also invalidate any current sessions for the user
Arsse::$db->sessionDestroy($user);
} }
return $out; return $out;
} }

View file

@ -116,6 +116,16 @@ trait SeriesSession {
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id)); $this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
} }
public function testDestroyAllSessions() {
$user = "jane.doe@example.com";
$this->assertTrue(Arsse::$db->sessionDestroy($user));
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
unset($state['arsse_sessions']['rows'][0]);
unset($state['arsse_sessions']['rows'][1]);
unset($state['arsse_sessions']['rows'][2]);
$this->compareExpectations(static::$drv, $state);
}
public function testDestroyASessionForTheWrongUser() { public function testDestroyASessionForTheWrongUser() {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$id = "80fa94c1a11f11e78667001e673b2560"; $id = "80fa94c1a11f11e78667001e673b2560";