mirror of https://github.com/LemmyNet/lemmy.git
use lazy_static
parent
acdeae4aaa
commit
4f5aaee99f
|
@ -1629,6 +1629,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
|
"lazy_static",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"lemmy_db_views",
|
"lemmy_db_views",
|
||||||
|
|
|
@ -207,7 +207,7 @@ mod tests {
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_should_not_validate_user_token_after_password_change() {
|
async fn test_should_not_validate_user_token_after_password_change() {
|
||||||
let conn = establish_unpooled_connection();
|
let conn = establish_unpooled_connection();
|
||||||
let db_url = get_database_url_from_env().unwrap_or(Settings::get().get_database_url());
|
let db_url = get_database_url_from_env().unwrap_or_else(|_| Settings::get().get_database_url());
|
||||||
let pool = Pool::builder()
|
let pool = Pool::builder()
|
||||||
.build(ConnectionManager::<PgConnection>::new(&db_url))
|
.build(ConnectionManager::<PgConnection>::new(&db_url))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -25,3 +25,4 @@ chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
serde_json = { version = "1.0.66", features = ["preserve_order"] }
|
serde_json = { version = "1.0.66", features = ["preserve_order"] }
|
||||||
url = "2.2.2"
|
url = "2.2.2"
|
||||||
jsonwebtoken = "7.2.0"
|
jsonwebtoken = "7.2.0"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use crate::blocking;
|
use crate::blocking;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use diesel::PgConnection;
|
||||||
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
|
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use lemmy_db_queries::{source::secrets::Secrets_, DbPool};
|
use lemmy_db_queries::{source::secrets::Secrets_, DbPool};
|
||||||
use lemmy_db_schema::source::secrets::Secrets;
|
use lemmy_db_schema::source::secrets::Secrets;
|
||||||
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{ops::Deref, sync::RwLock};
|
||||||
|
|
||||||
type Jwt = String;
|
type Jwt = String;
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ impl Claims {
|
||||||
validate_exp: false,
|
validate_exp: false,
|
||||||
..Validation::default()
|
..Validation::default()
|
||||||
};
|
};
|
||||||
let secret = get_jwt_secret(pool).await?;
|
let secret = blocking(pool, move |conn| get_jwt_secret(conn)).await??;
|
||||||
let key = DecodingKey::from_secret(secret.as_ref());
|
let key = DecodingKey::from_secret(secret.as_ref());
|
||||||
Ok(decode::<Claims>(jwt, &key, &v)?)
|
Ok(decode::<Claims>(jwt, &key, &v)?)
|
||||||
}
|
}
|
||||||
|
@ -34,15 +37,27 @@ impl Claims {
|
||||||
iss: Settings::get().hostname,
|
iss: Settings::get().hostname,
|
||||||
iat: Utc::now().timestamp(),
|
iat: Utc::now().timestamp(),
|
||||||
};
|
};
|
||||||
let key = EncodingKey::from_secret(get_jwt_secret(pool).await?.as_ref());
|
|
||||||
|
let secret = blocking(pool, move |conn| get_jwt_secret(conn)).await??;
|
||||||
|
let key = EncodingKey::from_secret(secret.as_ref());
|
||||||
Ok(encode(&Header::default(), &my_claims, &key)?)
|
Ok(encode(&Header::default(), &my_claims, &key)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: would be good if we could store the jwt secret in memory, so we dont have to run db
|
lazy_static! {
|
||||||
/// queries all the time (which probably affects performance). but its tricky, we cant use a
|
static ref JWT_SECRET: RwLock<Option<String>> = RwLock::new(None);
|
||||||
/// static because it requires a db connection to initialize.
|
}
|
||||||
async fn get_jwt_secret(pool: &DbPool) -> Result<String, LemmyError> {
|
|
||||||
let jwt_secret = blocking(pool, move |conn| Secrets::read(conn)).await??;
|
fn get_jwt_secret(conn: &PgConnection) -> Result<String, LemmyError> {
|
||||||
Ok(jwt_secret)
|
let jwt_option: Option<String> = JWT_SECRET.read().unwrap().deref().clone();
|
||||||
|
match jwt_option {
|
||||||
|
Some(j) => Ok(j),
|
||||||
|
None => {
|
||||||
|
let jwt = Secrets::read(conn)?;
|
||||||
|
let jwt_static = JWT_SECRET.write();
|
||||||
|
let mut jwt_static = jwt_static.unwrap();
|
||||||
|
*jwt_static = Some(jwt.clone());
|
||||||
|
Ok(jwt)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue