package oauth import ( "cs-bridge/internal/auth" "cs-bridge/pkg/lua" "fmt" lua2 "github.com/yuin/gopher-lua" ) type LuaProvider struct { model ProviderModel engine *lua.Engine redirectURI string } // NewLuaProvider creates a new Lua-based provider func NewLuaProvider(model ProviderModel, redirectURI, scriptPath string) (*LuaProvider, error) { engine := lua.New() // Register all API modules (http, json, log, util) engine.RegisterAPI() // Load the Lua script if err := engine.LoadFile(scriptPath); err != nil { engine.Close() return nil, err } return &LuaProvider{ model: model, engine: engine, redirectURI: redirectURI, }, nil } // Close cleans up the Lua engine func (p *LuaProvider) Close() { p.engine.Close() } // Name implements [Provider]. func (p *LuaProvider) Name() string { return p.model.Name } // luaConfig constructs the config table passed to Lua functions func (p *LuaProvider) luaConfig() *lua2.LTable { L := p.engine.L config := L.NewTable() config.RawSetString("client_id", lua2.LString(p.model.ClientID)) config.RawSetString("client_secret", lua2.LString(p.model.ClientSecret)) config.RawSetString("base_url", lua2.LString(p.model.BaseURL)) config.RawSetString("authorize_url", lua2.LString(p.model.AuthorizeURL)) config.RawSetString("token_url", lua2.LString(p.model.TokenURL)) config.RawSetString("user_url", lua2.LString(p.model.UserURL)) config.RawSetString("redirect_uri", lua2.LString(p.redirectURI)) return config } // AuthURL implements [Provider]. func (p *LuaProvider) AuthURL(state string) (string, error) { cfg := p.luaConfig() return p.engine.CallString("auth_url", cfg, lua2.LString(state)) } // Exchange implements [Provider]. func (p *LuaProvider) Exchange(code string) (string, error) { cfg := p.luaConfig() return p.engine.CallString("exchange", cfg, lua2.LString(code)) } // UserInfo implements [Provider]. func (p *LuaProvider) UserInfo(token string) (auth.Identify, error) { cfg := p.luaConfig() var userInfo auth.Identify if err := p.engine.CallStruct("user_info", &userInfo, cfg, lua2.LString(token)); err != nil { return auth.Identify{}, fmt.Errorf("failed to get user info: %w", err) } // Set the provider name userInfo.Provider = p.model.Name return userInfo, nil }