diff --git a/internal/bootstrap/provider.go b/internal/bootstrap/provider.go index a166354..4607d16 100644 --- a/internal/bootstrap/provider.go +++ b/internal/bootstrap/provider.go @@ -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) + } + + 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(ctx) + 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(op) + return b, providers.EnableProvider(pi.Provider()) } else { - providers.DisableProvider(op) + providers.DisableProvider(pi.Provider()) return b, nil } - }), settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) { - defer Oauth2EnabledCache.Refresh(ctx) + }), + settings.WithInitPriorityBool(1), + settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) (bool, error) { + defer Oauth2EnabledCache.Refresh(context.Background()) if b { - return b, providers.EnableProvider(op) + return b, providers.EnableProvider(pi.Provider()) } else { - providers.DisableProvider(op) + providers.DisableProvider(pi.Provider()) return b, nil } - })) + }), + ) - opt := provider.Oauth2Option{} + 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) { + 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) { + }), + 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) { + 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) { + }), + 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) { + 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) { + }), + 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.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.SignupNeedReview = settings.NewBoolSetting(fmt.Sprintf("%s_signup_need_review", group), false, group) + 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 + }, + ), + ) } - return 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 + }), + ) } diff --git a/internal/bootstrap/setting.go b/internal/bootstrap/setting.go index 4da9a53..9f6957b 100644 --- a/internal/bootstrap/setting.go +++ b/internal/bootstrap/setting.go @@ -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 } diff --git a/internal/model/setting.go b/internal/model/setting.go index cb75ed3..5970f7d 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -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" diff --git a/internal/provider/aggregation.go b/internal/provider/aggregation.go new file mode 100644 index 0000000..b6f5889 --- /dev/null +++ b/internal/provider/aggregation.go @@ -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 +} diff --git a/internal/provider/aggregations/aggregations.go b/internal/provider/aggregations/aggregations.go new file mode 100644 index 0000000..e32f86d --- /dev/null +++ b/internal/provider/aggregations/aggregations.go @@ -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 +} diff --git a/internal/provider/aggregations/rainbow.go b/internal/provider/aggregations/rainbow.go new file mode 100644 index 0000000..8630f87 --- /dev/null +++ b/internal/provider/aggregations/rainbow.go @@ -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)) +} diff --git a/internal/provider/plugins/client.go b/internal/provider/plugins/client.go index a765623..803420c 100644 --- a/internal/provider/plugins/client.go +++ b/internal/provider/plugins/client.go @@ -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 resp.Url -} - -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 "", err } - return &oauth2.Token{ - AccessToken: resp.Token.AccessToken, - TokenType: resp.Token.TokenType, - RefreshToken: resp.Token.RefreshToken, - Expiry: time.Unix(resp.Token.Expiry, 0), - }, nil + return resp.Url, 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 diff --git a/internal/provider/plugins/example/example_authing/example_authing.go b/internal/provider/plugins/example/example_authing/example_authing.go index cfbf886..c7fb397 100644 --- a/internal/provider/plugins/example/example_authing/example_authing.go +++ b/internal/provider/plugins/example/example_authing/example_authing.go @@ -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) 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) NewAuthURL(ctx context.Context, state string) (string, error) { + return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil } -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 { diff --git a/internal/provider/plugins/example/example_feishu-sso/example_feishu-sso.go b/internal/provider/plugins/example/example_feishu-sso/example_feishu-sso.go index 5825b5a..f6e8fc6 100644 --- a/internal/provider/plugins/example/example_feishu-sso/example_feishu-sso.go +++ b/internal/provider/plugins/example/example_feishu-sso/example_feishu-sso.go @@ -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 { diff --git a/internal/provider/plugins/example/example_gitee/example_gitee.go b/internal/provider/plugins/example/example_gitee/example_gitee.go index 32a1f57..f5e2520 100644 --- a/internal/provider/plugins/example/example_gitee/example_gitee.go +++ b/internal/provider/plugins/example/example_gitee/example_gitee.go @@ -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 { diff --git a/internal/provider/plugins/server.go b/internal/provider/plugins/server.go index 06c5578..b81cc9e 100644 --- a/internal/provider/plugins/server.go +++ b/internal/provider/plugins/server.go @@ -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 } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 19119f1..67be8af 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -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) } diff --git a/internal/provider/providers/baidu-netdisk.go b/internal/provider/providers/baidu-netdisk.go index b3bd058..56cc23d 100644 --- a/internal/provider/providers/baidu-netdisk.go +++ b/internal/provider/providers/baidu-netdisk.go @@ -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 { diff --git a/internal/provider/providers/baidu.go b/internal/provider/providers/baidu.go index b35df39..aeb4997 100644 --- a/internal/provider/providers/baidu.go +++ b/internal/provider/providers/baidu.go @@ -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 { diff --git a/internal/provider/providers/gitee.go b/internal/provider/providers/gitee.go index 8674b29..1ef8410 100644 --- a/internal/provider/providers/gitee.go +++ b/internal/provider/providers/gitee.go @@ -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 { diff --git a/internal/provider/providers/github.go b/internal/provider/providers/github.go index e6474c2..14e2bbe 100644 --- a/internal/provider/providers/github.go +++ b/internal/provider/providers/github.go @@ -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 { diff --git a/internal/provider/providers/gitlab.go b/internal/provider/providers/gitlab.go index 3542e67..23ea721 100644 --- a/internal/provider/providers/gitlab.go +++ b/internal/provider/providers/gitlab.go @@ -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 { diff --git a/internal/provider/providers/google.go b/internal/provider/providers/google.go index 0007e0f..832c5d8 100644 --- a/internal/provider/providers/google.go +++ b/internal/provider/providers/google.go @@ -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 { diff --git a/internal/provider/providers/microsoft.go b/internal/provider/providers/microsoft.go index cc29960..735bf12 100644 --- a/internal/provider/providers/microsoft.go +++ b/internal/provider/providers/microsoft.go @@ -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 { diff --git a/internal/provider/providers/providers.go b/internal/provider/providers/providers.go index 8c5071f..0fab6ac 100644 --- a/internal/provider/providers/providers.go +++ b/internal/provider/providers/providers.go @@ -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 diff --git a/internal/provider/providers/qq.go b/internal/provider/providers/qq.go index 040b44c..5a85c40 100644 --- a/internal/provider/providers/qq.go +++ b/internal/provider/providers/qq.go @@ -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 diff --git a/internal/provider/providers/xiaomi.go b/internal/provider/providers/xiaomi.go index 755f498..a7d2c6b 100644 --- a/internal/provider/providers/xiaomi.go +++ b/internal/provider/providers/xiaomi.go @@ -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 { diff --git a/internal/settings/bool.go b/internal/settings/bool.go index 4c04101..1c91947 100644 --- a/internal/settings/bool.go +++ b/internal/settings/bool.go @@ -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...) +} diff --git a/internal/settings/floate64.go b/internal/settings/floate64.go index c70d222..b1349ce 100644 --- a/internal/settings/floate64.go +++ b/internal/settings/floate64.go @@ -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...) +} diff --git a/internal/settings/int64.go b/internal/settings/int64.go index d00ad7b..842d442 100644 --- a/internal/settings/int64.go +++ b/internal/settings/int64.go @@ -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...) +} diff --git a/internal/settings/setting.go b/internal/settings/setting.go index 0a8ec0f..2c82ae8 100644 --- a/internal/settings/setting.go +++ b/internal/settings/setting.go @@ -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 +} diff --git a/internal/settings/string.go b/internal/settings/string.go index 0475b88..d5b02b8 100644 --- a/internal/settings/string.go +++ b/internal/settings/string.go @@ -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...) +} diff --git a/proto/message/message.pb.go b/proto/message/message.pb.go index 2c928ce..81d6cab 100644 --- a/proto/message/message.pb.go +++ b/proto/message/message.pb.go @@ -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 diff --git a/proto/provider/plugin.pb.go b/proto/provider/plugin.pb.go index a3b0964..91ab131 100644 --- a/proto/provider/plugin.pb.go +++ b/proto/provider/plugin.pb.go @@ -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, }, diff --git a/proto/provider/plugin.proto b/proto/provider/plugin.proto index 4d69116..b97270b 100644 --- a/proto/provider/plugin.proto +++ b/proto/provider/plugin.proto @@ -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) {} } \ No newline at end of file diff --git a/proto/provider/plugin_grpc.pb.go b/proto/provider/plugin_grpc.pb.go index 58fc47f..23c7327 100644 --- a/proto/provider/plugin_grpc.pb.go +++ b/proto/provider/plugin_grpc.pb.go @@ -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, diff --git a/server/handlers/admin.go b/server/handlers/admin.go index f205983..43eb656 100644 --- a/server/handlers/admin.go +++ b/server/handlers/admin.go @@ -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() } } diff --git a/server/handlers/init.go b/server/handlers/init.go index 4818f2b..9b65172 100644 --- a/server/handlers/init.go +++ b/server/handlers/init.go @@ -11,57 +11,53 @@ import ( ) func Init(e *gin.Engine) { - { - api := e.Group("/api") + api := e.Group("/api") - needAuthUserApi := api.Group("") - needAuthUserApi.Use(middlewares.AuthUserMiddleware) + needAuthUserApi := api.Group("", middlewares.AuthUserMiddleware) - needAuthRoomApi := api.Group("") - needAuthRoomApi.Use(middlewares.AuthRoomMiddleware) + needAuthRoomApi := api.Group("", middlewares.AuthRoomMiddleware) - { - public := api.Group("/public") + { + public := api.Group("/public") - public.GET("/settings", Settings) - } + public.GET("/settings", Settings) + } - { - admin := api.Group("/admin") - root := api.Group("/admin") - admin.Use(middlewares.AuthAdminMiddleware) - root.Use(middlewares.AuthRootMiddleware) + { + admin := api.Group("/admin") + root := api.Group("/admin") + admin.Use(middlewares.AuthAdminMiddleware) + root.Use(middlewares.AuthRootMiddleware) - initAdmin(admin, root) - } + initAdmin(admin, root) + } - { - room := api.Group("/room") - needAuthRoom := needAuthRoomApi.Group("/room") - needAuthUser := needAuthUserApi.Group("/room") + { + room := api.Group("/room") + needAuthRoom := needAuthRoomApi.Group("/room") + needAuthUser := needAuthUserApi.Group("/room") - initRoom(room, needAuthUser, needAuthRoom) - } + initRoom(room, needAuthUser, needAuthRoom) + } - { - movie := api.Group("/movie") - needAuthMovie := needAuthRoomApi.Group("/movie") + { + movie := api.Group("/movie") + needAuthMovie := needAuthRoomApi.Group("/movie") - initMovie(movie, needAuthMovie) - } + initMovie(movie, needAuthMovie) + } - { - user := api.Group("/user") - needAuthUser := needAuthUserApi.Group("/user") + { + user := api.Group("/user") + needAuthUser := needAuthUserApi.Group("/user") - initUser(user, needAuthUser) - } + initUser(user, needAuthUser) + } - { - vendor := needAuthUserApi.Group("/vendor") + { + vendor := needAuthUserApi.Group("/vendor") - initVendor(vendor) - } + initVendor(vendor) } } diff --git a/server/handlers/user.go b/server/handlers/user.go index 20574dc..6197080 100644 --- a/server/handlers/user.go +++ b/server/handlers/user.go @@ -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\"" diff --git a/server/oauth2/auth.go b/server/oauth2/auth.go index e8c411c..d62191f 100644 --- a/server/oauth2/auth.go +++ b/server/oauth2/auth.go @@ -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)) diff --git a/server/oauth2/bind.go b/server/oauth2/bind.go index c2b43db..d64d440 100644 --- a/server/oauth2/bind.go +++ b/server/oauth2/bind.go @@ -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))