aboutsummaryrefslogtreecommitdiff
path: root/server/src/logic
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/logic')
-rw-r--r--server/src/logic/session.rs94
1 files changed, 1 insertions, 93 deletions
diff --git a/server/src/logic/session.rs b/server/src/logic/session.rs
index 790e070..d77c4fc 100644
--- a/server/src/logic/session.rs
+++ b/server/src/logic/session.rs
@@ -13,6 +13,7 @@ use base64::Engine;
use chrono::{DateTime, Duration, Utc};
use jellybase::{database::Database, SECRETS};
use jellycommon::user::{PermissionSet, User};
+use jellylogic::session::validate;
use log::warn;
use rocket::{
async_trait,
@@ -24,19 +25,6 @@ use rocket::{
use serde::{Deserialize, Serialize};
use std::sync::LazyLock;
-pub struct Session {
- pub user: User,
-}
-
-pub struct AdminSession(pub Session);
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct SessionData {
- username: String,
- expire: DateTime<Utc>,
- permissions: PermissionSet,
-}
-
impl Session {
pub async fn from_request_ut(req: &Request<'_>) -> Result<Self, MyError> {
let username;
@@ -126,83 +114,3 @@ impl<'r> FromRequest<'r> for AdminSession {
}
}
}
-
-static SESSION_KEY: LazyLock<[u8; 32]> = LazyLock::new(|| {
- if let Some(sk) = &SECRETS.session_key {
- let r = base64::engine::general_purpose::STANDARD
- .decode(sk)
- .expect("key invalid; should be valid base64");
- r.try_into()
- .expect("key has the wrong length; should be 32 bytes")
- } else {
- warn!("session_key not configured; generating a random one.");
- [(); 32].map(|_| rand::random())
- }
-});
-
-pub fn create(username: String, permissions: PermissionSet, expire: Duration) -> String {
- let session_data = SessionData {
- expire: Utc::now() + expire,
- username: username.to_owned(),
- permissions,
- };
- let mut plaintext =
- bincode::serde::encode_to_vec(&session_data, bincode::config::standard()).unwrap();
-
- while plaintext.len() % 16 == 0 {
- plaintext.push(0);
- }
-
- let cipher = aes_gcm_siv::Aes256GcmSiv::new_from_slice(&*SESSION_KEY).unwrap();
- let nonce = [(); 12].map(|_| rand::random());
- let mut ciphertext = cipher
- .encrypt(&GenericArray::from(nonce), plaintext.as_slice())
- .unwrap();
- ciphertext.extend(nonce);
-
- base64::engine::general_purpose::URL_SAFE.encode(&ciphertext)
-}
-
-pub fn validate(token: &str) -> anyhow::Result<String> {
- let ciphertext = base64::engine::general_purpose::URL_SAFE.decode(token)?;
- let cipher = aes_gcm_siv::Aes256GcmSiv::new_from_slice(&*SESSION_KEY).unwrap();
- let (ciphertext, nonce) = ciphertext.split_at(ciphertext.len() - 12);
- let plaintext = cipher
- .decrypt(nonce.into(), ciphertext)
- .map_err(|e| anyhow!("decryption failed: {e:?}"))?;
-
- let (session_data, _): (SessionData, _) =
- bincode::serde::decode_from_slice(&plaintext, bincode::config::standard())?;
-
- if session_data.expire < Utc::now() {
- Err(anyhow!("session expired"))?
- }
-
- Ok(session_data.username)
-}
-
-#[test]
-fn test() {
- jellybase::use_test_config();
- let tok = create(
- "blub".to_string(),
- jellycommon::user::PermissionSet::default(),
- Duration::days(1),
- );
- validate(&tok).unwrap();
-}
-
-#[test]
-fn test_crypto() {
- jellybase::use_test_config();
- let nonce = [(); 12].map(|_| rand::random());
- let cipher = aes_gcm_siv::Aes256GcmSiv::new_from_slice(&*SESSION_KEY).unwrap();
- let plaintext = b"testing stuff---";
- let ciphertext = cipher
- .encrypt(&GenericArray::from(nonce), plaintext.as_slice())
- .unwrap();
- let plaintext2 = cipher
- .decrypt((&nonce).into(), ciphertext.as_slice())
- .unwrap();
- assert_eq!(plaintext, plaintext2.as_slice());
-}