Skip to content

Commit 7b08125

Browse files
Merge pull request #16 from OpenArchive/feature/repo-write-permissions
feat: add repo write permissions and tests
2 parents 1ca3d37 + 7386903 commit 7b08125

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,90 @@ mod tests {
625625
Ok(())
626626
}
627627

628+
#[actix_web::test]
629+
async fn test_repo_permissions() -> Result<()> {
630+
// Initialize the app
631+
let path = TmpDir::new("test_repo_permissions").await?;
632+
633+
// Initialize backend2 first (this will be the creator of the group/repo)
634+
let store2 = iroh_blobs::store::fs::Store::load(path.to_path_buf().join("iroh2")).await?;
635+
let (veilid_api2, update_rx2) = save_dweb_backend::common::init_veilid(
636+
path.to_path_buf().join("test2").as_path(),
637+
"test2".to_string(),
638+
)
639+
.await?;
640+
let backend2 = save_dweb_backend::backend::Backend::from_dependencies(
641+
&path.to_path_buf(),
642+
veilid_api2.clone(),
643+
update_rx2,
644+
store2,
645+
)
646+
.await
647+
.unwrap();
648+
649+
// Initialize the main backend (this will join the group)
650+
BACKEND.get_or_init(|| init_backend(path.to_path_buf().as_path()));
651+
{
652+
let backend = get_backend().await?;
653+
backend.start().await.expect("Backend failed to start");
654+
}
655+
656+
// Create group and repo in backend2 (creator)
657+
let mut group = backend2.create_group().await?;
658+
let join_url = group.get_url();
659+
group.set_name(TEST_GROUP_NAME).await?;
660+
661+
let repo = group.create_repo().await?;
662+
repo.set_name(TEST_GROUP_NAME).await?;
663+
664+
// Verify creator has write access
665+
let creator_repo: SnowbirdRepo = repo.clone().into();
666+
assert!(creator_repo.can_write, "Creator should have write access");
667+
668+
// Join the group with the main backend
669+
{
670+
let backend = get_backend().await?;
671+
backend.join_from_url(join_url.as_str()).await?;
672+
}
673+
674+
let app = test::init_service(
675+
App::new()
676+
.service(status)
677+
.service(web::scope("/api").service(groups::scope())),
678+
)
679+
.await;
680+
681+
// Get the repo info through the API for the joined backend
682+
let get_repo_req = test::TestRequest::get()
683+
.uri(&format!(
684+
"/api/groups/{}/repos/{}",
685+
group.id().to_string(),
686+
repo.id().to_string()
687+
))
688+
.to_request();
689+
let joined_repo: SnowbirdRepo = test::call_and_read_body_json(&app, get_repo_req).await;
690+
691+
// Verify joined backend has read-only access
692+
assert!(!joined_repo.can_write, "Joined backend should have read-only access");
693+
694+
// List repos to verify permissions are consistent
695+
let list_repos_req = test::TestRequest::get()
696+
.uri(&format!("/api/groups/{}/repos", group.id().to_string()))
697+
.to_request();
698+
let repos_response: ReposResponse = test::call_and_read_body_json(&app, list_repos_req).await;
699+
700+
assert_eq!(repos_response.repos.len(), 1, "Should see one repo");
701+
assert!(!repos_response.repos[0].can_write, "Listed repo should show read-only access");
702+
703+
// Clean up
704+
backend2.stop().await?;
705+
{
706+
let backend = get_backend().await?;
707+
backend.stop().await.expect("Backend failed to stop");
708+
}
709+
tokio::time::sleep(Duration::from_secs(2)).await;
710+
veilid_api2.shutdown().await;
711+
628712
Ok(())
629713
}
630714
}

src/models.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ impl IntoSnowbirdGroupsWithNames for Vec<Box<Group>> {
104104
pub struct SnowbirdRepo {
105105
pub key: String,
106106
pub name: String,
107+
pub can_write: bool,
107108
}
108109

109110
#[async_trait::async_trait]
@@ -120,6 +121,7 @@ impl AsyncFrom<Repo> for SnowbirdRepo {
120121
.get_name()
121122
.await
122123
.unwrap_or_else(|_| "Unknown".to_string()),
124+
can_write: repo.can_write(),
123125
}
124126
}
125127
}
@@ -129,6 +131,7 @@ impl From<&Repo> for SnowbirdRepo {
129131
SnowbirdRepo {
130132
key: repo.id().to_string(),
131133
name: "".to_string(),
134+
can_write: repo.can_write(),
132135
}
133136
}
134137
}
@@ -138,6 +141,7 @@ impl From<Repo> for SnowbirdRepo {
138141
SnowbirdRepo {
139142
key: repo.id().to_string(),
140143
name: "".to_string(),
144+
can_write: repo.can_write(),
141145
}
142146
}
143147
}

0 commit comments

Comments
 (0)