update oauth to use oauth2 library
Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
parent
c3bf4a3d6f
commit
cb126da5d9
|
|
@ -1 +1,59 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/github"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type githubOauth2 struct {
|
||||
baseOauth2
|
||||
}
|
||||
|
||||
func NewGithubOauth2(name string, clientID string, clientSecret string, db *gorm.DB) (Oauther, error) {
|
||||
|
||||
oa := &githubOauth2{}
|
||||
oa.Name = name
|
||||
oa.Config = &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"},
|
||||
Endpoint: github.Endpoint,
|
||||
}
|
||||
oa.UserInfoURL = "https://api.github.com/user"
|
||||
|
||||
redirectURL, err := oa.GetRediectURL(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oa.Config.RedirectURL = redirectURL
|
||||
return oa, nil
|
||||
}
|
||||
|
||||
func (oa *githubOauth2) GetOauthUserInfo(token string) (*oauth2User, error) {
|
||||
req, err := http.NewRequest("GET", oa.UserInfoURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Authorization", "token"+" "+token)
|
||||
response, err := (&http.Client{}).Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
contents, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := oauth2User{}
|
||||
err = json.Unmarshal(contents, &u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,32 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type googleOauth2 struct {
|
||||
oauth2
|
||||
baseOauth2
|
||||
}
|
||||
|
||||
func NewGoogle(name string, clientID string, clientSecret string, scopes string, authURL string, tokenURL string, db *gorm.DB) (*oauth, error) {
|
||||
func NewGoogleOauth2(name string, clientID string, clientSecret string, db *gorm.DB) (Oauther, error) {
|
||||
|
||||
oa := &googleOauth2{
|
||||
Name: name,
|
||||
Config: &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: strings.Split(scopes, ","),
|
||||
Endpoint: google.
|
||||
},
|
||||
oa := &googleOauth2{}
|
||||
oa.Name = name
|
||||
oa.Config = &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"},
|
||||
Endpoint: google.Endpoint,
|
||||
}
|
||||
oa.UserInfoURL = "https://www.googleapis.com/oauth2/v2/userinfo"
|
||||
|
||||
redirectURL, err := oa.GetRediectURL(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oa.Config.RedirectURL = redirectURL
|
||||
return oa, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,42 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"d7y.io/dragonfly/v2/manager/model"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/oauth2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type oauth2 struct {
|
||||
type baseOauth2 struct {
|
||||
Name string
|
||||
UserInfoURL string
|
||||
Config *oauth2.Config
|
||||
}
|
||||
|
||||
type oauth2User struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// oauth interface
|
||||
type Oauther interface {
|
||||
GetRediectURL(*gorm.DB) (string, error)
|
||||
GetOauthUserInfo(string) (*model.User, error)
|
||||
GetOauthUserInfo(string) (*oauth2User, error)
|
||||
ExchangeUserByCode(string, *gorm.DB) (*model.User, error)
|
||||
AuthCodeURL(string) string
|
||||
}
|
||||
|
||||
func NewOauth(name string, clientID string, clientSecret string, scopes string, authURL string, tokenURL string, db *gorm.DB) (*oauth, error) {
|
||||
func NewBaseOauth2(name string, clientID string, clientSecret string, scopes string, authURL string, tokenURL string, db *gorm.DB) (Oauther, error) {
|
||||
|
||||
oa := &oauth2{
|
||||
oa := &baseOauth2{
|
||||
Name: name,
|
||||
Config: &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
|
|
@ -43,7 +56,7 @@ func NewOauth(name string, clientID string, clientSecret string, scopes string,
|
|||
return oa, nil
|
||||
}
|
||||
|
||||
func (o *oauth2) GetRediectURL(db *gorm.DB) (string, error) {
|
||||
func (oa *baseOauth2) GetRediectURL(db *gorm.DB) (string, error) {
|
||||
|
||||
s := model.Settings{}
|
||||
if err := db.First(&s, model.Settings{
|
||||
|
|
@ -51,10 +64,74 @@ func (o *oauth2) GetRediectURL(db *gorm.DB) (string, error) {
|
|||
}).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s/api/v1/oauth/%s/sigin", s.Value, o.Name), nil
|
||||
return fmt.Sprintf("%s/api/v1/oauth/%s/sigin", s.Value, oa.Name), nil
|
||||
}
|
||||
|
||||
func (o *oauth2) GetOauthUserInfo(code string) (*model.User, error) {
|
||||
user := model.User{}
|
||||
return &user, nil
|
||||
func (oa *baseOauth2) AuthCodeURL(state string) string {
|
||||
return oa.Config.AuthCodeURL(state)
|
||||
}
|
||||
|
||||
func (oa *baseOauth2) GetOauthUserInfo(token string) (*oauth2User, error) {
|
||||
response, err := http.Get(fmt.Sprintf("%s?access_token=%s", oa.UserInfoURL, token))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
contents, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := oauth2User{}
|
||||
err = json.Unmarshal(contents, &u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
func (oa *baseOauth2) ExchangeUserByCode(code string, db *gorm.DB) (*model.User, error) {
|
||||
token, err := oa.Config.Exchange(context.Background(), code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if oa.UserInfoURL == "" {
|
||||
return nil, errors.New("UserInfoURL is empty")
|
||||
}
|
||||
u, err := oa.GetOauthUserInfo(token.AccessToken)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Name == "admin" {
|
||||
return nil, errors.New("admin is not allowed to login by oauth")
|
||||
}
|
||||
encryptedPasswordBytes, err := bcrypt.GenerateFromPassword([]byte("Dragonfly2"), bcrypt.MinCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var userCount int64
|
||||
if err := db.Model(model.User{}).Where("name = ?", u.Name).Count(&userCount).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userCount <= 0 {
|
||||
user := model.User{
|
||||
EncryptedPassword: string(encryptedPasswordBytes),
|
||||
Name: u.Name,
|
||||
Email: u.Email,
|
||||
}
|
||||
|
||||
if err := db.Create(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
|
||||
} else {
|
||||
user := model.User{}
|
||||
if err := db.Model(model.User{}).Where("name = ?", u.Name).First(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@ func (s *rest) OauthSignin(name string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
o, err := oauth.NewOauth(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
o, err := oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return o.Config.AuthCodeURL("state"), nil
|
||||
return o.AuthCodeURL("state"), nil
|
||||
}
|
||||
|
||||
func (s *rest) OauthCallback(name, code string) (*model.User, error) {
|
||||
|
|
@ -108,11 +108,11 @@ func (s *rest) OauthCallback(name, code string) (*model.User, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
o, err := oauth.NewOauth(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
o, err := oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, err := o.GetOauthUserInfo(code)
|
||||
user, err := o.ExchangeUserByCode(code, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue