90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package handler
|
|
|
|
import (
|
|
_ "embed"
|
|
"errors"
|
|
"github.com/google/uuid"
|
|
"github.com/loveuer/nf"
|
|
"github.com/loveuer/nf/nft/log"
|
|
"github.com/loveuer/nf/nft/resp"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
"uauth/model"
|
|
"uauth/pkg/cache"
|
|
"uauth/pkg/store"
|
|
"uauth/tool"
|
|
)
|
|
|
|
//go:embed serve_approve.html
|
|
var pageApprove string
|
|
|
|
func Approve(c *nf.Ctx) error {
|
|
// 获取表单数据
|
|
type Req struct {
|
|
ClientId string `form:"client_id"`
|
|
RedirectURI string `form:"redirect_uri"`
|
|
Scope string `form:"scope"`
|
|
State string `form:"state"`
|
|
}
|
|
|
|
var (
|
|
ok bool
|
|
op *model.User
|
|
err error
|
|
req = new(Req)
|
|
uri *url.URL
|
|
client = new(model.Client)
|
|
)
|
|
|
|
if op, ok = c.Locals("user").(*model.User); !ok {
|
|
return resp.Resp401(c, nil)
|
|
}
|
|
|
|
if err = c.BodyParser(req); err != nil {
|
|
return resp.Resp400(c, err)
|
|
}
|
|
|
|
if uri, err = url.Parse(req.RedirectURI); err != nil {
|
|
log.Warn("[S] parse redirect uri = %s, err = %s", req.RedirectURI, err.Error())
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request: invalid redirect uri")
|
|
}
|
|
|
|
if err = store.Default.Session(tool.TimeoutCtx(c.Context(), 3)).
|
|
Where("client_id", req.ClientId).Take(client).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return c.Status(http.StatusBadRequest).SendString("Bad Request: invalid client_id")
|
|
}
|
|
|
|
log.Error("[S] get client by id fail, client_id = %s, err = %s", req.ClientId, err.Error())
|
|
return c.Status(http.StatusInternalServerError).SendString("Internal Server Error")
|
|
}
|
|
|
|
store.Default.Session(tool.TimeoutCtx(c.Context(), 3)).
|
|
Clauses(clause.OnConflict{DoNothing: true}).
|
|
Create(&model.AuthorizationRecord{
|
|
UserId: op.Id,
|
|
ClientId: client.Id,
|
|
})
|
|
|
|
authorizationCode := uuid.New().String()[:8]
|
|
if err = cache.Client.SetEx(c.Context(), cache.Prefix+"auth_code:"+authorizationCode, op.Id, 10*time.Minute); err != nil {
|
|
return resp.Resp500(c, err)
|
|
}
|
|
|
|
qs := uri.Query()
|
|
qs.Add("code", authorizationCode)
|
|
qs.Add("client_id", req.ClientId)
|
|
qs.Add("scope", req.Scope)
|
|
qs.Add("state", req.State)
|
|
|
|
uri.ForceQuery = true
|
|
value := uri.String() + qs.Encode()
|
|
|
|
return c.RenderHTML("approve", pageApprove, map[string]interface{}{
|
|
"redirect_uri": value,
|
|
})
|
|
}
|