aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/store.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/store.rs')
-rw-r--r--src/api/store.rs14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/api/store.rs b/src/api/store.rs
index 16dd966..e43d129 100644
--- a/src/api/store.rs
+++ b/src/api/store.rs
@@ -472,7 +472,7 @@ pub(crate) async fn put_store_entry(
let path = if own_entry {
crate::access::registry::user_path(&user.0)
} else {
- parse_write_path(&state, &user, &access, &key, "PUT")?
+ parse_write_path(&state, &user, &access, &key, "PUT").await?
};
let sign = Sign::Write {
path: path.clone(),
@@ -662,8 +662,9 @@ fn parse_key_path(key: &str) -> Result<Vec<String>, StatusCode> {
/// what every node acts on, so a write there acts on the whole swarm, and each is
/// logged. Epoch metadata (and `_continuum` as a whole, which contains it) is never
/// writable: the protocol reads it at the snapshot change, so an edit only misleads
-/// whoever reads it later; nor is the swarm ID.
-fn parse_write_path(
+/// whoever reads it later; nor is the swarm ID. A path inside a list or text is
+/// judged where the rules judge the write (`inspect::placed`): at the list.
+async fn parse_write_path(
state: &AppState,
user: &AuthenticatedUser,
access: &Access,
@@ -671,12 +672,13 @@ fn parse_write_path(
method: &str,
) -> Result<Vec<String>, StatusCode> {
let path = parse_key_path(key)?;
+ let placed = crate::document::inspect::placed(&state.doc.read().await.doc, &path);
let protocol = meta::is_protocol(&path);
// `_continuum` itself, epoch metadata and the swarm ID: nobody.
let fixed = protocol && (path.len() < 2 || path[1] == meta::EPOCHS || path[1] == meta::SWARM);
let allowed = match access {
Access::Everything => !protocol || state.protocol_writers.contains(&user.0),
- Access::Caps(caps) => caps.allows(crate::access::Right::Write, &path),
+ Access::Caps(caps) => caps.allows(crate::access::Right::Write, &placed),
};
if !protocol && allowed {
return Ok(path);
@@ -936,7 +938,7 @@ pub(crate) async fn post_store_entry(
if !state.is_ready().await {
return Err(StatusCode::SERVICE_UNAVAILABLE.into());
}
- let path = parse_write_path(&state, &user, &access, &key, "POST")?;
+ let path = parse_write_path(&state, &user, &access, &key, "POST").await?;
let sign = Sign::Write {
path: path.clone(),
asked: query.signed,
@@ -1050,7 +1052,7 @@ pub(crate) async fn delete_store_entry(
Query(query): Query<DeleteQuery>,
RawQuery(raw_query): RawQuery,
) -> Result<Response, ApiError> {
- let path = parse_write_path(&state, &user, &access, &key, "DELETE")?;
+ let path = parse_write_path(&state, &user, &access, &key, "DELETE").await?;
let sign = Sign::Write {
path: path.clone(),
asked: query.signed,