Skip to content

Commit 654f5e6

Browse files
committed
#13 authenticate construct version
1 parent 747b7e5 commit 654f5e6

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

lib/src/plugins/versioning.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
collections::CollectionBuilder, endpoints::Endpoint, errors::AtomicResult, urls, Commit,
3-
Resource, Storelike,
2+
collections::CollectionBuilder, endpoints::Endpoint, errors::AtomicResult, urls, AtomicError,
3+
Commit, Resource, Storelike,
44
};
55

66
pub fn version_endpoint() -> Endpoint {
@@ -40,7 +40,7 @@ fn handle_version_request(
4040
if commit_url.is_none() {
4141
return version_endpoint().to_resource(store);
4242
}
43-
let mut resource = construct_version(&commit_url.unwrap(), store)?;
43+
let mut resource = construct_version(&commit_url.unwrap(), store, for_agent)?;
4444
resource.set_subject(url.to_string());
4545
Ok(resource)
4646
}
@@ -97,10 +97,23 @@ fn get_commits_for_resource(subject: &str, store: &impl Storelike) -> AtomicResu
9797

9898
/// Constructs a Resource version for a specific Commit
9999
/// Only works if the current store has the required Commits
100-
pub fn construct_version(commit_url: &str, store: &impl Storelike) -> AtomicResult<Resource> {
100+
pub fn construct_version(
101+
commit_url: &str,
102+
store: &impl Storelike,
103+
for_agent: Option<String>,
104+
) -> AtomicResult<Resource> {
101105
let commit = store.get_resource(commit_url)?;
102106
// Get all the commits for the subject of that Commit
103107
let subject = &commit.get(urls::SUBJECT)?.to_string();
108+
if let Some(agent) = for_agent {
109+
let current_resource = store.get_resource(subject)?;
110+
let can_open = crate::hierarchy::check_read(store, &current_resource, agent)?;
111+
if !can_open {
112+
return Err(AtomicError::unauthorized(
113+
"You do not have permission to construct this resource".to_string(),
114+
));
115+
}
116+
}
104117
let mut commits = get_commits_for_resource(subject, store)?;
105118
// Sort all commits by date
106119
commits.sort_by(|a, b| a.created_at.cmp(&b.created_at));
@@ -129,12 +142,16 @@ fn construct_version_endpoint_url(store: &impl Storelike, commit_url: &str) -> S
129142

130143
/// Gets a version of a Resource by Commit.
131144
/// Tries cached version, constructs one if there is no cached version.
132-
pub fn get_version(commit_url: &str, store: &impl Storelike) -> AtomicResult<Resource> {
145+
pub fn get_version(
146+
commit_url: &str,
147+
store: &impl Storelike,
148+
for_agent: Option<String>,
149+
) -> AtomicResult<Resource> {
133150
let version_url = construct_version_endpoint_url(store, commit_url);
134151
match store.get_resource(&version_url) {
135152
Ok(cached) => Ok(cached),
136153
Err(_not_cached) => {
137-
let version = construct_version(commit_url, store)?;
154+
let version = construct_version(commit_url, store, for_agent)?;
138155
// Store constructed version for caching
139156
store.add_resource(&version)?;
140157
Ok(version)
@@ -170,7 +187,7 @@ mod test {
170187
let commits = get_commits_for_resource(subject, &store).unwrap();
171188
assert_eq!(commits.len(), 2);
172189

173-
let first_version = construct_version(first_commit.get_subject(), &store).unwrap();
190+
let first_version = construct_version(first_commit.get_subject(), &store, None).unwrap();
174191
assert_eq!(
175192
first_version
176193
.get_shortname("description", &store)
@@ -179,7 +196,7 @@ mod test {
179196
first_val
180197
);
181198

182-
let second_version = construct_version(second_commit.get_subject(), &store).unwrap();
199+
let second_version = construct_version(second_commit.get_subject(), &store, None).unwrap();
183200
assert_eq!(
184201
second_version
185202
.get_shortname("description", &store)

0 commit comments

Comments
 (0)