yo es un dumbass
This commit is contained in:
parent
eb60011ebd
commit
f7bd45dff3
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="trifidapi@localhost" uuid="39c81b89-3fc4-493f-b203-7a00527cffe6">
|
<data-source source="LOCAL" name="trifid@localhost" uuid="39c81b89-3fc4-493f-b203-7a00527cffe6">
|
||||||
<driver-ref>postgresql</driver-ref>
|
<driver-ref>postgresql</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
<jdbc-url>jdbc:postgresql://localhost:5432/trifidapi</jdbc-url>
|
<jdbc-url>jdbc:postgresql://localhost:5432/trifid</jdbc-url>
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
</data-source>
|
</data-source>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/trifid-api/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/trifid-api/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/trifid-pki/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/trifid-pki/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/dnapi-rs/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/dnapi-rs/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/trifid-api/trifid_api_entities/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/trifid-api/trifid_api_migration/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
|
@ -206,6 +206,16 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aead"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -669,6 +679,30 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cipher",
|
||||||
|
"cpufeatures",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20poly1305"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
||||||
|
dependencies = [
|
||||||
|
"aead",
|
||||||
|
"chacha20",
|
||||||
|
"cipher",
|
||||||
|
"poly1305",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.24"
|
version = "0.4.24"
|
||||||
|
@ -685,6 +719,17 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cipher"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.2.23"
|
version = "3.2.23"
|
||||||
|
@ -877,6 +922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
|
"rand_core 0.6.4",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1069,7 +1115,7 @@ dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"trifid-pki",
|
"trifid-pki 0.1.9",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1602,6 +1648,15 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -1920,6 +1975,12 @@ version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.45"
|
version = "0.10.45"
|
||||||
|
@ -2139,6 +2200,17 @@ dependencies = [
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "poly1305"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
|
||||||
|
dependencies = [
|
||||||
|
"cpufeatures",
|
||||||
|
"opaque-debug",
|
||||||
|
"universal-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -3128,7 +3200,7 @@ dependencies = [
|
||||||
"tar",
|
"tar",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"toml 0.7.3",
|
"toml 0.7.3",
|
||||||
"trifid-pki",
|
"trifid-pki 0.1.9",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3401,6 +3473,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-request-identifier",
|
"actix-request-identifier",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
"chacha20poly1305",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -3410,6 +3483,7 @@ dependencies = [
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
"toml 0.7.3",
|
"toml 0.7.3",
|
||||||
"totp-rs",
|
"totp-rs",
|
||||||
|
"trifid-pki 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"trifid_api_entities",
|
"trifid_api_entities",
|
||||||
"trifid_api_migration",
|
"trifid_api_migration",
|
||||||
]
|
]
|
||||||
|
@ -3430,6 +3504,23 @@ dependencies = [
|
||||||
"x25519-dalek",
|
"x25519-dalek",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trifid-pki"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20f0b2d11a5219f67b42a0af7f07b10f1c6c1ea57f8cb9f1115d394176b64c6b"
|
||||||
|
dependencies = [
|
||||||
|
"ed25519-dalek",
|
||||||
|
"hex",
|
||||||
|
"ipnet",
|
||||||
|
"pem",
|
||||||
|
"quick-protobuf",
|
||||||
|
"rand",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"sha2",
|
||||||
|
"x25519-dalek",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trifid_api_entities"
|
name = "trifid_api_entities"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3503,6 +3594,16 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "universal-hash"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unsafe-libyaml"
|
name = "unsafe-libyaml"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
|
|
@ -24,3 +24,6 @@ trifid_api_entities = { version = "0.1.0", path = "trifid_api_entities" }
|
||||||
rand = "0.8" # Misc.
|
rand = "0.8" # Misc.
|
||||||
hex = "0.4" # Misc.
|
hex = "0.4" # Misc.
|
||||||
totp-rs = { version = "5.0.1", features = ["gen_secret", "otpauth"] } # Misc.
|
totp-rs = { version = "5.0.1", features = ["gen_secret", "otpauth"] } # Misc.
|
||||||
|
|
||||||
|
trifid-pki = { version = "0.1.9" } # Cryptography
|
||||||
|
chacha20poly1305 = "0.10.1" # Cryptography
|
|
@ -67,6 +67,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
.service(routes::v1::auth::verify_magic_link::verify_magic_link_request)
|
.service(routes::v1::auth::verify_magic_link::verify_magic_link_request)
|
||||||
.service(routes::v1::totp_authenticators::totp_authenticators_request)
|
.service(routes::v1::totp_authenticators::totp_authenticators_request)
|
||||||
.service(routes::v1::verify_totp_authenticators::verify_totp_authenticators_request)
|
.service(routes::v1::verify_totp_authenticators::verify_totp_authenticators_request)
|
||||||
|
.service(routes::v1::auth::totp::totp_request)
|
||||||
}).bind(CONFIG.server.bind)?.run().await?;
|
}).bind(CONFIG.server.bind)?.run().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod magic_link;
|
pub mod magic_link;
|
||||||
pub mod verify_magic_link;
|
pub mod verify_magic_link;
|
||||||
|
pub mod totp;
|
|
@ -0,0 +1,169 @@
|
||||||
|
use actix_web::{HttpRequest, HttpResponse, post};
|
||||||
|
use actix_web::web::{Data, Json};
|
||||||
|
use log::{debug, error};
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use trifid_api_entities::entity::totp_authenticator;
|
||||||
|
use crate::AppState;
|
||||||
|
use crate::auth_tokens::{enforce_session, TokenInfo};
|
||||||
|
use crate::error::{APIError, APIErrorsResponse};
|
||||||
|
use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, IntoActiveModel, ActiveModelTrait};
|
||||||
|
use sea_orm::ActiveValue::Set;
|
||||||
|
use totp_rs::{Algorithm, Secret, TOTP};
|
||||||
|
use trifid_api_entities::entity::auth_token;
|
||||||
|
use crate::config::CONFIG;
|
||||||
|
use crate::timers::expires_in_seconds;
|
||||||
|
use crate::tokens::random_token;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct TotpRequest {
|
||||||
|
pub code: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct TotpResponse {
|
||||||
|
pub data: TotpResponseData,
|
||||||
|
pub metadata: TotpResponseMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct TotpResponseData {
|
||||||
|
#[serde(rename = "authToken")]
|
||||||
|
pub auth_token: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct TotpResponseMetadata {}
|
||||||
|
|
||||||
|
#[post("/v1/auth/totp")]
|
||||||
|
pub async fn totp_request(req: Json<TotpRequest>, req_data: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
||||||
|
// require a user session
|
||||||
|
let session_token = match enforce_session(&req_data, &db.conn).await {
|
||||||
|
Ok(r) => {
|
||||||
|
match r {
|
||||||
|
TokenInfo::SessionToken(i) => i,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("error enforcing session: {}", e);
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_UNAUTHORIZED".to_string(),
|
||||||
|
message: "Unauthorized".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// determine if the user has a totp authenticator
|
||||||
|
let auther = match totp_authenticator::Entity::find().filter(totp_authenticator::Column::User.eq(&session_token.user.id)).one(&db.conn).await {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
error!("database error: {}", e);
|
||||||
|
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_DB_ERROR".to_string(),
|
||||||
|
message: "There was an error with the database request, please try again later.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let auther = match auther {
|
||||||
|
Some(a) => {
|
||||||
|
a
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_USER_NO_TOTP".to_string(),
|
||||||
|
message: "This user does not have a totp authenticator".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let secret = Secret::Encoded(auther.secret.clone());
|
||||||
|
let totpmachine = match TOTP::from_url(auther.url.clone()) {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(e) => {
|
||||||
|
error!("totp url error: {}", e);
|
||||||
|
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_SECRET_ERROR".to_string(),
|
||||||
|
message: "There was an error parsing the totpmachine. Please try again later.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let valid = match totpmachine.check_current(&req.code) {
|
||||||
|
Ok(valid) => valid,
|
||||||
|
Err(e) => {
|
||||||
|
error!("system time error: {}", e);
|
||||||
|
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_TIME_ERROR".to_string(),
|
||||||
|
message: "There was an with the server-side time clock.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
debug!("current: {}", totpmachine.generate_current().unwrap());
|
||||||
|
error!("user send invalid totp code");
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_UNAUTHORIZED".to_string(),
|
||||||
|
message: "Unauthorized".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let model: auth_token::Model = auth_token::Model {
|
||||||
|
id: random_token("auth"),
|
||||||
|
user: session_token.user.id,
|
||||||
|
expires_on: expires_in_seconds(CONFIG.tokens.mfa_tokens_expiry_time_seconds) as i64,
|
||||||
|
};
|
||||||
|
let token = model.id.clone();
|
||||||
|
let active_model = model.into_active_model();
|
||||||
|
match active_model.insert(&db.conn).await {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("database error: {}", e);
|
||||||
|
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_DB_ERROR".to_string(),
|
||||||
|
message: "There was an error issuing the authentication token.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse::Ok().json(TotpResponse {
|
||||||
|
data: TotpResponseData { auth_token: token },
|
||||||
|
metadata: TotpResponseMetadata {},
|
||||||
|
})
|
||||||
|
}
|
|
@ -66,7 +66,7 @@ pub async fn verify_magic_link_request(db: Data<AppState>, req: Json<VerifyMagic
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !expired(link.expires_on as u64) {
|
if expired(link.expires_on as u64) {
|
||||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
errors: vec![
|
errors: vec![
|
||||||
APIError {
|
APIError {
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub async fn verify_totp_authenticators_request(req: Json<VerifyTotpAuthenticato
|
||||||
};
|
};
|
||||||
|
|
||||||
// determine if the user has a totp authenticator
|
// determine if the user has a totp authenticator
|
||||||
let auther = match totp_authenticator::Entity::find().filter(totp_authenticator::Column::User.eq(&session_token.user.id)).one(&db.conn).await {
|
let auther = match totp_authenticator::Entity::find().filter(totp_authenticator::Column::Id.eq(&req.totp_token)).one(&db.conn).await {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("database error: {}", e);
|
error!("database error: {}", e);
|
||||||
|
|
|
@ -9,5 +9,6 @@ pub mod magic_link;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod organization;
|
pub mod organization;
|
||||||
pub mod session_token;
|
pub mod session_token;
|
||||||
|
pub mod signing_ca;
|
||||||
pub mod totp_authenticator;
|
pub mod totp_authenticator;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
|
@ -7,5 +7,6 @@ pub use super::magic_link::Entity as MagicLink;
|
||||||
pub use super::network::Entity as Network;
|
pub use super::network::Entity as Network;
|
||||||
pub use super::organization::Entity as Organization;
|
pub use super::organization::Entity as Organization;
|
||||||
pub use super::session_token::Entity as SessionToken;
|
pub use super::session_token::Entity as SessionToken;
|
||||||
|
pub use super::signing_ca::Entity as SigningCa;
|
||||||
pub use super::totp_authenticator::Entity as TotpAuthenticator;
|
pub use super::totp_authenticator::Entity as TotpAuthenticator;
|
||||||
pub use super::user::Entity as User;
|
pub use super::user::Entity as User;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||||
|
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
|
#[sea_orm(table_name = "signing_ca")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
pub organization: String,
|
||||||
|
pub cert: String,
|
||||||
|
#[sea_orm(unique)]
|
||||||
|
pub key: String,
|
||||||
|
pub expires: i64,
|
||||||
|
#[sea_orm(unique)]
|
||||||
|
pub nonce: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -11,6 +11,7 @@ pub mod m20230402_233043_create_table_api_keys;
|
||||||
pub mod m20230402_233047_create_table_api_keys_scopes;
|
pub mod m20230402_233047_create_table_api_keys_scopes;
|
||||||
mod m20230402_234025_create_table_totp_authenticators;
|
mod m20230402_234025_create_table_totp_authenticators;
|
||||||
mod m20230403_002256_create_table_auth_tokens;
|
mod m20230403_002256_create_table_auth_tokens;
|
||||||
|
mod m20230403_142517_create_table_signing_cas;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl MigratorTrait for Migrator {
|
impl MigratorTrait for Migrator {
|
||||||
|
@ -25,6 +26,7 @@ impl MigratorTrait for Migrator {
|
||||||
Box::new(m20230402_233047_create_table_api_keys_scopes::Migration),
|
Box::new(m20230402_233047_create_table_api_keys_scopes::Migration),
|
||||||
Box::new(m20230402_234025_create_table_totp_authenticators::Migration),
|
Box::new(m20230402_234025_create_table_totp_authenticators::Migration),
|
||||||
Box::new(m20230403_002256_create_table_auth_tokens::Migration),
|
Box::new(m20230403_002256_create_table_auth_tokens::Migration),
|
||||||
|
Box::new(m20230403_142517_create_table_signing_cas::Migration),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
|
#[derive(DeriveMigrationName)]
|
||||||
|
pub struct Migration;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl MigrationTrait for Migration {
|
||||||
|
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
manager.create_table(
|
||||||
|
Table::create()
|
||||||
|
.table(SigningCA::Table)
|
||||||
|
.col(ColumnDef::new(SigningCA::Id).string().not_null().primary_key())
|
||||||
|
.col(ColumnDef::new(SigningCA::Organization).string().not_null())
|
||||||
|
.col(ColumnDef::new(SigningCA::Cert).string().not_null())
|
||||||
|
.col(ColumnDef::new(SigningCA::Key).string().not_null().unique_key())
|
||||||
|
.col(ColumnDef::new(SigningCA::Expires).big_integer().not_null())
|
||||||
|
.col(ColumnDef::new(SigningCA::Nonce).string().not_null().unique_key())
|
||||||
|
.to_owned()
|
||||||
|
).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
manager.drop_table(Table::drop().table(SigningCA::Table).to_owned()).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Learn more at https://docs.rs/sea-query#iden
|
||||||
|
#[derive(Iden)]
|
||||||
|
pub enum SigningCA {
|
||||||
|
Table,
|
||||||
|
Id,
|
||||||
|
Organization,
|
||||||
|
Cert,
|
||||||
|
Key,
|
||||||
|
Expires,
|
||||||
|
Nonce
|
||||||
|
}
|
Loading…
Reference in New Issue