auth

Paddy 2014-09-07 Parent:88523dab00a5 Child:690561c6619a

33:607708cd8829 Go to Latest

auth/client.go

Add more tests for ClientStores. Test that deleting a client that doesn't exist throws an ErrClientNotFound. Test that adding a client twice returns an ErrClientAlreadyExists. Test that clients retrieve have properties that all match the client that was stored. Remove the unused error return from the internal MemoryStore helper for getting a list of clients by their OwnerID. If a profile doesn't exist, return an empty list of clients, as we're technically returning any client that has that OwnerID. There's no guarantee that that OwnerID is actually valid.

History
1 package auth
3 import (
4 "errors"
6 "secondbit.org/uuid"
7 )
9 var (
10 ErrClientNotFound = errors.New("Client not found in ClientStore.")
11 ErrClientAlreadyExists = errors.New("Client already exists in ClientStore.")
12 )
14 // Client represents a client that grants access
15 // to the auth server, exchanging grants for tokens,
16 // and tokens for access.
17 type Client struct {
18 ID uuid.ID
19 Secret string
20 RedirectURI string
21 OwnerID uuid.ID
22 Name string
23 Logo string
24 Website string
25 }
27 type ClientChange struct {
28 Secret *string
29 RedirectURI *string
30 OwnerID uuid.ID
31 Name *string
32 Logo *string
33 Website *string
34 }
36 // ClientStore abstracts the storage interface for
37 // storing and retrieving Clients.
38 type ClientStore interface {
39 GetClient(id uuid.ID) (Client, error)
40 SaveClient(client Client) error
41 UpdateClient(id uuid.ID, change ClientChange) error
42 DeleteClient(id uuid.ID) error
43 ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error)
44 }
46 func (m *Memstore) GetClient(id uuid.ID) (Client, error) {
47 m.clientLock.RLock()
48 defer m.clientLock.RUnlock()
49 c, ok := m.clients[id.String()]
50 if !ok {
51 return Client{}, ErrClientNotFound
52 }
53 return c, nil
54 }
56 func (m *Memstore) SaveClient(client Client) error {
57 m.clientLock.Lock()
58 defer m.clientLock.Unlock()
59 if _, ok := m.clients[client.ID.String()]; ok {
60 return ErrClientAlreadyExists
61 }
62 m.clients[client.ID.String()] = client
63 m.profileClientLookup[client.OwnerID.String()] = append(m.profileClientLookup[client.OwnerID.String()], client.ID)
64 return nil
65 }
67 func (m *Memstore) UpdateClient(id uuid.ID, change ClientChange) error {
68 return nil
69 }
71 func (m *Memstore) DeleteClient(id uuid.ID) error {
72 client, err := m.GetClient(id)
73 if err != nil {
74 return err
75 }
76 m.clientLock.Lock()
77 defer m.clientLock.Unlock()
78 delete(m.clients, id.String())
79 pos := -1
80 for p, item := range m.profileClientLookup[client.OwnerID.String()] {
81 if item.Equal(id) {
82 pos = p
83 break
84 }
85 }
86 if pos >= 0 {
87 m.profileClientLookup[client.OwnerID.String()] = append(m.profileClientLookup[client.OwnerID.String()][:pos], m.profileClientLookup[client.OwnerID.String()][pos+1:]...)
88 }
89 return nil
90 }
92 func (m *Memstore) ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error) {
93 ids := m.lookupClientsByProfileID(ownerID.String())
94 if len(ids) > num+offset {
95 ids = ids[offset : num+offset]
96 } else if len(ids) > offset {
97 ids = ids[offset:]
98 } else {
99 return []Client{}, nil
100 }
101 clients := []Client{}
102 for _, id := range ids {
103 client, err := m.GetClient(id)
104 if err != nil {
105 return []Client{}, err
106 }
107 clients = append(clients, client)
108 }
109 return clients, nil
110 }