uauth/internal/client/client.go

90 lines
2.0 KiB
Go
Raw Normal View History

2024-10-23 17:46:15 +08:00
package client
import (
"context"
_ "embed"
"encoding/json"
"github.com/google/uuid"
"github.com/loveuer/nf"
"github.com/loveuer/nf/nft/log"
"github.com/loveuer/nf/nft/resp"
"golang.org/x/oauth2"
"net/http"
"uauth/internal/tool"
)
//go:embed login.html
var page string
var (
config = oauth2.Config{
ClientID: "test",
ClientSecret: "Foobar123",
Endpoint: oauth2.Endpoint{
AuthURL: "http://localhost:8080/oauth/v2/authorize",
TokenURL: "http://localhost:8080/oauth/v2/token",
},
RedirectURL: "http://localhost:18080/oauth/v2/redirect",
Scopes: []string{"test"},
}
state = uuid.New().String()[:8]
)
func Run(ctx context.Context) error {
app := nf.New()
app.Get("/login", handleLogin)
app.Get("/oauth/v2/redirect", handleRedirect)
go func() {
<-ctx.Done()
_ = app.Shutdown(tool.Timeout(2))
}()
return app.Run(":18080")
}
func handleLogin(c *nf.Ctx) error {
if c.Query("oauth") != "" {
uri := config.AuthCodeURL(state)
log.Info("[C] oauth config client_secret = %s", config.ClientSecret)
log.Info("[C] redirect to oauth2 server uri = %s", uri)
return c.Redirect(uri, http.StatusFound)
}
return c.HTML(page)
}
func handleRedirect(c *nf.Ctx) error {
type Req struct {
State string `query:"state"`
Code string `query:"code"`
Scope string `query:"scope"`
ClientId string `query:"client_id"`
}
var (
err error
req = new(Req)
token *oauth2.Token
)
if err = c.QueryParser(req); err != nil {
return resp.Resp400(c, err.Error())
}
if req.State != state {
log.Error("[C] state mismatch, want = %s, got = %s", state, req.State)
return c.Status(http.StatusBadRequest).SendString("Bad Request: state mismatch")
}
if token, err = config.Exchange(c.Context(), req.Code); err != nil {
log.Error("[C] oauth config exchange err: %s", err.Error())
return resp.Resp500(c, err.Error())
}
bs, _ := json.Marshal(token)
log.Info("[C] oauth finally token =\n%s", string(bs))
return resp.Resp200(c, token)
}