chore(single_user): delete single user handlers
This commit is contained in:
parent
d0a8a6d43a
commit
cb478ca266
2 changed files with 0 additions and 303 deletions
|
@ -1,219 +0,0 @@
|
|||
package singleuserhdr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ihexxa/gocfg"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/depidx"
|
||||
q "github.com/ihexxa/quickshare/src/handlers"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidUser = errors.New("invalid user name or password")
|
||||
ErrInvalidConfig = errors.New("invalid user config")
|
||||
UserParam = "user"
|
||||
PwdParam = "pwd"
|
||||
NewPwdParam = "newpwd"
|
||||
RoleParam = "role"
|
||||
ExpireParam = "expire"
|
||||
InitTimeParam = "initTime"
|
||||
TokenCookie = "tk"
|
||||
AdminRole = "admin"
|
||||
VisitorRole = "visitor"
|
||||
InitNs = "usersInit"
|
||||
UsersNs = "users"
|
||||
RolesNs = "roles"
|
||||
)
|
||||
|
||||
type SimpleUserHandlers struct {
|
||||
cfg gocfg.ICfg
|
||||
deps *depidx.Deps
|
||||
}
|
||||
|
||||
func NewSimpleUserHandlers(cfg gocfg.ICfg, deps *depidx.Deps) (*SimpleUserHandlers, error) {
|
||||
var err error
|
||||
if err = deps.KV().AddNamespace(InitNs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = deps.KV().AddNamespace(UsersNs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = deps.KV().AddNamespace(RolesNs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SimpleUserHandlers{
|
||||
cfg: cfg,
|
||||
deps: deps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) IsInited() bool {
|
||||
_, ok := h.deps.KV().GetStringIn(InitNs, InitTimeParam)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) Init(userName, pwd string) (string, error) {
|
||||
if userName == "" {
|
||||
return "", errors.New("user name can not be empty")
|
||||
}
|
||||
|
||||
pwdHash, err := bcrypt.GenerateFromPassword([]byte(pwd), 10)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = h.deps.KV().SetStringIn(UsersNs, userName, string(pwdHash))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = h.deps.KV().SetStringIn(RolesNs, userName, AdminRole)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = h.deps.KV().SetStringIn(InitNs, InitTimeParam, fmt.Sprintf("%d", time.Now().Unix()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return pwd, nil
|
||||
}
|
||||
|
||||
type LoginReq struct {
|
||||
User string `json:"user"`
|
||||
Pwd string `json:"pwd"`
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) checkPwd(user, pwd string) error {
|
||||
expectedHash, ok := h.deps.KV().GetStringIn(UsersNs, user)
|
||||
if !ok {
|
||||
return ErrInvalidConfig
|
||||
}
|
||||
|
||||
return bcrypt.CompareHashAndPassword([]byte(expectedHash), []byte(pwd))
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) Login(c *gin.Context) {
|
||||
req := &LoginReq{}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.checkPwd(req.User, req.Pwd); err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
return
|
||||
}
|
||||
|
||||
role, ok := h.deps.KV().GetStringIn(RolesNs, req.User)
|
||||
if !ok {
|
||||
c.JSON(q.ErrResp(c, 501, ErrInvalidConfig))
|
||||
return
|
||||
}
|
||||
ttl := h.cfg.GrabInt("Users.CookieTTL")
|
||||
token, err := h.deps.Token().ToToken(map[string]string{
|
||||
UserParam: req.User,
|
||||
RoleParam: role,
|
||||
ExpireParam: fmt.Sprintf("%d", time.Now().Unix()+int64(ttl)),
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
return
|
||||
}
|
||||
|
||||
secure := h.cfg.GrabBool("Users.CookieSecure")
|
||||
httpOnly := h.cfg.GrabBool("Users.CookieHttpOnly")
|
||||
c.SetCookie(TokenCookie, token, ttl, "/", "", secure, httpOnly)
|
||||
|
||||
c.JSON(q.Resp(200))
|
||||
}
|
||||
|
||||
type LogoutReq struct {
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) Logout(c *gin.Context) {
|
||||
// token alreay verified in the authn middleware
|
||||
secure := h.cfg.GrabBool("Users.CookieSecure")
|
||||
httpOnly := h.cfg.GrabBool("Users.CookieHttpOnly")
|
||||
c.SetCookie(TokenCookie, "", 0, "/", "", secure, httpOnly)
|
||||
c.JSON(q.Resp(200))
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) IsAuthed(c *gin.Context) {
|
||||
// token alreay verified in the authn middleware
|
||||
c.JSON(q.Resp(200))
|
||||
}
|
||||
|
||||
type SetPwdReq struct {
|
||||
OldPwd string `json:"oldPwd"`
|
||||
NewPwd string `json:"newPwd"`
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) SetPwd(c *gin.Context) {
|
||||
req := &SetPwdReq{}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(q.ErrResp(c, 400, err))
|
||||
return
|
||||
} else if req.OldPwd == req.NewPwd {
|
||||
c.JSON(q.ErrResp(c, 400, errors.New("password is not updated")))
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := h.getUserInfo(c)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
|
||||
expectedHash, ok := h.deps.KV().GetStringIn(UsersNs, claims[UserParam])
|
||||
if !ok {
|
||||
c.JSON(q.ErrResp(c, 500, ErrInvalidConfig))
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(expectedHash), []byte(req.OldPwd))
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 401, ErrInvalidUser))
|
||||
return
|
||||
}
|
||||
|
||||
newHash, err := bcrypt.GenerateFromPassword([]byte(req.NewPwd), 10)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, errors.New("fail to set password")))
|
||||
return
|
||||
}
|
||||
err = h.deps.KV().SetStringIn(UsersNs, claims[UserParam], string(newHash))
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, ErrInvalidConfig))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(q.Resp(200))
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) getUserInfo(c *gin.Context) (map[string]string, error) {
|
||||
tokenStr, err := c.Cookie(TokenCookie)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claims, err := h.deps.Token().FromToken(
|
||||
tokenStr,
|
||||
map[string]string{
|
||||
UserParam: "",
|
||||
RoleParam: "",
|
||||
ExpireParam: "",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if claims[UserParam] == "" {
|
||||
return nil, ErrInvalidConfig
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package singleuserhdr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
q "github.com/ihexxa/quickshare/src/handlers"
|
||||
)
|
||||
|
||||
var exposedAPIs = map[string]bool{
|
||||
"Login-fm": true,
|
||||
"Health-fm": true,
|
||||
}
|
||||
|
||||
var publicRootPath = "/"
|
||||
var publicStaticPath = "/static"
|
||||
|
||||
func IsPublicPath(accessPath string) bool {
|
||||
return accessPath == publicRootPath || strings.HasPrefix(accessPath, publicStaticPath)
|
||||
}
|
||||
|
||||
func GetHandlerName(fullname string) (string, error) {
|
||||
parts := strings.Split(fullname, ".")
|
||||
if len(parts) == 0 {
|
||||
return "", errors.New("invalid handler name")
|
||||
}
|
||||
return parts[len(parts)-1], nil
|
||||
}
|
||||
|
||||
func (h *SimpleUserHandlers) Auth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
handlerName, err := GetHandlerName(c.HandlerName())
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
accessPath := c.Request.URL.String()
|
||||
|
||||
enableAuth := h.cfg.GrabBool("Users.EnableAuth")
|
||||
if enableAuth && !exposedAPIs[handlerName] && !IsPublicPath(accessPath) {
|
||||
token, err := c.Cookie(TokenCookie)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
|
||||
claims := map[string]string{
|
||||
UserParam: "",
|
||||
RoleParam: "",
|
||||
ExpireParam: "",
|
||||
}
|
||||
|
||||
claims, err = h.deps.Token().FromToken(token, claims)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
for key, val := range claims {
|
||||
c.Set(key, val)
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
expire, err := strconv.ParseInt(claims[ExpireParam], 10, 64)
|
||||
if err != nil || expire <= now {
|
||||
c.AbortWithStatusJSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
|
||||
// visitor is only allowed to download
|
||||
if claims[RoleParam] != AdminRole && handlerName != "Download-fm" {
|
||||
c.AbortWithStatusJSON(q.ErrResp(c, 401, errors.New("not allowed")))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// this is for UploadMgr to get user info to get related namespace
|
||||
c.Set(UserParam, "quickshare_anonymous")
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue