work
This commit is contained in:
parent
2045d7b636
commit
d44a6c1166
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<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>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/trifid-api-old/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/trifid-api-old/trifid_api_entities/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/trifid-api-old/trifid_api_migration/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/trifid-api-derive/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
|
|
@ -211,6 +211,16 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "aes"
|
||||
version = "0.8.3"
|
||||
|
@ -545,6 +555,30 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "checked_int_cast"
|
||||
version = "1.0.0"
|
||||
|
@ -574,6 +608,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
|||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -779,6 +814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
|
@ -1867,6 +1903,12 @@ version = "1.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
|
@ -1998,6 +2040,17 @@ version = "3.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8"
|
||||
|
||||
[[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]]
|
||||
name = "postgres-protocol"
|
||||
version = "0.6.6"
|
||||
|
@ -2721,7 +2774,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tfcli"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"comfy-table",
|
||||
|
@ -3027,17 +3080,29 @@ dependencies = [
|
|||
"actix-cors",
|
||||
"actix-web",
|
||||
"bb8",
|
||||
"chacha20poly1305",
|
||||
"diesel",
|
||||
"diesel-async",
|
||||
"diesel_migrations",
|
||||
"env_logger",
|
||||
"hex",
|
||||
"log",
|
||||
"mail-send",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"toml 0.8.5",
|
||||
"totp-rs",
|
||||
"trifid-pki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trifid-api-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3095,6 +3160,16 @@ version = "0.1.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.9"
|
||||
|
|
|
@ -5,6 +5,9 @@ members = [
|
|||
"dnapi-rs",
|
||||
"tfcli",
|
||||
"nebula-ffi",
|
||||
"trifid-api"
|
||||
|
||||
"trifid-api",
|
||||
"trifid-api-derive"
|
||||
]
|
||||
|
||||
resolver = "2"
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "trifid-api-derive"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "2", features = ["full", "fold"] }
|
||||
quote = "1"
|
|
@ -25,4 +25,8 @@ diesel_migrations = "2"
|
|||
bb8 = "0.8"
|
||||
rand = "0.8"
|
||||
mail-send = "0.4"
|
||||
totp-rs = { version = "5.4", features = ["gen_secret", "otpauth"] }
|
||||
totp-rs = { version = "5.4", features = ["gen_secret", "otpauth"] }
|
||||
trifid-pki = { version = "0.1", path = "../trifid-pki", features = ["serde_derive"] }
|
||||
chacha20poly1305 = "0.10"
|
||||
hex = "0.4"
|
||||
thiserror = "1"
|
|
@ -25,7 +25,7 @@ server = "mail.e3t.cc"
|
|||
port = 465
|
||||
# (Required) The username to authenticate with.
|
||||
username = "core"
|
||||
# (Required) The password to authenticate with. If set to %PASSWORD%, will be filled from the environment variable TRIFID_EMAIL_PASSWORD.
|
||||
# (Required) The password to authenticate with. If set to $PASSWORD$, will be filled from the environment variable TRIFID_EMAIL_PASSWORD.
|
||||
password = "$PASSWORD$"
|
||||
# (Required) The "From Name" to send the email from
|
||||
from_name = "Trifid"
|
||||
|
@ -45,4 +45,8 @@ magic_link_expiry_seconds = 3600 # 1 hour
|
|||
session_token_expiry_seconds = 31536000 # ~1 year
|
||||
# (Required) How long should auth tokens be valid for, in seconds? This controls how long users can remain logged in
|
||||
# before they must re-authenticate via 2FA.
|
||||
auth_token_expiry_seconds = 86400 # 24 hours
|
||||
auth_token_expiry_seconds = 86400 # 24 hours
|
||||
# (Required) (VERY IMPORTANT!) The per-instance encryption key used to encrypt sensitive data in the database.
|
||||
# It is INCREDIBLY IMPORTANT that you change this value! It should be a 32-byte/256-bit hex-encoded randomly generated
|
||||
# key.
|
||||
data_encryption_key = "dd5aa62f0fd9b7fb4ff65567493f889557212f3a8e9587a79268161f9ae070a6"
|
|
@ -0,0 +1,100 @@
|
|||
use std::error::Error;
|
||||
use std::time::SystemTime;
|
||||
use actix_web::cookie::time::Duration;
|
||||
use chacha20poly1305::{AeadCore, KeyInit, Nonce, XChaCha20Poly1305, XNonce};
|
||||
use chacha20poly1305::aead::{Aead, Payload};
|
||||
use log::error;
|
||||
use rand::Rng;
|
||||
use rand::rngs::OsRng;
|
||||
use thiserror::Error;
|
||||
use crate::models::SigningCA;
|
||||
use trifid_pki::cert::{NebulaCertificate, NebulaCertificateDetails};
|
||||
use trifid_pki::ed25519_dalek::{SignatureError, SigningKey};
|
||||
use crate::config::Config;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum CryptographyError {
|
||||
#[error("certificate signing error: {0}")]
|
||||
CertificateSigningError(Box<dyn Error>),
|
||||
#[error("PEM serialization error: {0}")]
|
||||
PemSerializeError(Box<dyn Error>),
|
||||
#[error("JSON serialization error: {0}")]
|
||||
JsonSerializeError(serde_json::Error),
|
||||
#[error("Invalid data_encryption_key content: {0}")]
|
||||
InvalidKey(hex::FromHexError),
|
||||
#[error("Invalid data_encryption_key length (must be 32 bytes)")]
|
||||
InvalidKeyLength,
|
||||
#[error("Error locking lockbox")]
|
||||
LockingError,
|
||||
#[error("Invalid salt length")]
|
||||
InvalidSaltLength,
|
||||
#[error("Key material decryption failed")]
|
||||
DecryptFailed,
|
||||
#[error("Invalid signing key length after lockbox unlock")]
|
||||
InvalidSigningKeyLength,
|
||||
#[error("Signature error {0}")]
|
||||
SignatureError(SignatureError)
|
||||
}
|
||||
|
||||
pub fn create_signing_ca(expires: SystemTime, org_id: String, user_email: String, config: &Config) -> Result<SigningCA, CryptographyError> {
|
||||
let key = SigningKey::generate(&mut OsRng);
|
||||
|
||||
let mut cert = NebulaCertificate {
|
||||
details: NebulaCertificateDetails {
|
||||
name: format!("Certificate Authority for {user_email}'s Organization"),
|
||||
ips: vec![],
|
||||
subnets: vec![],
|
||||
groups: vec![],
|
||||
not_before: SystemTime::now() - Duration::hours(24),
|
||||
not_after: expires,
|
||||
public_key: key.verifying_key().as_bytes().clone(),
|
||||
is_ca: true,
|
||||
issuer: "".to_string(),
|
||||
},
|
||||
signature: vec![],
|
||||
};
|
||||
cert.sign(&key).map_err(|e| CryptographyError::CertificateSigningError(e))?;
|
||||
|
||||
let pem = cert.serialize_to_pem().map_err(|e| CryptographyError::PemSerializeError(e))?;
|
||||
|
||||
let cert_value = serde_json::to_value(cert).map_err(|e| CryptographyError::JsonSerializeError(e))?;
|
||||
|
||||
let lockbox_key = XChaCha20Poly1305::new_from_slice(&hex::decode(&config.tokens.data_encryption_key).map_err(|e| CryptographyError::InvalidKey(e))?).map_err(|_| CryptographyError::InvalidKeyLength)?;
|
||||
|
||||
let salt = XChaCha20Poly1305::generate_nonce(&mut OsRng);
|
||||
|
||||
let aad: [u8; 16] = OsRng.gen();
|
||||
|
||||
let lockbox = lockbox_key.encrypt(&salt, Payload {
|
||||
msg: &key.to_keypair_bytes(),
|
||||
aad: &aad,
|
||||
}).map_err(|e| CryptographyError::LockingError)?;
|
||||
|
||||
Ok(SigningCA {
|
||||
id: randid!(id "ca"),
|
||||
pem: String::from_utf8(pem).unwrap(),
|
||||
cert: cert_value,
|
||||
expires_at: cert.details.not_after.clone(),
|
||||
organization_id: org_id,
|
||||
salt: salt.as_slice().to_vec(),
|
||||
info: aad.to_vec(),
|
||||
private_key: lockbox,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sign_cert_with_ca(ca: &SigningCA, cert: &mut NebulaCertificate, config: &Config) -> Result<(), CryptographyError> {
|
||||
let lockbox_key = XChaCha20Poly1305::new_from_slice(&hex::decode(&config.tokens.data_encryption_key).map_err(|e| CryptographyError::InvalidKey(e))?).map_err(|_| CryptographyError::InvalidKeyLength)?;
|
||||
|
||||
let salt_u24: [u8; 24] = ca.salt.try_into().map_err(|_| CryptographyError::InvalidSaltLength)?;
|
||||
|
||||
let salt = XNonce::from(salt_u24);
|
||||
|
||||
let plaintext = lockbox_key.decrypt(&salt, Payload {
|
||||
msg: &ca.private_key,
|
||||
aad: &ca.info,
|
||||
}).map_err(|_| CryptographyError::DecryptFailed)?;
|
||||
|
||||
let key = SigningKey::from_keypair_bytes(&plaintext.try_into().map_err(|_| CryptographyError::InvalidSigningKeyLength)?).map_err(|e| CryptographyError::SignatureError(e))?;
|
||||
|
||||
cert.sign(&key).map_err(|e| CryptographyError::CertificateSigningError(e))
|
||||
}
|
|
@ -43,4 +43,5 @@ pub struct ConfigTokens {
|
|||
pub magic_link_expiry_seconds: u64,
|
||||
pub session_token_expiry_seconds: u64,
|
||||
pub auth_token_expiry_seconds: u64,
|
||||
pub data_encryption_key: String
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ pub mod schema;
|
|||
pub mod id;
|
||||
pub mod auth;
|
||||
pub mod email;
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
pub mod ca;
|
||||
pub mod crypt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use diesel::{Associations, Identifiable, Insertable, Queryable, Selectable};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::SystemTime;
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Queryable, Selectable, Insertable, Identifiable, Debug, PartialEq, Clone)]
|
||||
#[derive(Queryable, Selectable, Insertable, Identifiable, Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
#[diesel(table_name = crate::schema::users)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct User {
|
||||
|
@ -11,7 +12,7 @@ pub struct User {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(table_name = crate::schema::magic_links)]
|
||||
|
@ -23,7 +24,7 @@ pub struct MagicLink {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(table_name = crate::schema::session_tokens)]
|
||||
|
@ -35,7 +36,7 @@ pub struct SessionToken {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(table_name = crate::schema::totp_authenticators)]
|
||||
|
@ -51,7 +52,7 @@ pub struct TotpAuthenticator {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(User))]
|
||||
#[diesel(table_name = crate::schema::auth_tokens)]
|
||||
|
@ -63,7 +64,7 @@ pub struct AuthToken {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(User, foreign_key = owner_id))]
|
||||
#[diesel(table_name = crate::schema::organizations)]
|
||||
|
@ -86,7 +87,7 @@ id -> Varchar,
|
|||
*/
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone, Serialize, Deserialize
|
||||
)]
|
||||
#[diesel(belongs_to(Organization))]
|
||||
#[diesel(table_name = crate::schema::signing_cas)]
|
||||
|
@ -101,6 +102,17 @@ pub struct SigningCA {
|
|||
pub info: Vec<u8>,
|
||||
pub private_key: Vec<u8>
|
||||
}
|
||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
||||
pub struct SigningCANormalized {
|
||||
pub id: String,
|
||||
pub pem: String,
|
||||
pub cert: Value,
|
||||
pub expires_at: String,
|
||||
pub organization_id: String,
|
||||
pub salt: Vec<u8>,
|
||||
pub info: Vec<u8>,
|
||||
pub private_key: Vec<u8>
|
||||
}
|
||||
|
||||
/*
|
||||
id VARCHAR NOT NULL PRIMARY KEY,
|
||||
|
@ -113,7 +125,7 @@ id VARCHAR NOT NULL PRIMARY KEY,
|
|||
*/
|
||||
|
||||
#[derive(
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone,
|
||||
Queryable, Selectable, Insertable, Identifiable, Associations, Debug, PartialEq, Clone
|
||||
)]
|
||||
#[diesel(belongs_to(Organization))]
|
||||
#[diesel(belongs_to(SigningCA, foreign_key = signing_ca_id))]
|
||||
|
@ -127,4 +139,14 @@ pub struct Network {
|
|||
pub created_at: SystemTime,
|
||||
pub name: String,
|
||||
pub lighthouses_as_relays: bool
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||
pub struct NetworkNormalized {
|
||||
pub id: String,
|
||||
pub cidr: String,
|
||||
pub organization_id: String,
|
||||
pub signing_ca_id: String,
|
||||
pub created_at: String,
|
||||
pub name: String,
|
||||
pub lighthouses_as_relays: bool
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
use std::time::{Duration, SystemTime};
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::web::Json;
|
||||
use serde::Deserialize;
|
||||
use crate::AppState;
|
||||
use actix_web::web::{Data, Json};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::{AppState, auth, enforce, randid};
|
||||
use crate::models::{Network, NetworkNormalized, Organization, SigningCA, User};
|
||||
use crate::response::JsonAPIResponse;
|
||||
use diesel::{SelectableHelper, ExpressionMethods, QueryDsl};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use crate::ca::create_signing_ca;
|
||||
use crate::schema::users;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct CreateNetworkReq {
|
||||
|
@ -9,8 +16,45 @@ pub struct CreateNetworkReq {
|
|||
pub name: String
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct CreateNetworkResp {
|
||||
|
||||
pub data: NetworkNormalized
|
||||
}
|
||||
|
||||
pub async fn create_network_req(req: Json<CreateNetworkReq>, state: Data<AppState>, req_info: HttpRequest)
|
||||
pub async fn create_network_req(req: Json<CreateNetworkReq>, state: Data<AppState>, req_info: HttpRequest) -> JsonAPIResponse<CreateNetworkResp> {
|
||||
let mut conn = handle_error!(state.pool.get().await);
|
||||
|
||||
let auth_info = auth!(req_info, conn);
|
||||
let (session_token, auth_token) = enforce!(sess auth auth_info);
|
||||
|
||||
let user = handle_error!(
|
||||
users::table
|
||||
.find(&session_token.user_id)
|
||||
.first::<User>(&mut conn)
|
||||
.await
|
||||
);
|
||||
|
||||
let new_org = Organization {
|
||||
id: randid!(id "org"),
|
||||
owner_id: user.id.clone(),
|
||||
name: format!("{}'s Organization", user.email),
|
||||
};
|
||||
|
||||
// create 3 signing CAs, to mimic upstream DN functionality
|
||||
|
||||
let ca_oneyear = handle_error!(create_signing_ca(SystemTime::now() + Duration::from_secs(86400 * 365), new_org.id.clone(), user.email.clone(), &state.config));
|
||||
let ca_twoyears = handle_error!(create_signing_ca(SystemTime::now() + Duration::from_secs(86400 * 365 * 2), new_org.id.clone(), user.email.clone(), &state.config));
|
||||
let ca_threeyears = handle_error!(create_signing_ca(SystemTime::now() + Duration::from_secs(86400 * 365 * 3), new_org.id.clone(), user.email.clone(), &state.config));
|
||||
|
||||
let new_network = Network {
|
||||
id: randid!(id "net"),
|
||||
cidr: req.0.cidr.clone(),
|
||||
organization_id: new_org.id.clone(),
|
||||
signing_ca_id: "".to_string(),
|
||||
created_at: SystemTime::now(),
|
||||
name: "".to_string(),
|
||||
lighthouses_as_relays: false,
|
||||
};
|
||||
|
||||
todo!()
|
||||
}
|
Loading…
Reference in New Issue