diff --git a/pixelapi/file.go b/pixelapi/file.go index a5f0940..b90ac85 100644 --- a/pixelapi/file.go +++ b/pixelapi/file.go @@ -7,7 +7,7 @@ import ( // GetFile makes a file download request and returns a readcloser. Don't forget // to close it! func (p *PixelAPI) GetFile(id string) (io.ReadCloser, error) { - return getRaw(p.apiEndpoint + "/file/" + id) + return p.getRaw(p.apiEndpoint + "/file/" + id) } // FileInfo File information object from the pixeldrain API @@ -28,7 +28,7 @@ type FileInfo struct { // GetFileInfo gets the FileInfo from the pixeldrain API func (p *PixelAPI) GetFileInfo(id string) (resp *FileInfo, err *Error) { resp = &FileInfo{} - err = getJSON(p.apiEndpoint+"/file/"+id+"/info", resp) + err = p.jsonRequest("GET", p.apiEndpoint+"/file/"+id+"/info", resp) if err != nil { return nil, err } diff --git a/pixelapi/list.go b/pixelapi/list.go index d4c9c36..2ee3836 100644 --- a/pixelapi/list.go +++ b/pixelapi/list.go @@ -29,7 +29,7 @@ type ListFile struct { // List.Error. Standard error checks apply. func (p *PixelAPI) GetList(id string) (resp *List, err *Error) { resp = &List{} - err = getJSON(p.apiEndpoint+"/list/"+id, resp) + err = p.jsonRequest("GET", p.apiEndpoint+"/list/"+id, resp) if err != nil { return nil, err } diff --git a/pixelapi/misc.go b/pixelapi/misc.go index 965d8b7..4c19157 100644 --- a/pixelapi/misc.go +++ b/pixelapi/misc.go @@ -5,7 +5,7 @@ type Recaptcha struct { } func (p *PixelAPI) GetRecaptcha() (resp *Recaptcha, err *Error) { - err = getJSON(p.apiEndpoint+"/misc/recpatcha", resp) + err = p.jsonRequest("GET", p.apiEndpoint+"/misc/recpatcha", resp) if err != nil { return nil, err } diff --git a/pixelapi/pixelapi.go b/pixelapi/pixelapi.go index e3e5102..4adaf1a 100644 --- a/pixelapi/pixelapi.go +++ b/pixelapi/pixelapi.go @@ -14,11 +14,12 @@ import ( // PixelAPI is the Pixeldrain API client type PixelAPI struct { apiEndpoint string + apiKey string } // New creates a new Pixeldrain API client to query the Pixeldrain API with -func New(apiEndpoint string) *PixelAPI { - return &PixelAPI{apiEndpoint} +func New(apiEndpoint, apiKey string) *PixelAPI { + return &PixelAPI{apiEndpoint, apiKey} } // Error is either an error that occurred during the API request @@ -30,15 +31,22 @@ func New(apiEndpoint string) *PixelAPI { // it's false it will contain a Pixeldrain API error code. type Error struct { ReqError bool - Success bool `json:"success"` - Value string `json:"value"` - Message string `json:"message"` + Success bool `json:"success"` + Value string `json:"value"` + Message string `json:"message"` + Extra interface{} `json:"extra,omitempty"` } func (e Error) Error() string { return e.Value } -func getJSON(url string, target interface{}) *Error { - req, err := http.NewRequest("GET", url, nil) +// SuccessResponse is a generic response the API returns when the action was +// successful and there is nothing interesting to report +type SuccessResponse struct { + Success bool `json:"success"` +} + +func (p *PixelAPI) jsonRequest(method, url string, target interface{}) *Error { + req, err := http.NewRequest(method, url, nil) if err != nil { return &Error{ ReqError: true, @@ -47,6 +55,9 @@ func getJSON(url string, target interface{}) *Error { Message: err.Error(), } } + if p.apiKey != "" { + req.SetBasicAuth("", p.apiKey) + } client := &http.Client{} resp, err := client.Do(req) @@ -63,11 +74,14 @@ func getJSON(url string, target interface{}) *Error { return parseJSONResponse(resp, target) } -func getString(url string) (string, error) { +func (p *PixelAPI) getString(url string) (string, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return "", err } + if p.apiKey != "" { + req.SetBasicAuth("", p.apiKey) + } client := &http.Client{} @@ -83,11 +97,14 @@ func getString(url string) (string, error) { return string(bodyBytes), err } -func getRaw(url string) (io.ReadCloser, error) { +func (p *PixelAPI) getRaw(url string) (io.ReadCloser, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } + if p.apiKey != "" { + req.SetBasicAuth("", p.apiKey) + } client := &http.Client{} @@ -99,7 +116,7 @@ func getRaw(url string) (io.ReadCloser, error) { return resp.Body, err } -func postForm(url string, vals url.Values, target interface{}) *Error { +func (p *PixelAPI) postForm(url string, vals url.Values, target interface{}) *Error { req, err := http.NewRequest("POST", url, strings.NewReader(vals.Encode())) if err != nil { return &Error{ @@ -109,6 +126,9 @@ func postForm(url string, vals url.Values, target interface{}) *Error { Message: err.Error(), } } + if p.apiKey != "" { + req.SetBasicAuth("", p.apiKey) + } client := &http.Client{} resp, err := client.Do(req) diff --git a/pixelapi/user.go b/pixelapi/user.go index f7d8ad9..1d1b920 100644 --- a/pixelapi/user.go +++ b/pixelapi/user.go @@ -27,7 +27,34 @@ func (p *PixelAPI) UserRegister(username, email, password, captcha string) (resp form.Add("email", email) form.Add("password", password) form.Add("recaptcha_response", captcha) - err = postForm(p.apiEndpoint+"/user/register", form, resp) + err = p.postForm(p.apiEndpoint+"/user/register", form, resp) + if err != nil { + return nil, err + } + return resp, nil +} + +// UserInfo contains information about the logged in user +type UserInfo struct { + Success bool `json:"success"` + Username string `json:"username"` +} + +// UserInfo returns information about the logged in user. Required an API key +func (p *PixelAPI) UserInfo() (resp *UserInfo, err *Error) { + resp = &UserInfo{} + err = p.jsonRequest("GET", p.apiEndpoint+"/user", resp) + if err != nil { + return nil, err + } + return resp, nil +} + +// UserSessionDestroy destroys an API key so it can no longer be used to perform +// actions +func (p *PixelAPI) UserSessionDestroy(key string) (resp *SuccessResponse, err *Error) { + resp = &SuccessResponse{} + err = p.jsonRequest("DELETE", p.apiEndpoint+"/user/session", resp) if err != nil { return nil, err } diff --git a/res/static/res/style/layout.css b/res/static/res/style/layout.css index d212c65..b04552e 100644 --- a/res/static/res/style/layout.css +++ b/res/static/res/style/layout.css @@ -119,12 +119,15 @@ html{ padding: 4px 0px 4px 0px; z-index: 101; } -.highlight_light {background-color: #484848;} -.highlight_middle {background-color: #3a3a3a;} -.highlight_dark {background-color: #303030;} +.highlight_light {background-color: #484848; border-color: #686868;} +.highlight_middle {background-color: #3a3a3a; border-color: #686868;} +.highlight_dark {background-color: #303030; border-color: #686868;} +.highlight_green {background-color: rgba(0, 255, 0, 0.05); border-color: #00d000;} +.highlight_blue {background-color: rgba(32, 32, 255, 0.2); border-color: rgb(54, 54, 255);} +.highlight_red {background-color: rgba(255, 0, 0, 0.05); border-color: #B00000;} -.border_top {border-top: #686868 1px solid;} -.border_bottom {border-bottom: #686868 1px solid;} +.border_top {border-top-width: 1px; border-top-style: solid;} +.border_bottom {border-bottom-width: 1px; border-bottom-style: solid;} /* Common elements */ diff --git a/res/template/account/login.html b/res/template/account/login.html index f56c8fc..57d1579 100644 --- a/res/template/account/login.html +++ b/res/template/account/login.html @@ -1,6 +1,6 @@ {{define "login"}} - +
+ We need you to confirm your action here so we can be sure that + you really requested a logout. If we didn't do this, anyone (or + any website) would be able to send you to the page + pixeldrain.com/logout and you would automatically get logged + out of Pixeldrain, which would be very annoying. +
++ To prevent this from happening we're verifying that you actually + want to log out by making you submit this form. Because this + logout button triggers a different request type than normal + page vitis we can confirm that you really want to log out. +
+ + {{template "footer"}} +