@@ -14,28 +14,48 @@ import (
14
14
core "github.com/textileio/go-threads/core/thread"
15
15
)
16
16
17
+ // PushPathAccessRoles pushes new access roles to bucket paths.
18
+ // Access roles are keyed by did.DID.
19
+ // Roles are inherited by path children.
17
20
func (b * Buckets ) PushPathAccessRoles (
18
21
ctx context.Context ,
19
22
thread core.ID ,
20
- key , pth string ,
21
- roles map [did.DID ]collection.Role ,
23
+ key string ,
22
24
identity did.Token ,
25
+ root path.Resolved ,
26
+ pth string ,
27
+ roles map [did.DID ]collection.Role ,
23
28
) (int64 , * Bucket , error ) {
24
- lk := b .locks .Get (lock (key ))
25
- lk .Acquire ()
26
- defer lk .Release ()
29
+ txn , err := b .NewTxn (thread , key , identity )
30
+ if err != nil {
31
+ return 0 , nil , err
32
+ }
33
+ defer txn .Close ()
34
+ return txn .PushPathAccessRoles (ctx , root , pth , roles )
35
+ }
27
36
37
+ // PushPathAccessRoles is Txn based PushPathInfo.
38
+ func (t * Txn ) PushPathAccessRoles (
39
+ ctx context.Context ,
40
+ root path.Resolved ,
41
+ pth string ,
42
+ roles map [did.DID ]collection.Role ,
43
+ ) (int64 , * Bucket , error ) {
28
44
pth , err := parsePath (pth )
29
45
if err != nil {
30
46
return 0 , nil , err
31
47
}
32
48
33
- instance , bpth , err := b .getBucketAndPath (ctx , thread , key , pth , identity )
49
+ instance , bpth , err := t . b .getBucketAndPath (ctx , t . thread , t . key , t . identity , pth )
34
50
if err != nil {
35
51
return 0 , nil , err
36
52
}
53
+ if root != nil && root .String () != instance .Path {
54
+ return 0 , nil , ErrNonFastForward
55
+ }
56
+
37
57
linkKey := instance .GetLinkEncryptionKey ()
38
- pathNode , err := dag .GetNodeAtPath (ctx , b .ipfs , bpth , linkKey )
58
+ pathNode , err := dag .GetNodeAtPath (ctx , t . b .ipfs , bpth , linkKey )
39
59
if err != nil {
40
60
return 0 , nil , err
41
61
}
@@ -86,7 +106,7 @@ func (b *Buckets) PushPathAccessRoles(
86
106
return 0 , nil , err
87
107
}
88
108
}
89
- if err := b .c .Verify (ctx , thread , instance , collection .WithIdentity (identity )); err != nil {
109
+ if err := t . b .c .Verify (ctx , t . thread , instance , collection .WithIdentity (t . identity )); err != nil {
90
110
return 0 , nil , err
91
111
}
92
112
@@ -97,7 +117,7 @@ func (b *Buckets) PushPathAccessRoles(
97
117
}
98
118
nmap , err := dag .EncryptDag (
99
119
ctx ,
100
- b .ipfs ,
120
+ t . b .ipfs ,
101
121
pathNode ,
102
122
pth ,
103
123
linkKey ,
@@ -117,41 +137,46 @@ func (b *Buckets) PushPathAccessRoles(
117
137
}
118
138
pn := nmap [pathNode .Cid ()].Node
119
139
var dirPath path.Resolved
120
- ctx , dirPath , err = dag .InsertNodeAtPath (ctx , b .ipfs , pn , path .Join (path .New (instance .Path ), pth ), linkKey )
140
+ ctx , dirPath , err = dag .InsertNodeAtPath (ctx , t . b .ipfs , pn , path .Join (path .New (instance .Path ), pth ), linkKey )
121
141
if err != nil {
122
142
return 0 , nil , err
123
143
}
124
- ctx , err = dag .AddAndPinNodes (ctx , b .ipfs , nodes )
144
+ ctx , err = dag .AddAndPinNodes (ctx , t . b .ipfs , nodes )
125
145
if err != nil {
126
146
return 0 , nil , err
127
147
}
128
148
instance .Path = dirPath .String ()
129
149
}
130
150
131
- if err := b .c .Save (ctx , thread , instance , collection .WithIdentity (identity )); err != nil {
151
+ if err := t . b .c .Save (ctx , t . thread , instance , collection .WithIdentity (t . identity )); err != nil {
132
152
return 0 , nil , err
133
153
}
134
154
}
135
155
136
- log .Debugf ("pushed access roles for %s in %s" , pth , key )
137
- return dag .GetPinnedBytes (ctx ), instanceToBucket (thread , instance ), nil
156
+ log .Debugf ("pushed access roles for %s in %s" , pth , t . key )
157
+ return dag .GetPinnedBytes (ctx ), instanceToBucket (t . thread , instance ), nil
138
158
}
139
159
160
+ // PullPathAccessRoles pulls access roles for a bucket path.
140
161
func (b * Buckets ) PullPathAccessRoles (
141
162
ctx context.Context ,
142
163
thread core.ID ,
143
- key , pth string ,
164
+ key string ,
144
165
identity did.Token ,
166
+ pth string ,
145
167
) (map [did.DID ]collection.Role , error ) {
168
+ if err := thread .Validate (); err != nil {
169
+ return nil , fmt .Errorf ("invalid thread id: %v" , err )
170
+ }
146
171
pth , err := parsePath (pth )
147
172
if err != nil {
148
173
return nil , err
149
174
}
150
- instance , bpth , err := b .getBucketAndPath (ctx , thread , key , pth , identity )
175
+ instance , bpth , err := b .getBucketAndPath (ctx , thread , key , identity , pth )
151
176
if err != nil {
152
177
return nil , err
153
178
}
154
- if _ , err : = dag .GetNodeAtPath (ctx , b .ipfs , bpth , instance .GetLinkEncryptionKey ()); err != nil {
179
+ if _ , err = dag .GetNodeAtPath (ctx , b .ipfs , bpth , instance .GetLinkEncryptionKey ()); err != nil {
155
180
return nil , fmt .Errorf ("could not resolve path: %s" , pth )
156
181
}
157
182
md , _ , ok := instance .GetMetadataForPath (pth , false )
@@ -162,3 +187,55 @@ func (b *Buckets) PullPathAccessRoles(
162
187
log .Debugf ("pulled access roles for %s in %s" , pth , key )
163
188
return md .Roles , nil
164
189
}
190
+
191
+ // IsReadablePath returns whether or not a path is readable by an identity.
192
+ func (b * Buckets ) IsReadablePath (
193
+ ctx context.Context ,
194
+ thread core.ID ,
195
+ key string ,
196
+ identity did.Token ,
197
+ pth string ,
198
+ ) (bool , error ) {
199
+ if err := thread .Validate (); err != nil {
200
+ return false , fmt .Errorf ("invalid thread id: %v" , err )
201
+ }
202
+ pth , err := parsePath (pth )
203
+ if err != nil {
204
+ return false , err
205
+ }
206
+ instance , err := b .c .GetSafe (ctx , thread , key , collection .WithIdentity (identity ))
207
+ if err != nil {
208
+ return false , err
209
+ }
210
+ _ , doc , err := core .Validate (identity , nil )
211
+ if err != nil {
212
+ return false , err
213
+ }
214
+ return instance .IsReadablePath (pth , doc .ID ), nil
215
+ }
216
+
217
+ // IsWritablePath returns whether or not a path is writable by an identity.
218
+ func (b * Buckets ) IsWritablePath (
219
+ ctx context.Context ,
220
+ thread core.ID ,
221
+ key string ,
222
+ identity did.Token ,
223
+ pth string ,
224
+ ) (bool , error ) {
225
+ if err := thread .Validate (); err != nil {
226
+ return false , fmt .Errorf ("invalid thread id: %v" , err )
227
+ }
228
+ pth , err := parsePath (pth )
229
+ if err != nil {
230
+ return false , err
231
+ }
232
+ instance , err := b .c .GetSafe (ctx , thread , key , collection .WithIdentity (identity ))
233
+ if err != nil {
234
+ return false , err
235
+ }
236
+ _ , doc , err := core .Validate (identity , nil )
237
+ if err != nil {
238
+ return false , err
239
+ }
240
+ return instance .IsWritablePath (pth , doc .ID ), nil
241
+ }
0 commit comments