Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain verification chanllenge refactor #154

Merged
merged 9 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ r-cache = "0.5.0"
lettre = "0.11.6"
addr = "0.15.6"
hickory-resolver = "0.24.0"
webauthn-rs = { version = "0.4.8", features = [
"danger-allow-state-serialisation",
] }

# If you're updating sqlx, make sure that chrono version below is the same as the one in sqlx
sqlx = { version = "0.7.3", features = [
Expand Down
1 change: 1 addition & 0 deletions database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ log = { workspace = true }
strum = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
webauthn-rs = { workspace = true }

[features]
cloud_db_tests = []
9 changes: 0 additions & 9 deletions database/migrations/0003_grafana_users.sql

This file was deleted.

10 changes: 10 additions & 0 deletions database/migrations/0003_users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE users(
user_id TEXT NOT NULL UNIQUE,
email TEXT NOT NULL UNIQUE,
password_hash TEXT,
passkeys TEXT,
creation_timestamp TIMESTAMPTZ NOT NULL
);

CREATE INDEX users_name_idx ON users(user_id);
CREATE INDEX users_email_idx ON users(email);
2 changes: 1 addition & 1 deletion database/migrations/0005_user_app_privilages.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ CREATE TABLE user_app_privileges (
creation_timestamp TIMESTAMPTZ NOT NULL,
privilege_level privilege_level_enum NOT NULL,
PRIMARY KEY (user_id, app_id),
FOREIGN KEY (user_id) REFERENCES grafana_users (user_id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE,
FOREIGN KEY (app_id) REFERENCES registered_apps (app_id) ON DELETE CASCADE
);
9 changes: 9 additions & 0 deletions database/migrations/0014_domain_verifications.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE domain_verifications(
domain_name TEXT PRIMARY KEY,
app_id TEXT NOT NULL,
code TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
finished_at TIMESTAMPTZ
);

CREATE INDEX domain_verifications_app_id_idx ON domain_verifications(app_id);
39 changes: 39 additions & 0 deletions database/src/tables/domain_verifications/select.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::{
db::Db,
structs::db_error::DbError,
tables::domain_verifications::table_struct::{
DomainVerification, DOMAIN_VERIFICATIONS_TABLE_NAME,
},
};
use sqlx::query_as;

impl Db {
pub async fn get_domain_verifications_by_app_id(
&self,
app_id: &String,
) -> Result<Vec<DomainVerification>, DbError> {
let query = format!("SELECT * FROM {DOMAIN_VERIFICATIONS_TABLE_NAME} WHERE app_id = $1 ORDER BY created_at DESC");
let typed_query = query_as::<_, DomainVerification>(&query);

return typed_query
.bind(&app_id)
.fetch_all(&self.connection_pool)
.await
.map_err(|e| e.into());
}

pub async fn get_domain_verification_by_domain_name(
&self,
domain_name: &String,
) -> Result<Option<DomainVerification>, DbError> {
let query =
format!("SELECT * FROM {DOMAIN_VERIFICATIONS_TABLE_NAME} WHERE domain_name = $1");
let typed_query = query_as::<_, DomainVerification>(&query);

return typed_query
.bind(&domain_name)
.fetch_optional(&self.connection_pool)
.await
.map_err(|e| e.into());
}
}
29 changes: 29 additions & 0 deletions database/src/tables/domain_verifications/table_struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use sqlx::{
postgres::PgRow,
types::chrono::{DateTime, Utc},
FromRow, Row,
};

pub const DOMAIN_VERIFICATIONS_TABLE_NAME: &str = "domain_verifications";
pub const DOMAIN_VERIFICATIONS_KEYS: &str = "domain_name, app_id, code, created_at, finished_at";

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DomainVerification {
pub domain_name: String,
pub app_id: String,
pub code: String,
pub created_at: DateTime<Utc>,
pub finished_at: Option<DateTime<Utc>>,
}

impl FromRow<'_, PgRow> for DomainVerification {
fn from_row(row: &sqlx::postgres::PgRow) -> std::result::Result<Self, sqlx::Error> {
Ok(DomainVerification {
domain_name: row.get("domain_name"),
app_id: row.get("app_id"),
code: row.get("code"),
created_at: row.get("created_at"),
finished_at: row.get("finished_at"),
})
}
}
52 changes: 52 additions & 0 deletions database/src/tables/domain_verifications/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::table_struct::{DOMAIN_VERIFICATIONS_KEYS, DOMAIN_VERIFICATIONS_TABLE_NAME};
use crate::db::Db;
use crate::structs::db_error::DbError;
use crate::tables::utils::get_current_datetime;
use sqlx::query;

impl Db {
pub async fn create_new_domain_verification_entry(
&self,
domain_name: &String,
app_id: &String,
code: &String,
) -> Result<(), DbError> {
let query_body = format!(
"INSERT INTO {DOMAIN_VERIFICATIONS_TABLE_NAME} ({DOMAIN_VERIFICATIONS_KEYS}) VALUES ($1, $2, $3, $4, NULL)"
);

let query_result = query(&query_body)
.bind(&domain_name)
.bind(&app_id)
.bind(&code)
.bind(&get_current_datetime())
.execute(&self.connection_pool)
.await;

match query_result {
Ok(_) => Ok(()),
Err(e) => Err(e).map_err(|e| e.into()),
}
}

pub async fn finish_domain_verification(
&self,
tx: &mut sqlx::Transaction<'_, sqlx::Postgres>,
domain_name: &String,
) -> Result<(), DbError> {
let query_body = format!(
"UPDATE {DOMAIN_VERIFICATIONS_TABLE_NAME} SET finished_at = $1 WHERE domain_name = $2"
);

let query_result = query(&query_body)
.bind(&get_current_datetime())
.bind(&domain_name)
.execute(&mut **tx)
.await;

match query_result {
Ok(_) => Ok(()),
Err(e) => Err(e).map_err(|e| e.into()),
}
}
}
32 changes: 0 additions & 32 deletions database/src/tables/grafana_users/select.rs

This file was deleted.

27 changes: 0 additions & 27 deletions database/src/tables/grafana_users/table_struct.rs

This file was deleted.

104 changes: 0 additions & 104 deletions database/src/tables/grafana_users/update.rs

This file was deleted.

3 changes: 2 additions & 1 deletion database/src/tables/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
pub mod client_profiles;
pub mod connection_events;
pub mod events;
pub mod grafana_users;
pub mod ip_addresses;
pub mod public_keys;
pub mod registered_app;
pub mod users;
// pub mod requests;
pub mod domain_verifications;
pub mod session_public_keys;
pub mod sessions;
pub mod team;
Expand Down
3 changes: 2 additions & 1 deletion database/src/tables/registered_app/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl Db {

pub async fn add_new_whitelisted_domain(
&self,
tx: &mut sqlx::Transaction<'_, sqlx::Postgres>,
app_id: &str,
domain: &str,
) -> Result<(), DbError> {
Expand All @@ -62,7 +63,7 @@ impl Db {
let query_result = query(&query_body)
.bind(domain)
.bind(app_id)
.execute(&self.connection_pool)
.execute(&mut **tx)
.await;

match query_result {
Expand Down
Loading
Loading