Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-16 04:12:53 +01:00
Add db schema and models for Duo 2FA state storage
Dieser Commit ist enthalten in:
Ursprung
27e9c330a6
Commit
99dae538d4
11 geänderte Dateien mit 148 neuen und 0 gelöschten Zeilen
1
migrations/mysql/2024-06-05-131359_add_2fa_duo_store/down.sql
Normale Datei
1
migrations/mysql/2024-06-05-131359_add_2fa_duo_store/down.sql
Normale Datei
|
@ -0,0 +1 @@
|
|||
DROP TABLE twofactor_duo_ctx;
|
8
migrations/mysql/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
8
migrations/mysql/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE twofactor_duo_ctx (
|
||||
state VARCHAR(1024) NOT NULL,
|
||||
user_email VARCHAR(255) NOT NULL,
|
||||
nonce VARCHAR(1024) NOT NULL,
|
||||
exp BIGINT NOT NULL,
|
||||
|
||||
PRIMARY KEY (state)
|
||||
);
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE twofactor_duo_ctx;
|
8
migrations/postgresql/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
8
migrations/postgresql/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE twofactor_duo_ctx (
|
||||
state VARCHAR(1024) NOT NULL,
|
||||
user_email VARCHAR(255) NOT NULL,
|
||||
nonce VARCHAR(1024) NOT NULL,
|
||||
exp BIGINT NOT NULL,
|
||||
|
||||
PRIMARY KEY (state)
|
||||
);
|
1
migrations/sqlite/2024-06-05-131359_add_2fa_duo_store/down.sql
Normale Datei
1
migrations/sqlite/2024-06-05-131359_add_2fa_duo_store/down.sql
Normale Datei
|
@ -0,0 +1 @@
|
|||
DROP TABLE twofactor_duo_ctx;
|
8
migrations/sqlite/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
8
migrations/sqlite/2024-06-05-131359_add_2fa_duo_store/up.sql
Normale Datei
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE twofactor_duo_ctx (
|
||||
state TEXT NOT NULL,
|
||||
user_email TEXT NOT NULL,
|
||||
nonce TEXT NOT NULL,
|
||||
exp INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (state)
|
||||
);
|
|
@ -13,6 +13,7 @@ mod organization;
|
|||
mod send;
|
||||
mod two_factor;
|
||||
mod two_factor_incomplete;
|
||||
mod two_factor_duo_context;
|
||||
mod user;
|
||||
|
||||
pub use self::attachment::Attachment;
|
||||
|
@ -29,5 +30,6 @@ pub use self::org_policy::{OrgPolicy, OrgPolicyErr, OrgPolicyType};
|
|||
pub use self::organization::{Organization, OrganizationApiKey, UserOrgStatus, UserOrgType, UserOrganization};
|
||||
pub use self::send::{Send, SendType};
|
||||
pub use self::two_factor::{TwoFactor, TwoFactorType};
|
||||
pub use self::two_factor_duo_context::TwoFactorDuoContext;
|
||||
pub use self::two_factor_incomplete::TwoFactorIncomplete;
|
||||
pub use self::user::{Invitation, User, UserKdfType, UserStampException};
|
||||
|
|
92
src/db/models/two_factor_duo_context.rs
Normale Datei
92
src/db/models/two_factor_duo_context.rs
Normale Datei
|
@ -0,0 +1,92 @@
|
|||
use chrono::Utc;
|
||||
|
||||
use crate::{api::EmptyResult, db::DbConn, error::MapResult};
|
||||
|
||||
db_object! {
|
||||
#[derive(Identifiable, Queryable, Insertable, AsChangeset)]
|
||||
#[diesel(table_name = twofactor_duo_ctx)]
|
||||
#[diesel(primary_key(state))]
|
||||
pub struct TwoFactorDuoContext {
|
||||
pub state: String,
|
||||
pub user_email: String,
|
||||
pub nonce: String,
|
||||
pub exp: i64,
|
||||
}
|
||||
}
|
||||
|
||||
impl TwoFactorDuoContext {
|
||||
pub async fn find_by_state(state: &str, conn: &mut DbConn) -> Option<Self> {
|
||||
db_run! {
|
||||
conn: {
|
||||
twofactor_duo_ctx::table
|
||||
.filter(twofactor_duo_ctx::state.eq(state))
|
||||
.first::<TwoFactorDuoContextDb>(conn)
|
||||
.ok()
|
||||
.from_db()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save(
|
||||
state: &str,
|
||||
user_email: &str,
|
||||
nonce: &str,
|
||||
ttl: i64,
|
||||
conn: &mut DbConn,
|
||||
) -> EmptyResult {
|
||||
// A saved context should never be changed, only created or deleted.
|
||||
let exists = Self::find_by_state(state, conn).await;
|
||||
if exists.is_some() {
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
let exp = Utc::now().timestamp() + ttl;
|
||||
|
||||
db_run! {
|
||||
conn: {
|
||||
diesel::insert_into(twofactor_duo_ctx::table)
|
||||
.values((
|
||||
twofactor_duo_ctx::state.eq(state),
|
||||
twofactor_duo_ctx::user_email.eq(user_email),
|
||||
twofactor_duo_ctx::nonce.eq(nonce),
|
||||
twofactor_duo_ctx::exp.eq(exp)
|
||||
))
|
||||
.execute(conn)
|
||||
.map_res("Error saving context to twofactor_duo_ctx")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn find_expired(conn: &mut DbConn) -> Vec<Self> {
|
||||
let now = Utc::now().timestamp();
|
||||
db_run! {
|
||||
conn: {
|
||||
twofactor_duo_ctx::table
|
||||
.filter(twofactor_duo_ctx::exp.lt(now))
|
||||
.load::<TwoFactorDuoContextDb>(conn)
|
||||
.expect("Error finding expired contexts in twofactor_duo_ctx")
|
||||
.from_db()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete(&self, conn: &mut DbConn) -> EmptyResult {
|
||||
db_run! {
|
||||
conn: {
|
||||
diesel::delete(
|
||||
twofactor_duo_ctx::table
|
||||
.filter(twofactor_duo_ctx::state.eq(&self.state)))
|
||||
.execute(conn)
|
||||
.map_res("Error deleting from twofactor_duo_ctx")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn purge_expired_duo_contexts(conn: &mut DbConn) {
|
||||
for context in Self::find_expired(conn).await {
|
||||
if context.exp < Utc::now().timestamp() {
|
||||
context.delete(conn).await.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -174,6 +174,15 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
twofactor_duo_ctx (state) {
|
||||
state -> Text,
|
||||
user_email -> Text,
|
||||
nonce -> Text,
|
||||
exp -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
users (uuid) {
|
||||
uuid -> Text,
|
||||
|
|
|
@ -174,6 +174,15 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
twofactor_duo_ctx (state) {
|
||||
state -> Text,
|
||||
user_email -> Text,
|
||||
nonce -> Text,
|
||||
exp -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
users (uuid) {
|
||||
uuid -> Text,
|
||||
|
|
|
@ -174,6 +174,15 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
twofactor_duo_ctx (state) {
|
||||
state -> Text,
|
||||
user_email -> Text,
|
||||
nonce -> Text,
|
||||
exp -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
users (uuid) {
|
||||
uuid -> Text,
|
||||
|
|
Laden …
In neuem Issue referenzieren