1
1
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 ,
4
4
} ;
5
5
6
6
pub fn version_endpoint ( ) -> Endpoint {
@@ -40,7 +40,7 @@ fn handle_version_request(
40
40
if commit_url. is_none ( ) {
41
41
return version_endpoint ( ) . to_resource ( store) ;
42
42
}
43
- let mut resource = construct_version ( & commit_url. unwrap ( ) , store) ?;
43
+ let mut resource = construct_version ( & commit_url. unwrap ( ) , store, for_agent ) ?;
44
44
resource. set_subject ( url. to_string ( ) ) ;
45
45
Ok ( resource)
46
46
}
@@ -97,10 +97,23 @@ fn get_commits_for_resource(subject: &str, store: &impl Storelike) -> AtomicResu
97
97
98
98
/// Constructs a Resource version for a specific Commit
99
99
/// 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 > {
101
105
let commit = store. get_resource ( commit_url) ?;
102
106
// Get all the commits for the subject of that Commit
103
107
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
+ }
104
117
let mut commits = get_commits_for_resource ( subject, store) ?;
105
118
// Sort all commits by date
106
119
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
129
142
130
143
/// Gets a version of a Resource by Commit.
131
144
/// 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 > {
133
150
let version_url = construct_version_endpoint_url ( store, commit_url) ;
134
151
match store. get_resource ( & version_url) {
135
152
Ok ( cached) => Ok ( cached) ,
136
153
Err ( _not_cached) => {
137
- let version = construct_version ( commit_url, store) ?;
154
+ let version = construct_version ( commit_url, store, for_agent ) ?;
138
155
// Store constructed version for caching
139
156
store. add_resource ( & version) ?;
140
157
Ok ( version)
@@ -170,7 +187,7 @@ mod test {
170
187
let commits = get_commits_for_resource ( subject, & store) . unwrap ( ) ;
171
188
assert_eq ! ( commits. len( ) , 2 ) ;
172
189
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 ( ) ;
174
191
assert_eq ! (
175
192
first_version
176
193
. get_shortname( "description" , & store)
@@ -179,7 +196,7 @@ mod test {
179
196
first_val
180
197
) ;
181
198
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 ( ) ;
183
200
assert_eq ! (
184
201
second_version
185
202
. get_shortname( "description" , & store)
0 commit comments