-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #80 from mikewilson-dd/memory-data-store
Add in memory keyring.
- Loading branch information
Showing
7 changed files
with
256 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
.vagrant | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package examples | ||
|
||
import ( | ||
"github.com/99designs/keyring" | ||
"log" | ||
) | ||
|
||
// ExampleOpen is an example of how you would create a new keyring and how you would | ||
// retrieve data from it. | ||
func ExampleOpen() { | ||
// Use the best keyring implementation for your operating system | ||
kr, err := keyring.Open(keyring.Config{ | ||
ServiceName: "my-service", | ||
}) | ||
|
||
v, err := kr.Get("llamas") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
log.Printf("llamas was %v", v) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,64 @@ | ||
package keyring_test | ||
package keyring | ||
|
||
import ( | ||
"log" | ||
import "testing" | ||
|
||
"github.com/99designs/keyring" | ||
) | ||
func TestItemsEqual(t *testing.T) { | ||
i := Item{ | ||
Key: "key", | ||
Data: []byte("data"), | ||
Label: "label", | ||
Description: "description", | ||
KeychainNotTrustApplication: false, | ||
KeychainNotSynchronizable: false, | ||
} | ||
|
||
// We're basically going to create copies of i and make sure each field difference generates a false return value | ||
// from Equals. | ||
|
||
// First, make sure identity is true. | ||
o := i | ||
if !i.Equals(o) { | ||
t.Fatalf("identity case should result in true") | ||
} | ||
|
||
// Test key differences | ||
o.Key = "something else" | ||
if i.Equals(o) { | ||
t.Fatalf("key difference should result in false") | ||
} | ||
|
||
func ExampleOpen() { | ||
// Use the best keyring implementation for your operating system | ||
kr, err := keyring.Open(keyring.Config{ | ||
ServiceName: "my-service", | ||
}) | ||
// Test key differences | ||
o = i | ||
o.Data = []byte("something else") | ||
if i.Equals(o) { | ||
t.Fatalf("data difference should result in false") | ||
} | ||
|
||
// Test label differences | ||
o = i | ||
o.Label = "something else" | ||
if i.Equals(o) { | ||
t.Fatalf("label difference should result in false") | ||
} | ||
|
||
v, err := kr.Get("llamas") | ||
if err != nil { | ||
log.Fatal(err) | ||
// Test description differences | ||
o = i | ||
o.Description = "something else" | ||
if i.Equals(o) { | ||
t.Fatalf("description difference should result in false") | ||
} | ||
|
||
log.Printf("llamas was %v", v) | ||
// Test KeychainNotTrustApplication differences | ||
o = i | ||
o.KeychainNotTrustApplication = true | ||
if i.Equals(o) { | ||
t.Fatalf("KeyChainNotTrustApplication difference should result in false") | ||
} | ||
|
||
// Test KeychainNotSynchronizable differences | ||
o = i | ||
o.KeychainNotSynchronizable = true | ||
if i.Equals(o) { | ||
t.Fatalf("KeyChainNotSynchronizable difference should result in false") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package keyring | ||
|
||
import ( | ||
"sync" | ||
) | ||
|
||
func init() { | ||
supportedBackends[MemoryBackend] = opener(func(cfg Config) (Keyring, error) { | ||
memory := newMemoryKeyring() | ||
|
||
return memory, nil | ||
}) | ||
} | ||
|
||
type memoryKeyring struct { | ||
mutex sync.RWMutex | ||
mapStore map[string]Item | ||
} | ||
|
||
func newMemoryKeyring() *memoryKeyring { | ||
return &memoryKeyring{ | ||
mutex: sync.RWMutex{}, | ||
mapStore: map[string]Item{}, | ||
} | ||
} | ||
|
||
func (k *memoryKeyring) Get(key string) (Item, error) { | ||
k.mutex.RLock() | ||
defer k.mutex.RUnlock() | ||
|
||
if item, ok := k.mapStore[key]; !ok { | ||
return Item{}, ErrKeyNotFound | ||
} else { | ||
return item, nil | ||
} | ||
} | ||
|
||
// GetMetadata for memory returns an error indicating that it's unsupported | ||
// for this backend. | ||
// | ||
// It doesn't really apply to the memory backend, as it's a simple wrapper around a map. | ||
func (k *memoryKeyring) GetMetadata(_ string) (Metadata, error) { | ||
return Metadata{}, ErrNoAvailImpl | ||
} | ||
|
||
func (k *memoryKeyring) Set(item Item) error { | ||
k.mutex.Lock() | ||
defer k.mutex.Unlock() | ||
|
||
k.mapStore[item.Key] = item | ||
return nil | ||
} | ||
|
||
func (k *memoryKeyring) Remove(key string) error { | ||
k.mutex.Lock() | ||
defer k.mutex.Unlock() | ||
|
||
delete(k.mapStore, key) | ||
return nil | ||
} | ||
|
||
func (k *memoryKeyring) Keys() ([]string, error) { | ||
k.mutex.RLock() | ||
defer k.mutex.RUnlock() | ||
|
||
keys := []string{} | ||
for k := range k.mapStore { | ||
keys = append(keys, k) | ||
} | ||
return keys, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package keyring | ||
|
||
import "testing" | ||
|
||
func TestSetAndGets(t *testing.T) { | ||
k := newMemoryKeyring() | ||
|
||
// Set a few items and try to retrieve them | ||
items := []Item{ | ||
makeItem("key1", "data1", "label1", "description1"), | ||
makeItem("key2", "data2", "label2", "description2"), | ||
makeItem("key3", "data3", "label3", "description3"), | ||
makeItem("key4", "data4", "label4", "description4"), | ||
} | ||
|
||
for _, item := range items { | ||
k.Set(item) | ||
} | ||
|
||
for _, item := range items { | ||
getItem, _ := k.Get(item.Key) | ||
|
||
if !item.Equals(getItem) { | ||
t.Fatalf("%s is not equal to its version from the store", item.Key) | ||
} | ||
} | ||
|
||
if _, err := k.Get("non-existent key"); err != ErrKeyNotFound { | ||
t.Fatalf("error for non-existent key should have been key not found, was: %v", err) | ||
} | ||
} | ||
|
||
func TestRemove(t *testing.T) { | ||
k := newMemoryKeyring() | ||
|
||
item := makeItem("key1", "data1", "label1", "description1") | ||
|
||
k.Set(item) | ||
|
||
if _, err := k.Get(item.Key); err != nil { | ||
t.Fatalf("unable to find stored item") | ||
} | ||
|
||
k.Remove(item.Key) | ||
|
||
if _, err := k.Get(item.Key); err == nil { | ||
t.Fatalf("after removal, should not have been able to find item") | ||
} | ||
} | ||
|
||
func TestKeys(t *testing.T) { | ||
k := newMemoryKeyring() | ||
|
||
items := []Item{ | ||
makeItem("key1", "data1", "label1", "description1"), | ||
makeItem("key2", "data2", "label2", "description2"), | ||
makeItem("key3", "data3", "label3", "description3"), | ||
makeItem("key4", "data4", "label4", "description4"), | ||
} | ||
|
||
for _, item := range items { | ||
k.Set(item) | ||
} | ||
|
||
keys, _ := k.Keys() | ||
for _, item := range items { | ||
foundKey := false | ||
|
||
for _, key := range keys { | ||
if item.Key == key { | ||
foundKey = true | ||
break | ||
} | ||
} | ||
|
||
if !foundKey { | ||
t.Errorf("unable to find key %s", item.Key) | ||
} | ||
} | ||
} | ||
|
||
func makeItem(key, data, label, description string) Item { | ||
return Item{ | ||
Key: key, | ||
Data: []byte(data), | ||
Label: label, | ||
Description: description, | ||
} | ||
} |