feat(db): basic application relations
This commit is contained in:
parent
935ea5555d
commit
b0fe35f69e
|
@ -1253,11 +1253,13 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"async-std",
|
||||
"futures",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tide",
|
||||
"tokio",
|
||||
"tokio-postgres",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1452,6 +1454,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"fallible-iterator",
|
||||
"postgres-protocol",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2200,6 +2203,28 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
|
||||
dependencies = [
|
||||
"getrandom 0.2.12",
|
||||
"rand 0.8.5",
|
||||
"uuid-macro-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid-macro-internal"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.8.1"
|
||||
|
|
|
@ -11,5 +11,7 @@ async-std = { version = "1.8.0", features = ["attributes"] }
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
tokio-postgres = "0.7.10"
|
||||
tokio-postgres = { version = "0.7.10", features = ["with-uuid-1"] }
|
||||
futures = "0.3.30"
|
||||
uuid = { verion = "1.0.0", features = ["v4", "fast-rng", "macro-diagnostics"] }
|
||||
rand = "0.8.5"
|
||||
|
|
72
src/db.rs
72
src/db.rs
|
@ -1,33 +1,102 @@
|
|||
use std::time::Duration;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct OAuthApplication {
|
||||
pub client_id: Uuid,
|
||||
pub client_secret: crate::misc::U256,
|
||||
}
|
||||
|
||||
impl OAuthApplication {
|
||||
// TEST: functionality
|
||||
pub fn new() -> Self {
|
||||
Self { client_id: Uuid::new_v4(), client_secret: crate::misc::random_256() }
|
||||
}
|
||||
|
||||
pub fn from(client_id: Uuid, client_secret: crate::misc::U256) -> Self {
|
||||
Self { client_id, client_secret }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OAuthScope {
|
||||
pub scope_id: Uuid,
|
||||
pub scope_desc: String,
|
||||
}
|
||||
|
||||
impl OAuthScope {
|
||||
// TEST: functionality
|
||||
pub fn new(description: String) -> Self {
|
||||
Self { scope_id: Uuid::new_v4(), scope_desc: description }
|
||||
}
|
||||
|
||||
pub fn from(scope_id: Uuid, scope_desc: String) -> Self {
|
||||
Self { scope_id, scope_desc }
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper struct for Postgres database with APIs related to OAuth database operations.
|
||||
pub struct OAuthDatabase {
|
||||
client: tokio_postgres::Client,
|
||||
handle: tokio::task::JoinHandle<Result<(), tokio_postgres::Error>>,
|
||||
}
|
||||
|
||||
impl OAuthDatabase {
|
||||
/// Establish a new connection to a database.
|
||||
pub async fn connect(host: &str, port: u16, user: &str, password: &str, db_name: &str) -> Result<Self, tokio_postgres::Error> {
|
||||
let (client, connection) = tokio_postgres::connect(format!("host={} port={} user={} password={} dbname={}", host, port, user, password, db_name).as_str(), tokio_postgres::NoTls).await?;
|
||||
Ok(Self::new(client, connection).await?)
|
||||
}
|
||||
|
||||
/// Attach a connection to a new `OAuthDatabase` instance.
|
||||
pub async fn new(client: tokio_postgres::Client, connection: tokio_postgres::Connection<tokio_postgres::Socket, tokio_postgres::tls::NoTlsStream>) -> Result<Self, tokio_postgres::Error> {
|
||||
let handle = tokio::spawn(connection);
|
||||
let obj = Self { client, handle };
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
/// Perform arbitrary SQL operations on the database. This method shouldn't be called directly
|
||||
/// by other modules. This method has the same signature with
|
||||
/// `tokio_postgres::Client::execute`.
|
||||
async fn psql_execute<T: ?Sized + tokio_postgres::ToStatement>(&mut self, query: &T, params: &[&(dyn tokio_postgres::types::ToSql + Sync)]) -> Result<u64, tokio_postgres::Error> {
|
||||
self.client.execute(query, params).await
|
||||
}
|
||||
|
||||
/// Perform arbitrary SQL operations on the database (with return value). This method shouldn't be called directly
|
||||
/// by other modules. This method has the same signature with `tokio_postgres::Client::query`.
|
||||
async fn psql_query<T: ?Sized + tokio_postgres::ToStatement>(&mut self, query: &T, params: &[&(dyn tokio_postgres::types::ToSql + Sync)]) -> Result<Vec<tokio_postgres::Row>, tokio_postgres::Error> {
|
||||
self.client.query(query, params).await
|
||||
}
|
||||
|
||||
/// Disconnect from the current database. The instance will become invalid since then.
|
||||
pub fn disconnect(&mut self) {
|
||||
self.handle.abort();
|
||||
}
|
||||
|
||||
/// Initialize the database.
|
||||
pub async fn init(&mut self) -> Result<(), tokio_postgres::Error> {
|
||||
// TEST: functionality
|
||||
self.psql_execute("create table Applications(client_id uuid primary key, client_secret bytea)", &[]).await?;
|
||||
self.psql_execute("create table Scopes(scope_id uuid primary key, scope_desc text)", &[]).await?;
|
||||
// TODO: OAuthApplicationAccess struct
|
||||
self.psql_execute("create table ApplicationAccess(access_id uuid primary key, client_id uuid, scope_id uuid)", &[]).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register an application.
|
||||
/// Applicant: client
|
||||
pub async fn trusted_register_application(&mut self) -> Result<OAuthApplication, tokio_postgres::Error> {
|
||||
// TEST: functionality
|
||||
let app = OAuthApplication::new();
|
||||
self.psql_execute("insert into Applications (client_id, client_secret) values ($1, $2)", &[&app.client_id, &&app.client_secret[..]]).await?;
|
||||
Ok(app)
|
||||
}
|
||||
|
||||
/// Register a scope.
|
||||
/// Applicant: Resource
|
||||
pub async fn trusted_register_scope(&mut self, description: String) -> Result<OAuthScope, tokio_postgres::Error> {
|
||||
// TEST: functionality
|
||||
let scope = OAuthScope::new(description);
|
||||
self.psql_execute("insert into Scopes (scope_id, scope_desc) values ($1, $2)", &[&scope.scope_id, &scope.scope_desc]).await?;
|
||||
Ok(scope)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -61,7 +130,6 @@ pub mod db_tests {
|
|||
}
|
||||
|
||||
pub async fn read(&mut self) -> Result<Vec<DBTestEntryType>, tokio_postgres::Error> {
|
||||
// TODO:
|
||||
let v = self.d.psql_query("select * from rust_test", &[]).await?;
|
||||
let mut res = Vec::new();
|
||||
for row in v {
|
||||
|
|
|
@ -2,6 +2,7 @@ use tide::Request;
|
|||
use tide::prelude::*;
|
||||
|
||||
mod db;
|
||||
mod misc;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Test {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
pub type U256 = [u8; 8];
|
||||
|
||||
pub fn random_256() -> U256 {
|
||||
let mut res = [0; 8];
|
||||
for x in &mut res {
|
||||
*x = rand::random::<i8>() as u8;
|
||||
}
|
||||
res
|
||||
}
|
Loading…
Reference in New Issue