golang-sdk/api.go

205 lines
3.9 KiB
Go

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)
}