diff --git a/backend/Dockerfile b/backend/Dockerfile index 92d9c1a..262d52c 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -20,7 +20,7 @@ COPY migrations ./migrations COPY tests ./tests COPY diesel.toml ./ -RUN cargo build --release --bin backend --bin worker --bin webdav +RUN cargo build --release --bin backend --bin worker --bin webdav --bin admin RUN cargo install diesel_cli --no-default-features --features postgres FROM debian:trixie-slim AS runtime @@ -53,6 +53,7 @@ RUN apt-get update \ COPY --from=builder /app/target/release/backend /usr/local/bin/papercrate-backend COPY --from=builder /app/target/release/worker /usr/local/bin/papercrate-worker COPY --from=builder /app/target/release/webdav /usr/local/bin/papercrate-webdav +COPY --from=builder /app/target/release/admin /usr/local/bin/papercrate-admin COPY --from=builder /usr/local/cargo/bin/diesel /usr/local/bin/diesel COPY migrations ./migrations COPY diesel.toml ./ diff --git a/backend/migrations/20240902014000_add_tenant_id/up.sql b/backend/migrations/20240902014000_add_tenant_id/up.sql index b393c92..c757f2b 100644 --- a/backend/migrations/20240902014000_add_tenant_id/up.sql +++ b/backend/migrations/20240902014000_add_tenant_id/up.sql @@ -91,19 +91,15 @@ CREATE INDEX folders_tenant_id_idx ON folders (tenant_id); -- Add tenant_id to users ALTER TABLE users ADD COLUMN tenant_id UUID; -UPDATE users -SET tenant_id = (SELECT tenant_id FROM public.tenants WHERE slug = 'admin'); -ALTER TABLE users ALTER COLUMN tenant_id SET NOT NULL; -ALTER TABLE users - ADD CONSTRAINT users_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenants(tenant_id); -CREATE INDEX users_tenant_id_idx ON users (tenant_id); - -- Add tenant_id to refresh_tokens ALTER TABLE refresh_tokens ADD COLUMN tenant_id UUID; UPDATE refresh_tokens AS rt -SET tenant_id = u.tenant_id -FROM users AS u -WHERE rt.user_id = u.id; +SET tenant_id = ( + SELECT um.tenant_id + FROM user_memberships AS um + WHERE um.user_id = rt.user_id + LIMIT 1 +); ALTER TABLE refresh_tokens ALTER COLUMN tenant_id SET NOT NULL; ALTER TABLE refresh_tokens ADD CONSTRAINT refresh_tokens_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenants(tenant_id); @@ -112,7 +108,12 @@ CREATE INDEX refresh_tokens_tenant_id_idx ON refresh_tokens (tenant_id); -- Add tenant_id to jobs ALTER TABLE jobs ADD COLUMN tenant_id UUID; UPDATE jobs -SET tenant_id = (SELECT tenant_id FROM public.tenants WHERE slug = 'admin'); +SET tenant_id = ( + SELECT um.tenant_id + FROM user_memberships AS um + WHERE um.user_id = jobs.user_id + LIMIT 1 +); ALTER TABLE jobs ALTER COLUMN tenant_id SET NOT NULL; ALTER TABLE jobs ADD CONSTRAINT jobs_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenants(tenant_id); diff --git a/backend/migrations/20240902160000_add_tenant_unique_constraints/down.sql b/backend/migrations/20240902160000_add_tenant_unique_constraints/down.sql new file mode 100644 index 0000000..040cb42 --- /dev/null +++ b/backend/migrations/20240902160000_add_tenant_unique_constraints/down.sql @@ -0,0 +1,2 @@ +DROP INDEX IF EXISTS tenants_quickwit_index_unique; +DROP INDEX IF EXISTS tenants_storage_root_unique; diff --git a/backend/migrations/20240902160000_add_tenant_unique_constraints/up.sql b/backend/migrations/20240902160000_add_tenant_unique_constraints/up.sql new file mode 100644 index 0000000..665f35c --- /dev/null +++ b/backend/migrations/20240902160000_add_tenant_unique_constraints/up.sql @@ -0,0 +1,7 @@ +CREATE UNIQUE INDEX tenants_storage_root_unique + ON public.tenants (storage_root) + WHERE storage_root IS NOT NULL; + +CREATE UNIQUE INDEX tenants_quickwit_index_unique + ON public.tenants (quickwit_index) + WHERE quickwit_index IS NOT NULL; diff --git a/backend/migrations/20240902164000_drop_users_tenant_id/down.sql b/backend/migrations/20240902164000_drop_users_tenant_id/down.sql new file mode 100644 index 0000000..3662792 --- /dev/null +++ b/backend/migrations/20240902164000_drop_users_tenant_id/down.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN tenant_id UUID; diff --git a/backend/migrations/20240902164000_drop_users_tenant_id/up.sql b/backend/migrations/20240902164000_drop_users_tenant_id/up.sql new file mode 100644 index 0000000..b154b4f --- /dev/null +++ b/backend/migrations/20240902164000_drop_users_tenant_id/up.sql @@ -0,0 +1,3 @@ +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_tenant_id_fkey; +DROP INDEX IF EXISTS users_tenant_id_idx; +ALTER TABLE users DROP COLUMN IF EXISTS tenant_id; diff --git a/backend/src/bin/maintenance.rs b/backend/src/bin/admin.rs similarity index 98% rename from backend/src/bin/maintenance.rs rename to backend/src/bin/admin.rs index 1140837..096404f 100644 --- a/backend/src/bin/maintenance.rs +++ b/backend/src/bin/admin.rs @@ -20,7 +20,7 @@ use backend::{ static QUICKWIT_INDEX_TEMPLATE: Lazy = Lazy::new(|| { json!({ - "version": 0.8, + "version": "0.8", "index_id": "documents", "doc_mapping": { "tokenizers": [ @@ -56,7 +56,7 @@ enum Command { impl Command { fn usage() -> &'static str { - "Usage: maintenance |quickwit-create-index |quickwit-delete-index >" + "Usage: admin |quickwit-create-index |quickwit-delete-index >" } fn parse() -> Result { @@ -81,7 +81,7 @@ impl Command { async fn main() -> Result<()> { init_tracing("info"); let command = Command::parse()?; - let config = AppConfig::load_and_log("maintenance")?; + let config = AppConfig::load_and_log("admin")?; let pool = db::init_pool_with_size(&config.database_url, config.database_max_pool_size)?; match command { diff --git a/backend/src/models.rs b/backend/src/models.rs index 0387832..5abdd6a 100644 --- a/backend/src/models.rs +++ b/backend/src/models.rs @@ -48,7 +48,6 @@ pub struct User { pub password_hash: String, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, - pub tenant_id: Uuid, } #[derive(Debug, Insertable)] @@ -57,7 +56,6 @@ pub struct NewUser { pub id: Uuid, pub username: String, pub password_hash: String, - pub tenant_id: Uuid, } #[derive(Debug, Clone, Queryable, Identifiable)] diff --git a/backend/src/schema.rs b/backend/src/schema.rs index 9a6e54e..e492d1a 100644 --- a/backend/src/schema.rs +++ b/backend/src/schema.rs @@ -183,7 +183,6 @@ diesel::table! { password_hash -> Varchar, created_at -> Timestamptz, updated_at -> Timestamptz, - tenant_id -> Uuid, } } @@ -210,7 +209,6 @@ diesel::joinable!(refresh_tokens -> users (user_id)); diesel::joinable!(tags -> tenants (tenant_id)); diesel::joinable!(user_memberships -> tenants (tenant_id)); diesel::joinable!(user_memberships -> users (user_id)); -diesel::joinable!(users -> tenants (tenant_id)); diesel::allow_tables_to_appear_in_same_query!( correspondents, diff --git a/backend/src/state.rs b/backend/src/state.rs index 3dff178..21c1653 100644 --- a/backend/src/state.rs +++ b/backend/src/state.rs @@ -62,12 +62,13 @@ impl AppState { } pub fn db_for_tenant(&self, tenant_id: Uuid) -> AppResult { + debug_assert!(!tenant_id.is_nil(), "nil tenant_id passed to db_for_tenant"); let mut conn = self.db_unscoped()?; apply_tenant_guc(&mut conn, tenant_id)?; Ok(conn) } - pub fn db_unscoped(&self) -> AppResult { + pub(crate) fn db_unscoped(&self) -> AppResult { self.pool .get() .map_err(|err| AppError::internal(format!("database pool error: {err}"))) diff --git a/backend/tests/common/mod.rs b/backend/tests/common/mod.rs index dc1b3fd..8d87919 100644 --- a/backend/tests/common/mod.rs +++ b/backend/tests/common/mod.rs @@ -191,7 +191,6 @@ impl TestApp { id: Uuid::new_v4(), username, password_hash, - tenant_id, }; diesel::insert_into(backend::schema::users::table) .values(&user)