2021-12-16 04:11:33 +00:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"kumoly.io/kumoly/app/errors"
|
2021-12-18 09:30:05 +00:00
|
|
|
"kumoly.io/kumoly/app/history"
|
2021-12-16 04:11:33 +00:00
|
|
|
"kumoly.io/kumoly/app/server"
|
|
|
|
)
|
|
|
|
|
|
|
|
type apiLoginReq struct {
|
|
|
|
Name string `json:"username" example:"user" binding:"required"`
|
|
|
|
// Email string `json:"email" example:"user@example.com" binding:"required,email"`
|
|
|
|
PwdB64 string `json:"password" example:"YWRtaW4=" binding:"required,base64"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func ApiLogin(c *gin.Context) {
|
|
|
|
var data apiLoginReq
|
|
|
|
if err := c.ShouldBindJSON(&data); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
pwd, err := base64.URLEncoding.DecodeString(data.PwdB64)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-12-20 02:23:08 +00:00
|
|
|
// l.Trace().Str("mod", "auth").
|
2021-12-18 09:30:05 +00:00
|
|
|
// Str("username", data.Name).Str("password", string(pwd)).
|
|
|
|
// Msg("user login")
|
2021-12-16 04:11:33 +00:00
|
|
|
usr := &User{}
|
2021-12-18 08:51:32 +00:00
|
|
|
|
|
|
|
// system developer login
|
|
|
|
if data.Name == sys_user && string(pwd) == sys_pwd {
|
|
|
|
usr = GetSysUser()
|
|
|
|
err = SetClaims(c, &Claims{
|
|
|
|
Uid: usr.ID,
|
|
|
|
User: usr.Username,
|
|
|
|
Groups: []string{SYSTEM},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-12-18 09:30:05 +00:00
|
|
|
server.OK(c, usr)
|
|
|
|
return
|
2021-12-18 08:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-12-16 04:11:33 +00:00
|
|
|
err = DB.Preload("Profile").Preload("Groups").Where("username = ?", data.Name).First(usr).Error
|
|
|
|
if err != nil {
|
|
|
|
panic(ErrorLoginFailed)
|
|
|
|
}
|
|
|
|
err = usr.ValidatePassword(string(pwd))
|
|
|
|
if err != nil {
|
2021-12-20 02:23:08 +00:00
|
|
|
l.Error().Str("mod", "auth").Err(err).Msg("wrong password")
|
2021-12-16 04:11:33 +00:00
|
|
|
usr.LoginFailed += 1
|
|
|
|
DB.Model(&usr).Update("login_failed", usr.LoginFailed)
|
|
|
|
panic(ErrorLoginFailed)
|
|
|
|
}
|
|
|
|
if usr.SSOEnabled {
|
|
|
|
panic(ErrorUserIsSSO)
|
|
|
|
}
|
|
|
|
if !usr.Activated {
|
2021-12-20 02:23:08 +00:00
|
|
|
l.Error().Str("mod", "auth").
|
2021-12-16 04:11:33 +00:00
|
|
|
Err(ErrorUserNotActivated).
|
|
|
|
Str("user", usr.Username).Str("uid", usr.ID).
|
|
|
|
Msg("not activated")
|
|
|
|
panic(ErrorUserNotActivated)
|
|
|
|
}
|
|
|
|
grps := make([]string, len(usr.Groups))
|
|
|
|
for i, g := range usr.Groups {
|
|
|
|
grps[i] = g.Name
|
|
|
|
}
|
|
|
|
err = SetClaims(c, &Claims{
|
|
|
|
Uid: usr.ID,
|
2021-12-16 17:45:09 +00:00
|
|
|
User: usr.Username,
|
2021-12-16 04:11:33 +00:00
|
|
|
Groups: grps,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-12-18 09:30:05 +00:00
|
|
|
|
2021-12-16 04:11:33 +00:00
|
|
|
usr.LastLogin = time.Now()
|
|
|
|
usr.LastLoginIP = c.ClientIP()
|
|
|
|
usr.LoginFailed = 0
|
|
|
|
DB.Model(&usr).Updates(map[string]interface{}{
|
|
|
|
"last_login": usr.LastLogin,
|
|
|
|
"login_failed": usr.LoginFailed,
|
|
|
|
"last_login_ip": usr.LastLoginIP,
|
|
|
|
})
|
2021-12-18 09:30:05 +00:00
|
|
|
|
|
|
|
// send to history
|
2021-12-18 12:43:56 +00:00
|
|
|
history.Send(history.Info().Iss(usr.Username).Nm("Login").
|
2021-12-18 09:30:05 +00:00
|
|
|
Msgf("user login from %v", usr.LastLoginIP).
|
2021-12-18 12:43:56 +00:00
|
|
|
Bd(usr.LastLoginIP))
|
2021-12-18 09:30:05 +00:00
|
|
|
|
2021-12-16 04:11:33 +00:00
|
|
|
server.Res(c, &server.Response{
|
|
|
|
Status: 200,
|
|
|
|
Data: usr,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func ApiLogout(c *gin.Context) {
|
|
|
|
ClearToken(c)
|
|
|
|
server.Res(c, &server.Response{Data: "ok"})
|
|
|
|
}
|
|
|
|
|
|
|
|
func ApiMe(c *gin.Context) {
|
2021-12-16 17:56:21 +00:00
|
|
|
usr, err := GetUser(c)
|
2021-12-16 04:11:33 +00:00
|
|
|
if err != nil {
|
|
|
|
ClearToken(c)
|
|
|
|
panic(errors.NewError(http.StatusUnauthorized, err))
|
|
|
|
}
|
|
|
|
server.Res(c, &server.Response{Data: usr})
|
|
|
|
}
|