Skip to content

Commit

Permalink
style: delete user and login APIs and Handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
lovehunter9 committed Feb 26, 2025
1 parent 06f711c commit cd940a5
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 501 deletions.
226 changes: 0 additions & 226 deletions packages/backend/http/auth.go
Original file line number Diff line number Diff line change
@@ -1,238 +1,12 @@
package http

import (
"encoding/json"
"log"
"net/http"
"os"
"strings"
"time"

"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v4/request"

"github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/users"
)

const (
TokenExpirationTime = time.Hour * 2
)

type userInfo struct {
ID uint `json:"id"`
Locale string `json:"locale"`
ViewMode users.ViewMode `json:"viewMode"`
SingleClick bool `json:"singleClick"`
Perm users.Permissions `json:"perm"`
Commands []string `json:"commands"`
LockPassword bool `json:"lockPassword"`
HideDotfiles bool `json:"hideDotfiles"`
DateFormat bool `json:"dateFormat"`
}

type authToken struct {
User userInfo `json:"user"`
jwt.RegisteredClaims
}

type extractor []string

func (e extractor) ExtractToken(r *http.Request) (string, error) {
token, _ := request.HeaderExtractor{"X-Auth"}.ExtractToken(r)

// Checks if the token isn't empty and if it contains two dots.
// The former prevents incompatibility with URLs that previously
// used basic auth.
if token != "" && strings.Count(token, ".") == 2 {
return token, nil
}

auth := r.URL.Query().Get("auth")
if auth != "" && strings.Count(auth, ".") == 2 {
return auth, nil
}

if r.Method == http.MethodGet {
cookie, _ := r.Cookie("auth")
if cookie != nil && strings.Count(cookie.Value, ".") == 2 {
return cookie.Value, nil
}
}

return "", request.ErrNoTokenInRequest
}

func withUser(fn handleFunc) handleFunc {
//log.Printf("withUser: start")
//return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
// keyFunc := func(token *jwt.Token) (interface{}, error) {
// return d.settings.Key, nil
// }
//
// var tk authToken
// token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
//
// if err != nil || !token.Valid {
// return http.StatusUnauthorized, nil
// }
//
// expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour), true)
// updated := tk.IssuedAt != nil && tk.IssuedAt.Unix() < d.store.Users.LastUpdate(tk.User.ID)
//
// if expired || updated {
// w.Header().Add("X-Renew-Token", "true")
// }
// log.Println("withUser: start %u", tk.User.ID)
// d.user, err = d.store.Users.Get(d.server.Root, tk.User.ID)
// if err != nil {
// return http.StatusInternalServerError, err
// }
// return fn(w, r, d)
//}
return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
//keyFunc := func(token *jwt.Token) (interface{}, error) {
// return d.settings.Key, nil
//}
//
//var tk authToken
//token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
//
//if err != nil || !token.Valid {
// return http.StatusUnauthorized, nil
//}
//
//expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour), true)
//updated := tk.IssuedAt != nil && tk.IssuedAt.Unix() < d.store.Users.LastUpdate(tk.User.ID)
//
//if expired || updated {
// w.Header().Add("X-Renew-Token", "true")
//}

d.user, _ = d.store.Users.Get(d.server.Root, uint(1))

//if err != nil {
// return http.StatusInternalServerError, err
//}
return fn(w, r, d)
}
}

func withAdmin(fn handleFunc) handleFunc {
return withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
if !d.user.Perm.Admin {
return http.StatusForbidden, nil
}

return fn(w, r, d)
})
}

var loginHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
log.Printf("d.settings.AuthMethod %s", d.settings.AuthMethod)
auther, err := d.store.Auth.Get(d.settings.AuthMethod)
if err != nil {
return http.StatusInternalServerError, err
}

user, err := auther.Auth(r, d.store.Users, d.settings, d.server)
if err == os.ErrPermission {
return http.StatusForbidden, nil
} else if err != nil {
return http.StatusInternalServerError, err
} else {
return printToken(w, r, d, user)
}
}

type signupBody struct {
Username string `json:"username"`
Password string `json:"password"`
}

var signupHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
if !d.settings.Signup {
return http.StatusMethodNotAllowed, nil
}

if r.Body == nil {
return http.StatusBadRequest, nil
}

info := &signupBody{}
err := json.NewDecoder(r.Body).Decode(info)
if err != nil {
return http.StatusBadRequest, err
}

if info.Password == "" || info.Username == "" {
return http.StatusBadRequest, nil
}

user := &users.User{
Username: info.Username,
}

d.settings.Defaults.Apply(user)

pwd, err := users.HashPwd(info.Password)
if err != nil {
return http.StatusInternalServerError, err
}

user.Password = pwd

userHome, err := d.settings.MakeUserDir(user.Username, user.Scope, d.server.Root)
if err != nil {
log.Printf("create user: failed to mkdir user home dir: [%s]", userHome)
return http.StatusInternalServerError, err
}
user.Scope = userHome
log.Printf("new user: %s, home dir: [%s].", user.Username, userHome)

err = d.store.Users.Save(user)
if err == errors.ErrExist {
return http.StatusConflict, err
} else if err != nil {
return http.StatusInternalServerError, err
}

return http.StatusOK, nil
}

var renewHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
return printToken(w, r, d, d.user)
})

func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User) (int, error) {
claims := &authToken{
User: userInfo{
ID: user.ID,
Locale: user.Locale,
ViewMode: user.ViewMode,
SingleClick: user.SingleClick,
Perm: user.Perm,
LockPassword: user.LockPassword,
Commands: user.Commands,
HideDotfiles: user.HideDotfiles,
DateFormat: user.DateFormat,
},
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpirationTime)),
Issuer: "File Browser",
},
}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, err := token.SignedString(d.settings.Key)
if err != nil {
return http.StatusInternalServerError, err
}

w.Header().Set("Content-Type", "text/plain")
if _, err := w.Write([]byte(signed)); err != nil {
return http.StatusInternalServerError, err
}
return 0, nil
}
19 changes: 6 additions & 13 deletions packages/backend/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,12 @@ func NewHandler(

api := r.PathPrefix("/api").Subrouter()

api.Handle("/login", monkey(loginHandler, ""))
api.Handle("/signup", monkey(signupHandler, ""))
api.Handle("/renew", monkey(renewHandler, ""))

users := api.PathPrefix("/users").Subrouter()
users.Handle("", monkey(usersGetHandler, "")).Methods("GET")
users.Handle("", monkey(userPostHandler, "")).Methods("POST")
users.Handle("/{id:[0-9]+}", monkey(userPutHandler, "")).Methods("PUT")
users.Handle("/{id:[0-9]+}", monkey(userGetHandler, "")).Methods("GET")
users.Handle("/{id:[0-9]+}", monkey(userDeleteHandler, "")).Methods("DELETE")
//users := api.PathPrefix("/users").Subrouter()
//users.Handle("", monkey(usersGetHandler, "")).Methods("GET")
//users.Handle("", monkey(userPostHandler, "")).Methods("POST")
//users.Handle("/{id:[0-9]+}", monkey(userPutHandler, "")).Methods("PUT")
//users.Handle("/{id:[0-9]+}", monkey(userGetHandler, "")).Methods("GET")
//users.Handle("/{id:[0-9]+}", monkey(userDeleteHandler, "")).Methods("DELETE")

api.PathPrefix("/resources").Handler(monkey(resourceGetHandler, "/api/resources")).Methods("GET")
api.PathPrefix("/resources").Handler(monkey(resourceDeleteHandler(fileCache), "/api/resources")).Methods("DELETE")
Expand All @@ -74,9 +70,6 @@ func NewHandler(

api.PathPrefix("/usage").Handler(monkey(diskUsage, "/api/usage")).Methods("GET")

api.Handle("/settings", monkey(settingsGetHandler, "")).Methods("GET")
api.Handle("/settings", monkey(settingsPutHandler, "")).Methods("PUT")

api.PathPrefix("/raw").Handler(monkey(rawHandler, "/api/raw")).Methods("GET")
api.PathPrefix("/md5").Handler(monkey(md5Handler, "/api/md5")).Methods("GET")
api.PathPrefix("/smb_history").Handler(monkey(smbHistoryGetHandler, "/api/smb_history")).Methods("GET")
Expand Down
55 changes: 0 additions & 55 deletions packages/backend/http/settings.go

This file was deleted.

Loading

0 comments on commit cd940a5

Please sign in to comment.