diff --git a/pixelapi/pixelapi.go b/pixelapi/pixelapi.go index f97b65f..e3e5102 100644 --- a/pixelapi/pixelapi.go +++ b/pixelapi/pixelapi.go @@ -5,6 +5,8 @@ import ( "io" "io/ioutil" "net/http" + "net/url" + "strings" "github.com/Fornaxian/log" ) @@ -19,6 +21,13 @@ func New(apiEndpoint string) *PixelAPI { return &PixelAPI{apiEndpoint} } +// Error is either an error that occurred during the API request +// (ReqError = true), or an error that was returned from the Pixeldrain API +// (ReqError = false). The Success field is also returned by the Pixeldrain API, +// but since this is struct represents an Error it will usually be false. +// +// When ReqError is true the Value field will contain a Go error message. When +// it's false it will contain a Pixeldrain API error code. type Error struct { ReqError bool Success bool `json:"success"` @@ -28,24 +37,6 @@ type Error struct { func (e Error) Error() string { return e.Value } -func errorResponseFromJSON(j string) *Error { - var r = &Error{} - var err = json.Unmarshal([]byte(j), r) - if err != nil { - r.Success = false - r.ReqError = true - r.Value = err.Error() - } - return r -} -func errorResponseFromError(e error) *Error { - var r = &Error{} - r.Success = false - r.ReqError = true - r.Value = e.Error() - return r -} - func getJSON(url string, target interface{}) *Error { req, err := http.NewRequest("GET", url, nil) if err != nil { @@ -58,7 +49,6 @@ func getJSON(url string, target interface{}) *Error { } client := &http.Client{} - resp, err := client.Do(req) if err != nil { return &Error{ @@ -70,38 +60,7 @@ func getJSON(url string, target interface{}) *Error { } defer resp.Body.Close() - var jdec = json.NewDecoder(resp.Body) - - // Test for client side and server side errors - if resp.StatusCode >= 400 { - var errResp = &Error{ - ReqError: false, - } - err = jdec.Decode(&errResp) - if err != nil { - log.Error("Can't decode this: %v", err) - return &Error{ - ReqError: true, - Success: false, - Value: err.Error(), - Message: err.Error(), - } - } - return errResp - } - - err = jdec.Decode(target) - if err != nil { - r, _ := ioutil.ReadAll(resp.Body) - log.Error("Can't decode this: %v. %s", err, r) - return &Error{ - ReqError: true, - Success: false, - Value: err.Error(), - Message: err.Error(), - } - } - return nil + return parseJSONResponse(resp, target) } func getString(url string) (string, error) { @@ -139,3 +98,65 @@ func getRaw(url string) (io.ReadCloser, error) { return resp.Body, err } + +func postForm(url string, vals url.Values, target interface{}) *Error { + req, err := http.NewRequest("POST", url, strings.NewReader(vals.Encode())) + if err != nil { + return &Error{ + ReqError: true, + Success: false, + Value: err.Error(), + Message: err.Error(), + } + } + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return &Error{ + ReqError: true, + Success: false, + Value: err.Error(), + Message: err.Error(), + } + } + + defer resp.Body.Close() + return parseJSONResponse(resp, target) +} + +func parseJSONResponse(resp *http.Response, target interface{}) *Error { + var jdec = json.NewDecoder(resp.Body) + var err error + + // Test for client side and server side errors + if resp.StatusCode >= 400 { + var errResp = &Error{ + ReqError: false, + } + err = jdec.Decode(&errResp) + if err != nil { + log.Error("Can't decode this: %v", err) + return &Error{ + ReqError: true, + Success: false, + Value: err.Error(), + Message: err.Error(), + } + } + return errResp + } + + err = jdec.Decode(target) + if err != nil { + r, _ := ioutil.ReadAll(resp.Body) + log.Error("Can't decode this: %v. %s", err, r) + return &Error{ + ReqError: true, + Success: false, + Value: err.Error(), + Message: err.Error(), + } + } + return nil +} diff --git a/pixelapi/user.go b/pixelapi/user.go new file mode 100644 index 0000000..f7d8ad9 --- /dev/null +++ b/pixelapi/user.go @@ -0,0 +1,35 @@ +package pixelapi + +import ( + "net/url" +) + +type Registration struct { + Success bool `json:"success"` + Message string `json:"message,omitempty"` + Errors []RegistrationError `json:"errors,omitempty"` +} + +type RegistrationError struct { + Code string `json:"error_code"` + Message string `json:"message"` +} + +// UserRegister registers a new user on the Pixeldrain server. username and +// password are always required. email is optional, but without it you will +// never be able to reset your password in case you forget it. captcha depends +// on whether reCaptcha is enabled on the Pixeldrain server, this can be checked +// through the GetRecaptcha function. +func (p *PixelAPI) UserRegister(username, email, password, captcha string) (resp *Registration, err *Error) { + resp = &Registration{} + var form = url.Values{} + form.Add("username", username) + form.Add("email", email) + form.Add("password", password) + form.Add("recaptcha_response", captcha) + err = postForm(p.apiEndpoint+"/user/register", form, resp) + if err != nil { + return nil, err + } + return resp, nil +} diff --git a/res/template/account/login.html b/res/template/account/login.html index 4126f28..f56c8fc 100644 --- a/res/template/account/login.html +++ b/res/template/account/login.html @@ -30,7 +30,7 @@