key

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2021 License: MIT Imports: 16 Imported by: 0

README

We allow different kind of keys to be stored. Examples are API keys, and Auth keys. In practice, these keys are very similar and creating their own storage systems for them would result in lots of duplicate code (which our CI system does not approve of).

So instead, we have a generic "key" system that allows us to store multiple types of keys, each with their own properties. This however, results in a more complex setup, as Go isn't able to do OO.

+-------------------+           +------------------+          +-----------+
| ApiKeyRepository  |           | (storageBackend) |          | boltRepo  |
|   (ApiKeyRepo)    | ------+-> |                  | -+-----> |           |
+-------------------+       |   +------------------+  |       +-----------+
                            |                         |
                            |                         |
                            |                         |
+-------------------+       |                         |       +-----------+
| AuthKeyRepository |       |                         |       | mockRepo  |
|   (AuthKeyRepo)   | ------+                         +-----> |           |
+-------------------+                                 |       +-----------+
                                                      |       +-----------+
                                                      +-----> | redisRepo |
                                                              +-----------+

Both the ApiKeyRepository and AuthKeyRepository deal with the corresponding ApiKeyType and AuthKeyType structures. They both are a small wrapper around a storage repository that deals with interfaces{}. So, we convert these interfaces to actual correct types in the api and key repository:

func (a AuthKeyRepository) Fetch(ID string) (AuthKeyType, error) {
    v := &AuthkeyType{}
	err := a.repo.Fetch(ID, v)
	return v, err
}

The storage repository will simply fetch data from the storage, and unmarshals this trough the given v value. Sometimes we need to use GenericKey functionality (GetID(), GetHashAddress()), which is where we typecast this at certain places in the storage repositories.

There is a bit of reflection going on when dealing with lists. This is because we need to allocate items, but we don't know which items. We deal with this in the Fetch methods by passing the actual storage value, but we cannot do this in the FetchByHash method. Instead, we pass again, a single structure (like in Fetch()), and based on that value, we create with reflection a new variable. This variable gets marshalled through JSON and stored in the list.

Finally, the ApiKey and AuthKey repositories will retrieve these lists with undefined interfaces, and cast them to either []ApiKeyType or []AuthKeyType.

With the amount of effort it took to get this up and running decently, DRY isn't always holy.

Documentation

Index

Constants

View Source
const BoltDBFile = "keys.db"

BoltDBFile is the filename to store the boltdb database

Variables

This section is empty.

Functions

func GenerateKey

func GenerateKey(prefix string, n int) string

GenerateKey generates a random key based on a given string length

Types

type APIKeyRepo

type APIKeyRepo interface {
	FetchByHash(h string) ([]APIKeyType, error)
	Fetch(ID string) (*APIKeyType, error)
	Store(v APIKeyType) error
	Remove(v APIKeyType) error
}

APIKeyRepo is the repository to the outside world. It allows us to fetch and store api keys

func NewAPIBoltRepository

func NewAPIBoltRepository(dbPath string) APIKeyRepo

NewAPIBoltRepository initializes a new BoltDb repository

func NewAPIKeyRedisRepository

func NewAPIKeyRedisRepository(opts *redis.Options) APIKeyRepo

NewAPIKeyRedisRepository initializes a new repository

func NewAPIMockRepository

func NewAPIMockRepository() APIKeyRepo

NewAPIMockRepository initializes a new mock repository

type APIKeyRepository

type APIKeyRepository struct {
	// contains filtered or unexported fields
}

APIKeyRepository is a repository to fetch and store API keys

func (APIKeyRepository) Fetch

func (a APIKeyRepository) Fetch(ID string) (*APIKeyType, error)

Fetch will get a single API key

func (APIKeyRepository) FetchByHash

func (a APIKeyRepository) FetchByHash(h string) ([]APIKeyType, error)

FetchByHash will fetch all api keys for the given address hash

func (APIKeyRepository) Remove

func (a APIKeyRepository) Remove(v APIKeyType) error

Remove will remove a single api key

func (APIKeyRepository) Store

func (a APIKeyRepository) Store(v APIKeyType) error

Store will store a single api key

type APIKeyType

type APIKeyType struct {
	ID          string     `json:"key"`          // ID
	AddressHash *hash.Hash `json:"address_hash"` // Address hash
	Expires     time.Time  `json:"expires"`      // Time the key expires
	Permissions []string   `json:"permissions"`  // List of permissions for this key
	Admin       bool       `json:"admin"`        // Admin key or not?
	Desc        string     `json:"description"`  // Description of the key
}

APIKeyType represents a key with a validity and permissions. When admin is true, permission checks are always true

func NewAPIAccountKey

func NewAPIAccountKey(addrHash hash.Hash, perms []string, expiry time.Time, desc string) APIKeyType

NewAPIAccountKey creates a new key with the given permissions and duration for the given account

func NewAPIAdminKey

func NewAPIAdminKey(expiry time.Time, desc string) APIKeyType

NewAPIAdminKey creates a new admin key

func NewAPIKey

func NewAPIKey(perms []string, expiry time.Time, desc string) APIKeyType

NewAPIKey creates a new key with the given permissions and duration

func (*APIKeyType) GetAddressHash

func (key *APIKeyType) GetAddressHash() *hash.Hash

GetAddressHash returns address hash or nil

func (*APIKeyType) GetID

func (key *APIKeyType) GetID() string

GetID returns ID

func (*APIKeyType) HasPermission

func (key *APIKeyType) HasPermission(perm string, addrHash *hash.Hash) bool

HasPermission returns true when this key contains the given permission, or when the key is an admin key (granted all permissions)

type AuthKeyRepo

type AuthKeyRepo interface {
	FetchByHash(h string) ([]AuthKeyType, error)
	Fetch(ID string) (*AuthKeyType, error)
	Store(v AuthKeyType) error
	Remove(v AuthKeyType) error
}

AuthKeyRepo is the repository to the outside world. It allows us to fetch and store auth keys

func NewAuthBoltRepository

func NewAuthBoltRepository(dbPath string) AuthKeyRepo

NewAuthBoltRepository initializes a new BoltDb repository

func NewAuthKeyRedisRepository

func NewAuthKeyRedisRepository(opts *redis.Options) AuthKeyRepo

NewAuthKeyRedisRepository initializes a new Redis repository

func NewAuthMockRepository

func NewAuthMockRepository() AuthKeyRepo

NewAuthMockRepository initializes a new mock repository

type AuthKeyRepository

type AuthKeyRepository struct {
	// contains filtered or unexported fields
}

AuthKeyRepository is a repository to fetch and store auth keys

func (AuthKeyRepository) Fetch

func (a AuthKeyRepository) Fetch(ID string) (*AuthKeyType, error)

Fetch will get a single API key

func (AuthKeyRepository) FetchByHash

func (a AuthKeyRepository) FetchByHash(h string) ([]AuthKeyType, error)

FetchByHash will fetch all api keys for the given address hash

func (AuthKeyRepository) Remove

func (a AuthKeyRepository) Remove(v AuthKeyType) error

Remove will remove a single api key

func (AuthKeyRepository) Store

func (a AuthKeyRepository) Store(v AuthKeyType) error

Store will store a single api key

type AuthKeyType

type AuthKeyType struct {
	Fingerprint string           `json:"fingerprint"`  // Fingerprint / ID
	AddressHash hash.Hash        `json:"address_hash"` // Address hash
	Expires     time.Time        `json:"expires"`      // Expiry time
	PublicKey   *bmcrypto.PubKey `json:"public_key"`   // Actual public key
	Signature   string           `json:"signature"`    // Signed public key by the owner's private key
	Description string           `json:"description"`  // User description
}

AuthKeyType represents a public key that is authorized to send email. This public key is signed by the private key of the owner and stored in the signature.

func NewAuthKey

func NewAuthKey(addrHash hash.Hash, pubKey *bmcrypto.PubKey, signature string, expiry time.Time, desc string) AuthKeyType

NewAuthKey creates a new authorized key

func (AuthKeyType) GetAddressHash

func (a AuthKeyType) GetAddressHash() *hash.Hash

GetAddressHash returns address hash

func (AuthKeyType) GetID

func (a AuthKeyType) GetID() string

GetID returns fingerprint of the public key

func (*AuthKeyType) Sign

func (a *AuthKeyType) Sign(privkey bmcrypto.PrivKey) error

Sign will sign the current authentication key with a private key

type GenericKey

type GenericKey interface {
	GetID() string
	GetAddressHash() *hash.Hash
}

GenericKey is a generic structure for storing and fetching keys

type StorageBackend

type StorageBackend interface {
	FetchByHash(h string, v interface{}) (interface{}, error)
	Fetch(ID string, v interface{}) error
	Store(v GenericKey) error
	Remove(v GenericKey) error
}

StorageBackend is the main backend interface which can stores undefined structures. This can be api keys or auth key or even other kind of keys.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL