efcdaa43a3
* lib/uplink: encryption context Change-Id: I5c23dca3286a46b713b30c4997e9ae6e630b2280 * lib/uplink: bucket operation examples Change-Id: Ia0f6e69f365dcff0cf11c731f51b30842bce053b * lib/uplink: encryption key sharing test cases Change-Id: I3a172d565f33f4e591402cdcb9460664a7cc7fbe * fix encrypted path prefix restriction issue Change-Id: I8f3921f9d52aaf4b84039de608b8cbbc88769554 * implement panics in libuplink encryption code todo on cipher suite selection as well as an api concern Change-Id: Ifa39eb3cc4b3443f7d96f9304df9b2ac4ec4085d * implement GetProjectInfo api call to get salt Change-Id: Ic5f6b3be9ea35df48c1aa214ab5d355fb328e2cf * some fixes and accessors for encryption store Change-Id: I3bb61f6712a037900e2a96e72ad4029ec1d3f718 * general fixes to builds/tests/etc Change-Id: I9930fa96acb3b221d9a001f8e274af5729cc8a47 * java bindings changes Change-Id: Ia2bd4c9c69739c8d3154d79616cff1f36fb403b6 * get libuplink examples passing Change-Id: I828f09a144160e0a5dd932324f78491ae2ec8a07 * fix proto.lock file Change-Id: I2fbbf4d0976a7d0473c2645e6dcb21aaa3be7651 * fix proto.lock again Change-Id: I92702cf49e1a340eef6379c2be4f7c4a268112a9 * fix golint issues Change-Id: I631ff9f43307a58e3b25a58cbb4a4cc2495f5eb6 * more linting fixes Change-Id: I51f8f30b367b5bca14c94b15417b9a4c9e7aa0ce * bug fixed by structs bump Change-Id: Ibb03c691fce7606c35c08721b3ef0781ab48a38a * retrigger Change-Id: Ieee0470b6a2d07168a1578552e8e7f271ae93a13 * retrigger Change-Id: I753d63853171e6a436c104ce176048892eb974c5 * semantic merge conflict Change-Id: I9419448496de90340569047a6a16a1b858a7978a * update total to match prod defaults Change-Id: I693d55c1ebb28b5803ee1d26e9e198decf82308b * retrigger Change-Id: I28b74d5d6202f61aa3866fe407d423f6a0a14b9e * retrigger Change-Id: I6fd054885c715f602e2cef623fd464c42e88742c * retrigger Change-Id: I6a01bae88c72406d4ed5a8f13bf8a2b3c650bd2d
175 lines
5.2 KiB
Go
175 lines
5.2 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package mobile
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"storj.io/storj/internal/memory"
|
|
libuplink "storj.io/storj/lib/uplink"
|
|
"storj.io/storj/pkg/storj"
|
|
)
|
|
|
|
// Config represents configuration options for an Uplink
|
|
type Config struct {
|
|
|
|
// MaxInlineSize determines whether the uplink will attempt to
|
|
// store a new object in the satellite's metainfo. Objects at
|
|
// or below this size will be marked for inline storage, and
|
|
// objects above this size will not. (The satellite may reject
|
|
// the inline storage and require remote storage, still.)
|
|
MaxInlineSize int64
|
|
|
|
// MaxMemory is the default maximum amount of memory to be
|
|
// allocated for read buffers while performing decodes of
|
|
// objects. (This option is overrideable per Bucket if the user
|
|
// so desires.) If set to zero, the library default (4 MiB) will
|
|
// be used. If set to a negative value, the system will use the
|
|
// smallest amount of memory it can.
|
|
MaxMemory int64
|
|
}
|
|
|
|
// Uplink represents the main entrypoint to Storj V3. An Uplink connects to
|
|
// a specific Satellite and caches connections and resources, allowing one to
|
|
// create sessions delineated by specific access controls.
|
|
type Uplink struct {
|
|
scope
|
|
lib *libuplink.Uplink
|
|
}
|
|
|
|
// NewUplink creates a new Uplink. This is the first step to create an uplink
|
|
// session with a user specified config or with default config, if nil config.
|
|
// Uplink needs also writable temporary directory.
|
|
func NewUplink(config *Config, tempDir string) (*Uplink, error) {
|
|
scope := rootScope(tempDir)
|
|
|
|
cfg := &libuplink.Config{}
|
|
if config != nil {
|
|
cfg.Volatile.TLS.SkipPeerCAWhitelist = true
|
|
cfg.Volatile.MaxInlineSize = memory.Size(config.MaxInlineSize)
|
|
cfg.Volatile.MaxMemory = memory.Size(config.MaxMemory)
|
|
}
|
|
|
|
lib, err := libuplink.NewUplink(scope.ctx, cfg)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
return &Uplink{scope, lib}, nil
|
|
}
|
|
|
|
// Close closes the Uplink. This may not do anything at present, but should
|
|
// still be called to allow forward compatibility. No Project or Bucket
|
|
// objects using this Uplink should be used after calling Close.
|
|
func (uplink *Uplink) Close() error {
|
|
uplink.cancel()
|
|
return safeError(uplink.lib.Close())
|
|
}
|
|
|
|
// Project represents a specific project access session.
|
|
type Project struct {
|
|
scope
|
|
lib *libuplink.Project
|
|
}
|
|
|
|
// OpenProject returns a Project handle with the given APIKey
|
|
func (uplink *Uplink) OpenProject(satellite string, apikey string) (*Project, error) {
|
|
scope := uplink.scope.child()
|
|
|
|
key, err := libuplink.ParseAPIKey(apikey)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
project, err := uplink.lib.OpenProject(scope.ctx, satellite, key)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
return &Project{scope, project}, nil
|
|
}
|
|
|
|
// Close closes the Project
|
|
func (project *Project) Close() error {
|
|
defer project.cancel()
|
|
return safeError(project.lib.Close())
|
|
}
|
|
|
|
// CreateBucket creates buckets in project
|
|
func (project *Project) CreateBucket(bucketName string, opts *BucketConfig) (*BucketInfo, error) {
|
|
scope := project.scope.child()
|
|
|
|
cfg := libuplink.BucketConfig{}
|
|
if opts != nil {
|
|
cfg.PathCipher = storj.CipherSuite(opts.PathCipher)
|
|
cfg.EncryptionParameters = newStorjEncryptionParameters(opts.EncryptionParameters)
|
|
cfg.Volatile.RedundancyScheme = newStorjRedundancyScheme(opts.RedundancyScheme)
|
|
cfg.Volatile.SegmentsSize = memory.Size(opts.SegmentsSize)
|
|
}
|
|
|
|
bucket, err := project.lib.CreateBucket(scope.ctx, bucketName, &cfg)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
return newBucketInfo(bucket), nil
|
|
}
|
|
|
|
// OpenBucket returns a Bucket handle with the given EncryptionAccess
|
|
// information.
|
|
func (project *Project) OpenBucket(bucketName string, encCtx *EncryptionCtx) (*Bucket, error) {
|
|
scope := project.scope.child()
|
|
|
|
bucket, err := project.lib.OpenBucket(scope.ctx, bucketName, encCtx.lib)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
return &Bucket{bucket.Name, scope, bucket}, nil
|
|
}
|
|
|
|
// GetBucketInfo returns info about the requested bucket if authorized.
|
|
func (project *Project) GetBucketInfo(bucketName string) (*BucketInfo, error) {
|
|
scope := project.scope.child()
|
|
|
|
bucket, _, err := project.lib.GetBucketInfo(scope.ctx, bucketName)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
return newBucketInfo(bucket), nil
|
|
}
|
|
|
|
// ListBuckets will list authorized buckets.
|
|
func (project *Project) ListBuckets(cursor string, direction, limit int) (*BucketList, error) {
|
|
scope := project.scope.child()
|
|
opts := libuplink.BucketListOptions{
|
|
Cursor: cursor,
|
|
Direction: storj.ListDirection(direction),
|
|
Limit: limit,
|
|
}
|
|
list, err := project.lib.ListBuckets(scope.ctx, &opts)
|
|
if err != nil {
|
|
return nil, safeError(err)
|
|
}
|
|
|
|
return &BucketList{list}, nil
|
|
}
|
|
|
|
// DeleteBucket deletes a bucket if authorized. If the bucket contains any
|
|
// Objects at the time of deletion, they may be lost permanently.
|
|
func (project *Project) DeleteBucket(bucketName string) error {
|
|
scope := project.scope.child()
|
|
|
|
err := project.lib.DeleteBucket(scope.ctx, bucketName)
|
|
return safeError(err)
|
|
}
|
|
|
|
func safeError(err error) error {
|
|
// workaround to avoid gomobile panic because of "hash of unhashable type errs.combinedError"
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
return fmt.Errorf("%v", err.Error())
|
|
}
|