exp.upspin.io@v0.0.0-20230625230448-5076e5b595ec/client/gobind/gobind.go (about)

     1  // Copyright 2016 The Upspin Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package gobind provides experimental Go bindings for a simplified
     6  // Upspin Client and related data structures in such a way that languages
     7  // such as Java and Objective-C can handle and gomobile can export.
     8  // Currently, gomobile cannot export slices other than byte, so slices are
     9  // converted to linked lists when necessary. Unsigned types are not supported
    10  // either, so they're converted to their signed equivalents and truncations
    11  // or roundings are silently ignored.
    12  // This package is experimental and is NOT an official upspin.Client
    13  // implementation. Its definition may change or break without warning.
    14  package gobind // import "exp.upspin.io/client/gobind"
    15  
    16  // To regenerate the .aar archive for Android Java, run:
    17  //	go generate
    18  
    19  //go:generate gomobile bind -target android upspin.io/client/gobind
    20  
    21  import (
    22  	"upspin.io/client"
    23  	"upspin.io/config"
    24  	"upspin.io/factotum"
    25  	"upspin.io/log"
    26  	"upspin.io/upspin"
    27  	"upspin.io/user"
    28  
    29  	// Load everything we need.
    30  	_ "upspin.io/pack/ee"
    31  	_ "upspin.io/pack/plain"
    32  	_ "upspin.io/transports"
    33  )
    34  
    35  // DirEntry represents the most relevant pieces of an upspin.DirEntry for clients.
    36  type DirEntry struct {
    37  	Name         string
    38  	IsDir        bool
    39  	Size         int64
    40  	LastModified int64
    41  	Writer       string
    42  	Next         *DirEntry
    43  }
    44  
    45  // ClientConfig is a setup data structure that configures the Client
    46  // for a given user with keys and server endpoints.
    47  type ClientConfig struct {
    48  	// UserName is the upspin.UserName.
    49  	UserName string
    50  
    51  	// PublicKey is the user's upspin.PublicKey.
    52  	PublicKey string
    53  
    54  	// PrivateKey is the user's private key.
    55  	PrivateKey string
    56  
    57  	// KeyNetAddr is the upspin.NetAddr of an upspin.Remote KeyServer endpoint.
    58  	KeyNetAddr string
    59  
    60  	// StoreNetAddr is the upspin.NetAddr of an upspin.Remote StoreServer endpoint.
    61  	StoreNetAddr string
    62  
    63  	// DirNetAddr is the upspin.NetAddr of an upspin.Remote DirServer endpoint.
    64  	DirNetAddr string
    65  }
    66  
    67  // NewClientConfig returns a new ClientConfig.
    68  func NewClientConfig() *ClientConfig {
    69  	return new(ClientConfig)
    70  }
    71  
    72  // Client is a wrapped upspin.Client.
    73  type Client struct {
    74  	c upspin.Client
    75  }
    76  
    77  // Glob returns a linked list of DirEntry listing the results of the Glob operation.
    78  func (c *Client) Glob(pattern string) (*DirEntry, error) {
    79  	des, err := c.c.Glob(pattern)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	var first *DirEntry
    84  	var last *DirEntry
    85  	for _, de := range des {
    86  		size, err := de.Size()
    87  		if err != nil {
    88  			return nil, err
    89  		}
    90  		dirEntry := &DirEntry{
    91  			Name:         string(de.Name),
    92  			IsDir:        de.IsDir(),
    93  			Size:         size,
    94  			LastModified: int64(de.Time),
    95  			Writer:       string(de.Writer),
    96  		}
    97  		if last != nil {
    98  			last.Next = dirEntry
    99  		} else {
   100  			first = dirEntry
   101  		}
   102  		last = dirEntry
   103  	}
   104  	return first, nil
   105  }
   106  
   107  // Get returns the contents of a path.
   108  func (c *Client) Get(path string) ([]byte, error) {
   109  	return c.c.Get(upspin.PathName(path))
   110  }
   111  
   112  // Put puts the data as the contents of name and returns its reference in the default location (at the default store).
   113  func (c *Client) Put(name string, data []byte) (string, error) {
   114  	entry, err := c.c.Put(upspin.PathName(name), data)
   115  	if err != nil {
   116  		return "", err
   117  	}
   118  	if len(entry.Blocks) == 0 {
   119  		return "<empty>", nil
   120  	}
   121  	return string(entry.Blocks[0].Location.Reference), nil // TODO: This should include all blocks.
   122  }
   123  
   124  // NewClient returns a new Client for a given user's configuration.
   125  func NewClient(clientConfig *ClientConfig) (*Client, error) {
   126  	userName, err := user.Clean(upspin.UserName(clientConfig.UserName))
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  	cfg := config.New()
   131  	cfg = config.SetUserName(cfg, userName)
   132  	cfg = config.SetPacking(cfg, upspin.EEPack)
   133  	f, err := factotum.NewFromKeys([]byte(clientConfig.PublicKey), []byte(clientConfig.PrivateKey), nil)
   134  	if err != nil {
   135  		log.Error.Printf("Error creating factotum: %s", err)
   136  		return nil, err
   137  	}
   138  	cfg = config.SetFactotum(cfg, f)
   139  	se := upspin.Endpoint{
   140  		Transport: upspin.Remote,
   141  		NetAddr:   upspin.NetAddr(clientConfig.StoreNetAddr),
   142  	}
   143  	cfg = config.SetStoreEndpoint(cfg, se)
   144  	de := upspin.Endpoint{
   145  		Transport: upspin.Remote,
   146  		NetAddr:   upspin.NetAddr(clientConfig.DirNetAddr),
   147  	}
   148  	cfg = config.SetDirEndpoint(cfg, de)
   149  	ue := upspin.Endpoint{
   150  		Transport: upspin.Remote,
   151  		NetAddr:   upspin.NetAddr(clientConfig.KeyNetAddr),
   152  	}
   153  	cfg = config.SetKeyEndpoint(cfg, ue)
   154  	return &Client{
   155  		c: client.New(cfg),
   156  	}, nil
   157  }