From 39404caa6edd4f420c71a88e907c5ffe8753c2fe Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Thu, 21 Jun 2018 23:41:50 +0200 Subject: [PATCH] work on registration form --- pixelapi/pixelapi.go | 123 +++++++++++++++++------------ pixelapi/user.go | 35 ++++++++ res/template/account/login.html | 2 +- res/template/account/register.html | 59 ++++++++++++-- res/template/apidoc.html | 20 ++--- res/template/error.html | 6 +- res/template/fragments/menu.html | 2 +- res/template/history.html | 16 ++-- res/template/home.html | 2 +- webcontroller/templateData.go | 10 ++- webcontroller/userAccount.go | 14 ---- webcontroller/webcontroller.go | 4 +- 12 files changed, 193 insertions(+), 100 deletions(-) create mode 100644 pixelapi/user.go 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 @@
- {{template "menu"}} + {{template "menu" .}}

Log in to your PixelDrain account

diff --git a/res/template/account/register.html b/res/template/account/register.html index 17c6865..b41d5af 100644 --- a/res/template/account/register.html +++ b/res/template/account/register.html @@ -28,28 +28,39 @@ +
- {{template "menu"}} + {{template "menu" .}}

Register a new Pixeldrain account

- + - + + + + + + + - - + + + - +
Username (Used to log in)
used for logging into your account

E-mail address (optional):
+ your e-mail address will only be used for password + resets and important account notifications. +

Enter your password twice:
- (So we can verify that you have not made any typing errors) + (so we can verify that you have not made any typing errors)

Prove that you're not a robot (Click the white box)

@@ -58,6 +69,40 @@ {{template "footer"}}
+ + {{template "analytics"}} diff --git a/res/template/apidoc.html b/res/template/apidoc.html index c6c49f4..659f227 100644 --- a/res/template/apidoc.html +++ b/res/template/apidoc.html @@ -14,11 +14,11 @@ - + {{template "bgpattern"}} - @@ -32,14 +32,14 @@
- {{template "menu"}} + {{template "menu" .}}

PixelDrain API Documentation

Welcome to the Pixeldrain API documentation.
- The methods for uploading and retrieving files don't require an - API key. The methods for creating and retrieving lists also - don't require an API key. All methods which delete or modify a + The methods for uploading and retrieving files don't require an + API key. The methods for creating and retrieving lists also + don't require an API key. All methods which delete or modify a resource do require an API key.

@@ -58,7 +58,7 @@ The base URL for the API is "{{apiUrl}}", all paths below are relative to that URL.

- +

File Methods

{{template "api-file-post"}} {{template "api-file-id-get"}} @@ -66,7 +66,7 @@ {{template "api-file-id-info-get"}} {{template "api-file-id-thumbnail-get"}} {{template "api-file-id-delete"}} - +

List Methods

{{template "api-list-post"}} {{template "api-list-get"}} @@ -76,4 +76,4 @@ {{template "analytics"}} -{{end}} \ No newline at end of file +{{end}} diff --git a/res/template/error.html b/res/template/error.html index e6ad48d..bed2008 100644 --- a/res/template/error.html +++ b/res/template/error.html @@ -13,7 +13,7 @@ - + {{template "bgpattern"}} @@ -28,7 +28,7 @@
- {{template "menu"}} + {{template "menu" .}}

Some Error occured

Either you made a mistake, or I made a mistake. @@ -42,4 +42,4 @@ {{template "analytics"}} -{{end}} \ No newline at end of file +{{end}} diff --git a/res/template/fragments/menu.html b/res/template/fragments/menu.html index a8dd01b..0984cb7 100644 --- a/res/template/fragments/menu.html +++ b/res/template/fragments/menu.html @@ -3,7 +3,7 @@ Home My Files API Documentation - Account + {{if .Authenticated}}{{.Username}}{{else}}Account{{end}} - - @@ -37,12 +37,12 @@
- {{template "menu"}} + {{template "menu" .}}
Here are all files you have previously uploaded to PixelDrain using this computer. This data is saved locally in your web browser and gets updated every time you upload a file through your current browser.

- +
{{template "footer"}}
@@ -50,4 +50,4 @@ {{template "analytics"}} -{{end}} \ No newline at end of file +{{end}} diff --git a/res/template/home.html b/res/template/home.html index 4ab0b75..ae5d7d6 100644 --- a/res/template/home.html +++ b/res/template/home.html @@ -35,7 +35,7 @@ Header image
- {{template "menu"}} + {{template "menu" .}}
diff --git a/webcontroller/templateData.go b/webcontroller/templateData.go index b83148b..c9feaa2 100644 --- a/webcontroller/templateData.go +++ b/webcontroller/templateData.go @@ -1,6 +1,7 @@ package webcontroller import ( + "html/template" "net/http" ) @@ -9,6 +10,7 @@ import ( type TemplateData struct { Authenticated bool Username string + APIEndpoint template.URL Recaptcha struct { Enabled bool @@ -18,8 +20,12 @@ type TemplateData struct { Other interface{} } -func (wc *WebController) newTemplateData(r http.Request) *TemplateData { - var t = &TemplateData{} +func (wc *WebController) newTemplateData(r *http.Request) *TemplateData { + var t = &TemplateData{ + Authenticated: false, + Username: "Fornax", + APIEndpoint: template.URL(wc.conf.APIURLExternal), + } return t } diff --git a/webcontroller/userAccount.go b/webcontroller/userAccount.go index 5e4340a..45c3c02 100644 --- a/webcontroller/userAccount.go +++ b/webcontroller/userAccount.go @@ -1,15 +1 @@ package webcontroller - -import ( - "net/http" - - "github.com/julienschmidt/httprouter" -) - -func (wc *WebController) handleLogin( - w http.ResponseWriter, - r *http.Request, - p httprouter.Params, -) { - -} diff --git a/webcontroller/webcontroller.go b/webcontroller/webcontroller.go index 91c90c6..7064557 100644 --- a/webcontroller/webcontroller.go +++ b/webcontroller/webcontroller.go @@ -61,7 +61,7 @@ func (wc *WebController) serveTemplate(tpl string) httprouter.Handle { r *http.Request, p httprouter.Params, ) { - err := wc.templates.Get().ExecuteTemplate(w, tpl, nil) + err := wc.templates.Get().ExecuteTemplate(w, tpl, wc.newTemplateData(r)) if err != nil { log.Error("Error executing template '%s': %s", tpl, err) } @@ -80,5 +80,5 @@ func (wc *WebController) serveFile(path string) httprouter.Handle { func (wc *WebController) serveNotFound(w http.ResponseWriter, r *http.Request) { log.Debug("Not Found: %s", r.URL) - wc.templates.Get().ExecuteTemplate(w, "error", nil) + wc.templates.Get().ExecuteTemplate(w, "error", wc.newTemplateData(r)) }