github.com/metacurrency/holochain@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 }