Feat: rainbow aggregation oauth2 provider support

This commit is contained in:
zijiren233 2024-02-25 22:26:54 +08:00
parent a3bc6113eb
commit cf83ed17ad
36 changed files with 984 additions and 648 deletions

View File

@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"slices"
"strings"
"github.com/hashicorp/go-hclog"
"github.com/maruel/natural"
@ -14,6 +15,7 @@ import (
"github.com/synctv-org/synctv/internal/conf"
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/aggregations"
"github.com/synctv-org/synctv/internal/provider/plugins"
"github.com/synctv-org/synctv/internal/provider/providers"
"github.com/synctv-org/synctv/internal/settings"
@ -21,7 +23,9 @@ import (
"github.com/zijiren233/gencontainer/refreshcache"
)
var ProviderGroupSettings = make(map[model.SettingGroup]*ProviderGroupSetting)
var (
ProviderGroupSettings = make(map[model.SettingGroup]*ProviderGroupSetting)
)
type ProviderGroupSetting struct {
Enabled settings.BoolSetting
@ -36,14 +40,14 @@ var (
Oauth2EnabledCache = refreshcache.NewRefreshCache[[]provider.OAuth2Provider](func(context.Context, ...any) ([]provider.OAuth2Provider, error) {
ps := providers.EnabledProvider()
r := make([]provider.OAuth2Provider, 0, ps.Len())
providers.EnabledProvider().Range(func(key provider.OAuth2Provider, value provider.ProviderInterface) bool {
r = append(r, key)
providers.EnabledProvider().Range(func(p provider.OAuth2Provider, value struct{}) bool {
r = append(r, p)
return true
})
slices.SortStableFunc(r, func(a, b provider.OAuth2Provider) int {
if a == b {
return 0
} else if natural.Less(string(a), string(b)) {
} else if natural.Less(a, b) {
return -1
} else {
return 1
@ -83,65 +87,212 @@ func InitProvider(ctx context.Context) (err error) {
}
}
for op, pi := range providers.AllProvider() {
op, pi := op, pi
group := model.SettingGroup(fmt.Sprintf("%s_%s", model.SettingGroupOauth2, op))
groupSettings := &ProviderGroupSetting{}
ProviderGroupSettings[group] = groupSettings
for _, pi := range providers.AllProvider() {
InitProviderSetting(pi)
}
groupSettings.Enabled = settings.NewBoolSetting(fmt.Sprintf("%s_enabled", group), false, group, settings.WithBeforeInitBool(func(bs settings.BoolSetting, b bool) (bool, error) {
defer Oauth2EnabledCache.Refresh(ctx)
if b {
return b, providers.EnableProvider(op)
} else {
providers.DisableProvider(op)
return b, nil
}
}), settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) {
defer Oauth2EnabledCache.Refresh(ctx)
if b {
return b, providers.EnableProvider(op)
} else {
providers.DisableProvider(op)
return b, nil
}
}))
opt := provider.Oauth2Option{}
groupSettings.ClientID = settings.NewStringSetting(fmt.Sprintf("%s_client_id", group), opt.ClientID, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientID = s
pi.Init(opt)
return s, nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientID = s
pi.Init(opt)
return s, nil
}))
groupSettings.ClientSecret = settings.NewStringSetting(fmt.Sprintf("%s_client_secret", group), opt.ClientSecret, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientSecret = s
pi.Init(opt)
return s, nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientSecret = s
pi.Init(opt)
return s, nil
}))
groupSettings.RedirectURL = settings.NewStringSetting(fmt.Sprintf("%s_redirect_url", group), opt.RedirectURL, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.RedirectURL = s
pi.Init(opt)
return s, nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.RedirectURL = s
pi.Init(opt)
return s, nil
}))
groupSettings.DisableUserSignup = settings.NewBoolSetting(fmt.Sprintf("%s_disable_user_signup", group), false, group)
groupSettings.SignupNeedReview = settings.NewBoolSetting(fmt.Sprintf("%s_signup_need_review", group), false, group)
for _, api := range aggregations.AllAggregation() {
InitAggregationSetting(api)
}
return nil
}
func InitProviderSetting(pi provider.Provider) {
group := model.SettingGroup(fmt.Sprintf("%s_%s", model.SettingGroupOauth2, pi.Provider()))
groupSettings := &ProviderGroupSetting{}
ProviderGroupSettings[group] = groupSettings
groupSettings.Enabled = settings.NewBoolSetting(fmt.Sprintf("%s_enabled", group), false, group,
settings.WithBeforeInitBool(func(bs settings.BoolSetting, b bool) (bool, error) {
defer Oauth2EnabledCache.Refresh(context.Background())
if b {
return b, providers.EnableProvider(pi.Provider())
} else {
providers.DisableProvider(pi.Provider())
return b, nil
}
}),
settings.WithInitPriorityBool(1),
settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) {
defer Oauth2EnabledCache.Refresh(context.Background())
if b {
return b, providers.EnableProvider(pi.Provider())
} else {
providers.DisableProvider(pi.Provider())
return b, nil
}
}),
)
opt := provider.Oauth2Option{}
groupSettings.ClientID = settings.NewStringSetting(fmt.Sprintf("%s_client_id", group), opt.ClientID, group,
settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientID = s
pi.Init(opt)
return s, nil
}),
settings.WithInitPriorityString(1),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientID = s
pi.Init(opt)
return s, nil
}))
groupSettings.ClientSecret = settings.NewStringSetting(fmt.Sprintf("%s_client_secret", group), opt.ClientSecret, group,
settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientSecret = s
pi.Init(opt)
return s, nil
}),
settings.WithInitPriorityString(1),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientSecret = s
pi.Init(opt)
return s, nil
}))
groupSettings.RedirectURL = settings.NewStringSetting(fmt.Sprintf("%s_redirect_url", group), opt.RedirectURL, group,
settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
opt.RedirectURL = s
pi.Init(opt)
return s, nil
}),
settings.WithInitPriorityString(1),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
opt.RedirectURL = s
pi.Init(opt)
return s, nil
}))
groupSettings.DisableUserSignup = settings.NewBoolSetting(fmt.Sprintf("%s_disable_user_signup", group), false, group)
groupSettings.SignupNeedReview = settings.NewBoolSetting(fmt.Sprintf("%s_signup_need_review", group), false, group)
}
func InitAggregationProviderSetting(pi provider.Provider) {
group := model.SettingGroup(fmt.Sprintf("%s_%s", model.SettingGroupOauth2, pi.Provider()))
groupSettings := &ProviderGroupSetting{}
ProviderGroupSettings[group] = groupSettings
groupSettings.Enabled = settings.LoadOrNewBoolSetting(fmt.Sprintf("%s_enabled", group), false, group,
settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) {
defer Oauth2EnabledCache.Refresh(context.Background())
if b {
return b, providers.EnableProvider(pi.Provider())
} else {
providers.DisableProvider(pi.Provider())
return b, nil
}
}),
)
opt := provider.Oauth2Option{}
groupSettings.ClientID = settings.LoadOrNewStringSetting(fmt.Sprintf("%s_client_id", group), opt.ClientID, group)
opt.ClientID = groupSettings.ClientID.Get()
groupSettings.ClientID.SetBeforeSet(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientID = s
pi.Init(opt)
return s, nil
})
groupSettings.ClientSecret = settings.LoadOrNewStringSetting(fmt.Sprintf("%s_client_secret", group), opt.ClientSecret, group)
opt.ClientSecret = groupSettings.ClientSecret.Get()
groupSettings.ClientSecret.SetBeforeSet(func(ss settings.StringSetting, s string) (string, error) {
opt.ClientSecret = s
pi.Init(opt)
return s, nil
})
groupSettings.RedirectURL = settings.LoadOrNewStringSetting(fmt.Sprintf("%s_redirect_url", group), opt.RedirectURL, group)
opt.RedirectURL = groupSettings.RedirectURL.Get()
groupSettings.RedirectURL.SetBeforeSet(func(ss settings.StringSetting, s string) (string, error) {
opt.RedirectURL = s
pi.Init(opt)
return s, nil
})
pi.Init(opt)
groupSettings.DisableUserSignup = settings.LoadOrNewBoolSetting(fmt.Sprintf("%s_disable_user_signup", group), false, group)
groupSettings.SignupNeedReview = settings.LoadOrNewBoolSetting(fmt.Sprintf("%s_signup_need_review", group), false, group)
}
func InitAggregationSetting(pi provider.AggregationProviderInterface) {
group := model.SettingGroup(fmt.Sprintf("%s_%s", model.SettingGroupOauth2, pi.Provider()))
switch pi := pi.(type) {
case *aggregations.Rainbow:
settings.NewStringSetting(fmt.Sprintf("%s_api", group), aggregations.DefaultRainbowApi, group,
settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
pi.SetAPI(s)
return s, nil
},
),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
pi.SetAPI(s)
return s, nil
},
),
)
}
list := settings.NewStringSetting(fmt.Sprintf("%s_enabled_list", group), "", group,
settings.WithBeforeInitString(func(ss settings.StringSetting, s string) (string, error) {
return s, nil
}),
settings.WithInitPriorityString(1),
settings.WithBeforeSetString(func(ss settings.StringSetting, s string) (string, error) {
if s == "" {
return s, nil
}
list := strings.Split(s, ",")
for _, p := range list {
if slices.Index(pi.Providers(), p) == -1 {
return s, fmt.Errorf("provider %s not found", p)
}
}
return s, nil
}),
)
settings.NewBoolSetting(fmt.Sprintf("%s_enabled", group), false, group,
settings.WithBeforeInitBool(func(bs settings.BoolSetting, b bool) (bool, error) {
if b {
s := list.Get()
if s == "" {
log.Warnf("aggregation provider %s enabled, but no provider enabled", pi.Provider())
}
all := pi.Providers()
list := strings.Split(s, ",")
enabled := make([]provider.OAuth2Provider, 0, len(list))
for _, p := range list {
if slices.Index(all, p) != -1 {
enabled = append(enabled, p)
} else {
log.Warnf("aggregation provider %s enabled, but provider %s not found", pi.Provider(), p)
}
}
pi2, err := provider.ExtractProviders(pi, enabled...)
if err != nil {
log.Errorf("aggregation provider %s enabled, but extract provider failed: %s", pi.Provider(), err)
return b, nil
}
for _, pi2 := range pi2 {
providers.RegisterProvider(pi2)
InitAggregationProviderSetting(pi2)
}
}
return b, nil
}),
settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) {
if len(list.Get()) == 0 {
return b, fmt.Errorf("enabled provider list is empty")
}
return b, nil
}),
)
}

View File

@ -6,17 +6,56 @@ import (
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/settings"
"github.com/zijiren233/gencontainer/heap"
)
var _ heap.Interface[maxHeapItem] = (*maxHeap)(nil)
type maxHeapItem struct {
priority int
settings.Setting
}
type maxHeap struct {
items []maxHeapItem
}
func (h *maxHeap) Len() int {
return len(h.items)
}
func (h *maxHeap) Less(i, j int) bool {
return h.items[i].priority > h.items[j].priority
}
func (h *maxHeap) Swap(i, j int) {
h.items[i], h.items[j] = h.items[j], h.items[i]
}
func (h *maxHeap) Push(x maxHeapItem) {
h.items = append(h.items, x)
}
func (h *maxHeap) Pop() maxHeapItem {
n := len(h.items)
x := h.items[n-1]
h.items = h.items[:n-1]
return x
}
func InitSetting(ctx context.Context) error {
return initAndFixSettings(settings.Settings)
ss := []settings.Setting{}
for _, s := range settings.Settings {
ss = append(ss, s)
}
return initAndFixSettings(ss)
}
func settingEqual(s *model.Setting, b settings.Setting) bool {
return s.Type == b.Type() && s.Group == b.Group() && s.Name == b.Name()
}
func initAndFixSettings(s map[string]settings.Setting) error {
func initAndFixSettings(ss []settings.Setting) error {
settingsCache, err := db.GetSettingItemsToMap()
if err != nil {
return err
@ -24,7 +63,17 @@ func initAndFixSettings(s map[string]settings.Setting) error {
var (
setting *model.Setting
)
for _, b := range s {
list := new(maxHeap)
for _, s := range ss {
heap.Push(list, maxHeapItem{
priority: s.InitPriority(),
Setting: s,
})
}
for list.Len() > 0 {
b := heap.Pop(list)
if sc, ok := settingsCache[b.Name()]; ok && settingEqual(sc, b) {
setting = sc
} else {
@ -48,5 +97,6 @@ func initAndFixSettings(s map[string]settings.Setting) error {
}
}
}
return nil
}

View File

@ -11,11 +11,7 @@ const (
SettingTypeString SettingType = "string"
)
type SettingGroup string
func (s SettingGroup) String() string {
return string(s)
}
type SettingGroup = string
const (
SettingGroupRoom SettingGroup = "room"

View File

@ -0,0 +1,22 @@
package provider
type AggregationProviderInterface interface {
ExtractProvider(OAuth2Provider) (ProviderInterface, error)
Provider() OAuth2Provider
Providers() []OAuth2Provider
}
func ExtractProviders(p AggregationProviderInterface, providers ...OAuth2Provider) ([]ProviderInterface, error) {
if len(providers) == 0 {
providers = p.Providers()
}
var pi []ProviderInterface = make([]ProviderInterface, len(providers))
for i, provider := range providers {
pi2, err := p.ExtractProvider(provider)
if err != nil {
return nil, err
}
pi[i] = pi2
}
return pi, nil
}

View File

@ -0,0 +1,17 @@
package aggregations
import (
"github.com/synctv-org/synctv/internal/provider"
)
var (
allAggregation []provider.AggregationProviderInterface
)
func addAggregation(ps ...provider.AggregationProviderInterface) {
allAggregation = append(allAggregation, ps...)
}
func AllAggregation() []provider.AggregationProviderInterface {
return allAggregation
}

View File

@ -0,0 +1,171 @@
package aggregations
import (
"context"
"fmt"
"net/http"
"net/url"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/provider"
)
var _ provider.AggregationProviderInterface = (*Rainbow)(nil)
const DefaultRainbowApi = "https://u.cccyun.cc"
type Rainbow struct {
api string
}
func (r *Rainbow) SetAPI(api string) {
r.api = api
}
func (r *Rainbow) Provider() provider.OAuth2Provider {
return "rainbow"
}
func (r *Rainbow) Providers() []provider.OAuth2Provider {
return []provider.OAuth2Provider{
"qq",
"wx",
"alipay",
"baidu",
"microsoft",
}
}
type rainbowGenericProvider struct {
parent *Rainbow
t string
conf provider.Oauth2Option
}
func (r *Rainbow) newGenericProvider(t string) provider.ProviderInterface {
return &rainbowGenericProvider{
parent: r,
t: t,
}
}
func (p *rainbowGenericProvider) Init(c provider.Oauth2Option) {
p.conf = c
}
func (p *rainbowGenericProvider) Provider() provider.OAuth2Provider {
switch p.t {
case "wx":
return "wechat"
default:
return p.t
}
}
func (p *rainbowGenericProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
result, err := url.JoinPath(p.parent.api, "/connect.php")
if err != nil {
return "", err
}
u, err := url.Parse(result)
if err != nil {
return "", err
}
query := url.Values{}
query.Set("act", "login")
query.Set("appid", p.conf.ClientID)
query.Set("appkey", p.conf.ClientSecret)
query.Set("type", p.t)
query.Set("redirect_uri", p.conf.RedirectURL)
query.Set("state", state)
u.RawQuery = query.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return "", err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
data := rainbowNewAuthURLResp{}
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return "", err
}
if data.Code != 0 {
return "", fmt.Errorf("error code: %d, msg: %s", data.ErrCode, data.Msg)
}
return data.URL, nil
}
type rainbowNewAuthURLResp struct {
Code int `json:"code"`
ErrCode int `json:"errcode"`
Msg string `json:"msg"`
Type string `json:"type"`
URL string `json:"url"`
}
func (p *rainbowGenericProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
result, err := url.JoinPath(p.parent.api, "/connect.php")
if err != nil {
return nil, err
}
u, err := url.Parse(result)
if err != nil {
return nil, err
}
query := url.Values{}
query.Set("act", "callback")
query.Set("appid", p.conf.ClientID)
query.Set("appkey", p.conf.ClientSecret)
query.Set("type", p.t)
query.Set("code", code)
u.RawQuery = query.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data := rainbowUserInfo{}
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return nil, err
}
if data.Code != 0 {
return nil, fmt.Errorf("error code: %d, msg: %s", data.ErrCode, data.Msg)
}
return &provider.UserInfo{
Username: data.Nickname,
ProviderUserID: data.SocialUID,
}, nil
}
type rainbowUserInfo struct {
Code int `json:"code"`
ErrCode int `json:"errcode"`
Msg string `json:"msg"`
Type string `json:"type"`
SocialUID string `json:"social_uid"`
Nickname string `json:"nickname"`
}
func (r *Rainbow) ExtractProvider(p provider.OAuth2Provider) (provider.ProviderInterface, error) {
switch p {
case "qq", "wx", "alipay", "baidu", "microsoft":
return r.newGenericProvider(p), nil
default:
return nil, fmt.Errorf("provider %s not supported", p)
}
}
func init() {
addAggregation(new(Rainbow))
}

View File

@ -2,11 +2,9 @@ package plugins
import (
"context"
"time"
"github.com/synctv-org/synctv/internal/provider"
providerpb "github.com/synctv-org/synctv/proto/provider"
"golang.org/x/oauth2"
)
type GRPCClient struct{ client providerpb.Oauth2PluginClient }
@ -30,50 +28,17 @@ func (c *GRPCClient) Provider() provider.OAuth2Provider {
return provider.OAuth2Provider(resp.Name)
}
func (c *GRPCClient) NewAuthURL(state string) string {
resp, err := c.client.NewAuthURL(context.Background(), &providerpb.NewAuthURLReq{State: state})
func (c *GRPCClient) NewAuthURL(ctx context.Context, state string) (string, error) {
resp, err := c.client.NewAuthURL(ctx, &providerpb.NewAuthURLReq{State: state})
if err != nil {
return ""
return "", err
}
return resp.Url
return resp.Url, nil
}
func (c *GRPCClient) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
resp, err := c.client.GetToken(ctx, &providerpb.GetTokenReq{Code: code})
if err != nil {
return nil, err
}
return &oauth2.Token{
AccessToken: resp.AccessToken,
TokenType: resp.TokenType,
RefreshToken: resp.RefreshToken,
Expiry: time.Unix(resp.Expiry, 0),
}, nil
}
func (c *GRPCClient) RefreshToken(ctx context.Context, tk string) (*oauth2.Token, error) {
resp, err := c.client.RefreshToken(ctx, &providerpb.RefreshTokenReq{
RefreshToken: tk,
})
if err != nil {
return nil, err
}
return &oauth2.Token{
AccessToken: resp.Token.AccessToken,
TokenType: resp.Token.TokenType,
RefreshToken: resp.Token.RefreshToken,
Expiry: time.Unix(resp.Token.Expiry, 0),
}, nil
}
func (c *GRPCClient) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (c *GRPCClient) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
resp, err := c.client.GetUserInfo(ctx, &providerpb.GetUserInfoReq{
Token: &providerpb.Token{
AccessToken: tk.AccessToken,
TokenType: tk.TokenType,
RefreshToken: tk.RefreshToken,
Expiry: tk.Expiry.Unix(),
},
Code: code,
})
if err != nil {
return nil, err

View File

@ -4,12 +4,13 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
plugin "github.com/hashicorp/go-plugin"
"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/plugins"
"golang.org/x/oauth2"
"net/http"
"os"
)
// Linux/Mac/Windows:
@ -52,19 +53,15 @@ func (p *AuthingProvider) Provider() provider.OAuth2Provider {
return "authing" //插件名
}
func (p *AuthingProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *AuthingProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *AuthingProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
return p.config.Exchange(ctx, code)
}
func (p *AuthingProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.Token, error) {
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *AuthingProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *AuthingProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.config.Exchange(ctx, code)
if err != nil {
return nil, err
}
client := p.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://core.authing.cn/oauth/me", nil) // 身份端点
if err != nil {

View File

@ -6,11 +6,12 @@ import (
"fmt"
"os"
"net/http"
plugin "github.com/hashicorp/go-plugin"
"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/plugins"
"golang.org/x/oauth2"
"net/http"
)
// Linux/Mac/Windows:
@ -55,8 +56,8 @@ func (p *FeishuSSOProvider) Provider() provider.OAuth2Provider {
return "feishu-sso" //插件名
}
func (p *FeishuSSOProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *FeishuSSOProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *FeishuSSOProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -67,7 +68,11 @@ func (p *FeishuSSOProvider) RefreshToken(ctx context.Context, tk string) (*oauth
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *FeishuSSOProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *FeishuSSOProvider) 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, fmt.Sprintf("https://anycross.feishu.cn/sso/%s/oauth2/userinfo", p.ssoid), nil) // 身份端点
if err != nil {

View File

@ -46,8 +46,8 @@ func (p *GiteeProvider) Provider() provider.OAuth2Provider {
return "gitee"
}
func (p *GiteeProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *GiteeProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *GiteeProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -58,7 +58,11 @@ func (p *GiteeProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.To
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *GiteeProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *GiteeProvider) 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, "https://gitee.com/api/v5/user", nil)
if err != nil {

View File

@ -2,11 +2,9 @@ package plugins
import (
"context"
"time"
"github.com/synctv-org/synctv/internal/provider"
providerpb "github.com/synctv-org/synctv/proto/provider"
"golang.org/x/oauth2"
)
type GRPCServer struct {
@ -29,29 +27,15 @@ func (s *GRPCServer) Provider(ctx context.Context, req *providerpb.Enpty) (*prov
}
func (s *GRPCServer) NewAuthURL(ctx context.Context, req *providerpb.NewAuthURLReq) (*providerpb.NewAuthURLResp, error) {
return &providerpb.NewAuthURLResp{Url: s.Impl.NewAuthURL(req.State)}, nil
}
func (s *GRPCServer) GetToken(ctx context.Context, req *providerpb.GetTokenReq) (*providerpb.Token, error) {
token, err := s.Impl.GetToken(ctx, req.Code)
s2, err := s.Impl.NewAuthURL(ctx, req.State)
if err != nil {
return nil, err
}
return &providerpb.Token{
AccessToken: token.AccessToken,
TokenType: token.TokenType,
RefreshToken: token.RefreshToken,
Expiry: token.Expiry.Unix(),
}, nil
return &providerpb.NewAuthURLResp{Url: s2}, nil
}
func (s *GRPCServer) GetUserInfo(ctx context.Context, req *providerpb.GetUserInfoReq) (*providerpb.GetUserInfoResp, error) {
userInfo, err := s.Impl.GetUserInfo(ctx, &oauth2.Token{
AccessToken: req.Token.AccessToken,
TokenType: req.Token.TokenType,
Expiry: time.Unix(req.Token.Expiry, 0),
RefreshToken: req.Token.RefreshToken,
})
userInfo, err := s.Impl.GetUserInfo(ctx, req.Code)
if err != nil {
return nil, err
}

View File

@ -2,11 +2,9 @@ package provider
import (
"context"
"golang.org/x/oauth2"
)
type OAuth2Provider string
type OAuth2Provider = string
type UserInfo struct {
Username string
@ -19,11 +17,13 @@ type Oauth2Option struct {
RedirectURL string
}
type ProviderInterface interface {
type Provider interface {
Init(Oauth2Option)
Provider() OAuth2Provider
NewAuthURL(string) string
GetToken(context.Context, string) (*oauth2.Token, error)
RefreshToken(context.Context, string) (*oauth2.Token, error)
GetUserInfo(context.Context, *oauth2.Token) (*UserInfo, error)
}
type ProviderInterface interface {
Provider
NewAuthURL(context.Context, string) (string, error)
GetUserInfo(context.Context, string) (*UserInfo, error)
}

View File

@ -38,8 +38,8 @@ func (p *BaiduNetDiskProvider) Provider() provider.OAuth2Provider {
return "baidu-netdisk"
}
func (p *BaiduNetDiskProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *BaiduNetDiskProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *BaiduNetDiskProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -50,7 +50,11 @@ func (p *BaiduNetDiskProvider) RefreshToken(ctx context.Context, tk string) (*oa
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *BaiduNetDiskProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *BaiduNetDiskProvider) 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, fmt.Sprintf("https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo&access_token=%s", tk.AccessToken), nil)
if err != nil {

View File

@ -37,8 +37,8 @@ func (p *BaiduProvider) Provider() provider.OAuth2Provider {
return "baidu"
}
func (p *BaiduProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *BaiduProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *BaiduProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -49,7 +49,11 @@ func (p *BaiduProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.To
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *BaiduProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *BaiduProvider) 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, fmt.Sprintf("https://openapi.baidu.com/rest/2.0/passport/users/getLoggedInUser?access_token=%s", tk.AccessToken), nil)
if err != nil {

View File

@ -36,8 +36,8 @@ func (p *GiteeProvider) Provider() provider.OAuth2Provider {
return "gitee"
}
func (p *GiteeProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *GiteeProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *GiteeProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -48,7 +48,11 @@ func (p *GiteeProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.To
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *GiteeProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *GiteeProvider) 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, "https://gitee.com/api/v5/user", nil)
if err != nil {

View File

@ -34,8 +34,8 @@ func (p *GithubProvider) Provider() provider.OAuth2Provider {
return "github"
}
func (p *GithubProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *GithubProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *GithubProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -46,7 +46,11 @@ func (p *GithubProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.T
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *GithubProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *GithubProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.config.Exchange(ctx, code)
if err != nil {
return nil, err
}
client := p.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/user", nil)
if err != nil {

View File

@ -32,8 +32,8 @@ func (g *GitlabProvider) Provider() provider.OAuth2Provider {
return "gitlab"
}
func (g *GitlabProvider) NewAuthURL(state string) string {
return g.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (g *GitlabProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return g.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (g *GitlabProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -44,7 +44,11 @@ func (g *GitlabProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.T
return g.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (g *GitlabProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (g *GitlabProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := g.GetToken(ctx, code)
if err != nil {
return nil, err
}
client := g.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://gitlab.com/api/v4/user", nil)
if err != nil {

View File

@ -33,8 +33,8 @@ func (g *GoogleProvider) Provider() provider.OAuth2Provider {
return "google"
}
func (g *GoogleProvider) NewAuthURL(state string) string {
return g.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (g *GoogleProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return g.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (g *GoogleProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -45,7 +45,11 @@ func (g *GoogleProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.T
return g.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (g *GoogleProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (g *GoogleProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := g.GetToken(ctx, code)
if err != nil {
return nil, err
}
client := g.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.googleapis.com/oauth2/v2/userinfo", nil)
if err != nil {

View File

@ -33,8 +33,8 @@ func (p *MicrosoftProvider) Provider() provider.OAuth2Provider {
return "microsoft"
}
func (p *MicrosoftProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *MicrosoftProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *MicrosoftProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -45,7 +45,11 @@ func (p *MicrosoftProvider) RefreshToken(ctx context.Context, tk string) (*oauth
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *MicrosoftProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *MicrosoftProvider) 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, "https://graph.microsoft.com/v1.0/me", nil)
if err != nil {

View File

@ -8,12 +8,12 @@ import (
)
var (
enabledProviders rwmap.RWMap[provider.OAuth2Provider, provider.ProviderInterface]
allProviders = make(map[provider.OAuth2Provider]provider.ProviderInterface)
enabledProviders rwmap.RWMap[provider.OAuth2Provider, struct{}]
allProviders rwmap.RWMap[provider.OAuth2Provider, provider.ProviderInterface]
)
func InitProvider(p provider.OAuth2Provider, c provider.Oauth2Option) (provider.ProviderInterface, error) {
pi, ok := allProviders[p]
pi, ok := allProviders.Load(p)
if !ok {
return nil, FormatErrNotImplemented(p)
}
@ -23,12 +23,16 @@ func InitProvider(p provider.OAuth2Provider, c provider.Oauth2Option) (provider.
func RegisterProvider(ps ...provider.ProviderInterface) {
for _, p := range ps {
allProviders[p.Provider()] = p
allProviders.Store(p.Provider(), p)
}
}
func GetProvider(p provider.OAuth2Provider) (provider.ProviderInterface, error) {
pi, ok := enabledProviders.Load(p)
_, ok := enabledProviders.Load(p)
if !ok {
return nil, FormatErrNotImplemented(p)
}
pi, ok := allProviders.Load(p)
if !ok {
return nil, FormatErrNotImplemented(p)
}
@ -36,24 +40,34 @@ func GetProvider(p provider.OAuth2Provider) (provider.ProviderInterface, error)
}
func AllProvider() map[provider.OAuth2Provider]provider.ProviderInterface {
return allProviders
m := make(map[provider.OAuth2Provider]provider.ProviderInterface)
allProviders.Range(func(key string, value provider.ProviderInterface) bool {
m[key] = value
return true
})
return m
}
func EnabledProvider() *rwmap.RWMap[provider.OAuth2Provider, provider.ProviderInterface] {
func EnabledProvider() *rwmap.RWMap[provider.OAuth2Provider, struct{}] {
return &enabledProviders
}
func EnableProvider(p provider.OAuth2Provider) error {
pi, ok := allProviders[p]
_, ok := allProviders.Load(p)
if !ok {
return FormatErrNotImplemented(p)
}
enabledProviders.Store(p, pi)
enabledProviders.Store(p, struct{}{})
return nil
}
func DisableProvider(p provider.OAuth2Provider) {
func DisableProvider(p provider.OAuth2Provider) error {
_, ok := allProviders.Load(p)
if !ok {
return FormatErrNotImplemented(p)
}
enabledProviders.Delete(p)
return nil
}
type FormatErrNotImplemented string

View File

@ -37,8 +37,8 @@ func (p *QQProvider) Provider() provider.OAuth2Provider {
return "qq"
}
func (p *QQProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *QQProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *QQProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -82,7 +82,11 @@ func (p *QQProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.Token
return newTk, json.NewDecoder(resp.Body).Decode(newTk)
}
func (p *QQProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *QQProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.GetToken(ctx, code)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://graph.qq.com/oauth2.0/me?access_token=%s&fmt=json", tk.AccessToken), nil)
if err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package providers
import (
"context"
"fmt"
"net/http"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/provider"
"golang.org/x/oauth2"
"net/http"
)
type XiaomiProvider struct {
@ -35,8 +36,8 @@ func (p *XiaomiProvider) Provider() provider.OAuth2Provider {
return "xiaomi"
}
func (p *XiaomiProvider) NewAuthURL(state string) string {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline)
func (p *XiaomiProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *XiaomiProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
@ -47,7 +48,11 @@ func (p *XiaomiProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.T
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *XiaomiProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provider.UserInfo, error) {
func (p *XiaomiProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.config.Exchange(ctx, code)
if err != nil {
return nil, err
}
client := p.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://open.account.xiaomi.com/user/profile?clientId=%s&token=%s", p.config.ClientID, tk.AccessToken), nil)
if err != nil {

View File

@ -16,6 +16,8 @@ type BoolSetting interface {
Default() bool
Parse(string) (bool, error)
Stringify(bool) string
SetBeforeInit(func(BoolSetting, bool) (bool, error))
SetBeforeSet(func(BoolSetting, bool) (bool, error))
}
var _ BoolSetting = (*Bool)(nil)
@ -29,15 +31,21 @@ type Bool struct {
type BoolSettingOption func(*Bool)
func WithInitPriorityBool(priority int) BoolSettingOption {
return func(s *Bool) {
s.SetInitPriority(priority)
}
}
func WithBeforeInitBool(beforeInit func(BoolSetting, bool) (bool, error)) BoolSettingOption {
return func(s *Bool) {
s.beforeInit = beforeInit
s.SetBeforeInit(beforeInit)
}
}
func WithBeforeSetBool(beforeSet func(BoolSetting, bool) (bool, error)) BoolSettingOption {
return func(s *Bool) {
s.beforeSet = beforeSet
s.SetBeforeSet(beforeSet)
}
}
@ -57,6 +65,18 @@ func newBool(name string, value bool, group model.SettingGroup, options ...BoolS
return b
}
func (b *Bool) SetInitPriority(priority int) {
b.initPriority = priority
}
func (b *Bool) SetBeforeInit(beforeInit func(BoolSetting, bool) (bool, error)) {
b.beforeInit = beforeInit
}
func (b *Bool) SetBeforeSet(beforeSet func(BoolSetting, bool) (bool, error)) {
b.beforeSet = beforeSet
}
func (b *Bool) set(value bool) {
if value {
atomic.StoreUint32(&b.value, 1)
@ -158,8 +178,31 @@ func NewBoolSetting(k string, v bool, g model.SettingGroup, options ...BoolSetti
if loaded {
panic(fmt.Sprintf("setting %s already exists", k))
}
return CoverBoolSetting(k, v, g, options...)
}
func CoverBoolSetting(k string, v bool, g model.SettingGroup, options ...BoolSettingOption) BoolSetting {
b := newBool(k, v, g, options...)
Settings[k] = b
GroupSettings[g] = append(GroupSettings[g], b)
if GroupSettings[g] == nil {
GroupSettings[g] = make(map[string]Setting)
}
GroupSettings[g][k] = b
return b
}
func LoadBoolSetting(k string) (BoolSetting, bool) {
s, ok := Settings[k]
if !ok {
return nil, false
}
b, ok := s.(BoolSetting)
return b, ok
}
func LoadOrNewBoolSetting(k string, v bool, g model.SettingGroup, options ...BoolSettingOption) BoolSetting {
if s, ok := LoadBoolSetting(k); ok {
return s
}
return CoverBoolSetting(k, v, g, options...)
}

View File

@ -17,6 +17,8 @@ type Float64Setting interface {
Default() float64
Parse(string) (float64, error)
Stringify(float64) string
SetBeforeInit(func(Float64Setting, float64) (float64, error))
SetBeforeSet(func(Float64Setting, float64) (float64, error))
}
var _ Float64Setting = (*Float64)(nil)
@ -31,6 +33,12 @@ type Float64 struct {
type Float64SettingOption func(*Float64)
func WithInitPriorityFloat64(priority int) Float64SettingOption {
return func(s *Float64) {
s.SetInitPriority(priority)
}
}
func WithValidatorFloat64(validator func(float64) error) Float64SettingOption {
return func(s *Float64) {
s.validator = validator
@ -39,13 +47,13 @@ func WithValidatorFloat64(validator func(float64) error) Float64SettingOption {
func WithBeforeInitFloat64(beforeInit func(Float64Setting, float64) (float64, error)) Float64SettingOption {
return func(s *Float64) {
s.beforeInit = beforeInit
s.SetBeforeInit(beforeInit)
}
}
func WithBeforeSetFloat64(beforeSet func(Float64Setting, float64) (float64, error)) Float64SettingOption {
return func(s *Float64) {
s.beforeSet = beforeSet
s.SetBeforeSet(beforeSet)
}
}
@ -65,6 +73,18 @@ func newFloat64(name string, value float64, group model.SettingGroup, options ..
return f
}
func (f *Float64) SetInitPriority(priority int) {
f.initPriority = priority
}
func (f *Float64) SetBeforeInit(beforeInit func(Float64Setting, float64) (float64, error)) {
f.beforeInit = beforeInit
}
func (f *Float64) SetBeforeSet(beforeSet func(Float64Setting, float64) (float64, error)) {
f.beforeSet = beforeSet
}
func (f *Float64) Parse(value string) (float64, error) {
v, err := strconv.ParseFloat(value, 64)
if err != nil {
@ -171,13 +191,37 @@ func (f *Float64) Interface() any {
return f.Get()
}
func NewFloat64Setting(k string, v float64, g model.SettingGroup, options ...Float64SettingOption) *Float64 {
func NewFloat64Setting(k string, v float64, g model.SettingGroup, options ...Float64SettingOption) Float64Setting {
_, loaded := Settings[k]
if loaded {
panic(fmt.Sprintf("setting %s already exists", k))
}
return CoverFloat64Setting(k, v, g, options...)
}
func CoverFloat64Setting(k string, v float64, g model.SettingGroup, options ...Float64SettingOption) Float64Setting {
f := newFloat64(k, v, g, options...)
Settings[k] = f
GroupSettings[g] = append(GroupSettings[g], f)
if GroupSettings[g] == nil {
GroupSettings[g] = make(map[string]Setting)
}
GroupSettings[g][k] = f
return f
}
func LoadFloat64Setting(k string) (Float64Setting, bool) {
s, ok := Settings[k]
if !ok {
return nil, false
}
f, ok := s.(Float64Setting)
return f, ok
}
func LoadOrNewFloat64Setting(k string, v float64, g model.SettingGroup, options ...Float64SettingOption) Float64Setting {
s, ok := LoadFloat64Setting(k)
if ok {
return s
}
return CoverFloat64Setting(k, v, g, options...)
}

View File

@ -16,6 +16,8 @@ type Int64Setting interface {
Default() int64
Parse(string) (int64, error)
Stringify(int64) string
SetBeforeInit(func(Int64Setting, int64) (int64, error))
SetBeforeSet(func(Int64Setting, int64) (int64, error))
}
var _ Int64Setting = (*Int64)(nil)
@ -30,6 +32,12 @@ type Int64 struct {
type Int64SettingOption func(*Int64)
func WithInitPriorityInt64(priority int) Int64SettingOption {
return func(s *Int64) {
s.SetInitPriority(priority)
}
}
func WithValidatorInt64(validator func(int64) error) Int64SettingOption {
return func(s *Int64) {
s.validator = validator
@ -38,13 +46,13 @@ func WithValidatorInt64(validator func(int64) error) Int64SettingOption {
func WithBeforeInitInt64(beforeInit func(Int64Setting, int64) (int64, error)) Int64SettingOption {
return func(s *Int64) {
s.beforeInit = beforeInit
s.SetBeforeInit(beforeInit)
}
}
func WithBeforeSetInt64(beforeSet func(Int64Setting, int64) (int64, error)) Int64SettingOption {
return func(s *Int64) {
s.beforeSet = beforeSet
s.SetBeforeSet(beforeSet)
}
}
@ -64,6 +72,18 @@ func newInt64(name string, value int64, group model.SettingGroup, options ...Int
return i
}
func (i *Int64) SetInitPriority(priority int) {
i.initPriority = priority
}
func (i *Int64) SetBeforeInit(beforeInit func(Int64Setting, int64) (int64, error)) {
i.beforeInit = beforeInit
}
func (i *Int64) SetBeforeSet(beforeSet func(Int64Setting, int64) (int64, error)) {
i.beforeSet = beforeSet
}
func (i *Int64) Parse(value string) (int64, error) {
v, err := strconv.ParseInt(value, 10, 64)
if err != nil {
@ -170,13 +190,37 @@ func (i *Int64) Interface() any {
return i.Get()
}
func NewInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64SettingOption) *Int64 {
func NewInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64SettingOption) Int64Setting {
_, loaded := Settings[k]
if loaded {
panic(fmt.Sprintf("setting %s already exists", k))
}
return CoverInt64Setting(k, v, g, options...)
}
func CoverInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64SettingOption) Int64Setting {
i := newInt64(k, v, g, options...)
Settings[k] = i
GroupSettings[g] = append(GroupSettings[g], i)
if GroupSettings[g] == nil {
GroupSettings[g] = make(map[string]Setting)
}
GroupSettings[g][k] = i
return i
}
func LoadInt64Setting(k string) (Int64Setting, bool) {
s, ok := Settings[k]
if !ok {
return nil, false
}
i, ok := s.(Int64Setting)
return i, ok
}
func LoadOrNewInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64SettingOption) Int64Setting {
s, ok := LoadInt64Setting(k)
if ok {
return s
}
return CoverInt64Setting(k, v, g, options...)
}

View File

@ -9,7 +9,7 @@ import (
var (
Settings = make(map[string]Setting)
GroupSettings = make(map[model.SettingGroup][]Setting)
GroupSettings = make(map[model.SettingGroup]map[string]Setting)
)
type Setting interface {
@ -17,6 +17,8 @@ type Setting interface {
Type() model.SettingType
Group() model.SettingGroup
Init(string) error
SetInitPriority(int)
InitPriority() int
String() string
SetString(string) error
DefaultString() string
@ -33,9 +35,10 @@ func SetValue(name string, value any) error {
}
type setting struct {
name string
settingType model.SettingType
group model.SettingGroup
name string
settingType model.SettingType
group model.SettingGroup
initPriority int
}
func (d *setting) Name() string {
@ -49,3 +52,7 @@ func (d *setting) Type() model.SettingType {
func (d *setting) Group() model.SettingGroup {
return d.group
}
func (d *setting) InitPriority() int {
return d.initPriority
}

View File

@ -15,6 +15,8 @@ type StringSetting interface {
Default() string
Parse(string) (string, error)
Stringify(string) string
SetBeforeInit(func(StringSetting, string) (string, error))
SetBeforeSet(func(StringSetting, string) (string, error))
}
var _ StringSetting = (*String)(nil)
@ -30,6 +32,12 @@ type String struct {
type StringSettingOption func(*String)
func WithInitPriorityString(priority int) StringSettingOption {
return func(s *String) {
s.SetInitPriority(priority)
}
}
func WithValidatorString(validator func(string) error) StringSettingOption {
return func(s *String) {
s.validator = validator
@ -38,13 +46,13 @@ func WithValidatorString(validator func(string) error) StringSettingOption {
func WithBeforeInitString(beforeInit func(StringSetting, string) (string, error)) StringSettingOption {
return func(s *String) {
s.beforeInit = beforeInit
s.SetBeforeInit(beforeInit)
}
}
func WithBeforeSetString(beforeSet func(StringSetting, string) (string, error)) StringSettingOption {
return func(s *String) {
s.beforeSet = beforeSet
s.SetBeforeSet(beforeSet)
}
}
@ -64,6 +72,18 @@ func newString(name string, value string, group model.SettingGroup, options ...S
return s
}
func (s *String) SetInitPriority(priority int) {
s.initPriority = priority
}
func (s *String) SetBeforeInit(beforeInit func(StringSetting, string) (string, error)) {
s.beforeInit = beforeInit
}
func (s *String) SetBeforeSet(beforeSet func(StringSetting, string) (string, error)) {
s.beforeSet = beforeSet
}
func (s *String) Parse(value string) (string, error) {
if s.validator != nil {
return value, s.validator(value)
@ -170,13 +190,37 @@ func (s *String) Interface() any {
return s.Get()
}
func NewStringSetting(k string, v string, g model.SettingGroup, options ...StringSettingOption) *String {
func NewStringSetting(k string, v string, g model.SettingGroup, options ...StringSettingOption) StringSetting {
_, loaded := Settings[k]
if loaded {
panic(fmt.Sprintf("setting %s already exists", k))
}
return CoverStringSetting(k, v, g, options...)
}
func CoverStringSetting(k string, v string, g model.SettingGroup, options ...StringSettingOption) StringSetting {
s := newString(k, v, g, options...)
Settings[k] = s
GroupSettings[g] = append(GroupSettings[g], s)
if GroupSettings[g] == nil {
GroupSettings[g] = make(map[string]Setting)
}
GroupSettings[g][k] = s
return s
}
func LoadStringSetting(k string) (StringSetting, bool) {
s, ok := Settings[k]
if !ok {
return nil, false
}
ss, ok := s.(StringSetting)
return ss, ok
}
func LoadOrNewStringSetting(k string, v string, g model.SettingGroup, options ...StringSettingOption) StringSetting {
s, ok := LoadStringSetting(k)
if ok {
return s
}
return NewStringSetting(k, v, g, options...)
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.2
// protoc v4.25.3
// source: proto/message/message.proto
package pb

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.2
// protoc v4.25.3
// source: proto/provider/plugin.proto
package providerpb
@ -130,77 +130,6 @@ func (x *GetTokenReq) GetCode() string {
return ""
}
type Token struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
TokenType string `protobuf:"bytes,2,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"`
RefreshToken string `protobuf:"bytes,3,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
Expiry int64 `protobuf:"varint,4,opt,name=expiry,proto3" json:"expiry,omitempty"`
}
func (x *Token) Reset() {
*x = Token{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Token) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Token) ProtoMessage() {}
func (x *Token) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Token.ProtoReflect.Descriptor instead.
func (*Token) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{2}
}
func (x *Token) GetAccessToken() string {
if x != nil {
return x.AccessToken
}
return ""
}
func (x *Token) GetTokenType() string {
if x != nil {
return x.TokenType
}
return ""
}
func (x *Token) GetRefreshToken() string {
if x != nil {
return x.RefreshToken
}
return ""
}
func (x *Token) GetExpiry() int64 {
if x != nil {
return x.Expiry
}
return 0
}
type RefreshTokenReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -212,7 +141,7 @@ type RefreshTokenReq struct {
func (x *RefreshTokenReq) Reset() {
*x = RefreshTokenReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[3]
mi := &file_proto_provider_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -225,7 +154,7 @@ func (x *RefreshTokenReq) String() string {
func (*RefreshTokenReq) ProtoMessage() {}
func (x *RefreshTokenReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[3]
mi := &file_proto_provider_plugin_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -238,7 +167,7 @@ func (x *RefreshTokenReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use RefreshTokenReq.ProtoReflect.Descriptor instead.
func (*RefreshTokenReq) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{3}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{2}
}
func (x *RefreshTokenReq) GetRefreshToken() string {
@ -248,53 +177,6 @@ func (x *RefreshTokenReq) GetRefreshToken() string {
return ""
}
type RefreshTokenResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token *Token `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
}
func (x *RefreshTokenResp) Reset() {
*x = RefreshTokenResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RefreshTokenResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RefreshTokenResp) ProtoMessage() {}
func (x *RefreshTokenResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RefreshTokenResp.ProtoReflect.Descriptor instead.
func (*RefreshTokenResp) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{4}
}
func (x *RefreshTokenResp) GetToken() *Token {
if x != nil {
return x.Token
}
return nil
}
type ProviderResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -306,7 +188,7 @@ type ProviderResp struct {
func (x *ProviderResp) Reset() {
*x = ProviderResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[5]
mi := &file_proto_provider_plugin_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -319,7 +201,7 @@ func (x *ProviderResp) String() string {
func (*ProviderResp) ProtoMessage() {}
func (x *ProviderResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[5]
mi := &file_proto_provider_plugin_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -332,7 +214,7 @@ func (x *ProviderResp) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProviderResp.ProtoReflect.Descriptor instead.
func (*ProviderResp) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{5}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{3}
}
func (x *ProviderResp) GetName() string {
@ -353,7 +235,7 @@ type NewAuthURLReq struct {
func (x *NewAuthURLReq) Reset() {
*x = NewAuthURLReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[6]
mi := &file_proto_provider_plugin_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -366,7 +248,7 @@ func (x *NewAuthURLReq) String() string {
func (*NewAuthURLReq) ProtoMessage() {}
func (x *NewAuthURLReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[6]
mi := &file_proto_provider_plugin_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -379,7 +261,7 @@ func (x *NewAuthURLReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use NewAuthURLReq.ProtoReflect.Descriptor instead.
func (*NewAuthURLReq) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{6}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{4}
}
func (x *NewAuthURLReq) GetState() string {
@ -400,7 +282,7 @@ type NewAuthURLResp struct {
func (x *NewAuthURLResp) Reset() {
*x = NewAuthURLResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[7]
mi := &file_proto_provider_plugin_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -413,7 +295,7 @@ func (x *NewAuthURLResp) String() string {
func (*NewAuthURLResp) ProtoMessage() {}
func (x *NewAuthURLResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[7]
mi := &file_proto_provider_plugin_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -426,7 +308,7 @@ func (x *NewAuthURLResp) ProtoReflect() protoreflect.Message {
// Deprecated: Use NewAuthURLResp.ProtoReflect.Descriptor instead.
func (*NewAuthURLResp) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{7}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{5}
}
func (x *NewAuthURLResp) GetUrl() string {
@ -441,13 +323,13 @@ type GetUserInfoReq struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token *Token `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
}
func (x *GetUserInfoReq) Reset() {
*x = GetUserInfoReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[8]
mi := &file_proto_provider_plugin_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -460,7 +342,7 @@ func (x *GetUserInfoReq) String() string {
func (*GetUserInfoReq) ProtoMessage() {}
func (x *GetUserInfoReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[8]
mi := &file_proto_provider_plugin_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -473,14 +355,14 @@ func (x *GetUserInfoReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetUserInfoReq.ProtoReflect.Descriptor instead.
func (*GetUserInfoReq) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{8}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{6}
}
func (x *GetUserInfoReq) GetToken() *Token {
func (x *GetUserInfoReq) GetCode() string {
if x != nil {
return x.Token
return x.Code
}
return nil
return ""
}
type GetUserInfoResp struct {
@ -495,7 +377,7 @@ type GetUserInfoResp struct {
func (x *GetUserInfoResp) Reset() {
*x = GetUserInfoResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[9]
mi := &file_proto_provider_plugin_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -508,7 +390,7 @@ func (x *GetUserInfoResp) String() string {
func (*GetUserInfoResp) ProtoMessage() {}
func (x *GetUserInfoResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[9]
mi := &file_proto_provider_plugin_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -521,7 +403,7 @@ func (x *GetUserInfoResp) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetUserInfoResp.ProtoReflect.Descriptor instead.
func (*GetUserInfoResp) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{9}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{7}
}
func (x *GetUserInfoResp) GetUsername() string {
@ -547,7 +429,7 @@ type Enpty struct {
func (x *Enpty) Reset() {
*x = Enpty{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[10]
mi := &file_proto_provider_plugin_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -560,7 +442,7 @@ func (x *Enpty) String() string {
func (*Enpty) ProtoMessage() {}
func (x *Enpty) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[10]
mi := &file_proto_provider_plugin_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -573,7 +455,7 @@ func (x *Enpty) ProtoReflect() protoreflect.Message {
// Deprecated: Use Enpty.ProtoReflect.Descriptor instead.
func (*Enpty) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{10}
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{8}
}
var File_proto_provider_plugin_proto protoreflect.FileDescriptor
@ -590,62 +472,42 @@ var file_proto_provider_plugin_proto_rawDesc = []byte{
0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63,
0x74, 0x55, 0x72, 0x6c, 0x22, 0x21, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79,
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54,
0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69,
0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79,
0x22, 0x36, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x36, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x05,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x22, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55,
0x52, 0x4c, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x22, 0x0a, 0x0e, 0x4e,
0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a,
0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22,
0x34, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x71, 0x12, 0x22, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x05,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x57, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x07,
0x0a, 0x05, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x32, 0xd7, 0x02, 0x0a, 0x0c, 0x4f, 0x61, 0x75, 0x74,
0x68, 0x32, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74,
0x12, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71,
0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x22, 0x00,
0x12, 0x2f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0c, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22,
0x00, 0x12, 0x3b, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x12,
0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55,
0x52, 0x4c, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65,
0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2e,
0x0a, 0x08, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0c,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x41,
0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22,
0x00, 0x12, 0x3e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22,
0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x70,
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65,
0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65,
0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22,
0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52,
0x4c, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x22, 0x0a, 0x0e, 0x4e, 0x65,
0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03,
0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x24,
0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71,
0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x22, 0x57, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49,
0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f,
0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x07, 0x0a,
0x05, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x32, 0xe4, 0x01, 0x0a, 0x0c, 0x4f, 0x61, 0x75, 0x74, 0x68,
0x32, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12,
0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a,
0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
0x2f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0c, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00,
0x12, 0x3b, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x12, 0x14,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52,
0x4c, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77,
0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a,
0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0e, 0x5a,
0x0c, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -660,40 +522,32 @@ func file_proto_provider_plugin_proto_rawDescGZIP() []byte {
return file_proto_provider_plugin_proto_rawDescData
}
var file_proto_provider_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_proto_provider_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_proto_provider_plugin_proto_goTypes = []interface{}{
(*InitReq)(nil), // 0: proto.InitReq
(*GetTokenReq)(nil), // 1: proto.GetTokenReq
(*Token)(nil), // 2: proto.Token
(*RefreshTokenReq)(nil), // 3: proto.RefreshTokenReq
(*RefreshTokenResp)(nil), // 4: proto.RefreshTokenResp
(*ProviderResp)(nil), // 5: proto.ProviderResp
(*NewAuthURLReq)(nil), // 6: proto.NewAuthURLReq
(*NewAuthURLResp)(nil), // 7: proto.NewAuthURLResp
(*GetUserInfoReq)(nil), // 8: proto.GetUserInfoReq
(*GetUserInfoResp)(nil), // 9: proto.GetUserInfoResp
(*Enpty)(nil), // 10: proto.Enpty
(*InitReq)(nil), // 0: proto.InitReq
(*GetTokenReq)(nil), // 1: proto.GetTokenReq
(*RefreshTokenReq)(nil), // 2: proto.RefreshTokenReq
(*ProviderResp)(nil), // 3: proto.ProviderResp
(*NewAuthURLReq)(nil), // 4: proto.NewAuthURLReq
(*NewAuthURLResp)(nil), // 5: proto.NewAuthURLResp
(*GetUserInfoReq)(nil), // 6: proto.GetUserInfoReq
(*GetUserInfoResp)(nil), // 7: proto.GetUserInfoResp
(*Enpty)(nil), // 8: proto.Enpty
}
var file_proto_provider_plugin_proto_depIdxs = []int32{
2, // 0: proto.RefreshTokenResp.token:type_name -> proto.Token
2, // 1: proto.GetUserInfoReq.token:type_name -> proto.Token
0, // 2: proto.Oauth2Plugin.Init:input_type -> proto.InitReq
10, // 3: proto.Oauth2Plugin.Provider:input_type -> proto.Enpty
6, // 4: proto.Oauth2Plugin.NewAuthURL:input_type -> proto.NewAuthURLReq
1, // 5: proto.Oauth2Plugin.GetToken:input_type -> proto.GetTokenReq
3, // 6: proto.Oauth2Plugin.RefreshToken:input_type -> proto.RefreshTokenReq
8, // 7: proto.Oauth2Plugin.GetUserInfo:input_type -> proto.GetUserInfoReq
10, // 8: proto.Oauth2Plugin.Init:output_type -> proto.Enpty
5, // 9: proto.Oauth2Plugin.Provider:output_type -> proto.ProviderResp
7, // 10: proto.Oauth2Plugin.NewAuthURL:output_type -> proto.NewAuthURLResp
2, // 11: proto.Oauth2Plugin.GetToken:output_type -> proto.Token
4, // 12: proto.Oauth2Plugin.RefreshToken:output_type -> proto.RefreshTokenResp
9, // 13: proto.Oauth2Plugin.GetUserInfo:output_type -> proto.GetUserInfoResp
8, // [8:14] is the sub-list for method output_type
2, // [2:8] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
0, // 0: proto.Oauth2Plugin.Init:input_type -> proto.InitReq
8, // 1: proto.Oauth2Plugin.Provider:input_type -> proto.Enpty
4, // 2: proto.Oauth2Plugin.NewAuthURL:input_type -> proto.NewAuthURLReq
6, // 3: proto.Oauth2Plugin.GetUserInfo:input_type -> proto.GetUserInfoReq
8, // 4: proto.Oauth2Plugin.Init:output_type -> proto.Enpty
3, // 5: proto.Oauth2Plugin.Provider:output_type -> proto.ProviderResp
5, // 6: proto.Oauth2Plugin.NewAuthURL:output_type -> proto.NewAuthURLResp
7, // 7: proto.Oauth2Plugin.GetUserInfo:output_type -> proto.GetUserInfoResp
4, // [4:8] is the sub-list for method output_type
0, // [0:4] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_proto_provider_plugin_proto_init() }
@ -727,18 +581,6 @@ func file_proto_provider_plugin_proto_init() {
}
}
file_proto_provider_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Token); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RefreshTokenReq); i {
case 0:
return &v.state
@ -750,19 +592,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RefreshTokenResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProviderResp); i {
case 0:
return &v.state
@ -774,7 +604,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewAuthURLReq); i {
case 0:
return &v.state
@ -786,7 +616,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewAuthURLResp); i {
case 0:
return &v.state
@ -798,7 +628,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoReq); i {
case 0:
return &v.state
@ -810,7 +640,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoResp); i {
case 0:
return &v.state
@ -822,7 +652,7 @@ func file_proto_provider_plugin_proto_init() {
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
file_proto_provider_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Enpty); i {
case 0:
return &v.state
@ -841,7 +671,7 @@ func file_proto_provider_plugin_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_provider_plugin_proto_rawDesc,
NumEnums: 0,
NumMessages: 11,
NumMessages: 9,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -11,24 +11,15 @@ message InitReq {
message GetTokenReq { string code = 1; }
message Token {
string access_token = 1;
string token_type = 2;
string refresh_token = 3;
int64 expiry = 4;
}
message RefreshTokenReq { string refresh_token = 1; }
message RefreshTokenResp { Token token = 1; }
message ProviderResp { string name = 1; }
message NewAuthURLReq { string state = 1; }
message NewAuthURLResp { string url = 1; }
message GetUserInfoReq { Token token = 1; }
message GetUserInfoReq { string code = 1; }
message GetUserInfoResp {
string username = 1;
@ -41,7 +32,5 @@ service Oauth2Plugin {
rpc Init(InitReq) returns (Enpty) {}
rpc Provider(Enpty) returns (ProviderResp) {}
rpc NewAuthURL(NewAuthURLReq) returns (NewAuthURLResp) {}
rpc GetToken(GetTokenReq) returns (Token) {}
rpc RefreshToken(RefreshTokenReq) returns (RefreshTokenResp) {}
rpc GetUserInfo(GetUserInfoReq) returns (GetUserInfoResp) {}
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.25.2
// - protoc v4.25.3
// source: proto/provider/plugin.proto
package providerpb
@ -19,12 +19,10 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Oauth2Plugin_Init_FullMethodName = "/proto.Oauth2Plugin/Init"
Oauth2Plugin_Provider_FullMethodName = "/proto.Oauth2Plugin/Provider"
Oauth2Plugin_NewAuthURL_FullMethodName = "/proto.Oauth2Plugin/NewAuthURL"
Oauth2Plugin_GetToken_FullMethodName = "/proto.Oauth2Plugin/GetToken"
Oauth2Plugin_RefreshToken_FullMethodName = "/proto.Oauth2Plugin/RefreshToken"
Oauth2Plugin_GetUserInfo_FullMethodName = "/proto.Oauth2Plugin/GetUserInfo"
Oauth2Plugin_Init_FullMethodName = "/proto.Oauth2Plugin/Init"
Oauth2Plugin_Provider_FullMethodName = "/proto.Oauth2Plugin/Provider"
Oauth2Plugin_NewAuthURL_FullMethodName = "/proto.Oauth2Plugin/NewAuthURL"
Oauth2Plugin_GetUserInfo_FullMethodName = "/proto.Oauth2Plugin/GetUserInfo"
)
// Oauth2PluginClient is the client API for Oauth2Plugin service.
@ -34,8 +32,6 @@ type Oauth2PluginClient interface {
Init(ctx context.Context, in *InitReq, opts ...grpc.CallOption) (*Enpty, error)
Provider(ctx context.Context, in *Enpty, opts ...grpc.CallOption) (*ProviderResp, error)
NewAuthURL(ctx context.Context, in *NewAuthURLReq, opts ...grpc.CallOption) (*NewAuthURLResp, error)
GetToken(ctx context.Context, in *GetTokenReq, opts ...grpc.CallOption) (*Token, error)
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
GetUserInfo(ctx context.Context, in *GetUserInfoReq, opts ...grpc.CallOption) (*GetUserInfoResp, error)
}
@ -74,24 +70,6 @@ func (c *oauth2PluginClient) NewAuthURL(ctx context.Context, in *NewAuthURLReq,
return out, nil
}
func (c *oauth2PluginClient) GetToken(ctx context.Context, in *GetTokenReq, opts ...grpc.CallOption) (*Token, error) {
out := new(Token)
err := c.cc.Invoke(ctx, Oauth2Plugin_GetToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *oauth2PluginClient) RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error) {
out := new(RefreshTokenResp)
err := c.cc.Invoke(ctx, Oauth2Plugin_RefreshToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *oauth2PluginClient) GetUserInfo(ctx context.Context, in *GetUserInfoReq, opts ...grpc.CallOption) (*GetUserInfoResp, error) {
out := new(GetUserInfoResp)
err := c.cc.Invoke(ctx, Oauth2Plugin_GetUserInfo_FullMethodName, in, out, opts...)
@ -108,8 +86,6 @@ type Oauth2PluginServer interface {
Init(context.Context, *InitReq) (*Enpty, error)
Provider(context.Context, *Enpty) (*ProviderResp, error)
NewAuthURL(context.Context, *NewAuthURLReq) (*NewAuthURLResp, error)
GetToken(context.Context, *GetTokenReq) (*Token, error)
RefreshToken(context.Context, *RefreshTokenReq) (*RefreshTokenResp, error)
GetUserInfo(context.Context, *GetUserInfoReq) (*GetUserInfoResp, error)
mustEmbedUnimplementedOauth2PluginServer()
}
@ -127,12 +103,6 @@ func (UnimplementedOauth2PluginServer) Provider(context.Context, *Enpty) (*Provi
func (UnimplementedOauth2PluginServer) NewAuthURL(context.Context, *NewAuthURLReq) (*NewAuthURLResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewAuthURL not implemented")
}
func (UnimplementedOauth2PluginServer) GetToken(context.Context, *GetTokenReq) (*Token, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetToken not implemented")
}
func (UnimplementedOauth2PluginServer) RefreshToken(context.Context, *RefreshTokenReq) (*RefreshTokenResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method RefreshToken not implemented")
}
func (UnimplementedOauth2PluginServer) GetUserInfo(context.Context, *GetUserInfoReq) (*GetUserInfoResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserInfo not implemented")
}
@ -203,42 +173,6 @@ func _Oauth2Plugin_NewAuthURL_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Oauth2Plugin_GetToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetTokenReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(Oauth2PluginServer).GetToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Oauth2Plugin_GetToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(Oauth2PluginServer).GetToken(ctx, req.(*GetTokenReq))
}
return interceptor(ctx, in, info, handler)
}
func _Oauth2Plugin_RefreshToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RefreshTokenReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(Oauth2PluginServer).RefreshToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Oauth2Plugin_RefreshToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(Oauth2PluginServer).RefreshToken(ctx, req.(*RefreshTokenReq))
}
return interceptor(ctx, in, info, handler)
}
func _Oauth2Plugin_GetUserInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserInfoReq)
if err := dec(in); err != nil {
@ -276,14 +210,6 @@ var Oauth2Plugin_ServiceDesc = grpc.ServiceDesc{
MethodName: "NewAuthURL",
Handler: _Oauth2Plugin_NewAuthURL_Handler,
},
{
MethodName: "GetToken",
Handler: _Oauth2Plugin_GetToken_Handler,
},
{
MethodName: "RefreshToken",
Handler: _Oauth2Plugin_RefreshToken_Handler,
},
{
MethodName: "GetUserInfo",
Handler: _Oauth2Plugin_GetUserInfo_Handler,

View File

@ -4,14 +4,13 @@ import (
"context"
"fmt"
"net/http"
"reflect"
"slices"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/maruel/natural"
"github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/internal/bootstrap"
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
@ -54,21 +53,20 @@ func AdminSettings(ctx *gin.Context) {
group := ctx.Param("group")
switch group {
case "oauth2":
resp := make(model.AdminSettingsResp, len(bootstrap.ProviderGroupSettings))
for k, v := range bootstrap.ProviderGroupSettings {
reflectV := reflect.ValueOf(*v)
for i := 0; i < reflectV.NumField(); i++ {
f := reflectV.Field(i)
if resp[k] == nil {
resp[k] = make(gin.H, 0)
}
s, ok := f.Interface().(settings.Setting)
if !ok {
log.Error("type error")
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorStringResp("type error"))
return
}
resp[k][s.Name()] = s.Interface()
const groupPrefix = dbModel.SettingGroupOauth2
settingGroups := make(map[string]map[string]settings.Setting)
for sg, v := range settings.GroupSettings {
if strings.HasPrefix(sg, groupPrefix) {
settingGroups[sg] = v
}
}
resp := make(model.AdminSettingsResp, len(settingGroups))
for k, v := range settingGroups {
if resp[k] == nil {
resp[k] = make(gin.H, len(v))
}
for k2, s := range v {
resp[k][k2] = s.Interface()
}
}

View File

@ -11,57 +11,53 @@ import (
)
func Init(e *gin.Engine) {
api := e.Group("/api")
needAuthUserApi := api.Group("", middlewares.AuthUserMiddleware)
needAuthRoomApi := api.Group("", middlewares.AuthRoomMiddleware)
{
api := e.Group("/api")
public := api.Group("/public")
needAuthUserApi := api.Group("")
needAuthUserApi.Use(middlewares.AuthUserMiddleware)
public.GET("/settings", Settings)
}
needAuthRoomApi := api.Group("")
needAuthRoomApi.Use(middlewares.AuthRoomMiddleware)
{
admin := api.Group("/admin")
root := api.Group("/admin")
admin.Use(middlewares.AuthAdminMiddleware)
root.Use(middlewares.AuthRootMiddleware)
{
public := api.Group("/public")
initAdmin(admin, root)
}
public.GET("/settings", Settings)
}
{
room := api.Group("/room")
needAuthRoom := needAuthRoomApi.Group("/room")
needAuthUser := needAuthUserApi.Group("/room")
{
admin := api.Group("/admin")
root := api.Group("/admin")
admin.Use(middlewares.AuthAdminMiddleware)
root.Use(middlewares.AuthRootMiddleware)
initRoom(room, needAuthUser, needAuthRoom)
}
initAdmin(admin, root)
}
{
movie := api.Group("/movie")
needAuthMovie := needAuthRoomApi.Group("/movie")
{
room := api.Group("/room")
needAuthRoom := needAuthRoomApi.Group("/room")
needAuthUser := needAuthUserApi.Group("/room")
initMovie(movie, needAuthMovie)
}
initRoom(room, needAuthUser, needAuthRoom)
}
{
user := api.Group("/user")
needAuthUser := needAuthUserApi.Group("/user")
{
movie := api.Group("/movie")
needAuthMovie := needAuthRoomApi.Group("/movie")
initUser(user, needAuthUser)
}
initMovie(movie, needAuthMovie)
}
{
vendor := needAuthUserApi.Group("/vendor")
{
user := api.Group("/user")
needAuthUser := needAuthUserApi.Group("/user")
initUser(user, needAuthUser)
}
{
vendor := needAuthUserApi.Group("/vendor")
initVendor(vendor)
}
initVendor(vendor)
}
}

View File

@ -221,7 +221,7 @@ func UserBindProviders(ctx *gin.Context) {
}
}
m.Range(func(p provider.OAuth2Provider, pi provider.ProviderInterface) bool {
m.Range(func(p provider.OAuth2Provider, pi struct{}) bool {
if _, ok := resp[p]; !ok {
resp[p] = struct {
ProviderUserID string "json:\"providerUserID\""

View File

@ -32,9 +32,15 @@ func OAuth2(ctx *gin.Context) {
}
state := utils.RandString(16)
url, err := pi.NewAuthURL(ctx, state)
if err != nil {
log.Errorf("failed to get auth url: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
states.Store(state, newAuthFunc(ctx.Query("redirect")), time.Minute*5)
err = RenderRedirect(ctx, pi.NewAuthURL(state))
err = RenderRedirect(ctx, url)
if err != nil {
log.Errorf("failed to render redirect: %v", err)
}
@ -44,7 +50,7 @@ func OAuth2(ctx *gin.Context) {
func OAuth2Api(ctx *gin.Context) {
log := ctx.MustGet("log").(*logrus.Entry)
pi, err := providers.GetProvider(provider.OAuth2Provider(ctx.Param("type")))
pi, err := providers.GetProvider(ctx.Param("type"))
if err != nil {
log.Errorf("failed to get provider: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
@ -58,10 +64,15 @@ func OAuth2Api(ctx *gin.Context) {
}
state := utils.RandString(16)
url, err := pi.NewAuthURL(ctx, state)
if err != nil {
log.Errorf("failed to get auth url: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
states.Store(state, newAuthFunc(meta.Redirect), time.Minute*5)
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"url": pi.NewAuthURL(state),
"url": url,
}))
}
@ -136,14 +147,7 @@ func newAuthFunc(redirect string) stateHandler {
return func(ctx *gin.Context, pi provider.ProviderInterface, code string) {
log := ctx.MustGet("log").(*logrus.Entry)
t, err := pi.GetToken(ctx, code)
if err != nil {
log.Errorf("failed to get token: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
ui, err := pi.GetUserInfo(ctx, t)
ui, err := pi.GetUserInfo(ctx, code)
if err != nil {
log.Errorf("failed to get user info: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))

View File

@ -33,10 +33,15 @@ func BindApi(ctx *gin.Context) {
}
state := utils.RandString(16)
url, err := pi.NewAuthURL(ctx, state)
if err != nil {
log.Errorf("failed to get auth url: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
states.Store(state, newBindFunc(user.ID, meta.Redirect), time.Minute*5)
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"url": pi.NewAuthURL(state),
"url": url,
}))
}
@ -65,14 +70,7 @@ func newBindFunc(userID, redirect string) stateHandler {
return func(ctx *gin.Context, pi provider.ProviderInterface, code string) {
log := ctx.MustGet("log").(*logrus.Entry)
t, err := pi.GetToken(ctx, code)
if err != nil {
log.Errorf("failed to get token: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
ui, err := pi.GetUserInfo(ctx, t)
ui, err := pi.GetUserInfo(ctx, code)
if err != nil {
log.Errorf("failed to get user info: %v", err)
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))