-
Notifications
You must be signed in to change notification settings - Fork 45
/
buckets.go
141 lines (125 loc) · 3.45 KB
/
buckets.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package buckets
import (
"context"
"errors"
"fmt"
"strings"
"github.com/textileio/go-threads/core/thread"
pb "github.com/textileio/textile/v2/api/bucketsd/pb"
)
const (
// CollectionName is the name of the threaddb collection used for buckets.
CollectionName = "buckets"
// SeedName is the file name reserved for a random bucket seed.
SeedName = ".textileseed"
)
var (
// ErrNonFastForward is returned when an update in non-fast-forward.
ErrNonFastForward = fmt.Errorf("update is non-fast-forward")
// ErrNoCurrentArchive is returned when not status about the last archive
// can be retrieved, since the bucket was never archived.
ErrNoCurrentArchive = fmt.Errorf("the bucket was never archived")
// ErrZeroBalance is returned when archiving a bucket which
// underlying Account Powergate user balance is zero.
ErrZeroBalance = errors.New("wallet FIL balance is zero, if recently created wait 30s")
)
type ctxKey string
// BucketOwner provides owner context to the bucket service.
type BucketOwner struct {
StorageUsed int64
StorageAvailable int64
StorageDelta int64
}
func NewBucketOwnerContext(ctx context.Context, owner *BucketOwner) context.Context {
return context.WithValue(ctx, ctxKey("bucketOwner"), owner)
}
func BucketOwnerFromContext(ctx context.Context) (*BucketOwner, bool) {
owner, ok := ctx.Value(ctxKey("bucketOwner")).(*BucketOwner)
return owner, ok
}
// Role describes an access role for a bucket item.
type Role int
const (
None Role = iota
Reader
Writer
Admin
)
// NewRoleFromString returns the role associated with the given string.
func NewRoleFromString(s string) (Role, error) {
switch strings.ToLower(s) {
case "none":
return None, nil
case "reader":
return Reader, nil
case "writer":
return Writer, nil
case "admin":
return Admin, nil
default:
return None, fmt.Errorf("invalid role: %s", s)
}
}
// String returns the string representation of the role.
func (r Role) String() string {
switch r {
case None:
return "None"
case Reader:
return "Reader"
case Writer:
return "Writer"
case Admin:
return "Admin"
default:
return "Invalid"
}
}
// RolesToPb maps native type roles to protobuf type roles.
func RolesToPb(in map[string]Role) (map[string]pb.PathAccessRole, error) {
roles := make(map[string]pb.PathAccessRole)
for k, r := range in {
var pr pb.PathAccessRole
switch r {
case None:
pr = pb.PathAccessRole_PATH_ACCESS_ROLE_UNSPECIFIED
case Reader:
pr = pb.PathAccessRole_PATH_ACCESS_ROLE_READER
case Writer:
pr = pb.PathAccessRole_PATH_ACCESS_ROLE_WRITER
case Admin:
pr = pb.PathAccessRole_PATH_ACCESS_ROLE_ADMIN
default:
return nil, fmt.Errorf("unknown path access role %d", r)
}
roles[k] = pr
}
return roles, nil
}
// RolesFromPb maps protobuf type roles to native type roles.
func RolesFromPb(in map[string]pb.PathAccessRole) (map[string]Role, error) {
roles := make(map[string]Role)
for k, pr := range in {
if k != "*" {
pk := &thread.Libp2pPubKey{}
if err := pk.UnmarshalString(k); err != nil {
return nil, fmt.Errorf("unmarshaling role public key: %s", err)
}
}
var r Role
switch pr {
case pb.PathAccessRole_PATH_ACCESS_ROLE_UNSPECIFIED:
r = None
case pb.PathAccessRole_PATH_ACCESS_ROLE_READER:
r = Reader
case pb.PathAccessRole_PATH_ACCESS_ROLE_WRITER:
r = Writer
case pb.PathAccessRole_PATH_ACCESS_ROLE_ADMIN:
r = Admin
default:
return nil, fmt.Errorf("unknown path access role %d", pr)
}
roles[k] = r
}
return roles, nil
}