auth

Paddy 2014-09-01 Parent:9fc5fd8196b4 Child:607708cd8829

31:88523dab00a5 Go to Latest

auth/client.go

Implement ClientStore in Memstore. Add the ClientStore interface implementation to Memstore. Change the ClientStore interface's UpdateClient function to take a new type, ClientChange, rather than enumerating the arguments in the function signature, which is a much cleaner interface. Add tests for the successful (works-as-intended) scenarios involving ClientStores. Ignore UpdateClient for now--I want to do tests that test every combination of ClientUpdate attributes being specified, to be sure that only the attributes specified are updated and that all the attributes specified are updated.

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