auth

Paddy 2015-12-14 Parent:4b68bac597b7

182:cd5f07f9811b Go to Latest

auth/client/client.go

Update nsq import path. go-nsq has moved to nsqio/go-nsq, so we need to update the import path appropriately.

History
paddy@172 1 package client
paddy@172 2
paddy@172 3 import (
paddy@172 4 "bytes"
paddy@172 5 "encoding/json"
paddy@172 6 "errors"
paddy@180 7 "fmt"
paddy@172 8 "io"
paddy@172 9 "net/http"
paddy@172 10 "strings"
paddy@173 11 "time"
paddy@172 12
paddy@172 13 "code.secondbit.org/auth.hg"
paddy@173 14 "code.secondbit.org/uuid.hg"
paddy@172 15 )
paddy@172 16
paddy@172 17 var (
paddy@172 18 ErrNilClient = errors.New("nil client wrapper")
paddy@172 19 ErrNilHTTPClient = errors.New("nil client")
paddy@172 20 )
paddy@172 21
paddy@172 22 type Client struct {
paddy@172 23 client *http.Client
paddy@172 24 address string
paddy@173 25 ID uuid.ID
paddy@172 26 }
paddy@172 27
paddy@173 28 func New(address string, id uuid.ID) *Client {
paddy@172 29 address = strings.TrimRight(address, "/")
paddy@172 30 return &Client{
paddy@172 31 address: address,
paddy@172 32 client: &http.Client{},
paddy@173 33 ID: id,
paddy@172 34 }
paddy@172 35 }
paddy@172 36
paddy@173 37 func (c *Client) do(method, url string, request interface{}, scopes []string, subject uuid.ID) (auth.Response, error) {
paddy@172 38 if c == nil {
paddy@172 39 return auth.Response{}, ErrNilClient
paddy@172 40 }
paddy@172 41 if c.client == nil {
paddy@172 42 return auth.Response{}, ErrNilHTTPClient
paddy@172 43 }
paddy@172 44 var response auth.Response
paddy@172 45 if !strings.HasPrefix(url, "http") {
paddy@172 46 url = strings.TrimLeft(url, "/")
paddy@172 47 url = "/" + url
paddy@172 48 url = c.address + url
paddy@172 49 }
paddy@172 50 var body io.Reader
paddy@172 51 if request != nil {
paddy@172 52 data, err := json.Marshal(request)
paddy@172 53 if err != nil {
paddy@172 54 return response, err
paddy@172 55 }
paddy@172 56 body = bytes.NewBuffer(data)
paddy@172 57 }
paddy@172 58 req, err := http.NewRequest(method, url, body)
paddy@172 59 if err != nil {
paddy@172 60 return response, err
paddy@172 61 }
paddy@173 62 req.Header.Set("Ducky-Scope", strings.Join(scopes, " "))
paddy@173 63 req.Header.Set("Ducky-Issuer", c.ID.String())
paddy@173 64 if subject != nil {
paddy@173 65 req.Header.Set("Ducky-Subject", subject.String())
paddy@173 66 }
paddy@173 67 req.Header.Set("Ducky-Expires", time.Now().Add(time.Hour).String())
paddy@173 68 req.Header.Set("Ducky-Issued-At", time.Now().String())
paddy@173 69 req.Header.Set("Ducky-Not-Before", time.Now().Add(-5*time.Minute).String())
paddy@172 70 resp, err := c.client.Do(req)
paddy@172 71 if err != nil {
paddy@172 72 return response, err
paddy@172 73 }
paddy@172 74 defer resp.Body.Close()
paddy@172 75 switch resp.Header.Get("Content-Type") {
paddy@172 76 case "application/json":
paddy@172 77 dec := json.NewDecoder(resp.Body)
paddy@172 78 err = dec.Decode(&response)
paddy@172 79 if err != nil {
paddy@172 80 return response, err
paddy@172 81 }
paddy@172 82 default:
paddy@172 83 dec := json.NewDecoder(resp.Body)
paddy@172 84 err = dec.Decode(&response)
paddy@172 85 if err != nil {
paddy@172 86 return response, err
paddy@172 87 }
paddy@172 88 }
paddy@180 89 if len(response.Errors) > 0 {
paddy@180 90 return response, httpErrors(response.Errors)
paddy@180 91 }
paddy@172 92 return response, nil
paddy@172 93 }
paddy@172 94
paddy@180 95 type httpErrors []auth.RequestError
paddy@180 96
paddy@180 97 func (h httpErrors) Error() string {
paddy@180 98 return fmt.Sprintf("%+#v", h)
paddy@180 99 }
paddy@180 100
paddy@173 101 func (c *Client) Get(url string, scopes []string, subject uuid.ID) (auth.Response, error) {
paddy@173 102 return c.do("GET", url, nil, scopes, subject)
paddy@172 103 }