| 323 |
323 |
|
assert!(resp.status.is_success(), "Owner should see private repo: {} {}", resp.status, resp.text);
|
| 324 |
324 |
|
}
|
| 325 |
325 |
|
|
|
326 |
+ |
#[tokio::test]
|
|
327 |
+ |
async fn git_private_repo_visible_to_read_collaborator() {
|
|
328 |
+ |
// Run #21 authz reconciliation: a read-collaborator (who can already clone
|
|
329 |
+ |
// over SSH) must be able to read a private repo over HTTP too — previously
|
|
330 |
+ |
// HTTP was owner-only and 404'd them.
|
|
331 |
+ |
let tmp = tempfile::TempDir::new().unwrap();
|
|
332 |
+ |
make_test_repo(tmp.path());
|
|
333 |
+ |
let mut h = setup_git_harness(&tmp).await;
|
|
334 |
+ |
|
|
335 |
+ |
let resp = h.client.get("/git/testowner/testrepo").await; // auto-register
|
|
336 |
+ |
assert!(resp.status.is_success());
|
|
337 |
+ |
sqlx::query("UPDATE git_repos SET visibility = 'private' WHERE name = 'testrepo'")
|
|
338 |
+ |
.execute(&h.db).await.unwrap();
|
|
339 |
+ |
|
|
340 |
+ |
// A logged-in non-collaborator is still denied.
|
|
341 |
+ |
let outsider = h.signup("outsider", "outsider@example.com", "password123").await;
|
|
342 |
+ |
h.login("outsider", "password123").await;
|
|
343 |
+ |
let resp = h.client.get("/git/testowner/testrepo").await;
|
|
344 |
+ |
assert_eq!(resp.status, 404, "non-collaborator must not see a private repo");
|
|
345 |
+ |
|
|
346 |
+ |
// Grant read access, then they can see it.
|
|
347 |
+ |
let repo_id: uuid::Uuid = sqlx::query_scalar("SELECT id FROM git_repos WHERE name = 'testrepo'")
|
|
348 |
+ |
.fetch_one(&h.db).await.unwrap();
|
|
349 |
+ |
sqlx::query("INSERT INTO repo_collaborators (repo_id, user_id, can_push) VALUES ($1, $2, false)")
|
|
350 |
+ |
.bind(repo_id).bind(outsider).execute(&h.db).await.unwrap();
|
|
351 |
+ |
|
|
352 |
+ |
let resp = h.client.get("/git/testowner/testrepo").await;
|
|
353 |
+ |
assert!(resp.status.is_success(), "read-collaborator should see private repo over HTTP: {} {}", resp.status, resp.text);
|
|
354 |
+ |
}
|
|
355 |
+ |
|
| 326 |
356 |
|
// ── Commit detail ──
|
| 327 |
357 |
|
|
| 328 |
358 |
|
#[tokio::test]
|