Skip to content

Commit

Permalink
feat: casdoor support
Browse files Browse the repository at this point in the history
  • Loading branch information
zijiren233 committed Dec 13, 2024
1 parent 61dba48 commit 18fd47f
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 5 deletions.
118 changes: 118 additions & 0 deletions internal/provider/providers/casdoor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package providers

import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"

"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/settings"
"golang.org/x/oauth2"
)

// https://door.casdoor.com/.well-known/openid-configuration
type casdoorProvider struct {
config oauth2.Config
endpoint string
}

func newCasdoorProvider() provider.Interface {
return &casdoorProvider{
config: oauth2.Config{
Scopes: []string{"profile", "email", "phone", "name", "openid"},
},
}
}

func (p *casdoorProvider) Init(opt provider.Oauth2Option) {
p.config.ClientID = opt.ClientID
p.config.ClientSecret = opt.ClientSecret
p.config.RedirectURL = opt.RedirectURL
}

func (p *casdoorProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}

func (p *casdoorProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
return p.config.Exchange(ctx, code)
}

func (p *casdoorProvider) RefreshToken(ctx context.Context, token string) (*oauth2.Token, error) {
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: token}).Token()
}

func (p *casdoorProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.GetToken(ctx, code)
if err != nil {
return nil, err
}
client := p.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.endpoint+"/api/userinfo", nil)
if err != nil {
return nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var ui casdoorUserInfo
err = json.NewDecoder(resp.Body).Decode(&ui)
if err != nil {
return nil, err
}
un := ui.PreferredUsername
if un == "" {
un = ui.Name
}
return &provider.UserInfo{
ProviderUserID: ui.Sub,
Username: un,
}, nil
}

type casdoorUserInfo struct {
Sub string `json:"sub"`
PreferredUsername string `json:"preferred_username"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
}

func (p *casdoorProvider) RegistSetting(group string) {
settings.NewStringSetting(
group+"_endpoint", "", group,
settings.WithAfterInitString(func(ss settings.StringSetting, s string) {
p.endpoint = s
p.config.Endpoint = oauth2.Endpoint{
AuthURL: s + "/login/oauth/authorize",
TokenURL: s + "/api/login/oauth/access_token",
}
}),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
u, err := url.Parse(s)
if err != nil {
return "", err
}
return fmt.Sprintf("%s://%s", u.Scheme, u.Host), nil
}),
settings.WithAfterSetString(func(ss settings.StringSetting, s string) {
p.endpoint = s
p.config.Endpoint = oauth2.Endpoint{
AuthURL: s + "/login/oauth/authorize",
TokenURL: s + "/api/login/oauth/access_token",
}
}),
)
}

func (p *casdoorProvider) Provider() provider.OAuth2Provider {
return "casdoor"
}

func init() {
RegisterProvider(newCasdoorProvider())
}
14 changes: 9 additions & 5 deletions internal/provider/providers/logto.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package providers
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"net/url"

"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/settings"
Expand Down Expand Up @@ -86,17 +87,20 @@ func (p *logtoProvider) RegistSetting(group string) {
settings.NewStringSetting(
group+"_endpoint", "", group,
settings.WithAfterInitString(func(ss settings.StringSetting, s string) {
s = strings.TrimSuffix(s, "/")
s = strings.TrimSuffix(s, "/oidc")
p.endpoint = s
p.config.Endpoint = oauth2.Endpoint{
AuthURL: s + "/oidc/auth",
TokenURL: s + "/oidc/token",
}
}),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
u, err := url.Parse(s)
if err != nil {
return "", err
}
return fmt.Sprintf("%s://%s", u.Scheme, u.Host), nil
}),
settings.WithAfterSetString(func(ss settings.StringSetting, s string) {
s = strings.TrimSuffix(s, "/")
s = strings.TrimSuffix(s, "/oidc")
p.endpoint = s
p.config.Endpoint = oauth2.Endpoint{
AuthURL: s + "/oidc/auth",
Expand Down

0 comments on commit 18fd47f

Please sign in to comment.