storj.io/uplink@v1.13.0/edge/access.go (about) 1 // Copyright (C) 2021 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 package edge 5 6 import ( 7 "context" 8 "errors" 9 10 "github.com/zeebo/errs" 11 12 "storj.io/common/pb" 13 "storj.io/common/rpc" 14 "storj.io/uplink" 15 ) 16 17 // We use uplinkError.* instead of errs.* to add a prefix "uplink" to every error. 18 // It is not called "edge" on purpose so that the entire library emits the same error prefix. 19 var uplinkError = errs.Class("uplink") 20 21 // ErrAuthDialFailed is a network or protocol error. 22 var ErrAuthDialFailed = errors.New("dial to auth service failed") 23 24 // ErrRegisterAccessFailed is an internal error in the auth service. 25 var ErrRegisterAccessFailed = errors.New("register access for edge services failed") 26 27 // Credentials give access to the multi-tenant gateway. 28 // These work in S3 clients. 29 type Credentials struct { 30 // Base32 31 // This is also used in the linkshare url path. 32 AccessKeyID string 33 // Base32 34 SecretKey string 35 // HTTP(S) URL to the gateway. 36 Endpoint string 37 } 38 39 // RegisterAccessOptions contains optional parameters for RegisterAccess. 40 type RegisterAccessOptions struct { 41 // Whether objects can be read without authentication. 42 Public bool 43 } 44 45 // RegisterAccess gets credentials for the Storj-hosted Gateway and linkshare service. 46 // All files accessible under the Access are then also accessible via those services. 47 // If you call this function a lot, and the use case allows it, 48 // please limit the lifetime of the credentials 49 // by setting Permission.NotAfter when creating the Access. 50 func (config *Config) RegisterAccess( 51 ctx context.Context, 52 access *uplink.Access, 53 options *RegisterAccessOptions, 54 ) (*Credentials, error) { 55 if config.AuthServiceAddress == "" { 56 return nil, uplinkError.New("AuthServiceAddress is missing") 57 } 58 59 if options == nil { 60 options = &RegisterAccessOptions{} 61 } 62 63 var conn *rpc.Conn 64 var err error 65 if config.InsecureUnencryptedConnection || config.InsecureSkipVerify { 66 conn, err = config.createDialer().DialAddressUnencrypted(ctx, config.AuthServiceAddress) 67 } else { 68 conn, err = config.createDialer().DialAddressHostnameVerification(ctx, config.AuthServiceAddress) 69 } 70 71 if err != nil { 72 return nil, uplinkError.New("%w: %v", ErrAuthDialFailed, err) 73 } 74 defer func() { 75 _ = conn.Close() 76 }() 77 78 client := pb.NewDRPCEdgeAuthClient(conn) 79 80 serializedAccess, err := access.Serialize() 81 if err != nil { 82 return nil, uplinkError.Wrap(err) 83 } 84 85 registerGatewayResponse, err := client.RegisterAccess(ctx, &pb.EdgeRegisterAccessRequest{ 86 AccessGrant: serializedAccess, 87 Public: options.Public, 88 }) 89 90 if err != nil { 91 return nil, uplinkError.New("%w: %v", ErrRegisterAccessFailed, err) 92 } 93 94 credentials := Credentials{ 95 AccessKeyID: registerGatewayResponse.AccessKeyId, 96 SecretKey: registerGatewayResponse.SecretKey, 97 Endpoint: registerGatewayResponse.Endpoint, 98 } 99 100 return &credentials, nil 101 }