Hi all,
I’m trying to create a shared access with a bucket/prefix. I’m able to create a shared serialized access. I try to then use that serialized access to call to upload and I get “Unauthorized API credentials”. It’s worth mentioning that the upload works fine with a bucket/prefix when I use the serialized access created from the tardigrade api token. It’s also worth mentioning that when I don’t send in a prefix to the share, with only a bucket, I’m also able to upload.
Here’s my code for the access share in GO:
.... some prep code above I haven't included
//p contains parameters from http post
access, err := uplink.ParseAccess(p.SerializedAccess)
if err != nil {
log.Fatalln("error parsing serialized access:", err)
}
var permission uplink.Permission
if p.Permission == "read" {
permission = uplink.ReadOnlyPermission()
}
if p.Permission == "write" {
permission = uplink.WriteOnlyPermission()
}
if p.Permission == "full" {
permission = uplink.FullPermission()
}
permission.NotBefore = time.Now()
shared := uplink.SharePrefix{
Bucket: p.Bucket,
Prefix: p.Prefix + "/",
}
restrictedAccess, err := access.Share(permission, shared)
if err != nil {
log.Fatalln("error restrincting access:", err)
}
//serializedAccess is what I send back
serializedAccess, err := restrictedAccess.Serialize()
if err != nil {
log.Fatalln("error serializing access grant:", err)
}
...some code after
}
And this is the body of a sample Http post:
Body:
{
“SerializedAccess”:“some_serialized_access_from_API_token”,
“Bucket”:“public”,
“Permission”:“full”,
“Prefix”:“111aaa”
}
Any help would be appreciated!
@AkaashMukherjee I wasn’t able to reproduce the error you received. I made a self contained CLI to do roughly what you have outlined:
package main
import (
"fmt"
"os"
"time"
"storj.io/uplink"
)
func cannot(err error) {
if err != nil {
panic(err)
}
}
func main() {
perm := os.Args[1] // "read"
bucket := os.Args[2] // "public"
prefix := os.Args[3] // "111aaa"
access, err := uplink.ParseAccess(os.Getenv("ACCESS"))
cannot(err)
var permission uplink.Permission
switch perm {
case "read":
permission = uplink.ReadOnlyPermission()
case "write":
permission = uplink.WriteOnlyPermission()
case "full":
permission = uplink.FullPermission()
}
permission.NotBefore = time.Now()
shared := uplink.SharePrefix{
Bucket: bucket,
Prefix: prefix + "/",
}
restrictedAccess, err := access.Share(permission, shared)
cannot(err)
serializedAccess, err := restrictedAccess.Serialize()
cannot(err)
fmt.Println(serializedAccess)
}
Here are some trial runs:
export ACCESS=my-root-level-grant
# Bucket listing works:
$ uplink --access $(./uplink-share read caleb-test 111aaa) ls
BKT 2020-12-23 07:13:41 caleb-test
# Listing without proper prefix does not:
$ uplink --access $(./uplink-share read caleb-test 111aaa) ls sj://caleb-test
Error: uplink: metainfo: unable to find encryption base for: caleb-test/""
# Listing with proper prefix does:
$ uplink --access $(./uplink-share read caleb-test 111aaa) ls sj://caleb-test/111aaa
OBJ 2021-02-01 13:44:50 823 111aaa/main.go
# Can't remove with a read-only grant:
$ uplink --access $(./uplink-share read caleb-test 111aaa) rm sj://caleb-test/111aaa/main.go
Error: uplink: permission denied (metainfo error: Unauthorized API credentials)
# Can't upload with a read-only grant:
$ uplink --access $(./uplink-share read caleb-test 111aaa) cp main.go sj://caleb-test/111aaa/main.go
13:48:15.866 WARN Failed deleting object
Bucket: caleb-test
key: 111aaa/main.go
error: metainfo error: Unauthorized API credentials
Error: uplink: permission denied (stream error: metainfo error: Unauthorized API credentials)
$ uplink --access $(./uplink-share read caleb-test 111aaa) cp main.go sj://caleb-test/111aaa/main.go.2
823 B / 823 B [------------------------------------------------------------------------------------------------------------------------------->] 100.00% ? p/s13:48:30.588 WARN Failed deleting object
Bucket: caleb-test
key: 111aaa/main.go.2
error: metainfo error: Unauthorized API credentials
Error: uplink: permission denied (stream error: metainfo error: Unauthorized API credentials)
# Can read with read-only grant:
$ uplink --access $(./uplink-share read caleb-test 111aaa) cat sj://caleb-test/111aaa/main.go | head
package main
import (
"fmt"
"os"
"time"
"storj.io/uplink"
)
I’ve go through read, write, and full and I don’t see any issues. I do however see that if for some reason your permission is empty string the grant will not have permissions to do anything. You may want to have a default case there.
Hmm… just saw this. So the code you used is the same as what I’m doing and it’s properly granting access to the prefix from what I see. I have no idea why for me it’s only working at the bucket level.