138 lines
3.9 KiB
Go
138 lines
3.9 KiB
Go
package handler
|
|
|
|
import (
|
|
_ "embed"
|
|
"errors"
|
|
"github.com/loveuer/nf"
|
|
"github.com/loveuer/nf/nft/log"
|
|
"github.com/loveuer/nf/nft/resp"
|
|
"gorm.io/gorm"
|
|
"net/http"
|
|
"time"
|
|
"uauth/internal/store/cache"
|
|
"uauth/internal/store/db"
|
|
"uauth/internal/tool"
|
|
"uauth/model"
|
|
)
|
|
|
|
var (
|
|
//go:embed serve_login.html
|
|
pageLogin string
|
|
)
|
|
|
|
func LoginPage(c *nf.Ctx) error {
|
|
type Req struct {
|
|
ClientId string `query:"client_id" json:"client_id"`
|
|
Scope string `query:"scope" json:"scope"`
|
|
RedirectURI string `query:"redirect_uri" json:"redirect_uri"`
|
|
State string `query:"state" json:"state"`
|
|
ResponseType string `query:"response_type" json:"response_type"`
|
|
}
|
|
|
|
var (
|
|
err error
|
|
req = new(Req)
|
|
client = new(model.Client)
|
|
)
|
|
|
|
if err = c.QueryParser(req); err != nil {
|
|
return resp.Resp400(c, err.Error())
|
|
}
|
|
|
|
if req.ClientId == "" || req.RedirectURI == "" {
|
|
return resp.Resp400(c, req)
|
|
}
|
|
|
|
if err = db.Default.Session().Model(&model.Client{}).
|
|
Where("client_id = ?", req.ClientId).
|
|
Take(client).
|
|
Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return c.Status(http.StatusForbidden).SendString("Client Not Registry")
|
|
}
|
|
|
|
log.Error("[S] model take client id = %s, err = %s", req.ClientId, err.Error())
|
|
return c.Status(http.StatusInternalServerError).SendString("Internal Server Error")
|
|
}
|
|
|
|
return c.RenderHTML("login", pageLogin, map[string]interface{}{
|
|
"client_id": req.ClientId,
|
|
"redirect_uri": req.RedirectURI,
|
|
"scope": req.Scope,
|
|
"state": req.State,
|
|
"response_type": req.ResponseType,
|
|
"client_name": client.Name,
|
|
"client_icon": client.Icon,
|
|
})
|
|
}
|
|
|
|
//go:embed serve_login_success.html
|
|
var pageLoginSuccess string
|
|
|
|
func LoginAction(c *nf.Ctx) error {
|
|
type Req struct {
|
|
Username string `form:"username"`
|
|
Password string `form:"password"`
|
|
ClientId string `form:"client_id"`
|
|
RedirectURI string `form:"redirect_uri"`
|
|
Scope string `form:"scope"`
|
|
State string `form:"state"`
|
|
ResponseType string `form:"response_type"`
|
|
}
|
|
|
|
var (
|
|
err error
|
|
req = new(Req)
|
|
op = new(model.User)
|
|
token string
|
|
)
|
|
|
|
if err = c.BodyParser(req); err != nil {
|
|
log.Warn("[S] LoginAction: body parser err = %s", err.Error())
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request")
|
|
}
|
|
|
|
if req.Username == "" || req.Password == "" {
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request: username, password is required")
|
|
}
|
|
|
|
if err = db.Default.Session().Model(&model.User{}).
|
|
Where("username = ?", req.Username).
|
|
Take(op).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
log.Warn("[S] LoginAction: username = %s not found", req.Username)
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request")
|
|
}
|
|
|
|
log.Error("[S] LoginAction: model take username = %s, err = %s", req.Username, err.Error())
|
|
return c.Status(http.StatusInternalServerError).SendString("Internal Server Error")
|
|
}
|
|
|
|
// todo: 验证用户登录是否成功,等等
|
|
if !tool.ComparePassword(req.Password, op.Password) {
|
|
log.Warn("[S] LoginAction: model take username = %s, password is invalid", req.Username)
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request")
|
|
}
|
|
|
|
if token, err = op.JwtEncode(); err != nil {
|
|
log.Error("[S] LoginAction: jwtEncode err = %s", err.Error())
|
|
return c.Status(http.StatusInternalServerError).SendString("Internal Server Error")
|
|
}
|
|
|
|
key := cache.Prefix + "token:" + token
|
|
if err = cache.Client.SetEx(c.Context(), key, op, 24*time.Hour); err != nil {
|
|
log.Error("[S] LoginAction: cache SetEx err = %s", err.Error())
|
|
return c.Status(http.StatusInternalServerError).SendString("Internal Server Error")
|
|
}
|
|
|
|
c.Writer.Header().Add("Set-Cookie", "access_token="+token)
|
|
|
|
return c.RenderHTML("login_success", pageLoginSuccess, map[string]interface{}{
|
|
"client_id": req.ClientId,
|
|
"redirect_uri": req.RedirectURI,
|
|
"scope": req.Scope,
|
|
"state": req.State,
|
|
"response_type": req.ResponseType,
|
|
})
|
|
}
|