storj/satellite/console/permission.go
Michal Niewrzal 7c384c8293 Merge 'master' branch
Change-Id: I1eefd5a56449e577820977d61fa4a22bdd4fc230
2020-11-16 10:02:54 +01:00

90 lines
2.8 KiB
Go

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package console
import (
"time"
"github.com/zeebo/errs"
"storj.io/common/macaroon"
)
// Permission defines what actions can be used to share.
//
// This struct has been taken from storj.io/uplink and duplicated to avoid
// pulling in that dependency.
type Permission struct {
// AllowDownload gives permission to download the object's content. It
// allows getting object metadata, but it does not allow listing buckets.
AllowDownload bool
// AllowUpload gives permission to create buckets and upload new objects.
// It does not allow overwriting existing objects unless AllowDelete is
// granted too.
AllowUpload bool
// AllowList gives permission to list buckets. It allows getting object
// metadata, but it does not allow downloading the object's content.
AllowList bool
// AllowDelete gives permission to delete buckets and objects. Unless
// either AllowDownload or AllowList is granted too, no object metadata and
// no error info will be returned for deleted objects.
AllowDelete bool
// NotBefore restricts when the resulting access grant is valid for.
// If set, the resulting access grant will not work if the Satellite
// believes the time is before NotBefore.
// If set, this value should always be before NotAfter.
NotBefore time.Time
// NotAfter restricts when the resulting access grant is valid for.
// If set, the resulting access grant will not work if the Satellite
// believes the time is after NotAfter.
// If set, this value should always be after NotBefore.
NotAfter time.Time
}
// SetPermission restricts the api key with the permissions and returns an api key with restricted permissions.
func SetPermission(key string, buckets []string, permission Permission) (*macaroon.APIKey, error) {
if permission == (Permission{}) {
return nil, errs.New("permission is empty")
}
var notBefore, notAfter *time.Time
if !permission.NotBefore.IsZero() {
notBefore = &permission.NotBefore
}
if !permission.NotAfter.IsZero() {
notAfter = &permission.NotAfter
}
if notBefore != nil && notAfter != nil && notAfter.Before(*notBefore) {
return nil, errs.New("invalid time range")
}
caveat := macaroon.Caveat{
DisallowReads: !permission.AllowDownload,
DisallowWrites: !permission.AllowUpload,
DisallowLists: !permission.AllowList,
DisallowDeletes: !permission.AllowDelete,
NotBefore: notBefore,
NotAfter: notAfter,
}
for _, b := range buckets {
caveat.AllowedPaths = append(caveat.AllowedPaths, &macaroon.Caveat_Path{
Bucket: []byte(b),
})
}
apiKey, err := macaroon.ParseAPIKey(key)
if err != nil {
return nil, err
}
restrictedKey, err := apiKey.Restrict(caveat)
if err != nil {
return nil, err
}
return restrictedKey, nil
}