filebrowser/auth/json.go
Henrique Dias 5a83d6736b fix: rename global scope as root and fix root md
License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>

Former-commit-id: 856c18bc9cf98a27b6cbea923b231e0aaf279190 [formerly 201c1a0294947930a7d0706af72ce719a8cc3b98] [formerly 0253e57e2994023e798f6fb0ae76f9c21d18fd69 [formerly 33a58c999a]]
Former-commit-id: e7d88b22207125c29ea85a5a539653a54584999c [formerly 77cb1e0172cdf7195cc25d557e5028a9250d655c]
Former-commit-id: 64288f5a475a82d5f88c91347a09aea67ebb169d
2019-01-07 20:34:44 +00:00

103 lines
2.0 KiB
Go

package auth
import (
"encoding/json"
"net/http"
"net/url"
"os"
"strings"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users"
)
// MethodJSONAuth is used to identify json auth.
const MethodJSONAuth settings.AuthMethod = "json"
type jsonCred struct {
Password string `json:"password"`
Username string `json:"username"`
ReCaptcha string `json:"recaptcha"`
}
// JSONAuth is a json implementaion of an Auther.
type JSONAuth struct {
ReCaptcha *ReCaptcha
}
// Auth authenticates the user via a json in content body.
func (a *JSONAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
var cred jsonCred
if r.Body == nil {
return nil, os.ErrPermission
}
err := json.NewDecoder(r.Body).Decode(&cred)
if err != nil {
return nil, os.ErrPermission
}
// If ReCaptcha is enabled, check the code.
if a.ReCaptcha != nil && len(a.ReCaptcha.Secret) > 0 {
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha)
if err != nil {
return nil, err
}
if !ok {
return nil, os.ErrPermission
}
}
u, err := sto.Get(root, cred.Username)
if err != nil || !users.CheckPwd(cred.Password, u.Password) {
return nil, os.ErrPermission
}
return u, nil
}
const reCaptchaAPI = "/recaptcha/api/siteverify"
// ReCaptcha identifies a recaptcha conenction.
type ReCaptcha struct {
Host string `json:"host"`
Key string `json:"key"`
Secret string `json:"secret"`
}
// Ok checks if a reCaptcha responde is correct.
func (r *ReCaptcha) Ok(response string) (bool, error) {
body := url.Values{}
body.Set("secret", r.Key)
body.Add("response", response)
client := &http.Client{}
resp, err := client.Post(
r.Host+reCaptchaAPI,
"application/x-www-form-urlencoded",
strings.NewReader(body.Encode()),
)
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, nil
}
var data struct {
Success bool `json:"success"`
}
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return false, err
}
return data.Success, nil
}