Skip to content

Commit

Permalink
Feat: make dev script for easy development
Browse files Browse the repository at this point in the history
Feat: Register page
Feat: First-time setup registration
Fix: Unify Back arrow button
  • Loading branch information
TobiasDeBruijn committed Dec 29, 2024
1 parent 8363604 commit e4493e0
Show file tree
Hide file tree
Showing 32 changed files with 660 additions and 288 deletions.
41 changes: 40 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
all: help
.SILENT:

SHELL := /bin/bash

.PHONY: help
help:
echo "Wilford OAuth2 Server"
Expand All @@ -20,14 +22,51 @@ test_oidc_key.pem.pub: test_oidc_key.pem
config.json: sample_config.json
cp sample_config.json config.json

config_docker.json: sample_config_docker.json
cp sample_config_docker.json config_docker.json


.PHONY: up
up: test_oidc_key.pem test_oidc_key.pem.pub config.json
up: test_oidc_key.pem test_oidc_key.pem.pub config_docker.json
docker compose up -d
echo "Wilford UI available at http://localhost:2522"
echo "Wilford Docs available at http://localhost:2523"
echo "EspoCRM UI availabel at http://localhost:2524"
echo "If this is the first run, please configure EspoCRM and Wilford."

.PHONY: dev
dev: test_oidc_key.pem test_oidc_key.pem.pub config.json ui/node_modules
# Database
docker compose up -d mariadb-wilford
echo "Waiting for Database to start..."
#sleep 5

# Server
echo "Starting server"

cd server && \
RUST_LOG=INFO,wilford=TRACE \
CONFIG_PATH=$(shell pwd)/config.json \
cargo run -p wilford & \
export SERVER_PID=$$!;

# Start UI
echo "Starting frontend"
cd ui && yarn run dev --clearScreen false & \
export UI_PID=$$!;

# Wait until user does Ctrl+C
sleep 2
echo "Server and UI running. Ctrl+C to exit"
read -r -d '' _ </dev/tty

# Kill UI and server
echo "Killing programs"
kill $(SERVER_PID)
kill $(UI_PID)
ui/node_modules: ui/package.json ui/yarn.lock
cd ui && yarn

.PHONY: upload-all
upload-all: upload-server upload-docs upload-ui

Expand Down
21 changes: 21 additions & 0 deletions config_docker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"http": {
"ui_login_path": "http://localhost:2522/login",
"authorization_endpoint": "http://localhost:2521/api/oauth/authorize",
"token_endpoint": "http://localhost:2521/api/oauth/token",
"jwks_uri_endpoint": "https://localhost:2521/.well-known/jwks.json"
},
"database": {
"user": "wilford",
"password": "wilford",
"host": "mariadb-wilford",
"database": "wilford"
},
"authorization_provider": "Local",
"default_client": {
"redirect_uri": "http://localhost:2522/login-ok"
},
"oidc_signing_key": "/test_oidc_key.pem",
"oidc_public_key": "/test_oidc_key.pem.pub",
"oidc_issuer": "http://localhost:2521"
}
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
- "CONFIG_PATH=/config.json"
- "RUST_LOG=DEBUG"
volumes:
- "./config.json:/config.json"
- "./config_docker.json:/config.json"
- "./test_oidc_key.pem:/test_oidc_key.pem"
- "./test_oidc_key.pem.pub:/test_oidc_key.pem.pub"
depends_on:
Expand Down
1 change: 0 additions & 1 deletion nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ server {
proxy_pass https://google.com;
}


location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
Expand Down
16 changes: 6 additions & 10 deletions sample_config.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
{
"http": {
"ui_login_path": "http://localhost:2522/login",
"ui_login_path": "http://localhost:3000/login",
"authorization_endpoint": "http://localhost:2521/api/oauth/authorize",
"token_endpoint": "http://localhost:2521/api/oauth/token",
"jwks_uri_endpoint": "https://localhost:2521/.well-known/jwks.json"
},
"database": {
"user": "wilford",
"password": "wilford",
"host": "mariadb-wilford",
"host": "localhost",
"database": "wilford"
},
"espo": {
"host": "http://espocrm",
"api_key": "",
"secret_key": ""
},
"authorization_provider": "Local",
"default_client": {
"redirect_uri": "http://localhost:2522/login-ok"
"redirect_uri": "http://localhost:3000/login-ok"
},
"oidc_signing_key": "/test_oidc_key.pem",
"oidc_public_key": "/test_oidc_key.pem.pub",
"oidc_signing_key": "../test_oidc_key.pem",
"oidc_public_key": "../test_oidc_key.pem.pub",
"oidc_issuer": "http://localhost:2521"
}
21 changes: 21 additions & 0 deletions sample_config_docker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"http": {
"ui_login_path": "http://localhost:2522/login",
"authorization_endpoint": "http://localhost:2521/api/oauth/authorize",
"token_endpoint": "http://localhost:2521/api/oauth/token",
"jwks_uri_endpoint": "https://localhost:2521/.well-known/jwks.json"
},
"database": {
"user": "wilford",
"password": "wilford",
"host": "mariadb-wilford",
"database": "wilford"
},
"authorization_provider": "Local",
"default_client": {
"redirect_uri": "http://localhost:2522/login-ok"
},
"oidc_signing_key": "/test_oidc_key.pem",
"oidc_public_key": "/test_oidc_key.pem.pub",
"oidc_issuer": "http://localhost:2521"
}
8 changes: 7 additions & 1 deletion server/database/src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ impl User {
.await?)
}

pub async fn count(driver: &Database) -> Result<i64> {
Ok(sqlx::query_scalar("SELECT COUNT(1) FROM users")
.fetch_one(&**driver)
.await?)
}

#[instrument]
pub async fn list(driver: &Database) -> Result<Vec<Self>> {
Ok(sqlx::query_as("SELECT * FROM users")
Expand Down Expand Up @@ -125,8 +131,8 @@ impl User {
.await?;
} else {
sqlx::query("INSERT INTO user_credentials (user_id, password_hash) VALUES (?, ?)")
.bind(password.as_ref())
.bind(&self.user_id)
.bind(password.as_ref())
.execute(&**driver)
.await?;
}
Expand Down
10 changes: 6 additions & 4 deletions server/wilford/src/authorization/combined.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
use crate::authorization::espo::{EspoAuthorizationProvider, EspoAuthorizationProviderError};
use crate::authorization::local_provider::{
LocalCredentialsProvider, LocalCredentialsProviderError,
LocalAuthorizationProvider, LocalAuthorizationProviderError,
};
use crate::authorization::{AuthorizationError, AuthorizationProvider, UserInformation};
use crate::config::{AuthorizationProviderType, Config};
use database::driver::Database;
use espocrm_rs::EspoApiClient;
use std::fmt::Debug;
use thiserror::Error;
use tracing::instrument;

#[derive(Debug, Error)]
pub enum CombinedAuthorizationProviderError {
#[error(transparent)]
Local(#[from] LocalCredentialsProviderError),
Local(#[from] LocalAuthorizationProviderError),
#[error(transparent)]
EspoCrm(#[from] EspoAuthorizationProviderError),
}

/// Abstraction over all the different authorization providers,
/// providing a single object to work with.
pub enum CombinedAuthorizationProvider<'a> {
Local(LocalCredentialsProvider<'a>),
Local(LocalAuthorizationProvider<'a>),
EspoCrm(EspoAuthorizationProvider<'a>),
}

Expand All @@ -35,7 +36,7 @@ impl<'a> CombinedAuthorizationProvider<'a> {
pub fn new(config: &'a Config, database: &'a Database) -> Self {
match config.authorization_provider {
AuthorizationProviderType::Local => {
Self::Local(LocalCredentialsProvider::new(database))
Self::Local(LocalAuthorizationProvider::new(database))
}
AuthorizationProviderType::EspoCrm => {
if let Some(espo_config) = &config.espo {
Expand Down Expand Up @@ -110,6 +111,7 @@ impl<'a> AuthorizationProvider for CombinedAuthorizationProvider<'a> {
}
}

#[instrument(skip(self, email, password))]
async fn register_user(
&self,
name: &str,
Expand Down
1 change: 1 addition & 0 deletions server/wilford/src/authorization/espo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use espocrm_rs::EspoApiClient;
use thiserror::Error;
use tracing::instrument;

/// Authorization provider utilizing EspoCRM as it's credentials validator and user database.
#[derive(Debug)]
pub struct EspoAuthorizationProvider<'a> {
database_driver: &'a Database,
Expand Down
16 changes: 8 additions & 8 deletions server/wilford/src/authorization/local_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ use thiserror::Error;
use tracing::{instrument, warn};

/// Credential provider utilizing the local database
pub struct LocalCredentialsProvider<'a> {
pub struct LocalAuthorizationProvider<'a> {
driver: &'a Database,
}

#[derive(Debug, Error)]
pub enum LocalCredentialsProviderError {
pub enum LocalAuthorizationProviderError {
#[error(transparent)]
Database(#[from] database::driver::Error),
#[error(transparent)]
Hashing(#[from] bcrypt::BcryptError),
}

impl<'a> LocalCredentialsProvider<'a> {
/// Create a new local credentials provider.
impl<'a> LocalAuthorizationProvider<'a> {
/// Create a new provider.
pub fn new(driver: &'a Database) -> Self {
Self { driver }
}
}

impl<'a> AuthorizationProvider for LocalCredentialsProvider<'a> {
type Error = LocalCredentialsProviderError;
impl<'a> AuthorizationProvider for LocalAuthorizationProvider<'a> {
type Error = LocalAuthorizationProviderError;

#[instrument(skip(self, password))]
async fn validate_credentials(
Expand Down Expand Up @@ -148,13 +148,13 @@ impl<'a> AuthorizationProvider for LocalCredentialsProvider<'a> {
///
/// # Errors
/// If hashing fails
fn hash_password(password: &str) -> Result<String, LocalCredentialsProviderError> {
fn hash_password(password: &str) -> Result<String, LocalAuthorizationProviderError> {
// We are explicit with the format wanted, thus we use `hash_with_result`, rather than
// `hash`. Although at the moment this block is identical to bcrypt's `hash` function,
// this could change in the future. That would result in some rather annoying
// differences in the way we hash.
hash_with_result(password, bcrypt::DEFAULT_COST)
.map_err(|e| LocalCredentialsProviderError::from(e))
.map_err(|e| LocalAuthorizationProviderError::from(e))
.map(|parts| parts.format_for_version(Version::TwoB))
}

Expand Down
11 changes: 9 additions & 2 deletions server/wilford/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::Deserialize;
use std::path::{Path, PathBuf};
use tokio::fs;
use tokio::io::AsyncReadExt;
use tracing::trace;

#[derive(Debug, Deserialize)]
struct EnvConfig {
Expand Down Expand Up @@ -99,6 +100,8 @@ impl EnvConfig {

impl Config {
async fn open(path: &Path) -> Result<Self> {
trace!("Opening config from {path:?}");

let mut f = fs::File::open(path).await?;
let mut buf = Vec::new();
f.read_to_end(&mut buf).await?;
Expand All @@ -107,11 +110,15 @@ impl Config {
}

pub async fn read_oidc_signing_key(&self) -> Result<String> {
Self::read_pem(&self.oidc_signing_key).await
let absolute = self.oidc_signing_key.canonicalize()?;
trace!("Reading OIDC signing key from {absolute:?}");
Self::read_pem(&absolute).await
}

pub async fn read_oidc_public_key(&self) -> Result<String> {
Self::file_read_string(&self.oidc_public_key).await
let absolute = self.oidc_public_key.canonicalize()?;
trace!("Reading OIDC public key from {absolute:?}");
Self::file_read_string(&absolute).await
}

async fn read_pem(p: &Path) -> Result<String> {
Expand Down
Loading

0 comments on commit e4493e0

Please sign in to comment.