github.com/holochain/holochain-proto@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/capabilities.go (about)

     1  // Copyright (C) 2013-2017, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.)
     2  // Use of this source code is governed by GPLv3 found in the LICENSE file
     3  //----------------------------------------------------------------------------------------
     4  // implements a general way for recording capabilities that can be stored, confirmed and revoked
     5  //
     6  // Used by various parts of the system, like for api keys for bridging between apps, etc.
     7  
     8  package holochain
     9  
    10  import (
    11  	"errors"
    12  	"fmt"
    13  	"github.com/tidwall/buntdb"
    14  	"math/rand"
    15  )
    16  
    17  type Capability struct {
    18  	Token string
    19  	db    *buntdb.DB
    20  	//Who list of public keys for whom this it valid
    21  }
    22  
    23  var CapabilityInvalidErr = errors.New("invalid capability")
    24  
    25  func makeToken(capability string) (token string) {
    26  	return fmt.Sprintf("%d", rand.Int63())
    27  }
    28  
    29  // NewCapability returns and registers a capability of a type, for a specific or anyone if who is nil
    30  func NewCapability(db *buntdb.DB, capability string, who interface{}) (c *Capability, err error) {
    31  	c = &Capability{db: db}
    32  	c.Token = makeToken(capability)
    33  	err = db.Update(func(tx *buntdb.Tx) error {
    34  		Debugf("NewCapability: save token:%s\n", c.Token)
    35  		_, _, err = tx.Set("tok:"+c.Token, capability, nil)
    36  		if err != nil {
    37  			return err
    38  		}
    39  		return nil
    40  	})
    41  	return
    42  }
    43  
    44  // Validate checks to see if the token has been registered and returns the capability it represent
    45  func (c *Capability) Validate(who interface{}) (capability string, err error) {
    46  	err = c.db.View(func(tx *buntdb.Tx) (e error) {
    47  		Debugf("Validate: get token:%s\n", c.Token)
    48  		capability, e = tx.Get("tok:" + c.Token)
    49  		if e == buntdb.ErrNotFound {
    50  			e = CapabilityInvalidErr
    51  		}
    52  		return
    53  	})
    54  	return
    55  }
    56  
    57  // Revoke unregisters the capability for a peer
    58  func (c *Capability) Revoke(who interface{}) (err error) {
    59  	err = c.db.Update(func(tx *buntdb.Tx) (e error) {
    60  		_, e = tx.Get("tok:" + c.Token)
    61  		if e == buntdb.ErrNotFound {
    62  			e = CapabilityInvalidErr
    63  		} else if e == nil {
    64  			_, e = tx.Delete("tok:" + c.Token)
    65  		}
    66  		return e
    67  	})
    68  	return
    69  }