store jwt secret in db

This commit is contained in:
Felix Ableitner 2023-12-19 16:15:43 +01:00
parent 5d89591894
commit c42556ed05
5 changed files with 44 additions and 9 deletions

View File

@ -5,3 +5,4 @@ drop table instance_follow;
drop table local_user;
drop table person;
drop table instance;
drop table jwt_secret;

View File

@ -60,3 +60,13 @@ create table conflict (
article_id int REFERENCES article ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
previous_version_id uuid not null
);
-- generate a jwt secret
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE jwt_secret (
id serial PRIMARY KEY,
secret varchar NOT NULL DEFAULT gen_random_uuid ()
);
INSERT INTO jwt_secret DEFAULT VALUES;

View File

@ -1,5 +1,5 @@
use crate::database::user::{DbLocalUser, DbPerson, LocalUserView};
use crate::database::MyDataHandle;
use crate::database::{read_jwt_secret, MyDataHandle};
use crate::error::MyResult;
use activitypub_federation::config::Data;
use anyhow::anyhow;
@ -25,9 +25,6 @@ pub struct Claims {
pub exp: u64,
}
// TODO: move to config
const SECRET: &[u8] = "secret".as_bytes();
pub(in crate::api) fn generate_login_token(
local_user: DbLocalUser,
data: &Data<MyDataHandle>,
@ -40,14 +37,16 @@ pub(in crate::api) fn generate_login_token(
exp: get_current_timestamp(),
};
let key = EncodingKey::from_secret(SECRET);
let secret = read_jwt_secret(data)?;
let key = EncodingKey::from_secret(secret.as_bytes());
let jwt = encode(&Header::default(), &claims, &key)?;
Ok(LoginResponse { jwt })
}
pub async fn validate(jwt: &str, data: &Data<MyDataHandle>) -> MyResult<LocalUserView> {
let validation = Validation::default();
let key = DecodingKey::from_secret(SECRET);
let secret = read_jwt_secret(data)?;
let key = DecodingKey::from_secret(secret.as_bytes());
let claims = decode::<Claims>(jwt, &key, &validation)?;
DbPerson::read_local_from_id(claims.claims.sub.parse()?, data)
}

View File

@ -1,8 +1,12 @@
use crate::database::article::DbArticle;
use diesel::PgConnection;
use std::ops::Deref;
use std::sync::{Arc, Mutex};
pub type MyDataHandle = MyData;
use crate::database::schema::jwt_secret;
use crate::error::MyResult;
use diesel::{QueryDsl, RunQueryDsl};
use std::ops::DerefMut;
pub mod article;
pub mod conflict;
@ -25,4 +29,9 @@ impl Deref for MyData {
}
}
pub type MyDataHandle = MyData;
pub fn read_jwt_secret(conn: &Mutex<PgConnection>) -> MyResult<String> {
let mut conn = conn.lock().unwrap();
Ok(jwt_secret::table
.select(jwt_secret::dsl::secret)
.first(conn.deref_mut())?)
}

View File

@ -59,6 +59,13 @@ diesel::table! {
}
}
diesel::table! {
jwt_secret (id) {
id -> Int4,
secret -> Varchar,
}
}
diesel::table! {
local_user (id) {
id -> Int4,
@ -81,6 +88,13 @@ diesel::table! {
}
}
diesel::table! {
secret (id) {
id -> Int4,
jwt_secret -> Varchar,
}
}
diesel::joinable!(article -> instance (instance_id));
diesel::joinable!(conflict -> article (article_id));
diesel::joinable!(conflict -> local_user (creator_id));
@ -96,6 +110,8 @@ diesel::allow_tables_to_appear_in_same_query!(
edit,
instance,
instance_follow,
jwt_secret,
local_user,
person,
secret,
);