Skip to content

Commit

Permalink
Add app/ directory, finish session middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
auguwu committed Sep 20, 2024
1 parent ab8b230 commit ce5508e
Show file tree
Hide file tree
Showing 47 changed files with 2,408 additions and 285 deletions.
218 changes: 164 additions & 54 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

[workspace]
resolver = "2"
members = ["crates/*", "crates/authz/*"]
members = ["crates/*", "crates/authz/*", "crates/tatsuki/macros"]

[workspace.package]
version = "0.1.0"
Expand Down Expand Up @@ -43,7 +43,7 @@ chrono = { version = "0.4.23", features = ["serde"] }
clap = { version = "4.5.16", features = ["derive", "env"] }
clap_complete = "4.5.26"
derive_more = "1.0.0"
diesel = "2.2.3"
diesel = { version = "2.2.4", features = ["postgres", "sqlite", "chrono"] }
eyre = "0.6.12"
multer = "3.1.0"
remi = "0.8.0"
Expand Down Expand Up @@ -72,4 +72,10 @@ which = "6.0.3"
[workspace.dependencies.azalia]
version = "0.1.0"
git = "https://github.com/Noelware/azalia"
rev = "06e3b85a496854086803917e263bc5427f8324dd"
rev = "1a722a0e785e4abfad62bce6738516e47afce89c"

[profile.release]
opt-level = "z"
strip = true
debug = 0
lto = "thin"
2 changes: 2 additions & 0 deletions app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 🐻‍❄️⭐ Hoshi
**Hoshi** is the main web interface for [charted-server](..). It is built with Vue and Vite, and is a single-page application.
3 changes: 2 additions & 1 deletion crates/authz/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ impl Error for InvalidPassword {}

/// Trait that allows to build an authenticator that allows to authenticate users.
pub trait Authenticator: Send + Sync {
fn authenticate(&self, user: User, password: String) -> BoxedFuture<eyre::Result<()>>;
/// Authenticate a given [`User`] with the password given.
fn authenticate<'u>(&'u self, user: &'u User, password: String) -> BoxedFuture<'u, eyre::Result<()>>;
}
6 changes: 3 additions & 3 deletions crates/authz/local/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ use tracing::error;

pub struct Backend;
impl charted_authz::Authenticator for Backend {
fn authenticate(&self, user: User, password: String) -> charted_core::BoxedFuture<eyre::Result<()>> {
fn authenticate<'u>(&'u self, user: &'u User, password: String) -> charted_core::BoxedFuture<'u, eyre::Result<()>> {
Box::pin(async move {
let Some(pass) = user.password else {
let Some(ref pass) = user.password else {
return Err(eyre!(
"missing `password` field, did you migrate all users from previous backends?"
));
};

let hash = PasswordHash::new(&pass)
let hash = PasswordHash::new(pass)
.inspect_err(|e| {
error!(error = %e, "failed to compute argon2 hash for password");
})
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ clap = { workspace = true, features = ["derive", "env"] }
clap_complete.workspace = true
eyre.workspace = true
num_cpus = "1.16.0"
owo-colors = { version = "4.0.0", features = ["supports-colors"] }
owo-colors = { version = "4.1.0", features = ["supports-colors"] }
remi-azure = { workspace = true, features = ["tracing"] }
remi-fs = { workspace = true, features = ["tracing"] }
remi-s3 = { workspace = true, features = ["tracing"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/cmds/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub async fn run(Args { config, .. }: Args) -> eyre::Result<()> {
storage::Config::S3(s3) => azalia::remi::StorageService::S3(remi_s3::StorageService::new(s3)),
};

azalia::remi::remi::StorageService::init(&storage).await?;
azalia::remi::core::StorageService::init(&storage).await?;
info!("initialized data storage successfully!");

info!("initializing authz backend...");
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ pub enum ErrorCode {
/// was unable to decode expected Base64 data.
UnableToDecodeBase64,

/// was unable to decode into a ULID.
UnableToDecodeUlid,

/// received invalid UTF-8 data
InvalidUtf8,

Expand Down
155 changes: 17 additions & 138 deletions crates/core/src/bitflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ impl<F: Bitflags> Bitfield<F> {
// Since both `ApiKeyScope` and `MemberPermission` use `u64` as its `Bit` type,
// we will do our own silly impls here.
impl<F: Bitflags<Bit = u64>> Bitfield<F> {
/// Returns all the possible enabled bits in the bitfield to determine
pub fn flags(&self) -> Vec<(&'static str, F::Bit)> {
let flags = F::flags();
flags.into_iter().filter(|(_, bit)| self.contains(*bit)).collect()
}

/// Adds multiple bits to this [`Bitfield`] and updating the current
/// value to what was acculumated.
///
Expand Down Expand Up @@ -127,6 +133,17 @@ impl<F: Bitflags<Bit = u64>> Bitfield<F> {

self.0 &= min(removed, 0)
}

/// Determines if `bit` is contained in the inner bit.
pub fn contains<B: Into<F::Bit>>(&self, bit: B) -> bool {
(self.value() & bit.into()) != 0
}
}

impl<F: Bitflags<Bit = u64>> Default for Bitfield<F> {
fn default() -> Self {
Bitfield(u64::default(), PhantomData)
}
}

/// Trait that is implemented by the [`bitflags`][bitflags] macro.
Expand Down Expand Up @@ -197,141 +214,3 @@ macro_rules! bitflags {
}
};
}

/*
// mod apikeyscope;
// pub use apikeyscope::*;
// use std::{
// collections::HashMap,
// marker::PhantomData,
// ops::{Add, BitAnd, BitOrAssign},
// };
// #[derive(Debug, Clone)]
// pub struct Bitfield<F: Bitflags> {
// value: F::Bit,
// _marker: PhantomData<F>,
// }
// impl<F: Bitflags> Bitfield<F> {
// /// Creates a new [`Bitfield`] instance with a given value.
// pub const fn new(value: F::Bit) -> Bitfield<F> {
// Bitfield {
// value,
// _marker: PhantomData,
// }
// }
// /*
// ` where <F as bitflags::Bitflags>::Bit: std::ops::BitOrAssign<u64>`
// let mut bits = bits.into_iter();
// let first = bits.next();
// if first.is_none() {
// return;
// }
// let mut additional = 0u64;
// additional |= first.unwrap();
// let max = self.max();
// for bit in bits {
// if bit == u64::MAX {
// continue;
// }
// if bit > max {
// continue;
// }
// additional |= bit;
// }
// self.value |= additional;
// */
// pub fn contains<I: Into<F::Bit>>(&self, value: I) -> bool
// where
// <F as Bitflags>::Bit: BitAnd,
// <<F as Bitflags>::Bit as BitAnd>::Output: PartialEq<u64>,
// {
// let value = value.into();
// (self.value & value) != 0
// }
// }
// impl<F: Bitflags> Add for Bitfield<F>
// where
// F::Bit: PartialEq<u64>,
// F::Bit: std::ops::BitOrAssign<u64>,
// {
// type Output = Bitfield<F>;
// fn add(mut self, rhs: Self) -> Self::Output {
// if rhs.value == u64::MAX {
// return self;
// }
// self.value |= rhs.value;
// Bitfield {
// value: self.value,
// _marker: PhantomData,
// }
// }
// }
/*
<F as Bitflags>::Bit: BitAnd,
<<F as Bitflags>::Bit as BitAnd>::Output: PartialEq<u64>,
pub fn add<S: IntoIterator<Item = u64>>(mut self, values: S) -> Bitfield<F>
where
<F as Bitflags>::Bit: BitOrAssign<u64>,
{
let mut bits = values.into_iter();
let mut value = 0u64;
for element in bits {
if element == u64::MAX {
continue;
}
value |= element;
}
self.value |= value;
Bitfield {
value: self.value,
_marker: PhantomData,
}
}
*/
// fn heck() {
// let bitfield = Bitfield::<apikeyscope::ApiKeyScope>::new(0);
// bitfield.contains(apikeyscope::ApiKeyScope::AdminOrgDelete);
// }
// impl<F: Bitflags> Bitfield<F> {
// /// Creates a new [`Bitfield`] object.
// pub const fn new(value: F::Bit) -> Bitfield<F> {
// Bitfield {
// value,
// _marker: PhantomData,
// }
// }
// pub fn contains(&self, value: F::Bit) -> bool
// where
// F::Bit: BitAnd,
// <F::Bit as BitAnd>::Output: PartialEq<u64>,
// {
// (self.value & value) != 0
// }
// }
// fn test() {
// let bit = Bitfield::<apikeyscope::ApiKeyScope>::new(0);
// bit.contains(apikeyscope::ApiKeyScope::AdminOrgDelete as u64);
// }
*/
1 change: 1 addition & 0 deletions crates/database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ diesel = { workspace = true, features = [
diesel_migrations = { version = "2.2.0", features = ["postgres", "sqlite"] }
eyre.workspace = true
sentry.workspace = true
serde.workspace = true
tracing.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS "users"(
verified_publisher BOOLEAN NOT NULL DEFAULT false,
gravatar_email TEXT NULL DEFAULT NULL,
description VARCHAR(240) NULL DEFAULT NULL,
avatar_hash TEXT NOT NULL DEFAULT NULL,
avatar_hash TEXT NULL DEFAULT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT(NOW()),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT(NOW()),
username VARCHAR(64) NOT NULL,
Expand All @@ -34,9 +34,9 @@ SELECT diesel_manage_updated_at('users');

CREATE TABLE IF NOT EXISTS "user_connections"(
noelware_account_id BIGINT NULL DEFAULT NULL,
google_account_id TEXT NOT NULL DEFAULT NULL,
github_account_id TEXT NOT NULL DEFAULT NULL,
apple_account_id TEXT NOT NULL DEFAULT NULL,
google_account_id TEXT NULL DEFAULT NULL,
github_account_id TEXT NULL DEFAULT NULL,
apple_account_id TEXT NULL DEFAULT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT(NOW()),
updated_at TIMESTAMPTZ NOT NULL DEFAULT(NOW()),
account TEXT NOT NULL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS `users`(
verified_publisher BOOLEAN NOT NULL DEFAULT false,
gravatar_email TEXT NULL DEFAULT NULL,
description VARCHAR(240) NULL DEFAULT NULL,
avatar_hash TEXT NOT NULL DEFAULT NULL,
avatar_hash TEXT NULL DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT(NOW()),
updated_at DATETIME NOT NULL DEFAULT(NOW()),
username VARCHAR(64) NOT NULL,
Expand All @@ -33,9 +33,9 @@ CREATE UNIQUE INDEX idx_users_email ON users(email);

CREATE TABLE IF NOT EXISTS `user_connections`(
noelware_account_id BIGINT NULL DEFAULT NULL,
google_account_id TEXT NOT NULL DEFAULT NULL,
github_account_id TEXT NOT NULL DEFAULT NULL,
apple_account_id TEXT NOT NULL DEFAULT NULL,
google_account_id TEXT NULL DEFAULT NULL,
github_account_id TEXT NULL DEFAULT NULL,
apple_account_id TEXT NULL DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT(NOW()),
updated_at DATETIME NOT NULL DEFAULT(NOW()),
account TEXT NOT NULL,
Expand Down
37 changes: 32 additions & 5 deletions crates/database/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,48 @@ pub fn version(pool: &DbPool) -> eyre::Result<String> {

#[macro_export]
macro_rules! connection {
(@raw $conn:ident {
$(
$db:ident($c:ident) => $code:expr;
)*
}) => {{
#[allow(unused)]
use ::diesel::prelude::*;
match *$conn {
$(
$crate::DbConnection::$db(ref mut $c) => $code,
)*
}
}};

(@raw $conn:ident {
$(
$db:ident($c:ident) $code:block;
)*
}) => {{
#[allow(unused)]
use ::diesel::prelude::*;
match *$conn {
$(
$crate::DbConnection::$db(ref mut $c) => $code,
)*
}
}};

($pool:ident, {
$(
$db:ident($conn:ident) $code:block;
)*
}) => {{
#[allow(unused)]
use ::diesel::prelude::*;
use ::eyre::Context;

let mut conn = ($pool).get().context("failed to get connection from pool")?;
match *conn {
let mut conn = ($pool).get().context("failed to get db connection")?;
$crate::connection!(@raw conn {
$(
$crate::DbConnection::$db(ref mut $conn) => $code,
$db($conn) $code;
)*
}
})
}};
}

Expand Down
2 changes: 1 addition & 1 deletion crates/database/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub mod sqlite;

/// All of the custom SQL types
pub mod sql_types {
#[derive(Debug, diesel::QueryId, diesel::SqlType)]
#[derive(Debug, diesel::QueryId, diesel::SqlType, diesel::FromSqlRow)]
#[diesel(postgres_type(name = "chart_type"))]
#[diesel(sqlite_type(name = "Text"))]
pub struct ChartType;
Expand Down
8 changes: 4 additions & 4 deletions crates/database/src/schema/postgresql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ diesel::table! {

user_connections (id) {
noelware_account_id -> Nullable<Int8>,
google_account_id -> Text,
github_account_id -> Text,
apple_account_id -> Text,
google_account_id -> Nullable<Text>,
github_account_id -> Nullable<Text>,
apple_account_id -> Nullable<Text>,
created_at -> Timestamptz,
updated_at -> Timestamptz,
account -> Text,
Expand All @@ -160,7 +160,7 @@ diesel::table! {
gravatar_email -> Nullable<Text>,
#[max_length = 240]
description -> Nullable<Varchar>,
avatar_hash -> Text,
avatar_hash -> Nullable<Text>,
created_at -> Timestamptz,
updated_at -> Timestamptz,
#[max_length = 64]
Expand Down
Loading

0 comments on commit ce5508e

Please sign in to comment.