POST /v1/hosts
This commit is contained in:
parent
fe67c34fd5
commit
5bb1f8ec71
|
@ -96,6 +96,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
.service(routes::v1::roles::update_role_request)
|
.service(routes::v1::roles::update_role_request)
|
||||||
.service(routes::v1::trifid::trifid_extensions)
|
.service(routes::v1::trifid::trifid_extensions)
|
||||||
.service(routes::v1::hosts::get_hosts)
|
.service(routes::v1::hosts::get_hosts)
|
||||||
|
.service(routes::v1::hosts::create_hosts_request)
|
||||||
}).bind(CONFIG.server.bind)?.run().await?;
|
}).bind(CONFIG.server.bind)?.run().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -18,19 +18,27 @@
|
||||||
// This endpoint has full parity with the original API. It has been recreated from the original API documentation.
|
// This endpoint has full parity with the original API. It has been recreated from the original API documentation.
|
||||||
// This endpoint is considered done. No major features should be added or removed, unless it fixes bugs.
|
// This endpoint is considered done. No major features should be added or removed, unless it fixes bugs.
|
||||||
// This endpoint requires the `definednetworking` extension to be enabled to be used.
|
// This endpoint requires the `definednetworking` extension to be enabled to be used.
|
||||||
|
//
|
||||||
|
//#POST /v1/hosts t+parity:full t+type:documented t+status:done t+feature:definednetworking
|
||||||
|
// This endpoint has full parity with the original API. It has been recreated from the original API documentation.
|
||||||
|
// This endpoint is considered done. No major features should be added or removed, unless it fixes bugs.
|
||||||
|
// This endpoint requires the `definednetworking` extension to be enabled to be used.
|
||||||
|
|
||||||
use std::net::SocketAddrV4;
|
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use actix_web::{HttpRequest, HttpResponse, get};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use actix_web::web::{Data, Query};
|
use actix_web::{HttpRequest, HttpResponse, get, post};
|
||||||
|
use actix_web::web::{Data, Json, Query};
|
||||||
|
use chrono::{TimeZone, Utc};
|
||||||
use log::error;
|
use log::error;
|
||||||
use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, QueryOrder, PaginatorTrait};
|
use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, QueryOrder, PaginatorTrait, IntoActiveModel, ActiveModelTrait};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use trifid_api_entities::entity::{host, host_static_address, network, organization};
|
use trifid_api_entities::entity::{host, host_static_address, network, organization};
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use crate::auth_tokens::{enforce_2fa, enforce_api_token, TokenInfo};
|
use crate::auth_tokens::{enforce_2fa, enforce_api_token, TokenInfo};
|
||||||
use crate::cursor::Cursor;
|
use crate::cursor::Cursor;
|
||||||
use crate::error::{APIError, APIErrorsResponse};
|
use crate::error::{APIError, APIErrorsResponse};
|
||||||
|
use crate::tokens::random_id;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct ListHostsRequestOpts {
|
pub struct ListHostsRequestOpts {
|
||||||
|
@ -112,7 +120,7 @@ fn page_default() -> u64 { 25 }
|
||||||
|
|
||||||
#[get("/v1/hosts")]
|
#[get("/v1/hosts")]
|
||||||
pub async fn get_hosts(opts: Query<ListHostsRequestOpts>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
pub async fn get_hosts(opts: Query<ListHostsRequestOpts>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
||||||
// For this endpoint, you either need to be a fully authenticated user OR a token with roles:list
|
// For this endpoint, you either need to be a fully authenticated user OR a token with hosts:list
|
||||||
let session_info = enforce_2fa(&req_info, &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
let session_info = enforce_2fa(&req_info, &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
||||||
let api_token_info = enforce_api_token(&req_info, &["hosts:list"], &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
let api_token_info = enforce_api_token(&req_info, &["hosts:list"], &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
||||||
|
|
||||||
|
@ -231,7 +239,7 @@ pub async fn get_hosts(opts: Query<ListHostsRequestOpts>, req_info: HttpRequest,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let host_pages = host::Entity::find().filter(host::Column::Network.eq(net_id)).order_by_asc(host::Column::CreatedAt).paginate(&db.conn, opts.page_size);
|
let host_pages = host::Entity::find().filter(host::Column::Network.eq(&net_id)).order_by_asc(host::Column::CreatedAt).paginate(&db.conn, opts.page_size);
|
||||||
|
|
||||||
let total = match host_pages.num_items().await {
|
let total = match host_pages.num_items().await {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
|
@ -308,17 +316,16 @@ pub async fn get_hosts(opts: Query<ListHostsRequestOpts>, req_info: HttpRequest,
|
||||||
name: u.name,
|
name: u.name,
|
||||||
ip_address: u.ip,
|
ip_address: u.ip,
|
||||||
static_addresses: ips.iter().map(|u| SocketAddrV4::from_str(&u.address).unwrap()).collect(),
|
static_addresses: ips.iter().map(|u| SocketAddrV4::from_str(&u.address).unwrap()).collect(),
|
||||||
|
|
||||||
listen_port: u.listen_port as u16,
|
listen_port: u.listen_port as u16,
|
||||||
is_lighthouse: false,
|
is_lighthouse: u.is_lighthouse,
|
||||||
is_relay: false,
|
is_relay: u.is_relay,
|
||||||
created_at: "".to_string(),
|
created_at: Utc.timestamp_opt(u.created_at, 0).unwrap().format("%Y-%m-%dT%H-%M-%S%.3fZ").to_string(),
|
||||||
is_blocked: false,
|
is_blocked: u.is_blocked,
|
||||||
metadata: HostResponseMetadata {
|
metadata: HostResponseMetadata {
|
||||||
last_seen_at: None,
|
last_seen_at: Some(Utc.timestamp_opt(u.last_seen_at, 0).unwrap().format("%Y-%m-%dT%H-%M-%S%.3fZ").to_string()),
|
||||||
version: "".to_string(),
|
version: u.last_version.to_string(),
|
||||||
platform: "".to_string(),
|
platform: u.last_platform,
|
||||||
update_available: false,
|
update_available: u.last_out_of_date,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -356,3 +363,262 @@ pub async fn get_hosts(opts: Query<ListHostsRequestOpts>, req_info: HttpRequest,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct CreateHostRequest {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(rename = "networkID")]
|
||||||
|
pub network_id: String,
|
||||||
|
#[serde(rename = "roleID", default)]
|
||||||
|
pub role_id: Option<String>,
|
||||||
|
#[serde(rename = "ipAddress")]
|
||||||
|
pub ip_address: Ipv4Addr,
|
||||||
|
#[serde(rename = "staticAddresses", default)]
|
||||||
|
pub static_addresses: Vec<SocketAddrV4>,
|
||||||
|
#[serde(rename = "listenPort")]
|
||||||
|
pub listen_port: u16,
|
||||||
|
#[serde(rename = "isLighthouse")]
|
||||||
|
pub is_lighthouse: bool,
|
||||||
|
#[serde(rename = "isRelay")]
|
||||||
|
pub is_relay: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct CreateHostResponse {
|
||||||
|
pub data: HostResponse,
|
||||||
|
pub metadata: CreateHostResponseMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct CreateHostResponseMetadata {}
|
||||||
|
|
||||||
|
#[post("/v1/hosts")]
|
||||||
|
pub async fn create_hosts_request(req: Json<CreateHostRequest>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
||||||
|
// For this endpoint, you either need to be a fully authenticated user OR a token with hosts:create
|
||||||
|
let session_info = enforce_2fa(&req_info, &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
||||||
|
let api_token_info = enforce_api_token(&req_info, &["hosts:create"], &db.conn).await.unwrap_or(TokenInfo::NotPresent);
|
||||||
|
|
||||||
|
// If neither are present, throw an error
|
||||||
|
if matches!(session_info, TokenInfo::NotPresent) && matches!(api_token_info, TokenInfo::NotPresent) {
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_UNAUTHORIZED".to_string(),
|
||||||
|
message: "This endpoint requires either a fully authenticated user or a token with the hosts:create scope".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both are present, throw an error
|
||||||
|
if matches!(session_info, TokenInfo::AuthToken(_)) && matches!(api_token_info, TokenInfo::ApiToken(_)) {
|
||||||
|
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_AMBIGUOUS_AUTHENTICATION".to_string(),
|
||||||
|
message: "Both a user token and an API token with the proper scope was provided. Please only provide one.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let org_id = match api_token_info {
|
||||||
|
TokenInfo::ApiToken(tkn) => tkn.organization,
|
||||||
|
_ => {
|
||||||
|
// we have a session token, which means we have to do a db request to get the organization that this user owns
|
||||||
|
let user = match session_info {
|
||||||
|
TokenInfo::AuthToken(tkn) => tkn.session_info.user,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let org = match organization::Entity::find().filter(organization::Column::Owner.eq(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 performing the database request, please try again later.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(org) = org {
|
||||||
|
org.id
|
||||||
|
} else {
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_NO_ORG".to_string(),
|
||||||
|
message: "This user does not own any organizations. Try using an API token instead.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let net_id;
|
||||||
|
|
||||||
|
let net = match network::Entity::find().filter(network::Column::Organization.eq(&org_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 performing the database request, please try again later.".to_string(),
|
||||||
|
path: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(net) = net {
|
||||||
|
net_id = net.id;
|
||||||
|
} else {
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_NO_NET".to_string(),
|
||||||
|
message: "This user does not own any networks. Try using an API token instead.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if net_id != req.network_id {
|
||||||
|
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_WRONG_NET".to_string(),
|
||||||
|
message: "The network on the request does not match the network associated with this token or user.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.is_lighthouse && req.is_relay {
|
||||||
|
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_CANNOT_BE_RELAY_AND_LIGHTHOUSE".to_string(),
|
||||||
|
message: "A host cannot be a relay and a lighthouse at the same time.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.is_lighthouse || req.is_relay && req.static_addresses.is_empty() {
|
||||||
|
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||||
|
errors: vec![
|
||||||
|
APIError {
|
||||||
|
code: "ERR_NEEDS_STATIC_ADDR".to_string(),
|
||||||
|
message: "A relay or lighthouse requires at least one static address.".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_host_model = host::Model {
|
||||||
|
id: random_id("host"),
|
||||||
|
name: req.name.clone(),
|
||||||
|
network: net_id.clone(),
|
||||||
|
role: req.role_id.clone().unwrap_or("".to_string()),
|
||||||
|
ip: req.ip_address.to_string(),
|
||||||
|
listen_port: req.listen_port as i32,
|
||||||
|
is_lighthouse: req.is_lighthouse,
|
||||||
|
is_relay: req.is_relay,
|
||||||
|
counter: 0,
|
||||||
|
created_at: SystemTime::now().duration_since(UNIX_EPOCH).expect("time went backwards").as_secs() as i64,
|
||||||
|
is_blocked: false,
|
||||||
|
last_seen_at: 0,
|
||||||
|
last_version: 0,
|
||||||
|
last_platform: "".to_string(),
|
||||||
|
last_out_of_date: false,
|
||||||
|
};
|
||||||
|
let static_addresses: Vec<host_static_address::Model> = req.static_addresses.iter().map(|u| {
|
||||||
|
host_static_address::Model {
|
||||||
|
id: random_id("hsaddress"),
|
||||||
|
host: new_host_model.id.clone(),
|
||||||
|
address: u.to_string(),
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
let new_host_model_clone = new_host_model.clone();
|
||||||
|
let static_addresses_clone = static_addresses.clone();
|
||||||
|
|
||||||
|
let new_host_active_model = new_host_model.into_active_model();
|
||||||
|
match new_host_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 creating the new host. Please try again later".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for rule in &static_addresses_clone {
|
||||||
|
let active_model = rule.clone().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 creating the new host. Please try again later".to_string(),
|
||||||
|
path: None
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse::Ok().json(CreateHostResponse {
|
||||||
|
data: HostResponse {
|
||||||
|
id: new_host_model_clone.id,
|
||||||
|
organization_id: org_id,
|
||||||
|
network_id: net_id,
|
||||||
|
role_id: new_host_model_clone.role,
|
||||||
|
name: new_host_model_clone.name,
|
||||||
|
ip_address: req.ip_address.to_string(),
|
||||||
|
static_addresses: req.static_addresses.clone(),
|
||||||
|
listen_port: req.listen_port,
|
||||||
|
is_lighthouse: req.is_lighthouse,
|
||||||
|
is_relay: req.is_relay,
|
||||||
|
created_at: "".to_string(),
|
||||||
|
is_blocked: false,
|
||||||
|
metadata: HostResponseMetadata {
|
||||||
|
last_seen_at: Some(Utc.timestamp_opt(new_host_model_clone.last_seen_at, 0).unwrap().format("%Y-%m-%dT%H-%M-%S%.3fZ").to_string()),
|
||||||
|
version: new_host_model_clone.last_version.to_string(),
|
||||||
|
platform: new_host_model_clone.last_platform,
|
||||||
|
update_available: new_host_model_clone.last_out_of_date,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
metadata: CreateHostResponseMetadata {},
|
||||||
|
})
|
||||||
|
}
|
|
@ -16,6 +16,11 @@ pub struct Model {
|
||||||
pub is_relay: bool,
|
pub is_relay: bool,
|
||||||
pub counter: i32,
|
pub counter: i32,
|
||||||
pub created_at: i64,
|
pub created_at: i64,
|
||||||
|
pub is_blocked: bool,
|
||||||
|
pub last_seen_at: i64,
|
||||||
|
pub last_version: i32,
|
||||||
|
pub last_platform: String,
|
||||||
|
pub last_out_of_date: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
|
|
@ -21,6 +21,11 @@ impl MigrationTrait for Migration {
|
||||||
.col(ColumnDef::new(Host::IsRelay).boolean().not_null())
|
.col(ColumnDef::new(Host::IsRelay).boolean().not_null())
|
||||||
.col(ColumnDef::new(Host::Counter).unsigned().not_null())
|
.col(ColumnDef::new(Host::Counter).unsigned().not_null())
|
||||||
.col(ColumnDef::new(Host::CreatedAt).big_integer().not_null())
|
.col(ColumnDef::new(Host::CreatedAt).big_integer().not_null())
|
||||||
|
.col(ColumnDef::new(Host::IsBlocked).boolean().not_null())
|
||||||
|
.col(ColumnDef::new(Host::LastSeenAt).big_integer().not_null())
|
||||||
|
.col(ColumnDef::new(Host::LastVersion).integer().not_null())
|
||||||
|
.col(ColumnDef::new(Host::LastPlatform).string().not_null())
|
||||||
|
.col(ColumnDef::new(Host::LastOutOfDate).boolean().not_null())
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.from(Host::Table, Host::Network)
|
.from(Host::Table, Host::Network)
|
||||||
|
@ -67,5 +72,10 @@ pub enum Host {
|
||||||
IsLighthouse,
|
IsLighthouse,
|
||||||
IsRelay,
|
IsRelay,
|
||||||
Counter,
|
Counter,
|
||||||
CreatedAt
|
CreatedAt,
|
||||||
|
IsBlocked,
|
||||||
|
LastSeenAt,
|
||||||
|
LastVersion,
|
||||||
|
LastPlatform,
|
||||||
|
LastOutOfDate
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
//! `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 = "api_key")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
#[sea_orm(unique)]
|
||||||
|
pub key: String,
|
||||||
|
pub organization: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::api_key_scope::Entity")]
|
||||||
|
ApiKeyScope,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::organization::Entity",
|
||||||
|
from = "Column::Organization",
|
||||||
|
to = "super::organization::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
Organization,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::api_key_scope::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::ApiKeyScope.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::organization::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Organization.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,32 @@
|
||||||
|
//! `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 = "api_key_scope")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
pub scope: String,
|
||||||
|
pub api_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::api_key::Entity",
|
||||||
|
from = "Column::ApiKey",
|
||||||
|
to = "super::api_key::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
ApiKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::api_key::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::ApiKey.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,32 @@
|
||||||
|
//! `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 = "auth_token")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
pub user: String,
|
||||||
|
pub expires_on: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::user::Entity",
|
||||||
|
from = "Column::User",
|
||||||
|
to = "super::user::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::user::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::User.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,38 @@
|
||||||
|
//! `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 = "firewall_rule")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
pub role: String,
|
||||||
|
pub protocol: String,
|
||||||
|
pub description: String,
|
||||||
|
pub allowed_role_id: Option<String>,
|
||||||
|
pub port_range_from: i32,
|
||||||
|
pub port_range_to: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::role::Entity",
|
||||||
|
from = "Column::AllowedRoleId",
|
||||||
|
to = "super::role::Column::Id",
|
||||||
|
on_update = "NoAction",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
Role2,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::role::Entity",
|
||||||
|
from = "Column::Role",
|
||||||
|
to = "super::role::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
Role1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,32 @@
|
||||||
|
//! `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 = "magic_link")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub id: String,
|
||||||
|
pub user: String,
|
||||||
|
pub expires_on: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::user::Entity",
|
||||||
|
from = "Column::User",
|
||||||
|
to = "super::user::Column::Id",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "Cascade"
|
||||||
|
)]
|
||||||
|
User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::user::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::User.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,16 @@
|
||||||
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||||
|
|
||||||
|
pub mod prelude ;
|
||||||
|
|
||||||
|
pub mod api_key ;
|
||||||
|
pub mod api_key_scope ;
|
||||||
|
pub mod auth_token ;
|
||||||
|
pub mod firewall_rule ;
|
||||||
|
pub mod magic_link ;
|
||||||
|
pub mod network ;
|
||||||
|
pub mod organization ;
|
||||||
|
pub mod role ;
|
||||||
|
pub mod session_token ;
|
||||||
|
pub mod signing_ca ;
|
||||||
|
pub mod totp_authenticator ;
|
||||||
|
pub mod user ;
|
|
@ -0,0 +1,15 @@
|
||||||
|
//! `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 = "network")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , pub cidr : String , # [sea_orm (unique)] pub organization : String , # [sea_orm (unique)] pub signing_ca : String , pub created_at : i64 , pub name : String , pub lighthouses_as_relays : bool , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (belongs_to = "super::organization::Entity" , from = "Column::Organization" , to = "super::organization::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] Organization , # [sea_orm (belongs_to = "super::signing_ca::Entity" , from = "Column::SigningCa" , to = "super::signing_ca::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] SigningCa , }
|
||||||
|
|
||||||
|
impl Related < super :: organization :: Entity > for Entity { fn to () -> RelationDef { Relation :: Organization . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: signing_ca :: Entity > for Entity { fn to () -> RelationDef { Relation :: SigningCa . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,19 @@
|
||||||
|
//! `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 = "organization")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , pub name : String , # [sea_orm (unique)] pub owner : String , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (has_many = "super::api_key::Entity")] ApiKey , # [sea_orm (has_one = "super::network::Entity")] Network , # [sea_orm (has_many = "super::role::Entity")] Role , # [sea_orm (belongs_to = "super::user::Entity" , from = "Column::Owner" , to = "super::user::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] User , }
|
||||||
|
|
||||||
|
impl Related < super :: api_key :: Entity > for Entity { fn to () -> RelationDef { Relation :: ApiKey . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: network :: Entity > for Entity { fn to () -> RelationDef { Relation :: Network . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: role :: Entity > for Entity { fn to () -> RelationDef { Relation :: Role . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: user :: Entity > for Entity { fn to () -> RelationDef { Relation :: User . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,14 @@
|
||||||
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||||
|
|
||||||
|
pub use super :: api_key :: Entity as ApiKey ;
|
||||||
|
pub use super :: api_key_scope :: Entity as ApiKeyScope ;
|
||||||
|
pub use super :: auth_token :: Entity as AuthToken ;
|
||||||
|
pub use super :: firewall_rule :: Entity as FirewallRule ;
|
||||||
|
pub use super :: magic_link :: Entity as MagicLink ;
|
||||||
|
pub use super :: network :: Entity as Network ;
|
||||||
|
pub use super :: organization :: Entity as Organization ;
|
||||||
|
pub use super :: role :: Entity as Role ;
|
||||||
|
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 :: user :: Entity as User ;
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! `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 = "role")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , # [sea_orm (unique)] pub name : String , pub description : String , pub organization : String , pub created_at : i64 , pub modified_at : i64 , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (belongs_to = "super::organization::Entity" , from = "Column::Organization" , to = "super::organization::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] Organization , }
|
||||||
|
|
||||||
|
impl Related < super :: organization :: Entity > for Entity { fn to () -> RelationDef { Relation :: Organization . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! `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 = "session_token")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , pub user : String , pub expires_on : i64 , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (belongs_to = "super::user::Entity" , from = "Column::User" , to = "super::user::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] User , }
|
||||||
|
|
||||||
|
impl Related < super :: user :: Entity > for Entity { fn to () -> RelationDef { Relation :: User . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! `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 { # [sea_orm (has_one = "super::network::Entity")] Network , }
|
||||||
|
|
||||||
|
impl Related < super :: network :: Entity > for Entity { fn to () -> RelationDef { Relation :: Network . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! `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 = "totp_authenticator")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , # [sea_orm (unique)] pub secret : String , # [sea_orm (unique)] pub url : String , pub verified : bool , pub expires_on : i64 , # [sea_orm (unique)] pub user : String , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (belongs_to = "super::user::Entity" , from = "Column::User" , to = "super::user::Column::Id" , on_update = "Cascade" , on_delete = "Cascade" ,)] User , }
|
||||||
|
|
||||||
|
impl Related < super :: user :: Entity > for Entity { fn to () -> RelationDef { Relation :: User . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
|
@ -0,0 +1,21 @@
|
||||||
|
//! `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 = "user")] pub struct Model { # [sea_orm (primary_key , auto_increment = false)] pub id : String , # [sea_orm (unique)] pub email : String , }
|
||||||
|
|
||||||
|
# [derive (Copy , Clone , Debug , EnumIter , DeriveRelation)] pub enum Relation { # [sea_orm (has_many = "super::auth_token::Entity")] AuthToken , # [sea_orm (has_many = "super::magic_link::Entity")] MagicLink , # [sea_orm (has_one = "super::organization::Entity")] Organization , # [sea_orm (has_many = "super::session_token::Entity")] SessionToken , # [sea_orm (has_one = "super::totp_authenticator::Entity")] TotpAuthenticator , }
|
||||||
|
|
||||||
|
impl Related < super :: auth_token :: Entity > for Entity { fn to () -> RelationDef { Relation :: AuthToken . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: magic_link :: Entity > for Entity { fn to () -> RelationDef { Relation :: MagicLink . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: organization :: Entity > for Entity { fn to () -> RelationDef { Relation :: Organization . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: session_token :: Entity > for Entity { fn to () -> RelationDef { Relation :: SessionToken . def () } }
|
||||||
|
|
||||||
|
impl Related < super :: totp_authenticator :: Entity > for Entity { fn to () -> RelationDef { Relation :: TotpAuthenticator . def () } }
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel { }
|
Loading…
Reference in New Issue