Skip to content

Commit b39d576

Browse files
committed
Filter all DB queries by user_id
- Initialize user_id on DbBackend construction - Add user_id filtering to all list/get/create/update/delete queries - Ensures unique (user_id, name) constraints are respected - Resources are now properly scoped to the cli-admin user
1 parent a91bfcc commit b39d576

2 files changed

Lines changed: 54 additions & 57 deletions

File tree

src/backend/db.rs

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ use zip::ZipArchive;
1212

1313
pub struct DbBackend {
1414
pool: PgPool,
15+
user_id: uuid::Uuid,
1516
}
1617

1718
impl DbBackend {
18-
pub fn new(pool: PgPool) -> Self {
19-
Self { pool }
20-
}
21-
22-
async fn get_or_create_admin_user(&self) -> Result<uuid::Uuid, BackendError> {
19+
pub async fn new(pool: PgPool) -> Result<Self, BackendError> {
20+
// Get or create admin user on initialization
2321
let user_id: uuid::Uuid = sqlx::query_scalar(
2422
r#"
2523
INSERT INTO users (id, username, created_at, updated_at)
@@ -28,10 +26,10 @@ impl DbBackend {
2826
RETURNING id
2927
"#,
3028
)
31-
.fetch_one(&self.pool)
29+
.fetch_one(&pool)
3230
.await?;
3331

34-
Ok(user_id)
32+
Ok(Self { pool, user_id })
3533
}
3634

3735
async fn get_environment_values(
@@ -70,9 +68,11 @@ impl Backend for DbBackend {
7068
r#"
7169
SELECT id, name, "desc", current_version, created_at, updated_at
7270
FROM workers
71+
WHERE user_id = $1
7372
ORDER BY name
7473
"#,
7574
)
75+
.bind(self.user_id)
7676
.fetch_all(&self.pool)
7777
.await?;
7878

@@ -96,10 +96,11 @@ impl Backend for DbBackend {
9696
r#"
9797
SELECT id, name, "desc", current_version, created_at, updated_at
9898
FROM workers
99-
WHERE name = $1
99+
WHERE name = $1 AND user_id = $2
100100
"#,
101101
)
102102
.bind(name)
103+
.bind(self.user_id)
103104
.fetch_optional(&self.pool)
104105
.await?
105106
.ok_or_else(|| BackendError::NotFound(format!("Worker '{}' not found", name)))?;
@@ -115,19 +116,6 @@ impl Backend for DbBackend {
115116
}
116117

117118
async fn create_worker(&self, input: CreateWorkerInput) -> Result<Worker, BackendError> {
118-
// For CLI/admin mode, we need a user_id
119-
// For now, get or create an "admin" user
120-
let user_id: uuid::Uuid = sqlx::query_scalar(
121-
r#"
122-
INSERT INTO users (id, username, created_at, updated_at)
123-
VALUES (gen_random_uuid(), 'cli-admin', now(), now())
124-
ON CONFLICT (username) DO UPDATE SET username = users.username
125-
RETURNING id
126-
"#,
127-
)
128-
.fetch_one(&self.pool)
129-
.await?;
130-
131119
let row = sqlx::query(
132120
r#"
133121
INSERT INTO workers (name, "desc", user_id)
@@ -137,7 +125,7 @@ impl Backend for DbBackend {
137125
)
138126
.bind(&input.name)
139127
.bind(&input.description)
140-
.bind(user_id)
128+
.bind(self.user_id)
141129
.fetch_one(&self.pool)
142130
.await?;
143131

@@ -154,8 +142,9 @@ impl Backend for DbBackend {
154142
}
155143

156144
async fn delete_worker(&self, name: &str) -> Result<(), BackendError> {
157-
let result = sqlx::query("DELETE FROM workers WHERE name = $1")
145+
let result = sqlx::query("DELETE FROM workers WHERE name = $1 AND user_id = $2")
158146
.bind(name)
147+
.bind(self.user_id)
159148
.execute(&self.pool)
160149
.await?;
161150

@@ -181,13 +170,16 @@ impl Backend for DbBackend {
181170
Some(uuid)
182171
} else {
183172
Some(
184-
sqlx::query_scalar("SELECT id FROM environments WHERE name = $1")
185-
.bind(env_ref)
186-
.fetch_optional(&self.pool)
187-
.await?
188-
.ok_or_else(|| {
189-
BackendError::NotFound(format!("Environment '{}' not found", env_ref))
190-
})?,
173+
sqlx::query_scalar(
174+
"SELECT id FROM environments WHERE name = $1 AND user_id = $2",
175+
)
176+
.bind(env_ref)
177+
.bind(self.user_id)
178+
.fetch_optional(&self.pool)
179+
.await?
180+
.ok_or_else(|| {
181+
BackendError::NotFound(format!("Environment '{}' not found", env_ref))
182+
})?,
191183
)
192184
}
193185
} else {
@@ -199,12 +191,13 @@ impl Backend for DbBackend {
199191
UPDATE workers
200192
SET environment_id = COALESCE($2, environment_id),
201193
updated_at = now()
202-
WHERE name = $1
194+
WHERE name = $1 AND user_id = $3
203195
RETURNING id, name, "desc", current_version, created_at, updated_at
204196
"#,
205197
)
206198
.bind(name)
207199
.bind(env_id)
200+
.bind(self.user_id)
208201
.fetch_optional(&self.pool)
209202
.await?
210203
.ok_or_else(|| BackendError::NotFound(format!("Worker '{}' not found", name)))?;
@@ -474,9 +467,11 @@ impl Backend for DbBackend {
474467
r#"
475468
SELECT id, name, "desc", created_at, updated_at
476469
FROM environments
470+
WHERE user_id = $1
477471
ORDER BY name
478472
"#,
479473
)
474+
.bind(self.user_id)
480475
.fetch_all(&self.pool)
481476
.await?;
482477

@@ -504,10 +499,11 @@ impl Backend for DbBackend {
504499
r#"
505500
SELECT id, name, "desc", created_at, updated_at
506501
FROM environments
507-
WHERE name = $1
502+
WHERE name = $1 AND user_id = $2
508503
"#,
509504
)
510505
.bind(name)
506+
.bind(self.user_id)
511507
.fetch_optional(&self.pool)
512508
.await?
513509
.ok_or_else(|| BackendError::NotFound(format!("Environment '{}' not found", name)))?;
@@ -529,9 +525,6 @@ impl Backend for DbBackend {
529525
&self,
530526
input: CreateEnvironmentInput,
531527
) -> Result<Environment, BackendError> {
532-
// Get cli-admin user
533-
let user_id = self.get_or_create_admin_user().await?;
534-
535528
let row = sqlx::query(
536529
r#"
537530
INSERT INTO environments (name, "desc", user_id)
@@ -541,7 +534,7 @@ impl Backend for DbBackend {
541534
)
542535
.bind(&input.name)
543536
.bind(&input.desc)
544-
.bind(user_id)
537+
.bind(self.user_id)
545538
.fetch_one(&self.pool)
546539
.await?;
547540

@@ -560,15 +553,15 @@ impl Backend for DbBackend {
560553
name: &str,
561554
input: UpdateEnvironmentInput,
562555
) -> Result<Environment, BackendError> {
563-
// Get environment ID and user_id
564-
let row = sqlx::query("SELECT id, user_id FROM environments WHERE name = $1")
556+
// Get environment ID
557+
let row = sqlx::query("SELECT id FROM environments WHERE name = $1 AND user_id = $2")
565558
.bind(name)
559+
.bind(self.user_id)
566560
.fetch_optional(&self.pool)
567561
.await?
568562
.ok_or_else(|| BackendError::NotFound(format!("Environment '{}' not found", name)))?;
569563

570564
let env_id: uuid::Uuid = row.get("id");
571-
let user_id: uuid::Uuid = row.get("user_id");
572565

573566
// Update name if provided
574567
if let Some(new_name) = &input.name {
@@ -612,7 +605,7 @@ impl Backend for DbBackend {
612605
"#,
613606
)
614607
.bind(env_id)
615-
.bind(user_id)
608+
.bind(self.user_id)
616609
.bind(&value.key)
617610
.bind(val)
618611
.bind(&value.value_type)
@@ -628,8 +621,9 @@ impl Backend for DbBackend {
628621
}
629622

630623
async fn delete_environment(&self, name: &str) -> Result<(), BackendError> {
631-
let result = sqlx::query("DELETE FROM environments WHERE name = $1")
624+
let result = sqlx::query("DELETE FROM environments WHERE name = $1 AND user_id = $2")
632625
.bind(name)
626+
.bind(self.user_id)
633627
.execute(&self.pool)
634628
.await?;
635629

@@ -649,9 +643,11 @@ impl Backend for DbBackend {
649643
r#"
650644
SELECT id, name, "desc", 'r2' as provider, bucket, prefix, endpoint, region, public_url, created_at, updated_at
651645
FROM storage_configs
646+
WHERE user_id = $1
652647
ORDER BY name
653648
"#,
654649
)
650+
.bind(self.user_id)
655651
.fetch_all(&self.pool)
656652
.await?;
657653

@@ -680,10 +676,11 @@ impl Backend for DbBackend {
680676
r#"
681677
SELECT id, name, "desc", 'r2' as provider, bucket, prefix, endpoint, region, public_url, created_at, updated_at
682678
FROM storage_configs
683-
WHERE name = $1
679+
WHERE name = $1 AND user_id = $2
684680
"#,
685681
)
686682
.bind(name)
683+
.bind(self.user_id)
687684
.fetch_optional(&self.pool)
688685
.await?
689686
.ok_or_else(|| BackendError::NotFound(format!("Storage config '{}' not found", name)))?;
@@ -707,9 +704,6 @@ impl Backend for DbBackend {
707704
&self,
708705
input: CreateStorageInput,
709706
) -> Result<StorageConfig, BackendError> {
710-
// Get cli-admin user
711-
let user_id = self.get_or_create_admin_user().await?;
712-
713707
let row = sqlx::query(
714708
r#"
715709
INSERT INTO storage_configs (name, "desc", user_id, bucket, prefix, access_key_id, secret_access_key, endpoint, region, public_url)
@@ -719,7 +713,7 @@ impl Backend for DbBackend {
719713
)
720714
.bind(&input.name)
721715
.bind(&input.desc)
722-
.bind(user_id)
716+
.bind(self.user_id)
723717
.bind(&input.bucket)
724718
.bind(&input.prefix)
725719
.bind(&input.access_key_id)
@@ -746,8 +740,9 @@ impl Backend for DbBackend {
746740
}
747741

748742
async fn delete_storage(&self, name: &str) -> Result<(), BackendError> {
749-
let result = sqlx::query("DELETE FROM storage_configs WHERE name = $1")
743+
let result = sqlx::query("DELETE FROM storage_configs WHERE name = $1 AND user_id = $2")
750744
.bind(name)
745+
.bind(self.user_id)
751746
.execute(&self.pool)
752747
.await?;
753748

@@ -767,9 +762,11 @@ impl Backend for DbBackend {
767762
r#"
768763
SELECT id, name, "desc", created_at, updated_at
769764
FROM kv_configs
765+
WHERE user_id = $1
770766
ORDER BY name
771767
"#,
772768
)
769+
.bind(self.user_id)
773770
.fetch_all(&self.pool)
774771
.await?;
775772

@@ -792,10 +789,11 @@ impl Backend for DbBackend {
792789
r#"
793790
SELECT id, name, "desc", created_at, updated_at
794791
FROM kv_configs
795-
WHERE name = $1
792+
WHERE name = $1 AND user_id = $2
796793
"#,
797794
)
798795
.bind(name)
796+
.bind(self.user_id)
799797
.fetch_optional(&self.pool)
800798
.await?
801799
.ok_or_else(|| BackendError::NotFound(format!("KV namespace '{}' not found", name)))?;
@@ -810,8 +808,6 @@ impl Backend for DbBackend {
810808
}
811809

812810
async fn create_kv(&self, input: CreateKvInput) -> Result<KvNamespace, BackendError> {
813-
let user_id = self.get_or_create_admin_user().await?;
814-
815811
let row = sqlx::query(
816812
r#"
817813
INSERT INTO kv_configs (name, "desc", user_id)
@@ -821,7 +817,7 @@ impl Backend for DbBackend {
821817
)
822818
.bind(&input.name)
823819
.bind(&input.desc)
824-
.bind(user_id)
820+
.bind(self.user_id)
825821
.fetch_one(&self.pool)
826822
.await?;
827823

@@ -835,8 +831,9 @@ impl Backend for DbBackend {
835831
}
836832

837833
async fn delete_kv(&self, name: &str) -> Result<(), BackendError> {
838-
let result = sqlx::query("DELETE FROM kv_configs WHERE name = $1")
834+
let result = sqlx::query("DELETE FROM kv_configs WHERE name = $1 AND user_id = $2")
839835
.bind(name)
836+
.bind(self.user_id)
840837
.execute(&self.pool)
841838
.await?;
842839

src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ async fn run_workers_command(alias: Option<String>, command: WorkersCommand) ->
145145
.await
146146
.map_err(|e| e.to_string())?;
147147

148-
let backend = DbBackend::new(pool);
148+
let backend = DbBackend::new(pool).await.map_err(format_backend_error)?;
149149
command.run(&backend).await.map_err(format_backend_error)
150150
}
151151

@@ -171,7 +171,7 @@ async fn run_env_command(alias: Option<String>, command: EnvCommand) -> Result<(
171171
.await
172172
.map_err(|e| e.to_string())?;
173173

174-
let backend = DbBackend::new(pool);
174+
let backend = DbBackend::new(pool).await.map_err(format_backend_error)?;
175175
command.run(&backend).await.map_err(format_backend_error)
176176
}
177177

@@ -197,7 +197,7 @@ async fn run_storage_command(alias: Option<String>, command: StorageCommand) ->
197197
.await
198198
.map_err(|e| e.to_string())?;
199199

200-
let backend = DbBackend::new(pool);
200+
let backend = DbBackend::new(pool).await.map_err(format_backend_error)?;
201201
command.run(&backend).await.map_err(format_backend_error)
202202
}
203203

@@ -223,7 +223,7 @@ async fn run_kv_command(alias: Option<String>, command: KvCommand) -> Result<(),
223223
.await
224224
.map_err(|e| e.to_string())?;
225225

226-
let backend = DbBackend::new(pool);
226+
let backend = DbBackend::new(pool).await.map_err(format_backend_error)?;
227227
command.run(&backend).await.map_err(format_backend_error)
228228
}
229229

@@ -252,7 +252,7 @@ async fn run_databases_command(
252252
.await
253253
.map_err(|e| e.to_string())?;
254254

255-
let backend = DbBackend::new(pool);
255+
let backend = DbBackend::new(pool).await.map_err(format_backend_error)?;
256256
command.run(&backend).await.map_err(format_backend_error)
257257
}
258258

0 commit comments

Comments
 (0)