Feat: oauth2 settings

pull/39/head
zijiren233 2 years ago
parent f0136b0134
commit e3c92fb7b4

@ -29,11 +29,11 @@ var ServerCmd = &cobra.Command{
bootstrap.InitLog, bootstrap.InitLog,
bootstrap.InitGinMode, bootstrap.InitGinMode,
bootstrap.InitDatabase, bootstrap.InitDatabase,
bootstrap.InitSetting,
bootstrap.InitProvider, bootstrap.InitProvider,
bootstrap.InitOp, bootstrap.InitOp,
bootstrap.InitRtmp, bootstrap.InitRtmp,
bootstrap.InitVendor, bootstrap.InitVendor,
bootstrap.InitSetting,
) )
if !flags.DisableUpdateCheck { if !flags.DisableUpdateCheck {
boot.Add(bootstrap.InitCheckUpdate) boot.Add(bootstrap.InitCheckUpdate)

@ -2,6 +2,7 @@ package bootstrap
import ( import (
"context" "context"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -9,20 +10,24 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/cmd/flags" "github.com/synctv-org/synctv/cmd/flags"
"github.com/synctv-org/synctv/internal/conf" "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"
"github.com/synctv-org/synctv/internal/provider/plugins" "github.com/synctv-org/synctv/internal/provider/plugins"
"github.com/synctv-org/synctv/internal/provider/providers" "github.com/synctv-org/synctv/internal/provider/providers"
"github.com/synctv-org/synctv/internal/settings"
serverAuth "github.com/synctv-org/synctv/server/oauth2"
"github.com/synctv-org/synctv/utils" "github.com/synctv-org/synctv/utils"
"golang.org/x/oauth2"
) )
var ProviderGroupSettings = make(map[model.SettingGroup][]settings.Setting)
func InitProvider(ctx context.Context) (err error) { func InitProvider(ctx context.Context) (err error) {
logOur := log.StandardLogger().Writer() logOur := log.StandardLogger().Writer()
logLevle := hclog.Info logLevle := hclog.Info
if flags.Dev { if flags.Dev {
logLevle = hclog.Debug logLevle = hclog.Debug
} }
for _, op := range conf.Conf.OAuth2.Plugins { for _, op := range conf.Conf.OAuth2 {
op.PluginFile, err = utils.OptFilePath(op.PluginFile) op.PluginFile, err = utils.OptFilePath(op.PluginFile)
if err != nil { if err != nil {
log.Fatalf("oauth2 plugin file path error: %v", err) log.Fatalf("oauth2 plugin file path error: %v", err)
@ -34,7 +39,7 @@ func InitProvider(ctx context.Context) (err error) {
log.Fatalf("create plugin dir: %s failed: %s", filepath.Dir(op.PluginFile), err) log.Fatalf("create plugin dir: %s failed: %s", filepath.Dir(op.PluginFile), err)
return err return err
} }
err = plugins.InitProviderPlugins(op.PluginFile, op.Arges, hclog.New(&hclog.LoggerOptions{ err = plugins.InitProviderPlugins(op.PluginFile, op.Args, hclog.New(&hclog.LoggerOptions{
Name: op.PluginFile, Name: op.PluginFile,
Level: logLevle, Level: logLevle,
Output: logOur, Output: logOur,
@ -45,23 +50,64 @@ func InitProvider(ctx context.Context) (err error) {
return err return err
} }
} }
for op, v := range conf.Conf.OAuth2.Providers {
opt := provider.Oauth2Option{ for op, pi := range providers.AllProvider() {
ClientID: v.ClientID, op, pi := op, pi
ClientSecret: v.ClientSecret, group := model.SettingGroup(fmt.Sprintf("%s_%s", model.SettingGroupOauth2, op))
RedirectURL: v.RedirectURL,
} e := settings.NewBoolSetting(fmt.Sprintf("%s_enabled", group), false, group, settings.WithBeforeInitBool(func(bs settings.BoolSetting, b bool) error {
if v.Endpoint != nil { defer serverAuth.Oauth2EnabledCache.Refresh()
opt.Endpoint = &oauth2.Endpoint{ if b {
AuthURL: v.Endpoint.AuthURL, return providers.EnableProvider(op)
DeviceAuthURL: v.Endpoint.DeviceAuthURL, } else {
TokenURL: v.Endpoint.TokenURL, providers.DisableProvider(op)
} return nil
} }
err := providers.InitProvider(op, opt) }), settings.WithBeforeSetBool(func(bs settings.BoolSetting, b bool) error {
if err != nil { defer serverAuth.Oauth2EnabledCache.Refresh()
return err if b {
return providers.EnableProvider(op)
} else {
providers.DisableProvider(op)
return nil
} }
}))
ProviderGroupSettings[group] = []settings.Setting{e}
opt := provider.Oauth2Option{}
cid := settings.NewStringSetting(fmt.Sprintf("%s_client_id", group), opt.ClientID, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) error {
opt.ClientID = s
pi.Init(opt)
return nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) error {
opt.ClientID = s
pi.Init(opt)
return nil
}))
ProviderGroupSettings[group] = append(ProviderGroupSettings[group], cid)
cs := settings.NewStringSetting(fmt.Sprintf("%s_client_secret", group), opt.ClientSecret, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) error {
opt.ClientSecret = s
pi.Init(opt)
return nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) error {
opt.ClientSecret = s
pi.Init(opt)
return nil
}))
ProviderGroupSettings[group] = append(ProviderGroupSettings[group], cs)
ru := settings.NewStringSetting(fmt.Sprintf("%s_redirect_url", group), opt.RedirectURL, group, settings.WithBeforeInitString(func(ss settings.StringSetting, s string) error {
opt.RedirectURL = s
pi.Init(opt)
return nil
}), settings.WithBeforeSetString(func(ss settings.StringSetting, s string) error {
opt.RedirectURL = s
pi.Init(opt)
return nil
}))
ProviderGroupSettings[group] = append(ProviderGroupSettings[group], ru)
} }
return nil return nil
} }

@ -1,35 +1,12 @@
package conf package conf
import ( type OAuth2Config []Oauth2Plugin
"github.com/synctv-org/synctv/internal/provider"
)
type OAuth2Config struct {
Providers map[provider.OAuth2Provider]OAuth2ProviderConfig `yaml:"providers"`
Plugins []Oauth2Plugin `yaml:"plugins"`
}
type Oauth2Plugin struct { type Oauth2Plugin struct {
PluginFile string `yaml:"plugin_file"` PluginFile string `yaml:"plugin_file"`
Arges []string `yaml:"arges"` Args []string `yaml:"args"`
}
type Endpoint struct {
AuthURL string `yaml:"auth_url"`
DeviceAuthURL string `yaml:"device_auth_url"`
TokenURL string `yaml:"token_url"`
}
type OAuth2ProviderConfig struct {
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
RedirectURL string `yaml:"redirect_url"`
Endpoint *Endpoint `yaml:"endpoint,omitempty"`
} }
func DefaultOAuth2Config() OAuth2Config { func DefaultOAuth2Config() OAuth2Config {
return OAuth2Config{ return nil
Providers: map[provider.OAuth2Provider]OAuth2ProviderConfig{},
Plugins: []Oauth2Plugin{},
}
} }

@ -21,6 +21,7 @@ const (
SettingGroupProxy SettingGroup = "proxy" SettingGroupProxy SettingGroup = "proxy"
SettingGroupRtmp SettingGroup = "rtmp" SettingGroupRtmp SettingGroup = "rtmp"
SettingGroupDatabase SettingGroup = "database" SettingGroupDatabase SettingGroup = "database"
SettingGroupOauth2 SettingGroup = "oauth2"
) )
type Setting struct { type Setting struct {

@ -19,13 +19,6 @@ func (c *GRPCClient) Init(o provider.Oauth2Option) {
ClientSecret: o.ClientSecret, ClientSecret: o.ClientSecret,
RedirectUrl: o.RedirectURL, RedirectUrl: o.RedirectURL,
} }
if o.Endpoint != nil {
opt.Endpoint = &providerpb.InitReq_Endpoint{
AuthUrl: o.Endpoint.AuthURL,
DeviceAuthUrl: o.Endpoint.DeviceAuthURL,
TokenUrl: o.Endpoint.TokenURL,
}
}
c.client.Init(context.Background(), &opt) c.client.Init(context.Background(), &opt)
} }

@ -4,12 +4,13 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http"
"os"
plugin "github.com/hashicorp/go-plugin" plugin "github.com/hashicorp/go-plugin"
"github.com/synctv-org/synctv/internal/provider" "github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/plugins" "github.com/synctv-org/synctv/internal/provider/plugins"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"net/http"
"os"
) )
// Mac/Linux: // Mac/Linux:
@ -39,12 +40,20 @@ type FeishuProvider struct {
ssoid string // Your SSO Application ID in Feishu Anycross ssoid string // Your SSO Application ID in Feishu Anycross
} }
func (p *FeishuProvider) Init(c provider.Oauth2Option) { func newFeishuProvider(ssoid string) provider.ProviderInterface {
p.config.Scopes = []string{"profile"} return &FeishuProvider{
p.config.Endpoint = oauth2.Endpoint{ config: oauth2.Config{
AuthURL: fmt.Sprintf("https://anycross.feishu.cn/sso/%s/oauth2/auth", p.ssoid), // 认证端点 Scopes: []string{"profile"},
TokenURL: fmt.Sprintf("https://anycross.feishu.cn/sso/%s/oauth2/token", p.ssoid), //Token 端点 Endpoint: oauth2.Endpoint{
AuthURL: fmt.Sprintf("https://anycross.feishu.cn/sso/%s/oauth2/auth", ssoid), // 认证端点
TokenURL: fmt.Sprintf("https://anycross.feishu.cn/sso/%s/oauth2/token", ssoid), //Token 端点
},
},
ssoid: ssoid,
}
} }
func (p *FeishuProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -96,7 +105,7 @@ type feishuUserInfo struct {
func main() { func main() {
args := os.Args args := os.Args
var pluginMap = map[string]plugin.Plugin{ var pluginMap = map[string]plugin.Plugin{
"Provider": &plugins.ProviderPlugin{Impl: &FeishuProvider{ssoid: args[1]}}, "Provider": &plugins.ProviderPlugin{Impl: newFeishuProvider(args[1])},
} }
plugin.Serve(&plugin.ServeConfig{ plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: plugins.HandshakeConfig, HandshakeConfig: plugins.HandshakeConfig,

@ -31,16 +31,19 @@ type GiteeProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *GiteeProvider) Init(c provider.Oauth2Option) { func newGiteeProvider() provider.ProviderInterface {
p.config.Scopes = []string{"user_info"} return &GiteeProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"user_info"},
} else { Endpoint: oauth2.Endpoint{
p.config.Endpoint = oauth2.Endpoint{
AuthURL: "https://gitee.com/oauth/authorize", AuthURL: "https://gitee.com/oauth/authorize",
TokenURL: "https://gitee.com/oauth/token", TokenURL: "https://gitee.com/oauth/token",
},
},
} }
} }
func (p *GiteeProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -91,7 +94,7 @@ type giteeUserInfo struct {
func main() { func main() {
var pluginMap = map[string]plugin.Plugin{ var pluginMap = map[string]plugin.Plugin{
"Provider": &plugins.ProviderPlugin{Impl: &GiteeProvider{}}, "Provider": &plugins.ProviderPlugin{Impl: newGiteeProvider()},
} }
plugin.Serve(&plugin.ServeConfig{ plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: plugins.HandshakeConfig, HandshakeConfig: plugins.HandshakeConfig,

@ -20,13 +20,6 @@ func (s *GRPCServer) Init(ctx context.Context, req *providerpb.InitReq) (*provid
ClientSecret: req.ClientSecret, ClientSecret: req.ClientSecret,
RedirectURL: req.RedirectUrl, RedirectURL: req.RedirectUrl,
} }
if req.Endpoint != nil {
opt.Endpoint = &oauth2.Endpoint{
AuthURL: req.Endpoint.AuthUrl,
DeviceAuthURL: req.Endpoint.DeviceAuthUrl,
TokenURL: req.Endpoint.TokenUrl,
}
}
s.Impl.Init(opt) s.Impl.Init(opt)
return &providerpb.Enpty{}, nil return &providerpb.Enpty{}, nil
} }

@ -17,7 +17,6 @@ type Oauth2Option struct {
ClientID string ClientID string
ClientSecret string ClientSecret string
RedirectURL string RedirectURL string
Endpoint *oauth2.Endpoint
} }
type ProviderInterface interface { type ProviderInterface interface {

@ -16,16 +16,19 @@ type BaiduNetDiskProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *BaiduNetDiskProvider) Init(c provider.Oauth2Option) { func newBaiduNetDiskProvider() provider.ProviderInterface {
p.config.Scopes = []string{"basic", "netdisk"} return &BaiduNetDiskProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"basic", "netdisk"},
} else { Endpoint: oauth2.Endpoint{
p.config.Endpoint = oauth2.Endpoint{
AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize", AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize",
TokenURL: "https://openapi.baidu.com/oauth/2.0/token", TokenURL: "https://openapi.baidu.com/oauth/2.0/token",
},
},
} }
} }
func (p *BaiduNetDiskProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -80,5 +83,5 @@ type baiduNetDiskProviderUserInfo struct {
} }
func init() { func init() {
RegisterProvider(new(BaiduNetDiskProvider)) RegisterProvider(newBaiduNetDiskProvider())
} }

@ -15,16 +15,19 @@ type BaiduProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *BaiduProvider) Init(c provider.Oauth2Option) { func newBaiduProvider() provider.ProviderInterface {
p.config.Scopes = []string{"basic"} return &BaiduProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"basic"},
} else { Endpoint: oauth2.Endpoint{
p.config.Endpoint = oauth2.Endpoint{
AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize", AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize",
TokenURL: "https://openapi.baidu.com/oauth/2.0/token", TokenURL: "https://openapi.baidu.com/oauth/2.0/token",
},
},
} }
} }
func (p *BaiduProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -68,11 +71,11 @@ func (p *BaiduProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*pro
}, nil }, nil
} }
func init() {
RegisterProvider(new(BaiduProvider))
}
type baiduProviderUserInfo struct { type baiduProviderUserInfo struct {
Uname string `json:"uname"` Uname string `json:"uname"`
Openid string `json:"openid"` Openid string `json:"openid"`
} }
func init() {
RegisterProvider(newBaiduProvider())
}

@ -14,16 +14,19 @@ type GiteeProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *GiteeProvider) Init(c provider.Oauth2Option) { func newGiteeProvider() provider.ProviderInterface {
p.config.Scopes = []string{"user_info"} return &GiteeProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"user_info"},
} else { Endpoint: oauth2.Endpoint{
p.config.Endpoint = oauth2.Endpoint{
AuthURL: "https://gitee.com/oauth/authorize", AuthURL: "https://gitee.com/oauth/authorize",
TokenURL: "https://gitee.com/oauth/token", TokenURL: "https://gitee.com/oauth/token",
},
},
} }
} }
func (p *GiteeProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -73,5 +76,5 @@ type giteeUserInfo struct {
} }
func init() { func init() {
RegisterProvider(new(GiteeProvider)) RegisterProvider(newGiteeProvider())
} }

@ -15,13 +15,16 @@ type GithubProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *GithubProvider) Init(c provider.Oauth2Option) { func newGithubProvider() provider.ProviderInterface {
p.config.Scopes = []string{"user"} return &GithubProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"user"},
} else { Endpoint: github.Endpoint,
p.config.Endpoint = github.Endpoint },
}
} }
func (p *GithubProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -71,5 +74,5 @@ type githubUserInfo struct {
} }
func init() { func init() {
RegisterProvider(new(GithubProvider)) RegisterProvider(newGithubProvider())
} }

@ -13,13 +13,16 @@ type GitlabProvider struct {
config oauth2.Config config oauth2.Config
} }
func (g *GitlabProvider) Init(c provider.Oauth2Option) { func newGitlabProvider() provider.ProviderInterface {
g.config.Scopes = []string{"read_user"} return &GitlabProvider{
if c.Endpoint != nil { config: oauth2.Config{
g.config.Endpoint = *c.Endpoint Scopes: []string{"read_user"},
} else { Endpoint: gitlab.Endpoint,
g.config.Endpoint = gitlab.Endpoint },
}
} }
func (g *GitlabProvider) Init(c provider.Oauth2Option) {
g.config.ClientID = c.ClientID g.config.ClientID = c.ClientID
g.config.ClientSecret = c.ClientSecret g.config.ClientSecret = c.ClientSecret
g.config.RedirectURL = c.RedirectURL g.config.RedirectURL = c.RedirectURL
@ -56,5 +59,5 @@ func (g *GitlabProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*pr
} }
func init() { func init() {
RegisterProvider(new(GitlabProvider)) RegisterProvider(newGitlabProvider())
} }

@ -14,13 +14,16 @@ type GoogleProvider struct {
config oauth2.Config config oauth2.Config
} }
func (g *GoogleProvider) Init(c provider.Oauth2Option) { func newGoogleProvider() provider.ProviderInterface {
g.config.Scopes = []string{"profile"} return &GoogleProvider{
if c.Endpoint != nil { config: oauth2.Config{
g.config.Endpoint = *c.Endpoint Scopes: []string{"profile"},
} else { Endpoint: google.Endpoint,
g.config.Endpoint = google.Endpoint },
}
} }
func (g *GoogleProvider) Init(c provider.Oauth2Option) {
g.config.ClientID = c.ClientID g.config.ClientID = c.ClientID
g.config.ClientSecret = c.ClientSecret g.config.ClientSecret = c.ClientSecret
g.config.RedirectURL = c.RedirectURL g.config.RedirectURL = c.RedirectURL
@ -65,7 +68,7 @@ func (g *GoogleProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*pr
} }
func init() { func init() {
RegisterProvider(new(GoogleProvider)) RegisterProvider(newGoogleProvider())
} }
type googleUserInfo struct { type googleUserInfo struct {

@ -14,13 +14,16 @@ type MicrosoftProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *MicrosoftProvider) Init(c provider.Oauth2Option) { func newMicrosoftProvider() provider.ProviderInterface {
p.config.Scopes = []string{"user.read"} return &MicrosoftProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"user.read"},
} else { Endpoint: microsoft.LiveConnectEndpoint,
p.config.Endpoint = microsoft.LiveConnectEndpoint },
}
} }
func (p *MicrosoftProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -70,5 +73,5 @@ type microsoftUserInfo struct {
} }
func init() { func init() {
RegisterProvider(new(MicrosoftProvider)) RegisterProvider(newMicrosoftProvider())
} }

@ -4,46 +4,56 @@ import (
"fmt" "fmt"
"github.com/synctv-org/synctv/internal/provider" "github.com/synctv-org/synctv/internal/provider"
"github.com/zijiren233/gencontainer/rwmap"
) )
var ( var (
enabledProviders map[provider.OAuth2Provider]provider.ProviderInterface enabledProviders rwmap.RWMap[provider.OAuth2Provider, provider.ProviderInterface]
allowedProviders = make(map[provider.OAuth2Provider]provider.ProviderInterface) allProviders = make(map[provider.OAuth2Provider]provider.ProviderInterface)
) )
func InitProvider(p provider.OAuth2Provider, c provider.Oauth2Option) error { func InitProvider(p provider.OAuth2Provider, c provider.Oauth2Option) (provider.ProviderInterface, error) {
pi, ok := allowedProviders[p] pi, ok := allProviders[p]
if !ok { if !ok {
return FormatErrNotImplemented(p) return nil, FormatErrNotImplemented(p)
} }
pi.Init(c) pi.Init(c)
if enabledProviders == nil { return pi, nil
enabledProviders = make(map[provider.OAuth2Provider]provider.ProviderInterface)
}
enabledProviders[pi.Provider()] = pi
return nil
} }
func RegisterProvider(ps ...provider.ProviderInterface) { func RegisterProvider(ps ...provider.ProviderInterface) {
for _, p := range ps { for _, p := range ps {
allowedProviders[p.Provider()] = p allProviders[p.Provider()] = p
} }
} }
func GetProvider(p provider.OAuth2Provider) (provider.ProviderInterface, error) { func GetProvider(p provider.OAuth2Provider) (provider.ProviderInterface, error) {
pi, ok := enabledProviders[p] pi, ok := enabledProviders.Load(p)
if !ok { if !ok {
return nil, FormatErrNotImplemented(p) return nil, FormatErrNotImplemented(p)
} }
return pi, nil return pi, nil
} }
func AllowedProvider() map[provider.OAuth2Provider]provider.ProviderInterface { func AllProvider() map[provider.OAuth2Provider]provider.ProviderInterface {
return allowedProviders return allProviders
}
func EnabledProvider() *rwmap.RWMap[provider.OAuth2Provider, provider.ProviderInterface] {
return &enabledProviders
}
func EnableProvider(p provider.OAuth2Provider) error {
pi, ok := allProviders[p]
if !ok {
return FormatErrNotImplemented(p)
}
enabledProviders.Store(p, pi)
return nil
} }
func EnabledProvider() map[provider.OAuth2Provider]provider.ProviderInterface { func DisableProvider(p provider.OAuth2Provider) {
return enabledProviders enabledProviders.Delete(p)
} }
type FormatErrNotImplemented string type FormatErrNotImplemented string

@ -14,16 +14,19 @@ type QQProvider struct {
config oauth2.Config config oauth2.Config
} }
func (p *QQProvider) Init(c provider.Oauth2Option) { func newQQProvider() provider.ProviderInterface {
p.config.Scopes = []string{"get_user_info"} return &QQProvider{
if c.Endpoint != nil { config: oauth2.Config{
p.config.Endpoint = *c.Endpoint Scopes: []string{"get_user_info"},
} else { Endpoint: oauth2.Endpoint{
p.config.Endpoint = oauth2.Endpoint{
AuthURL: "https://graph.qq.com/oauth2.0/authorize", AuthURL: "https://graph.qq.com/oauth2.0/authorize",
TokenURL: "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code", TokenURL: "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code",
},
},
} }
} }
func (p *QQProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL p.config.RedirectURL = c.RedirectURL
@ -67,11 +70,11 @@ func (p *QQProvider) GetUserInfo(ctx context.Context, tk *oauth2.Token) (*provid
}, nil }, nil
} }
func init() {
RegisterProvider(new(QQProvider))
}
type qqProviderUserInfo struct { type qqProviderUserInfo struct {
ClientID string `json:"client_id"` ClientID string `json:"client_id"`
Openid string `json:"openid"` Openid string `json:"openid"`
} }
func init() {
RegisterProvider(newQQProvider())
}

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
@ -23,11 +24,17 @@ type Bool struct {
setting setting
defaultValue bool defaultValue bool
value uint32 value uint32
beforeSet func(BoolSetting, bool) error beforeInit, beforeSet func(BoolSetting, bool) error
} }
type BoolSettingOption func(*Bool) type BoolSettingOption func(*Bool)
func WithBeforeInitBool(beforeInit func(BoolSetting, bool) error) BoolSettingOption {
return func(s *Bool) {
s.beforeInit = beforeInit
}
}
func WithBeforeSetBool(beforeSet func(BoolSetting, bool) error) BoolSettingOption { func WithBeforeSetBool(beforeSet func(BoolSetting, bool) error) BoolSettingOption {
return func(s *Bool) { return func(s *Bool) {
s.beforeSet = beforeSet s.beforeSet = beforeSet
@ -67,6 +74,14 @@ func (b *Bool) Init(value string) error {
if err != nil { if err != nil {
return err return err
} }
if b.beforeInit != nil {
err = b.beforeInit(b, v)
if err != nil {
return err
}
}
b.set(v) b.set(v)
return nil return nil
} }
@ -108,6 +123,11 @@ func (b *Bool) SetString(value string) error {
} }
} }
err = db.UpdateSettingItemValue(b.name, b.Stringify(v))
if err != nil {
return err
}
b.set(v) b.set(v)
return nil return nil
} }
@ -120,6 +140,11 @@ func (b *Bool) Set(value bool) (err error) {
} }
} }
err = db.UpdateSettingItemValue(b.name, b.Stringify(value))
if err != nil {
return err
}
b.set(value) b.set(value)
return return
} }

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
@ -25,7 +26,7 @@ type Float64 struct {
defaultValue float64 defaultValue float64
value uint64 value uint64
validator func(float64) error validator func(float64) error
beforeSet func(Float64Setting, float64) error beforeInit, beforeSet func(Float64Setting, float64) error
} }
type Float64SettingOption func(*Float64) type Float64SettingOption func(*Float64)
@ -36,6 +37,12 @@ func WithValidatorFloat64(validator func(float64) error) Float64SettingOption {
} }
} }
func WithBeforeInitFloat64(beforeInit func(Float64Setting, float64) error) Float64SettingOption {
return func(s *Float64) {
s.beforeInit = beforeInit
}
}
func WithBeforeSetFloat64(beforeSet func(Float64Setting, float64) error) Float64SettingOption { func WithBeforeSetFloat64(beforeSet func(Float64Setting, float64) error) Float64SettingOption {
return func(s *Float64) { return func(s *Float64) {
s.beforeSet = beforeSet s.beforeSet = beforeSet
@ -78,6 +85,14 @@ func (f *Float64) Init(value string) error {
if err != nil { if err != nil {
return err return err
} }
if f.beforeInit != nil {
err = f.beforeInit(f, v)
if err != nil {
return err
}
}
f.set(v) f.set(v)
return nil return nil
} }
@ -111,6 +126,11 @@ func (f *Float64) SetString(value string) error {
} }
} }
err = db.UpdateSettingItemValue(f.name, f.Stringify(v))
if err != nil {
return err
}
f.set(v) f.set(v)
return nil return nil
} }
@ -134,6 +154,11 @@ func (f *Float64) Set(value float64) (err error) {
} }
} }
err = db.UpdateSettingItemValue(f.name, f.Stringify(value))
if err != nil {
return err
}
f.set(value) f.set(value)
return return
} }

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
@ -24,7 +25,7 @@ type Int64 struct {
defaultValue int64 defaultValue int64
value int64 value int64
validator func(int64) error validator func(int64) error
beforeSet func(Int64Setting, int64) error beforeInit, beforeSet func(Int64Setting, int64) error
} }
type Int64SettingOption func(*Int64) type Int64SettingOption func(*Int64)
@ -35,6 +36,12 @@ func WithValidatorInt64(validator func(int64) error) Int64SettingOption {
} }
} }
func WithBeforeInitInt64(beforeInit func(Int64Setting, int64) error) Int64SettingOption {
return func(s *Int64) {
s.beforeInit = beforeInit
}
}
func WithBeforeSetInt64(beforeSet func(Int64Setting, int64) error) Int64SettingOption { func WithBeforeSetInt64(beforeSet func(Int64Setting, int64) error) Int64SettingOption {
return func(s *Int64) { return func(s *Int64) {
s.beforeSet = beforeSet s.beforeSet = beforeSet
@ -77,6 +84,14 @@ func (i *Int64) Init(value string) error {
if err != nil { if err != nil {
return err return err
} }
if i.beforeInit != nil {
err = i.beforeInit(i, v)
if err != nil {
return err
}
}
i.set(v) i.set(v)
return nil return nil
} }
@ -110,6 +125,11 @@ func (i *Int64) SetString(value string) error {
} }
} }
err = db.UpdateSettingItemValue(i.name, i.Stringify(v))
if err != nil {
return err
}
i.set(v) i.set(v)
return nil return nil
} }
@ -133,6 +153,11 @@ func (i *Int64) Set(value int64) (err error) {
} }
} }
err = db.UpdateSettingItemValue(i.name, i.Stringify(value))
if err != nil {
return err
}
i.set(value) i.set(value)
return return
} }

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"sync" "sync"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
@ -24,7 +25,7 @@ type String struct {
lock sync.RWMutex lock sync.RWMutex
value string value string
validator func(string) error validator func(string) error
beforeSet func(StringSetting, string) error beforeInit, beforeSet func(StringSetting, string) error
} }
type StringSettingOption func(*String) type StringSettingOption func(*String)
@ -35,6 +36,12 @@ func WithValidatorString(validator func(string) error) StringSettingOption {
} }
} }
func WithBeforeInitString(beforeInit func(StringSetting, string) error) StringSettingOption {
return func(s *String) {
s.beforeInit = beforeInit
}
}
func WithBeforeSetString(beforeSet func(StringSetting, string) error) StringSettingOption { func WithBeforeSetString(beforeSet func(StringSetting, string) error) StringSettingOption {
return func(s *String) { return func(s *String) {
s.beforeSet = beforeSet s.beforeSet = beforeSet
@ -73,6 +80,14 @@ func (s *String) Init(value string) error {
if err != nil { if err != nil {
return err return err
} }
if s.beforeInit != nil {
err = s.beforeInit(s, v)
if err != nil {
return err
}
}
s.set(v) s.set(v)
return nil return nil
} }
@ -106,6 +121,11 @@ func (s *String) SetString(value string) error {
} }
} }
err = db.UpdateSettingItemValue(s.name, s.Stringify(v))
if err != nil {
return err
}
s.set(v) s.set(v)
return nil return nil
} }
@ -131,6 +151,11 @@ func (s *String) Set(value string) (err error) {
} }
} }
err = db.UpdateSettingItemValue(s.name, s.Stringify(value))
if err != nil {
return err
}
s.set(value) s.set(value)
return return
} }

@ -4,52 +4,35 @@ import (
"errors" "errors"
"time" "time"
"github.com/synctv-org/synctv/internal/db"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
) )
func BeforeSetBoolFunc(s BoolSetting, v bool) error {
return db.UpdateSettingItemValue(s.Name(), s.Stringify(v))
}
func BeforeSetStringFunc(s StringSetting, v string) error {
return db.UpdateSettingItemValue(s.Name(), s.Stringify(v))
}
func BeforeSetInt64Func(s Int64Setting, v int64) error {
return db.UpdateSettingItemValue(s.Name(), s.Stringify(v))
}
func BeforeSetFloat64Func(s Float64Setting, v float64) error {
return db.UpdateSettingItemValue(s.Name(), s.Stringify(v))
}
var ( var (
DisableCreateRoom = NewBoolSetting("disable_create_room", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) DisableCreateRoom = NewBoolSetting("disable_create_room", false, model.SettingGroupRoom)
RoomMustNeedPwd = NewBoolSetting("room_must_need_pwd", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) RoomMustNeedPwd = NewBoolSetting("room_must_need_pwd", false, model.SettingGroupRoom)
CreateRoomNeedReview = NewBoolSetting("create_room_need_review", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) CreateRoomNeedReview = NewBoolSetting("create_room_need_review", false, model.SettingGroupRoom)
RoomTTL = NewInt64Setting("room_ttl", int64(time.Hour*48), model.SettingGroupRoom, WithBeforeSetInt64(BeforeSetInt64Func)) RoomTTL = NewInt64Setting("room_ttl", int64(time.Hour*48), model.SettingGroupRoom)
UserMaxRoomCount = NewInt64Setting("user_max_room_count", 3, model.SettingGroupRoom, WithBeforeSetInt64(BeforeSetInt64Func)) UserMaxRoomCount = NewInt64Setting("user_max_room_count", 3, model.SettingGroupRoom)
) )
var ( var (
DisableUserSignup = NewBoolSetting("disable_user_signup", false, model.SettingGroupUser, WithBeforeSetBool(BeforeSetBoolFunc)) DisableUserSignup = NewBoolSetting("disable_user_signup", false, model.SettingGroupUser)
SignupNeedReview = NewBoolSetting("signup_need_review", false, model.SettingGroupUser, WithBeforeSetBool(BeforeSetBoolFunc)) SignupNeedReview = NewBoolSetting("signup_need_review", false, model.SettingGroupUser)
) )
var ( var (
MovieProxy = NewBoolSetting("movie_proxy", true, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) MovieProxy = NewBoolSetting("movie_proxy", true, model.SettingGroupProxy)
LiveProxy = NewBoolSetting("live_proxy", true, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) LiveProxy = NewBoolSetting("live_proxy", true, model.SettingGroupProxy)
AllowProxyToLocal = NewBoolSetting("allow_proxy_to_local", false, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) AllowProxyToLocal = NewBoolSetting("allow_proxy_to_local", false, model.SettingGroupProxy)
) )
var ( var (
// can watch live streams through the RTMP protocol (without authentication, insecure). // can watch live streams through the RTMP protocol (without authentication, insecure).
RtmpPlayer = NewBoolSetting("rtmp_player", false, model.SettingGroupRtmp, WithBeforeSetBool(BeforeSetBoolFunc)) RtmpPlayer = NewBoolSetting("rtmp_player", false, model.SettingGroupRtmp)
// default use http header host // default use http header host
CustomPublishHost = NewStringSetting("custom_publish_host", "", model.SettingGroupRtmp, WithBeforeSetString(BeforeSetStringFunc)) CustomPublishHost = NewStringSetting("custom_publish_host", "", model.SettingGroupRtmp)
// disguise the .ts file as a .png file // disguise the .ts file as a .png file
TsDisguisedAsPng = NewBoolSetting("ts_disguised_as_png", true, model.SettingGroupRtmp, WithBeforeSetBool(BeforeSetBoolFunc)) TsDisguisedAsPng = NewBoolSetting("ts_disguised_as_png", true, model.SettingGroupRtmp)
) )
var ( var (

@ -28,7 +28,6 @@ type InitReq struct {
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
ClientSecret string `protobuf:"bytes,2,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"` ClientSecret string `protobuf:"bytes,2,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
RedirectUrl string `protobuf:"bytes,3,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` RedirectUrl string `protobuf:"bytes,3,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"`
Endpoint *InitReq_Endpoint `protobuf:"bytes,4,opt,name=endpoint,proto3,oneof" json:"endpoint,omitempty"`
} }
func (x *InitReq) Reset() { func (x *InitReq) Reset() {
@ -84,13 +83,6 @@ func (x *InitReq) GetRedirectUrl() string {
return "" return ""
} }
func (x *InitReq) GetEndpoint() *InitReq_Endpoint {
if x != nil {
return x.Endpoint
}
return nil
}
type GetTokenReq struct { type GetTokenReq struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -584,150 +576,76 @@ func (*Enpty) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{10} return file_proto_provider_plugin_proto_rawDescGZIP(), []int{10}
} }
type InitReq_Endpoint struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AuthUrl string `protobuf:"bytes,1,opt,name=auth_url,json=authUrl,proto3" json:"auth_url,omitempty"`
DeviceAuthUrl string `protobuf:"bytes,2,opt,name=device_auth_url,json=deviceAuthUrl,proto3" json:"device_auth_url,omitempty"`
TokenUrl string `protobuf:"bytes,3,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"`
}
func (x *InitReq_Endpoint) Reset() {
*x = InitReq_Endpoint{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *InitReq_Endpoint) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InitReq_Endpoint) ProtoMessage() {}
func (x *InitReq_Endpoint) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[11]
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 InitReq_Endpoint.ProtoReflect.Descriptor instead.
func (*InitReq_Endpoint) Descriptor() ([]byte, []int) {
return file_proto_provider_plugin_proto_rawDescGZIP(), []int{0, 0}
}
func (x *InitReq_Endpoint) GetAuthUrl() string {
if x != nil {
return x.AuthUrl
}
return ""
}
func (x *InitReq_Endpoint) GetDeviceAuthUrl() string {
if x != nil {
return x.DeviceAuthUrl
}
return ""
}
func (x *InitReq_Endpoint) GetTokenUrl() string {
if x != nil {
return x.TokenUrl
}
return ""
}
var File_proto_provider_plugin_proto protoreflect.FileDescriptor var File_proto_provider_plugin_proto protoreflect.FileDescriptor
var file_proto_provider_plugin_proto_rawDesc = []byte{ var file_proto_provider_plugin_proto_rawDesc = []byte{
0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x02, 0x0a, 0x07, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6e, 0x0a, 0x07, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12,
0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d,
0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65,
0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72,
0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63,
0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x38, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x22, 0x21, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65,
0x48, 0x00, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x1a, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
0x6a, 0x0a, 0x08, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79,
0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54,
0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74,
0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72,
0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69,
0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79,
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x21, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x22, 0x36, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x05, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x36, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x72,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x05,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72,
0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55,
0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01,
0x70, 0x69, 0x72, 0x79, 0x22, 0x36, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x22, 0x0a, 0x0e, 0x4e,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a,
0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22,
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x36, 0x0a, 0x10, 0x34, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x71, 0x12, 0x22, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x12, 0x22, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x05,
0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x05, 0x74, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x57, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72,
0x52, 0x65, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x41, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x07,
0x22, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x0a, 0x05, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x32, 0xd7, 0x02, 0x0a, 0x0c, 0x4f, 0x61, 0x75, 0x74,
0x70, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x68, 0x32, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74,
0x75, 0x72, 0x6c, 0x22, 0x34, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x12, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71,
0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x22, 0x00,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x12, 0x2f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0c, 0x2e, 0x70,
0x65, 0x6e, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x57, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x00, 0x12, 0x3b, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x12,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55,
0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65,
0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2e,
0x49, 0x64, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x32, 0xd7, 0x02, 0x0a, 0x0c, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f,
0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0c,
0x49, 0x6e, 0x69, 0x74, 0x12, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x41,
0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16,
0x74, 0x79, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f,
0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22,
0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x00, 0x12, 0x3e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
0x55, 0x52, 0x4c, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x6f, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22,
0x22, 0x00, 0x12, 0x2e, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x70,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
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,
} }
var ( var (
@ -742,7 +660,7 @@ func file_proto_provider_plugin_proto_rawDescGZIP() []byte {
return file_proto_provider_plugin_proto_rawDescData return file_proto_provider_plugin_proto_rawDescData
} }
var file_proto_provider_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_proto_provider_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_proto_provider_plugin_proto_goTypes = []interface{}{ var file_proto_provider_plugin_proto_goTypes = []interface{}{
(*InitReq)(nil), // 0: proto.InitReq (*InitReq)(nil), // 0: proto.InitReq
(*GetTokenReq)(nil), // 1: proto.GetTokenReq (*GetTokenReq)(nil), // 1: proto.GetTokenReq
@ -755,29 +673,27 @@ var file_proto_provider_plugin_proto_goTypes = []interface{}{
(*GetUserInfoReq)(nil), // 8: proto.GetUserInfoReq (*GetUserInfoReq)(nil), // 8: proto.GetUserInfoReq
(*GetUserInfoResp)(nil), // 9: proto.GetUserInfoResp (*GetUserInfoResp)(nil), // 9: proto.GetUserInfoResp
(*Enpty)(nil), // 10: proto.Enpty (*Enpty)(nil), // 10: proto.Enpty
(*InitReq_Endpoint)(nil), // 11: proto.InitReq.Endpoint
} }
var file_proto_provider_plugin_proto_depIdxs = []int32{ var file_proto_provider_plugin_proto_depIdxs = []int32{
11, // 0: proto.InitReq.endpoint:type_name -> proto.InitReq.Endpoint 2, // 0: proto.RefreshTokenResp.token:type_name -> proto.Token
2, // 1: proto.RefreshTokenResp.token:type_name -> proto.Token 2, // 1: proto.GetUserInfoReq.token:type_name -> proto.Token
2, // 2: proto.GetUserInfoReq.token:type_name -> proto.Token 0, // 2: proto.Oauth2Plugin.Init:input_type -> proto.InitReq
0, // 3: proto.Oauth2Plugin.Init:input_type -> proto.InitReq 10, // 3: proto.Oauth2Plugin.Provider:input_type -> proto.Enpty
10, // 4: proto.Oauth2Plugin.Provider:input_type -> proto.Enpty 6, // 4: proto.Oauth2Plugin.NewAuthURL:input_type -> proto.NewAuthURLReq
6, // 5: proto.Oauth2Plugin.NewAuthURL:input_type -> proto.NewAuthURLReq 1, // 5: proto.Oauth2Plugin.GetToken:input_type -> proto.GetTokenReq
1, // 6: proto.Oauth2Plugin.GetToken:input_type -> proto.GetTokenReq 3, // 6: proto.Oauth2Plugin.RefreshToken:input_type -> proto.RefreshTokenReq
3, // 7: proto.Oauth2Plugin.RefreshToken:input_type -> proto.RefreshTokenReq 8, // 7: proto.Oauth2Plugin.GetUserInfo:input_type -> proto.GetUserInfoReq
8, // 8: proto.Oauth2Plugin.GetUserInfo:input_type -> proto.GetUserInfoReq 10, // 8: proto.Oauth2Plugin.Init:output_type -> proto.Enpty
10, // 9: proto.Oauth2Plugin.Init:output_type -> proto.Enpty 5, // 9: proto.Oauth2Plugin.Provider:output_type -> proto.ProviderResp
5, // 10: proto.Oauth2Plugin.Provider:output_type -> proto.ProviderResp 7, // 10: proto.Oauth2Plugin.NewAuthURL:output_type -> proto.NewAuthURLResp
7, // 11: proto.Oauth2Plugin.NewAuthURL:output_type -> proto.NewAuthURLResp 2, // 11: proto.Oauth2Plugin.GetToken:output_type -> proto.Token
2, // 12: proto.Oauth2Plugin.GetToken:output_type -> proto.Token 4, // 12: proto.Oauth2Plugin.RefreshToken:output_type -> proto.RefreshTokenResp
4, // 13: proto.Oauth2Plugin.RefreshToken:output_type -> proto.RefreshTokenResp 9, // 13: proto.Oauth2Plugin.GetUserInfo:output_type -> proto.GetUserInfoResp
9, // 14: proto.Oauth2Plugin.GetUserInfo:output_type -> proto.GetUserInfoResp 8, // [8:14] is the sub-list for method output_type
9, // [9:15] is the sub-list for method output_type 2, // [2:8] is the sub-list for method input_type
3, // [3:9] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension type_name 2, // [2:2] is the sub-list for extension extendee
3, // [3:3] is the sub-list for extension extendee 0, // [0:2] is the sub-list for field type_name
0, // [0:3] is the sub-list for field type_name
} }
func init() { file_proto_provider_plugin_proto_init() } func init() { file_proto_provider_plugin_proto_init() }
@ -918,27 +834,14 @@ func file_proto_provider_plugin_proto_init() {
return nil return nil
} }
} }
file_proto_provider_plugin_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitReq_Endpoint); 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[0].OneofWrappers = []interface{}{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_provider_plugin_proto_rawDesc, RawDescriptor: file_proto_provider_plugin_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 12, NumMessages: 11,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

@ -4,15 +4,9 @@ option go_package = ".;providerpb";
package proto; package proto;
message InitReq { message InitReq {
message Endpoint {
string auth_url = 1;
string device_auth_url = 2;
string token_url = 3;
}
string client_id = 1; string client_id = 1;
string client_secret = 2; string client_secret = 2;
string redirect_url = 3; string redirect_url = 3;
optional Endpoint endpoint = 4;
} }
message GetTokenReq { string code = 1; } message GetTokenReq { string code = 1; }

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/synctv-org/synctv/internal/bootstrap"
"github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model" dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op" "github.com/synctv-org/synctv/internal/op"
@ -35,20 +36,32 @@ func EditAdminSettings(ctx *gin.Context) {
func AdminSettings(ctx *gin.Context) { func AdminSettings(ctx *gin.Context) {
// user := ctx.MustGet("user").(*op.User) // user := ctx.MustGet("user").(*op.User)
group := ctx.Param("group") group := ctx.Param("group")
if group == "" { switch group {
resp := make(model.AdminSettingsResp, len(settings.GroupSettings)) case "oauth2":
for sg, v := range settings.GroupSettings { resp := make(model.AdminSettingsResp, len(bootstrap.ProviderGroupSettings))
if resp[string(sg)] == nil { for k, v := range bootstrap.ProviderGroupSettings {
resp[string(sg)] = make(gin.H, len(v)) if resp[k] == nil {
resp[k] = make(gin.H, len(v))
} }
for _, s2 := range v { for _, s2 := range v {
resp[string(sg)][s2.Name()] = s2.Interface() resp[k][s2.Name()] = s2.Interface()
} }
} }
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp)) ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
return case "":
resp := make(model.AdminSettingsResp, len(settings.GroupSettings))
for sg, v := range settings.GroupSettings {
if resp[sg] == nil {
resp[sg] = make(gin.H, len(v))
}
for _, s2 := range v {
resp[sg][s2.Name()] = s2.Interface()
}
} }
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
default:
s, ok := settings.GroupSettings[dbModel.SettingGroup(group)] s, ok := settings.GroupSettings[dbModel.SettingGroup(group)]
if !ok { if !ok {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("group not found")) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("group not found"))
@ -62,6 +75,8 @@ func AdminSettings(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(resp)) ctx.JSON(http.StatusOK, model.NewApiDataResp(resp))
} }
}
func Users(ctx *gin.Context) { func Users(ctx *gin.Context) {
// user := ctx.MustGet("user").(*op.User) // user := ctx.MustGet("user").(*op.User)
page, pageSize, err := GetPageAndPageSize(ctx) page, pageSize, err := GetPageAndPageSize(ctx)

@ -7,6 +7,7 @@ import (
"github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model" dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op" "github.com/synctv-org/synctv/internal/op"
"github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/providers" "github.com/synctv-org/synctv/internal/provider/providers"
"github.com/synctv-org/synctv/server/middlewares" "github.com/synctv-org/synctv/server/middlewares"
"github.com/synctv-org/synctv/server/model" "github.com/synctv-org/synctv/server/model"
@ -185,8 +186,9 @@ func UserBindProviders(ctx *gin.Context) {
m := providers.EnabledProvider() m := providers.EnabledProvider()
resp := make(model.UserBindProviderResp, len(up)) resp := make(model.UserBindProviderResp, len(up))
for _, v := range up { for _, v := range up {
if _, ok := m[v.Provider]; ok { if _, ok := m.Load(v.Provider); ok {
resp[v.Provider] = struct { resp[v.Provider] = struct {
ProviderUserID string "json:\"providerUserID\"" ProviderUserID string "json:\"providerUserID\""
CreatedAt int64 "json:\"createdAt\"" CreatedAt int64 "json:\"createdAt\""
@ -197,7 +199,7 @@ func UserBindProviders(ctx *gin.Context) {
} }
} }
for p := range m { m.Range(func(p provider.OAuth2Provider, pi provider.ProviderInterface) bool {
if _, ok := resp[p]; !ok { if _, ok := resp[p]; !ok {
resp[p] = struct { resp[p] = struct {
ProviderUserID string "json:\"providerUserID\"" ProviderUserID string "json:\"providerUserID\""
@ -207,7 +209,8 @@ func UserBindProviders(ctx *gin.Context) {
CreatedAt: 0, CreatedAt: 0,
} }
} }
} return true
})
ctx.JSON(http.StatusOK, resp) ctx.JSON(http.StatusOK, resp)
} }

@ -22,7 +22,7 @@ func (asr *AdminSettingsReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(asr) return json.NewDecoder(ctx.Request.Body).Decode(asr)
} }
type AdminSettingsResp map[string]map[string]any type AdminSettingsResp map[dbModel.SettingGroup]map[string]any
type AddUserReq struct { type AddUserReq struct {
Username string `json:"username"` Username string `json:"username"`

@ -1,31 +1,39 @@
package auth package auth
import ( import (
"sync" "net/http"
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/synctv-org/synctv/internal/provider" "github.com/synctv-org/synctv/internal/provider"
"github.com/synctv-org/synctv/internal/provider/providers" "github.com/synctv-org/synctv/internal/provider/providers"
"github.com/synctv-org/synctv/server/model"
"github.com/zijiren233/gencontainer/refreshcache"
"github.com/zijiren233/gencontainer/vec" "github.com/zijiren233/gencontainer/vec"
"golang.org/x/exp/maps"
) )
var ( var (
oauth2EnabledCache []provider.OAuth2Provider Oauth2EnabledCache = refreshcache.NewRefreshCache[[]provider.OAuth2Provider](func() ([]provider.OAuth2Provider, error) {
oauth2EnabledOnce sync.Once
)
func OAuth2EnabledApi(ctx *gin.Context) {
oauth2EnabledOnce.Do(func() {
oauth2EnabledCache = maps.Keys(providers.EnabledProvider())
a := vec.New[provider.OAuth2Provider](vec.WithCmpEqual[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool { a := vec.New[provider.OAuth2Provider](vec.WithCmpEqual[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool {
return v1 == v2 return v1 == v2
}), vec.WithCmpLess[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool { }), vec.WithCmpLess[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool {
return v1 < v2 return v1 < v2
})) }))
a.Push(oauth2EnabledCache...).SortStable().Slice() providers.EnabledProvider().Range(func(key provider.OAuth2Provider, value provider.ProviderInterface) bool {
a.Push(key)
return true
}) })
return a.SortStable().Slice(), nil
}, time.Hour)
)
func OAuth2EnabledApi(ctx *gin.Context) {
data, err := Oauth2EnabledCache.Get()
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(200, gin.H{ ctx.JSON(200, gin.H{
"enabled": oauth2EnabledCache, "enabled": data,
}) })
} }

Loading…
Cancel
Save