Replaced /api/auth response with cookies
This commit is contained in:
parent
360d864148
commit
eca4f68834
5 changed files with 56 additions and 34 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1491,6 +1491,7 @@ dependencies = [
|
||||||
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"simplelog 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -37,6 +37,7 @@ serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
simplelog = "0.7"
|
simplelog = "0.7"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
time = "0.1"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
|
|
||||||
[dependencies.rocket_contrib]
|
[dependencies.rocket_contrib]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"openapi": "3.0.0",
|
"openapi": "3.0.0",
|
||||||
"info": {
|
"info": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "3.0",
|
"version": "4.0",
|
||||||
"title": "Polaris",
|
"title": "Polaris",
|
||||||
"termsOfService": ""
|
"termsOfService": ""
|
||||||
},
|
},
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
"tags": [
|
"tags": [
|
||||||
"Other"
|
"Other"
|
||||||
],
|
],
|
||||||
"summary": "Returns information about user permissions and a session cookie for future authenticated requests.",
|
"summary": "Signs in a user. Response has Set-Cookie headers for the session, username and admin permission of the user.",
|
||||||
"operationId": "postAuth",
|
"operationId": "postAuth",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"required": true,
|
"required": true,
|
||||||
|
@ -196,14 +196,7 @@
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful operation",
|
"description": "Successful operation"
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#components/schemas/AuthOutput"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "Invalid credentials"
|
"description": "Invalid credentials"
|
||||||
|
@ -874,14 +867,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AuthOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"admin": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"CollectionFile": {
|
"CollectionFile": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
|
52
src/api.rs
52
src/api.rs
|
@ -12,6 +12,7 @@ use std::str;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use time::Duration;
|
||||||
|
|
||||||
use crate::config::{self, Config, Preferences};
|
use crate::config::{self, Config, Preferences};
|
||||||
use crate::db::DB;
|
use crate::db::DB;
|
||||||
|
@ -24,9 +25,11 @@ use crate::user;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use crate::vfs::VFSSource;
|
use crate::vfs::VFSSource;
|
||||||
|
|
||||||
const CURRENT_MAJOR_VERSION: i32 = 3;
|
const CURRENT_MAJOR_VERSION: i32 = 4;
|
||||||
const CURRENT_MINOR_VERSION: i32 = 1;
|
const CURRENT_MINOR_VERSION: i32 = 0;
|
||||||
const COOKIE_SESSION: &str = "session";
|
const COOKIE_SESSION: &str = "session";
|
||||||
|
const COOKIE_USERNAME: &str = "username";
|
||||||
|
const COOKIE_ADMIN: &str = "admin";
|
||||||
|
|
||||||
pub fn get_routes() -> Vec<rocket::Route> {
|
pub fn get_routes() -> Vec<rocket::Route> {
|
||||||
routes![
|
routes![
|
||||||
|
@ -86,11 +89,32 @@ struct Auth {
|
||||||
username: String,
|
username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_session_cookie(username: &str) -> Cookie<'static> {
|
fn add_session_cookies(cookies: &mut Cookies, username: &str, is_admin: bool) -> () {
|
||||||
Cookie::build(COOKIE_SESSION, username.to_owned())
|
let duration = Duration::days(1);
|
||||||
|
|
||||||
|
let session_cookie = Cookie::build(COOKIE_SESSION, username.to_owned())
|
||||||
.same_site(rocket::http::SameSite::Lax)
|
.same_site(rocket::http::SameSite::Lax)
|
||||||
.http_only(true)
|
.http_only(true)
|
||||||
.finish()
|
.max_age(duration)
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
let username_cookie = Cookie::build(COOKIE_USERNAME, username.to_owned())
|
||||||
|
.same_site(rocket::http::SameSite::Lax)
|
||||||
|
.http_only(false)
|
||||||
|
.max_age(duration)
|
||||||
|
.path("/")
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
let is_admin_cookie = Cookie::build(COOKIE_ADMIN, format!("{}", is_admin))
|
||||||
|
.same_site(rocket::http::SameSite::Lax)
|
||||||
|
.http_only(false)
|
||||||
|
.max_age(duration)
|
||||||
|
.path("/")
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
cookies.add_private(session_cookie);
|
||||||
|
cookies.add(username_cookie);
|
||||||
|
cookies.add(is_admin_cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for Auth {
|
impl<'a, 'r> FromRequest<'a, 'r> for Auth {
|
||||||
|
@ -116,7 +140,11 @@ impl<'a, 'r> FromRequest<'a, 'r> for Auth {
|
||||||
_ => return Outcome::Failure((Status::InternalServerError, ())),
|
_ => return Outcome::Failure((Status::InternalServerError, ())),
|
||||||
};
|
};
|
||||||
if user::auth(db.deref().deref(), &username, &password).unwrap_or(false) {
|
if user::auth(db.deref().deref(), &username, &password).unwrap_or(false) {
|
||||||
cookies.add_private(get_session_cookie(&username));
|
let is_admin = match user::is_admin(db.deref().deref(), &username) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(_) => return Outcome::Failure((Status::InternalServerError, ())),
|
||||||
|
};
|
||||||
|
add_session_cookies(&mut cookies, &username, is_admin);
|
||||||
return Outcome::Success(Auth {
|
return Outcome::Success(Auth {
|
||||||
username: username.to_string(),
|
username: username.to_string(),
|
||||||
});
|
});
|
||||||
|
@ -256,17 +284,13 @@ fn auth(
|
||||||
db: State<'_, Arc<DB>>,
|
db: State<'_, Arc<DB>>,
|
||||||
credentials: Json<AuthCredentials>,
|
credentials: Json<AuthCredentials>,
|
||||||
mut cookies: Cookies<'_>,
|
mut cookies: Cookies<'_>,
|
||||||
) -> std::result::Result<Json<AuthOutput>, APIError> {
|
) -> std::result::Result<(), APIError> {
|
||||||
if !user::auth::<DB>(&db, &credentials.username, &credentials.password)? {
|
if !user::auth::<DB>(&db, &credentials.username, &credentials.password)? {
|
||||||
return Err(APIError::IncorrectCredentials);
|
return Err(APIError::IncorrectCredentials);
|
||||||
}
|
}
|
||||||
|
let is_admin = user::is_admin::<DB>(&db, &credentials.username)?;
|
||||||
cookies.add_private(get_session_cookie(&credentials.username));
|
add_session_cookies(&mut cookies, &credentials.username, is_admin);
|
||||||
|
Ok(())
|
||||||
let auth_output = AuthOutput {
|
|
||||||
admin: user::is_admin::<DB>(&db, &credentials.username)?,
|
|
||||||
};
|
|
||||||
Ok(Json(auth_output))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/browse")]
|
#[get("/browse")]
|
||||||
|
|
|
@ -58,7 +58,7 @@ fn version() {
|
||||||
|
|
||||||
let response_body = response.body_string().unwrap();
|
let response_body = response.body_string().unwrap();
|
||||||
let response_json: api::Version = serde_json::from_str(&response_body).unwrap();
|
let response_json: api::Version = serde_json::from_str(&response_body).unwrap();
|
||||||
assert_eq!(response_json, api::Version { major: 3, minor: 1 });
|
assert_eq!(response_json, api::Version { major: 4, minor: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -271,7 +271,18 @@ fn auth() {
|
||||||
.body(serde_json::to_string(&credentials).unwrap())
|
.body(serde_json::to_string(&credentials).unwrap())
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.cookies()[0].name(), "session");
|
assert!(response
|
||||||
|
.cookies()
|
||||||
|
.iter()
|
||||||
|
.any(|cookie| cookie.name() == "username"));
|
||||||
|
assert!(response
|
||||||
|
.cookies()
|
||||||
|
.iter()
|
||||||
|
.any(|cookie| cookie.name() == "admin"));
|
||||||
|
assert!(response
|
||||||
|
.cookies()
|
||||||
|
.iter()
|
||||||
|
.any(|cookie| cookie.name() == "session"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue