mirror of https://github.com/LemmyNet/lemmy.git
use lazy_static
parent
3516939fd5
commit
48918f362d
|
@ -1629,6 +1629,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"diesel",
|
||||
"jsonwebtoken",
|
||||
"lazy_static",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
|
|
|
@ -207,7 +207,7 @@ mod tests {
|
|||
#[actix_rt::test]
|
||||
async fn test_should_not_validate_user_token_after_password_change() {
|
||||
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()
|
||||
.build(ConnectionManager::<PgConnection>::new(&db_url))
|
||||
.unwrap();
|
||||
|
|
|
@ -25,3 +25,4 @@ chrono = { version = "0.4.19", features = ["serde"] }
|
|||
serde_json = { version = "1.0.66", features = ["preserve_order"] }
|
||||
url = "2.2.2"
|
||||
jsonwebtoken = "7.2.0"
|
||||
lazy_static = "1.4.0"
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use crate::blocking;
|
||||
use chrono::Utc;
|
||||
use diesel::PgConnection;
|
||||
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_schema::source::secrets::Secrets;
|
||||
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{ops::Deref, sync::RwLock};
|
||||
|
||||
type Jwt = String;
|
||||
|
||||
|
@ -23,7 +26,7 @@ impl Claims {
|
|||
validate_exp: false,
|
||||
..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());
|
||||
Ok(decode::<Claims>(jwt, &key, &v)?)
|
||||
}
|
||||
|
@ -34,15 +37,27 @@ impl Claims {
|
|||
iss: Settings::get().hostname,
|
||||
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)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: would be good if we could store the jwt secret in memory, so we dont have to run db
|
||||
/// queries all the time (which probably affects performance). but its tricky, we cant use a
|
||||
/// 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??;
|
||||
Ok(jwt_secret)
|
||||
lazy_static! {
|
||||
static ref JWT_SECRET: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
fn get_jwt_secret(conn: &PgConnection) -> Result<String, LemmyError> {
|
||||
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