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, }) }