mirror of
https://github.com/chaitin/MonkeyCode.git
synced 2026-02-02 14:53:55 +08:00
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package oauth
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/oauth2"
|
|
|
|
"github.com/chaitin/MonkeyCode/backend/domain"
|
|
)
|
|
|
|
type CustomOAuth struct {
|
|
cfg domain.OAuthConfig
|
|
oauth *oauth2.Config
|
|
}
|
|
|
|
func NewCustomOAuth(config domain.OAuthConfig) domain.OAuther {
|
|
c := &CustomOAuth{
|
|
cfg: config,
|
|
oauth: &oauth2.Config{
|
|
ClientID: config.ClientID,
|
|
ClientSecret: config.ClientSecret,
|
|
Endpoint: oauth2.Endpoint{
|
|
AuthURL: config.AuthorizeURL,
|
|
TokenURL: config.TokenURL,
|
|
},
|
|
RedirectURL: config.RedirectURI,
|
|
Scopes: config.Scopes,
|
|
},
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
// GetAuthorizeURL implements domain.OAuther.
|
|
func (c *CustomOAuth) GetAuthorizeURL() (string, string) {
|
|
state := uuid.NewString()
|
|
url := c.oauth.AuthCodeURL(state)
|
|
return state, url
|
|
}
|
|
|
|
// GetUserInfo implements domain.OAuther.
|
|
func (c *CustomOAuth) GetUserInfo(code string) (*domain.OAuthUserInfo, error) {
|
|
info, err := c.getUserInfo(code)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &domain.OAuthUserInfo{
|
|
ID: fmt.Sprint(info[c.cfg.IDField]),
|
|
AvatarURL: fmt.Sprint(info[c.cfg.AvatarField]),
|
|
Name: fmt.Sprint(info[c.cfg.NameField]),
|
|
Email: fmt.Sprint(info[c.cfg.EmailField]),
|
|
}, nil
|
|
}
|
|
|
|
type UserInfo map[string]any
|
|
|
|
func (c *CustomOAuth) getUserInfo(code string) (UserInfo, error) {
|
|
token, err := c.oauth.Exchange(context.Background(), code)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := c.oauth.Client(context.Background(), token)
|
|
res, err := client.Get(c.cfg.UserInfoURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
buf, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var userInfo UserInfo
|
|
err = json.Unmarshal(buf, &userInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return userInfo, nil
|
|
}
|