fully migrate "interim" nomenclature to "phonograph"
This commit is contained in:
parent
624bfa2d93
commit
843750ac76
118 changed files with 189 additions and 263 deletions
176
Cargo.lock
generated
176
Cargo.lock
generated
|
|
@ -1750,94 +1750,6 @@ dependencies = [
|
||||||
"hashbrown 0.15.5",
|
"hashbrown 0.15.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "interim-models"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"bigdecimal",
|
|
||||||
"chrono",
|
|
||||||
"derive_builder",
|
|
||||||
"futures",
|
|
||||||
"interim-pgtypes",
|
|
||||||
"redact",
|
|
||||||
"regex",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sqlx",
|
|
||||||
"strum",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"tracing",
|
|
||||||
"url",
|
|
||||||
"uuid",
|
|
||||||
"validator",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "interim-namegen"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"rand 0.8.5",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "interim-pgtypes"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"derive_builder",
|
|
||||||
"nom 8.0.0",
|
|
||||||
"regex",
|
|
||||||
"serde",
|
|
||||||
"sqlx",
|
|
||||||
"strum",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"uuid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "interim-server"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"askama",
|
|
||||||
"async-session",
|
|
||||||
"axum",
|
|
||||||
"axum-extra",
|
|
||||||
"bigdecimal",
|
|
||||||
"chrono",
|
|
||||||
"clap",
|
|
||||||
"config",
|
|
||||||
"derive_builder",
|
|
||||||
"dotenvy",
|
|
||||||
"futures",
|
|
||||||
"headers",
|
|
||||||
"interim-models",
|
|
||||||
"interim-namegen",
|
|
||||||
"interim-pgtypes",
|
|
||||||
"markdown",
|
|
||||||
"oauth2",
|
|
||||||
"percent-encoding",
|
|
||||||
"rand 0.8.5",
|
|
||||||
"redact",
|
|
||||||
"regex",
|
|
||||||
"reqwest 0.12.15",
|
|
||||||
"scraper",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sqlx",
|
|
||||||
"strum",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"tokio",
|
|
||||||
"tower",
|
|
||||||
"tower-http",
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
|
||||||
"url",
|
|
||||||
"uuid",
|
|
||||||
"validator",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.11.0"
|
version = "2.11.0"
|
||||||
|
|
@ -2409,6 +2321,94 @@ dependencies = [
|
||||||
"siphasher",
|
"siphasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phono-backends"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"derive_builder",
|
||||||
|
"nom 8.0.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"sqlx",
|
||||||
|
"strum",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phono-models"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"bigdecimal",
|
||||||
|
"chrono",
|
||||||
|
"derive_builder",
|
||||||
|
"futures",
|
||||||
|
"phono-backends",
|
||||||
|
"redact",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sqlx",
|
||||||
|
"strum",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
"uuid",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phono-namegen"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.8.5",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phono-server"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"askama",
|
||||||
|
"async-session",
|
||||||
|
"axum",
|
||||||
|
"axum-extra",
|
||||||
|
"bigdecimal",
|
||||||
|
"chrono",
|
||||||
|
"clap",
|
||||||
|
"config",
|
||||||
|
"derive_builder",
|
||||||
|
"dotenvy",
|
||||||
|
"futures",
|
||||||
|
"headers",
|
||||||
|
"markdown",
|
||||||
|
"oauth2",
|
||||||
|
"percent-encoding",
|
||||||
|
"phono-backends",
|
||||||
|
"phono-models",
|
||||||
|
"phono-namegen",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"redact",
|
||||||
|
"regex",
|
||||||
|
"reqwest 0.12.15",
|
||||||
|
"scraper",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sqlx",
|
||||||
|
"strum",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-http",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"url",
|
||||||
|
"uuid",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ cargo-features = ["codegen-backend"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["interim-*"]
|
members = ["phono-*"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
@ -14,9 +14,9 @@ bigdecimal = { version = "0.4.9", features = ["serde-json"] }
|
||||||
chrono = { version = "0.4.41", features = ["serde"] }
|
chrono = { version = "0.4.41", features = ["serde"] }
|
||||||
derive_builder = "0.20.2"
|
derive_builder = "0.20.2"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
interim-models = { path = "./interim-models" }
|
phono-backends = { path = "./phono-backends" }
|
||||||
interim-namegen = { path = "./interim-namegen" }
|
phono-models = { path = "./phono-models" }
|
||||||
interim-pgtypes = { path = "./interim-pgtypes" }
|
phono-namegen = { path = "./phono-namegen" }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
redact = { version = "0.1.11", features = ["serde", "zeroize"] }
|
redact = { version = "0.1.11", features = ["serde", "zeroize"] }
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,16 @@ COPY --from=planner /app/recipe.json recipe.json
|
||||||
RUN cargo chef cook --release --recipe-path recipe.json
|
RUN cargo chef cook --release --recipe-path recipe.json
|
||||||
# Build application
|
# Build application
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN cargo build --release --bin interim
|
RUN cargo build --release --bin phonograph
|
||||||
|
|
||||||
# We do not need the Rust toolchain to run the binary!
|
# We do not need the Rust toolchain to run the binary!
|
||||||
FROM debian:bookworm-slim AS runtime
|
FROM debian:bookworm-slim AS runtime
|
||||||
RUN apt-get update && apt-get install -y libpq-dev
|
RUN apt-get update && apt-get install -y libpq-dev
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /app/target/release/interim /usr/local/bin
|
COPY --from=builder /app/target/release/phonograph /usr/local/bin
|
||||||
|
|
||||||
COPY ./css_dist ./css_dist
|
COPY ./css_dist ./css_dist
|
||||||
COPY ./js_dist ./js_dist
|
COPY ./js_dist ./js_dist
|
||||||
COPY ./static ./static
|
COPY ./static ./static
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/interim"]
|
ENTRYPOINT ["/usr/local/bin/phonograph"]
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,3 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- "./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro"
|
- "./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro"
|
||||||
- "./pgdata:/var/lib/postgresql/18/docker"
|
- "./pgdata:/var/lib/postgresql/18/docker"
|
||||||
|
|
||||||
# keycloak:
|
|
||||||
# depends_on: [pg]
|
|
||||||
# restart: always
|
|
||||||
# build:
|
|
||||||
# context: .
|
|
||||||
# dockerfile: keycloak.dockerfile
|
|
||||||
# environment:
|
|
||||||
# KC_DB: postgres
|
|
||||||
# KC_DB_URL: jdbc:postgresql://pg:5432/keycloak
|
|
||||||
# KC_DB_USERNAME: keycloak
|
|
||||||
# KC_DB_PASSWORD: guest
|
|
||||||
# KC_HOSTNAME: 0.0.0.0
|
|
||||||
# KEYCLOAK_ADMIN: admin
|
|
||||||
# KEYCLOAK_ADMIN_PASSWORD: guest
|
|
||||||
# command: [start, --optimized]
|
|
||||||
# ports:
|
|
||||||
# - "127.0.0.1:9000:9000"
|
|
||||||
# - "127.0.0.1:8443:8443"
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
CREATE USER interim_app WITH ENCRYPTED PASSWORD 'guest';
|
|
||||||
CREATE DATABASE interim_app;
|
|
||||||
ALTER DATABASE interim_app OWNER TO interim_app;
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
CREATE USER keycloak WITH ENCRYPTED PASSWORD 'guest';
|
|
||||||
CREATE DATABASE keycloak;
|
|
||||||
ALTER DATABASE keycloak OWNER TO keycloak;
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
FROM quay.io/keycloak/keycloak:26.3.2 as builder
|
|
||||||
|
|
||||||
# Enable health and metrics support
|
|
||||||
ENV KC_HEALTH_ENABLED=true
|
|
||||||
ENV KC_METRICS_ENABLED=true
|
|
||||||
|
|
||||||
# Configure a database vendor
|
|
||||||
ENV KC_DB=postgres
|
|
||||||
|
|
||||||
WORKDIR /opt/keycloak
|
|
||||||
# for demonstration purposes only, please make sure to use proper certificates in production instead
|
|
||||||
RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore
|
|
||||||
RUN /opt/keycloak/bin/kc.sh build
|
|
||||||
|
|
||||||
FROM quay.io/keycloak/keycloak:26.3.2
|
|
||||||
COPY --from=builder /opt/keycloak/ /opt/keycloak/
|
|
||||||
|
|
||||||
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
use askama::Template;
|
|
||||||
use interim_pgtypes::pg_role::{PgRole, RoleTree};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Template)]
|
|
||||||
#[template(path = "role_tree.html")]
|
|
||||||
pub struct RenderableRoleTree {
|
|
||||||
role: PgRole,
|
|
||||||
branches: Vec<RenderableRoleTree>,
|
|
||||||
inherit: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<RoleTree> for RenderableRoleTree {
|
|
||||||
fn from(value: RoleTree) -> Self {
|
|
||||||
Self {
|
|
||||||
role: value.role,
|
|
||||||
branches: value.branches.into_iter().map(Self::from).collect(),
|
|
||||||
inherit: value.inherit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<div class="role-tree {%- if !inherit %} role-tree--no-inherit{% endif -%}">
|
|
||||||
<div class="role-tree__rolname">
|
|
||||||
{{ role.rolname }}
|
|
||||||
</div>
|
|
||||||
{% if !branches.is_empty() %}
|
|
||||||
<ul class="role-tree__branches">
|
|
||||||
{% for branch in branches %}
|
|
||||||
<li class="role-tree__branch">{{ branch.render()? | safe }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "interim-pgtypes"
|
name = "phono-backends"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@ use sqlx::{postgres::types::Oid, prelude::FromRow, query_as};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::client::WorkspaceClient;
|
use crate::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, FromRow, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, FromRow, PartialEq)]
|
||||||
pub struct PgRole {
|
pub struct PgRole {
|
||||||
|
|
@ -356,18 +356,18 @@ fn compute_members(rows: &Vec<RoleTreeRow>, root: Oid) -> Vec<RoleTree> {
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum RolnameParseError {
|
pub enum RolnameParseError {
|
||||||
#[error("rolname does not have interim user prefix")]
|
#[error("rolname does not have phono user prefix")]
|
||||||
MissingPrefix,
|
MissingPrefix,
|
||||||
#[error("unable to parse uuid from rolname: {0}")]
|
#[error("unable to parse uuid from rolname: {0}")]
|
||||||
BadUuid(uuid::Error),
|
BadUuid(uuid::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_id_from_rolname(rolname: &str, role_prefix: &str) -> Result<Uuid, RolnameParseError> {
|
pub fn user_id_from_rolname(rolname: &str) -> Result<Uuid, RolnameParseError> {
|
||||||
if !rolname.starts_with(role_prefix) {
|
if rolname.starts_with(ROLE_PREFIX_USER) {
|
||||||
Err(RolnameParseError::MissingPrefix)
|
|
||||||
} else {
|
|
||||||
let mut rolname = rolname.to_owned();
|
let mut rolname = rolname.to_owned();
|
||||||
rolname.replace_range(0..role_prefix.len(), "");
|
rolname.replace_range(0..ROLE_PREFIX_USER.len(), "");
|
||||||
Uuid::parse_str(&rolname).map_err(RolnameParseError::BadUuid)
|
Uuid::parse_str(&rolname).map_err(RolnameParseError::BadUuid)
|
||||||
|
} else {
|
||||||
|
Err(RolnameParseError::MissingPrefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "interim-models"
|
name = "phono-models"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
|
@ -8,7 +8,7 @@ bigdecimal = { workspace = true }
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
derive_builder = { workspace = true }
|
derive_builder = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
interim-pgtypes = { path = "../interim-pgtypes" }
|
phono-backends = { workspace = true }
|
||||||
redact = { workspace = true }
|
redact = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use interim_pgtypes::{
|
use phono_backends::{
|
||||||
client::WorkspaceClient, pg_acl::PgPrivilegeType, pg_class::PgClass, pg_role::RoleTree,
|
client::WorkspaceClient, pg_acl::PgPrivilegeType, pg_class::PgClass, pg_role::RoleTree,
|
||||||
rolnames::ROLE_PREFIX_USER,
|
rolnames::ROLE_PREFIX_USER,
|
||||||
};
|
};
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use interim_pgtypes::escape_identifier;
|
use phono_backends::escape_identifier;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::datum::Datum;
|
use crate::datum::Datum;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use interim_pgtypes::pg_attribute::PgAttribute;
|
use phono_backends::pg_attribute::PgAttribute;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::Acquire as _;
|
use sqlx::Acquire as _;
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use interim_pgtypes::pg_attribute::PgAttribute;
|
use phono_backends::pg_attribute::PgAttribute;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum::{EnumDiscriminants, EnumIter, EnumString};
|
use strum::{EnumDiscriminants, EnumIter, EnumString};
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use interim_pgtypes::pg_acl::PgPrivilegeType;
|
use phono_backends::pg_acl::PgPrivilegeType;
|
||||||
use sqlx::{postgres::types::Oid, query_as};
|
use sqlx::{postgres::types::Oid, query_as};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "interim-namegen"
|
name = "phono-namegen"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
|
@ -6,12 +6,12 @@
|
||||||
//! ### Basic Usage
|
//! ### Basic Usage
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! let name: String = interim_namegen::default_generator().generate_name(3);
|
//! let name: String = phono_namegen::default_generator().generate_name(3);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use rand::{Rng, rngs::ThreadRng, seq::SliceRandom};
|
use rand::{rngs::ThreadRng, seq::SliceRandom, Rng};
|
||||||
|
|
||||||
// EFF wordlist for random password phrases.
|
// EFF wordlist for random password phrases.
|
||||||
//
|
//
|
||||||
|
|
@ -36,11 +36,13 @@ const WORDLIST_LEN: usize = 7776;
|
||||||
// LazyLock.
|
// LazyLock.
|
||||||
static WORDLIST: LazyLock<[&str; WORDLIST_LEN]> = LazyLock::new(|| {
|
static WORDLIST: LazyLock<[&str; WORDLIST_LEN]> = LazyLock::new(|| {
|
||||||
let mut words = [""; WORDLIST_LEN];
|
let mut words = [""; WORDLIST_LEN];
|
||||||
|
// Embed wordlist file rather than attempt to fetch it from disk at runtime.
|
||||||
for (i, word) in include_str!("./eff_large_wordlist.txt")
|
for (i, word) in include_str!("./eff_large_wordlist.txt")
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
assert!(i <= WORDLIST_LEN); // The wordlist may contain a trailing newline.
|
// The wordlist may contain a trailing newline.
|
||||||
|
assert!(i <= WORDLIST_LEN);
|
||||||
if i < WORDLIST_LEN {
|
if i < WORDLIST_LEN {
|
||||||
words[i] = word;
|
words[i] = word;
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "interim-server"
|
name = "phono-server"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
|
@ -17,12 +17,12 @@ derive_builder = { workspace = true }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
headers = "0.4.1"
|
headers = "0.4.1"
|
||||||
interim-models = { workspace = true }
|
|
||||||
interim-namegen = { workspace = true }
|
|
||||||
interim-pgtypes = { workspace = true }
|
|
||||||
markdown = "1.0.0"
|
markdown = "1.0.0"
|
||||||
oauth2 = "4.4.2"
|
oauth2 = "4.4.2"
|
||||||
percent-encoding = "2.3.1"
|
percent-encoding = "2.3.1"
|
||||||
|
phono-backends = { workspace = true }
|
||||||
|
phono-models = { workspace = true }
|
||||||
|
phono-namegen = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
redact = { workspace = true }
|
redact = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
|
|
@ -3,8 +3,8 @@ use axum::{
|
||||||
extract::{FromRef, FromRequestParts},
|
extract::{FromRef, FromRequestParts},
|
||||||
http::request::Parts,
|
http::request::Parts,
|
||||||
};
|
};
|
||||||
use interim_models::client::AppDbClient;
|
|
||||||
use oauth2::basic::BasicClient;
|
use oauth2::basic::BasicClient;
|
||||||
|
use phono_models::client::AppDbClient;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use interim_models::{field::Field, language::Language};
|
use phono_models::{field::Field, language::Language};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser as _;
|
use clap::Parser as _;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use interim_models::MIGRATOR;
|
use phono_models::MIGRATOR;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -19,7 +19,6 @@ mod field_info;
|
||||||
mod middleware;
|
mod middleware;
|
||||||
mod navigator;
|
mod navigator;
|
||||||
mod presentation_form;
|
mod presentation_form;
|
||||||
mod renderable_role_tree;
|
|
||||||
mod roles;
|
mod roles;
|
||||||
mod routes;
|
mod routes;
|
||||||
mod sessions;
|
mod sessions;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::iter::zip;
|
use std::iter::zip;
|
||||||
|
|
||||||
use interim_models::presentation::{
|
use phono_models::presentation::{
|
||||||
DropdownOption, Presentation, PresentationDiscriminants, RFC_3339_S, TextInputMode,
|
DropdownOption, Presentation, PresentationDiscriminants, RFC_3339_S, TextInputMode,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use interim_pgtypes::{
|
use phono_backends::{
|
||||||
client::WorkspaceClient,
|
client::WorkspaceClient,
|
||||||
pg_acl::{PgAclItem, PgPrivilegeType},
|
pg_acl::{PgAclItem, PgPrivilegeType},
|
||||||
pg_class::PgClass,
|
pg_class::PgClass,
|
||||||
|
|
@ -105,7 +105,7 @@ impl RoleDisplay {
|
||||||
oid: Oid,
|
oid: Oid,
|
||||||
relname: String,
|
relname: String,
|
||||||
}
|
}
|
||||||
// TODO: Consider moving this to [`interim-pgtypes`].
|
// TODO: Consider moving this to [`phono_backends`].
|
||||||
let mut rels: Vec<RelInfo> = query_as(
|
let mut rels: Vec<RelInfo> = query_as(
|
||||||
r#"
|
r#"
|
||||||
select oid, any_value(relname) as relname
|
select oid, any_value(relname) as relname
|
||||||
|
|
@ -5,14 +5,14 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse as _, Response},
|
response::{Html, IntoResponse as _, Response},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::pg_attribute::PgAttribute;
|
||||||
|
use phono_models::{
|
||||||
field::Field,
|
field::Field,
|
||||||
field_form_prompt::FieldFormPrompt,
|
field_form_prompt::FieldFormPrompt,
|
||||||
language::Language,
|
language::Language,
|
||||||
portal::Portal,
|
portal::Portal,
|
||||||
presentation::{Presentation, TextInputMode},
|
presentation::{Presentation, TextInputMode},
|
||||||
};
|
};
|
||||||
use interim_pgtypes::pg_attribute::PgAttribute;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -6,12 +6,12 @@ use axum::{
|
||||||
// [`axum_extra`]'s form extractor is preferred:
|
// [`axum_extra`]'s form extractor is preferred:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::{
|
use phono_backends::{escape_identifier, pg_class::PgClass};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
||||||
field::Field,
|
field::Field,
|
||||||
presentation::Presentation,
|
presentation::Presentation,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::{postgres::types::Oid, query};
|
use sqlx::{postgres::types::Oid, query};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use axum::{extract::Path, response::IntoResponse};
|
use axum::{extract::Path, response::IntoResponse};
|
||||||
use interim_models::portal::Portal;
|
use phono_models::portal::Portal;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -6,7 +6,8 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::pg_attribute::PgAttribute;
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
||||||
field::Field,
|
field::Field,
|
||||||
field_form_prompt::FieldFormPrompt,
|
field_form_prompt::FieldFormPrompt,
|
||||||
|
|
@ -15,7 +16,6 @@ use interim_models::{
|
||||||
portal::Portal,
|
portal::Portal,
|
||||||
workspace::Workspace,
|
workspace::Workspace,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::pg_attribute::PgAttribute;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use strum::IntoEnumIterator as _;
|
use strum::IntoEnumIterator as _;
|
||||||
|
|
@ -5,14 +5,14 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{IntoResponse as _, Response},
|
response::{IntoResponse as _, Response},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::{
|
||||||
|
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
|
||||||
|
};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
datum::Datum,
|
datum::Datum,
|
||||||
field::Field,
|
field::Field,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{
|
|
||||||
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
postgres::{PgRow, types::Oid},
|
postgres::{PgRow, types::Oid},
|
||||||
|
|
@ -8,11 +8,11 @@ use axum::{
|
||||||
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::{
|
use phono_backends::{escape_identifier, pg_acl::PgPrivilegeType, pg_class::PgClass};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
accessors::{Accessor as _, Actor, portal::PortalAccessor},
|
||||||
datum::Datum,
|
datum::Datum,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{escape_identifier, pg_acl::PgPrivilegeType, pg_class::PgClass};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::{postgres::types::Oid, query};
|
use sqlx::{postgres::types::Oid, query};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -3,12 +3,12 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse as _, Response},
|
response::{Html, IntoResponse as _, Response},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::{pg_acl::PgPrivilegeType, pg_attribute::PgAttribute};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
expression::PgExpressionAny,
|
expression::PgExpressionAny,
|
||||||
workspace::Workspace,
|
workspace::Workspace,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{pg_acl::PgPrivilegeType, pg_attribute::PgAttribute};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
portal::Portal,
|
portal::Portal,
|
||||||
workspace::Workspace,
|
workspace::Workspace,
|
||||||
|
|
@ -3,11 +3,11 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::Response,
|
response::Response,
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::{escape_identifier, pg_class::PgClass};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
field::Field,
|
field::Field,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::{postgres::types::Oid, query};
|
use sqlx::{postgres::types::Oid, query};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -6,7 +6,7 @@ use axum::{
|
||||||
// [`axum_extra`]'s form extractor is preferred:
|
// [`axum_extra`]'s form extractor is preferred:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::{
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
expression::PgExpressionAny,
|
expression::PgExpressionAny,
|
||||||
portal::Portal,
|
portal::Portal,
|
||||||
|
|
@ -4,8 +4,8 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::workspace::Workspace;
|
use phono_backends::pg_class::PgClass;
|
||||||
use interim_pgtypes::pg_class::PgClass;
|
use phono_models::workspace::Workspace;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -2,8 +2,8 @@ use axum::{debug_handler, extract::Path, response::Response};
|
||||||
// [`axum_extra`]'s form extractor is preferred:
|
// [`axum_extra`]'s form extractor is preferred:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::rel_invitation::RelInvitation;
|
use phono_backends::pg_acl::PgPrivilegeType;
|
||||||
use interim_pgtypes::pg_acl::PgPrivilegeType;
|
use phono_models::rel_invitation::RelInvitation;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use axum::{debug_handler, extract::Path, response::Response};
|
use axum::{debug_handler, extract::Path, response::Response};
|
||||||
use interim_models::{field::Field, presentation::Presentation};
|
use phono_models::{field::Field, presentation::Presentation};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use axum::{debug_handler, extract::Path, response::Response};
|
use axum::{debug_handler, extract::Path, response::Response};
|
||||||
use interim_models::field::Field;
|
use phono_models::field::Field;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::{debug_handler, extract::Path, response::Response};
|
||||||
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::form_transition::{self, FormTransition};
|
use phono_models::form_transition::{self, FormTransition};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -3,7 +3,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::Response,
|
response::Response,
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
portal::{Portal, RE_PORTAL_NAME},
|
portal::{Portal, RE_PORTAL_NAME},
|
||||||
};
|
};
|
||||||
|
|
@ -8,7 +8,7 @@ use axum::{
|
||||||
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
// [`axum_extra`]'s form extractor is required to support repeated keys:
|
||||||
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use interim_models::{
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
field::Field,
|
field::Field,
|
||||||
field_form_prompt::FieldFormPrompt,
|
field_form_prompt::FieldFormPrompt,
|
||||||
|
|
@ -5,7 +5,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::Response,
|
response::Response,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
|
use phono_backends::{escape_identifier, pg_class::PgClass};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::{postgres::types::Oid, query};
|
use sqlx::{postgres::types::Oid, query};
|
||||||
|
|
@ -64,7 +64,7 @@ pub(super) async fn post(
|
||||||
.await?;
|
.await?;
|
||||||
// FIXME ensure that user has ownership of the table.
|
// FIXME ensure that user has ownership of the table.
|
||||||
|
|
||||||
// TODO: move this to a function in `interim-pgtypes`.
|
// TODO: move this to a function in `phono_backends`.
|
||||||
query(&format!(
|
query(&format!(
|
||||||
"alter table {ident} rename to {name_esc}",
|
"alter table {ident} rename to {name_esc}",
|
||||||
ident = rel.get_identifier(),
|
ident = rel.get_identifier(),
|
||||||
|
|
@ -5,13 +5,13 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{IntoResponse as _, Response},
|
response::{IntoResponse as _, Response},
|
||||||
};
|
};
|
||||||
use interim_models::{
|
use phono_backends::{
|
||||||
|
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
|
||||||
|
};
|
||||||
|
use phono_models::{
|
||||||
accessors::{Accessor, Actor, portal::PortalAccessor},
|
accessors::{Accessor, Actor, portal::PortalAccessor},
|
||||||
datum::Datum,
|
datum::Datum,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{
|
|
||||||
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlx::{Acquire as _, postgres::types::Oid, query};
|
use sqlx::{Acquire as _, postgres::types::Oid, query};
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use axum::{extract::State, response::IntoResponse};
|
use axum::{extract::State, response::IntoResponse};
|
||||||
use interim_models::{
|
use phono_backends::{client::WorkspaceClient, escape_identifier, rolnames::ROLE_PREFIX_USER};
|
||||||
|
use phono_models::{
|
||||||
client::AppDbClient, cluster::Cluster, user::User, workspace::Workspace,
|
client::AppDbClient, cluster::Cluster, user::User, workspace::Workspace,
|
||||||
workspace_user_perm::WorkspaceMembership,
|
workspace_user_perm::WorkspaceMembership,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{client::WorkspaceClient, escape_identifier, rolnames::ROLE_PREFIX_USER};
|
|
||||||
use sqlx::{Connection as _, PgConnection, query};
|
use sqlx::{Connection as _, PgConnection, query};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -33,7 +33,7 @@ pub(super) async fn post(
|
||||||
// WARNING: `db_name` is injected directly into the `create database` SQL
|
// WARNING: `db_name` is injected directly into the `create database` SQL
|
||||||
// command. It **must not** contain spaces or any other unsafe characters.
|
// command. It **must not** contain spaces or any other unsafe characters.
|
||||||
// Additionally, it **must** be URL safe without percent encoding.
|
// Additionally, it **must** be URL safe without percent encoding.
|
||||||
let db_name = interim_namegen::default_generator()
|
let db_name = phono_namegen::default_generator()
|
||||||
.with_separator('_')
|
.with_separator('_')
|
||||||
.generate_name(NAME_LEN_WORDS);
|
.generate_name(NAME_LEN_WORDS);
|
||||||
{
|
{
|
||||||
|
|
@ -3,7 +3,7 @@ use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::workspace_user_perm::WorkspaceMembership;
|
use phono_models::workspace_user_perm::WorkspaceMembership;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::AppDbConn,
|
app::AppDbConn,
|
||||||
|
|
@ -3,11 +3,11 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use interim_models::{service_cred::ServiceCred, workspace::Workspace};
|
use phono_backends::{
|
||||||
use interim_pgtypes::{
|
|
||||||
escape_identifier,
|
escape_identifier,
|
||||||
rolnames::{ROLE_PREFIX_SERVICE_CRED, SERVICE_CRED_CONN_LIMIT, SERVICE_CRED_SUFFIX_LEN},
|
rolnames::{ROLE_PREFIX_SERVICE_CRED, SERVICE_CRED_CONN_LIMIT, SERVICE_CRED_SUFFIX_LEN},
|
||||||
};
|
};
|
||||||
|
use phono_models::{service_cred::ServiceCred, workspace::Workspace};
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
use redact::Secret;
|
use redact::Secret;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
@ -2,7 +2,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use interim_pgtypes::{
|
use phono_backends::{
|
||||||
escape_identifier,
|
escape_identifier,
|
||||||
rolnames::{
|
rolnames::{
|
||||||
ROLE_PREFIX_TABLE_OWNER, ROLE_PREFIX_TABLE_READER, ROLE_PREFIX_TABLE_WRITER,
|
ROLE_PREFIX_TABLE_OWNER, ROLE_PREFIX_TABLE_READER, ROLE_PREFIX_TABLE_WRITER,
|
||||||
|
|
@ -42,7 +42,7 @@ pub(super) async fn post(
|
||||||
// FIXME: CSRF, Check workspace authorization.
|
// FIXME: CSRF, Check workspace authorization.
|
||||||
|
|
||||||
const NAME_LEN_WORDS: usize = 3;
|
const NAME_LEN_WORDS: usize = 3;
|
||||||
let table_name = interim_namegen::default_generator()
|
let table_name = phono_namegen::default_generator()
|
||||||
.with_separator('_')
|
.with_separator('_')
|
||||||
.generate_name(NAME_LEN_WORDS);
|
.generate_name(NAME_LEN_WORDS);
|
||||||
|
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::workspace::Workspace;
|
use phono_models::workspace::Workspace;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -6,8 +6,8 @@ use axum::{
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use futures::{lock::Mutex, prelude::*, stream};
|
use futures::{lock::Mutex, prelude::*, stream};
|
||||||
use interim_models::{service_cred::ServiceCred, workspace::Workspace};
|
use phono_backends::{pg_class::PgClass, pg_role::RoleTree};
|
||||||
use interim_pgtypes::{pg_class::PgClass, pg_role::RoleTree};
|
use phono_models::{service_cred::ServiceCred, workspace::Workspace};
|
||||||
use redact::Secret;
|
use redact::Secret;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
};
|
};
|
||||||
use interim_models::workspace::Workspace;
|
use phono_models::workspace::Workspace;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -7,8 +7,8 @@ use axum::{
|
||||||
};
|
};
|
||||||
use axum_extra::extract::Form;
|
use axum_extra::extract::Form;
|
||||||
use futures::{lock::Mutex, prelude::*, stream};
|
use futures::{lock::Mutex, prelude::*, stream};
|
||||||
use interim_models::service_cred::ServiceCred;
|
use phono_backends::{escape_identifier, pg_class::PgClass};
|
||||||
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
|
use phono_models::service_cred::ServiceCred;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::query;
|
use sqlx::query;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -22,7 +22,7 @@ pub(crate) struct Settings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) dev: u8,
|
pub(crate) dev: u8,
|
||||||
|
|
||||||
/// postgresql:// URL for Interim's application database.
|
/// postgresql:// URL for Phonograph's application database.
|
||||||
pub(crate) database_url: Url,
|
pub(crate) database_url: Url,
|
||||||
|
|
||||||
#[serde(default = "default_app_db_max_connections")]
|
#[serde(default = "default_app_db_max_connections")]
|
||||||
|
|
@ -11,7 +11,7 @@ use axum_extra::extract::{
|
||||||
CookieJar,
|
CookieJar,
|
||||||
cookie::{Cookie, SameSite},
|
cookie::{Cookie, SameSite},
|
||||||
};
|
};
|
||||||
use interim_models::user::User;
|
use phono_models::user::User;
|
||||||
use sqlx::query_as;
|
use sqlx::query_as;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use interim_models::{client::AppDbClient, workspace::Workspace};
|
use phono_backends::client::WorkspaceClient;
|
||||||
use interim_pgtypes::client::WorkspaceClient;
|
use phono_models::{client::AppDbClient, workspace::Workspace};
|
||||||
use sqlx::postgres::types::Oid;
|
use sqlx::postgres::types::Oid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
@ -3,8 +3,8 @@ use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use axum::extract::FromRef;
|
use axum::extract::FromRef;
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use interim_models::{client::AppDbClient, workspace::Workspace};
|
use phono_backends::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER};
|
||||||
use interim_pgtypes::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER};
|
use phono_models::{client::AppDbClient, workspace::Workspace};
|
||||||
use sqlx::{Executor, PgPool, postgres::PgPoolOptions, raw_sql};
|
use sqlx::{Executor, PgPool, postgres::PgPoolOptions, raw_sql};
|
||||||
use tokio::sync::{OnceCell, RwLock};
|
use tokio::sync::{OnceCell, RwLock};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -91,10 +91,10 @@ discard sequences;
|
||||||
/// should **NEVER** execute untrusted SQL.
|
/// should **NEVER** execute untrusted SQL.
|
||||||
pub async fn acquire_for(
|
pub async fn acquire_for(
|
||||||
&mut self,
|
&mut self,
|
||||||
base_id: Uuid,
|
workspace_id: Uuid,
|
||||||
set_role: RoleAssignment,
|
set_role: RoleAssignment,
|
||||||
) -> Result<WorkspaceClient> {
|
) -> Result<WorkspaceClient> {
|
||||||
let pool = self.get_pool_for(base_id).await?;
|
let pool = self.get_pool_for(workspace_id).await?;
|
||||||
let mut client = WorkspaceClient::from_pool_conn(pool.acquire().await?);
|
let mut client = WorkspaceClient::from_pool_conn(pool.acquire().await?);
|
||||||
match set_role {
|
match set_role {
|
||||||
RoleAssignment::User(uid) => {
|
RoleAssignment::User(uid) => {
|
||||||
|
|
@ -107,15 +107,15 @@ discard sequences;
|
||||||
Ok(client)
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn close_for(&mut self, base_id: Uuid) -> Result<()> {
|
pub async fn close_for(&mut self, workspace_id: Uuid) -> Result<()> {
|
||||||
let pools = self.pools.read().await;
|
let pools = self.pools.read().await;
|
||||||
if let Some(cell) = pools.get(&base_id)
|
if let Some(cell) = pools.get(&workspace_id)
|
||||||
&& let Some(pool) = cell.get()
|
&& let Some(pool) = cell.get()
|
||||||
{
|
{
|
||||||
let pool = pool.clone();
|
let pool = pool.clone();
|
||||||
drop(pools); // Release read lock
|
drop(pools); // Release read lock
|
||||||
let mut pools = self.pools.write().await;
|
let mut pools = self.pools.write().await;
|
||||||
pools.remove(&base_id);
|
pools.remove(&workspace_id);
|
||||||
drop(pools); // Release write lock
|
drop(pools); // Release write lock
|
||||||
pool.close().await;
|
pool.close().await;
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
//! This module is named with the `_utils` suffix to help differentiate it from
|
//! This module is named with the `_utils` suffix to help differentiate it from
|
||||||
//! the [`interim_models::workspace`] module, which is also used extensively
|
//! the [`phono_models::workspace`] module, which is also used extensively
|
||||||
//! across the server code.
|
//! across the server code.
|
||||||
|
|
||||||
use interim_models::{client::AppDbClient, portal::Portal};
|
use phono_backends::{
|
||||||
use interim_pgtypes::{
|
|
||||||
client::WorkspaceClient,
|
client::WorkspaceClient,
|
||||||
pg_class::{PgClass, PgRelKind},
|
pg_class::{PgClass, PgRelKind},
|
||||||
};
|
};
|
||||||
|
use phono_models::{client::AppDbClient, portal::Portal};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub const PHONO_TABLE_NAMESPACE: &str = "phono";
|
pub const PHONO_TABLE_NAMESPACE: &str = "phono";
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue