package happydomain import ( "bytes" "encoding/json" "fmt" "io" "net/http" "net/url" "path" "git.happydns.org/happyDomain/api" model "git.happydns.org/happyDomain/model" ) var DefaultAPI = HappyDomainAPI{ API: url.URL{ Scheme: "https", Host: "app.happydomain.org", Path: "/api", }, } type HappyDomainAPI struct { API url.URL Token *string } func NewAPI(api_url url.URL, token *string) *HappyDomainAPI { return &HappyDomainAPI{ API: api_url, Token: token, } } func (h *HappyDomainAPI) Login(username, password string) error { url := h.API url.Path = path.Join(url.Path, "auth") form := api.LoginForm{ Email: username, Password: password, } formstream := new(bytes.Buffer) err := json.NewEncoder(formstream).Encode(form) if err != nil { return err } res, err := http.Post(url.String(), "application/json", formstream) if err != nil { return err } defer res.Body.Close() if res.StatusCode != http.StatusOK { return handleError(res) } for _, cookie := range res.Cookies() { if cookie.Name == api.COOKIE_NAME { h.Token = &cookie.Value return nil } } return fmt.Errorf("unable to find authentication token.") } func (h *HappyDomainAPI) NewRequest(method string, u *url.URL, body io.Reader) (*http.Request, error) { req, err := http.NewRequest(method, u.String(), body) if err != nil { return nil, err } if h.Token != nil { req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", *h.Token)) } return req, nil } func (h *HappyDomainAPI) DoRequest(method string, u *url.URL, body io.Reader) (*http.Response, error) { req, err := h.NewRequest(method, u, body) if err != nil { return nil, err } resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { defer resp.Body.Close() return nil, handleError(resp) } return resp, nil } func (h *HappyDomainAPI) DomainList() ([]Domain, error) { u := h.API u.Path = path.Join(u.Path, "domains") resp, err := h.DoRequest("GET", &u, nil) if err != nil { return nil, err } defer resp.Body.Close() var domains []*model.Domain err = json.NewDecoder(resp.Body).Decode(&domains) if err != nil { return nil, err } return h.NewDomainsFromModel(domains), nil } func (h *HappyDomainAPI) ProviderList() ([]*Provider, error) { u := h.API u.Path = path.Join(u.Path, "providers") resp, err := h.DoRequest("GET", &u, nil) if err != nil { return nil, err } defer resp.Body.Close() var providers []*model.ProviderCombined err = json.NewDecoder(resp.Body).Decode(&providers) if err != nil { return nil, err } var ret []*Provider for _, p := range providers { ret = append(ret, h.NewProvider(p)) } return ret, nil } func (h *HappyDomainAPI) ProviderGet(pid model.Identifier) (*Provider, error) { u := h.API u.Path = path.Join(u.Path, "providers", pid.String()) resp, err := h.DoRequest("GET", &u, nil) if err != nil { return nil, err } defer resp.Body.Close() var provider *model.ProviderCombined err = json.NewDecoder(resp.Body).Decode(&provider) if err != nil { return nil, err } return h.NewProvider(provider), nil } func (h *HappyDomainAPI) ProviderAdd(kind, name string, data *model.Provider) (*Provider, error) { u := h.API u.Path = path.Join(u.Path, "providers") formstream := new(bytes.Buffer) err := json.NewEncoder(formstream).Encode(model.ProviderCombined{ ProviderMeta: model.ProviderMeta{ Type: kind, Comment: name, }, Provider: *data, }) if err != nil { return nil, err } resp, err := h.DoRequest("POST", &u, formstream) if err != nil { return nil, err } defer resp.Body.Close() var provider *model.ProviderCombined err = json.NewDecoder(resp.Body).Decode(&provider) if err != nil { return nil, err } return h.NewProvider(provider), nil } func handleError(resp *http.Response) error { var e model.Error err := json.NewDecoder(resp.Body).Decode(&e) if err != nil { return err } return fmt.Errorf("%s", e.Err) }