diff --git a/cmd/olcrtc/main.go b/cmd/olcrtc/main.go index c9d3e14..6849261 100644 --- a/cmd/olcrtc/main.go +++ b/cmd/olcrtc/main.go @@ -106,7 +106,15 @@ func runWithConfig(cfg config) error { return runGen(cfg) } - if err := session.Validate(toSessionConfig(cfg)); err != nil { + return runSessionMode(cfg) +} + +func runSessionMode(cfg config) error { + scfg, err := session.ApplyAuthDefaults(toSessionConfig(cfg)) + if err != nil { + return fmt.Errorf("validate config: %w", err) + } + if err := session.Validate(scfg); err != nil { return fmt.Errorf("validate config: %w", err) } @@ -131,7 +139,7 @@ func runWithConfig(cfg config) error { errCh := make(chan error, 1) go func() { - errCh <- runSession(ctx, toSessionConfig(cfg)) + errCh <- runSession(ctx, scfg) }() select { @@ -145,7 +153,10 @@ func runWithConfig(cfg config) error { } func execGen(cfg config) error { - scfg := toSessionConfig(cfg) + scfg, err := session.ApplyAuthDefaults(toSessionConfig(cfg)) + if err != nil { + return fmt.Errorf("validate gen config: %w", err) + } if err := session.ValidateGen(scfg); err != nil { return fmt.Errorf("validate gen config: %w", err) } diff --git a/internal/app/session/session.go b/internal/app/session/session.go index 804e34b..95ef09c 100644 --- a/internal/app/session/session.go +++ b/internal/app/session/session.go @@ -46,6 +46,8 @@ var ( // ErrAuthRequired indicates that no auth provider was selected. ErrAuthRequired = errors.New( "auth provider required (use -auth telemost, -auth jazz, -auth wbstream or -auth none)") + // ErrURLRequired indicates that -url must be provided when the auth provider has no default URL. + ErrURLRequired = errors.New("SFU URL required (use -url wss://...)") // ErrUnsupportedCarrier indicates that carrier is not registered. ErrUnsupportedCarrier = errors.New("unsupported carrier") // ErrUnsupportedLink indicates that link is not registered. @@ -151,6 +153,29 @@ func RegisterDefaults() { transport.Register("vp8channel", vp8channel.New) } +// ApplyAuthDefaults fills in Engine and URL from the auth provider when they are not set explicitly. +// For -auth none the fields are left untouched (the caller supplies them directly). +// Returns an error if the auth provider has no default URL and -url was not given. +func ApplyAuthDefaults(cfg Config) (Config, error) { + if cfg.Auth == authNone || cfg.Auth == "" { + return cfg, nil + } + p, _ := auth.Get(cfg.Auth) // unknown auth is caught later by validateAuth + if p == nil { + return cfg, nil + } + if cfg.Engine == "" { + cfg.Engine = p.Engine() + } + if cfg.URL == "" { + cfg.URL = p.DefaultServiceURL() + } + if cfg.URL == "" { + return cfg, fmt.Errorf("%w: auth provider %q has no default URL", ErrURLRequired, cfg.Auth) + } + return cfg, nil +} + // Validate verifies that the runtime config refers to registered components and all required fields are present. func Validate(cfg Config) error { if err := validateMode(cfg); err != nil { diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 1ac3e34..19613a2 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -53,10 +53,12 @@ type Config struct { // Provider produces engine credentials. type Provider interface { - // Engine reports which engine this auth provider feeds. This is what lets - // a carrier resolve (auth, engine) pairs consistently — e.g. auth=jazz - // always pairs with engine=livekit. + // Engine reports which engine this auth provider feeds. Engine() string + // DefaultServiceURL returns the well-known service URL for this provider + // (e.g. "https://stream.wb.ru"). Returns "" if no default exists — in that + // case the caller must supply -url explicitly. + DefaultServiceURL() string // Issue obtains credentials for the given room. Issue(ctx context.Context, cfg Config) (Credentials, error) } diff --git a/internal/auth/salutejazz/salutejazz.go b/internal/auth/salutejazz/salutejazz.go index d166707..6dd6abf 100644 --- a/internal/auth/salutejazz/salutejazz.go +++ b/internal/auth/salutejazz/salutejazz.go @@ -14,6 +14,9 @@ type Provider struct{} // Engine reports which engine consumes credentials from this auth provider. func (Provider) Engine() string { return "salutejazz" } +// DefaultServiceURL returns the SaluteJazz service URL. +func (Provider) DefaultServiceURL() string { return "https://bk.salutejazz.ru" } + // Issue runs the SaluteJazz API flow and returns engine credentials. // // cfg.RoomURL accepts either an empty value (a new room is created on the diff --git a/internal/auth/telemost/telemost.go b/internal/auth/telemost/telemost.go index 048b348..bf1748b 100644 --- a/internal/auth/telemost/telemost.go +++ b/internal/auth/telemost/telemost.go @@ -16,6 +16,9 @@ type Provider struct{} // Engine reports which engine consumes credentials from this auth provider. func (Provider) Engine() string { return "goolom" } +// DefaultServiceURL returns the Telemost conference base URL. +func (Provider) DefaultServiceURL() string { return "https://telemost.yandex.ru" } + // Issue fetches connection info for a Telemost room and returns engine credentials. // // cfg.RoomURL accepts either a full Telemost conference URL diff --git a/internal/auth/wbstream/wbstream.go b/internal/auth/wbstream/wbstream.go index d14e771..5637e38 100644 --- a/internal/auth/wbstream/wbstream.go +++ b/internal/auth/wbstream/wbstream.go @@ -13,6 +13,9 @@ type Provider struct{} // Engine reports which engine consumes credentials from this auth provider. func (Provider) Engine() string { return "livekit" } +// DefaultServiceURL returns the WB Stream service URL. +func (Provider) DefaultServiceURL() string { return "https://stream.wb.ru" } + // Issue runs the WB Stream auth flow and returns LiveKit credentials. // // If cfg.RoomURL is empty or "any", a fresh room is created on the fly — diff --git a/pkg/olcrtc/olcrtc_test.go b/pkg/olcrtc/olcrtc_test.go index 27ca8a4..bbad3fd 100644 --- a/pkg/olcrtc/olcrtc_test.go +++ b/pkg/olcrtc/olcrtc_test.go @@ -71,7 +71,8 @@ func registerStubEngineControlled(t *testing.T, name string, stub *stubSession) type stubAuth struct{ engineName string } -func (a stubAuth) Engine() string { return a.engineName } +func (a stubAuth) Engine() string { return a.engineName } +func (stubAuth) DefaultServiceURL() string { return "https://stub.example" } func (a stubAuth) Issue(_ context.Context, cfg auth.Config) (auth.Credentials, error) { if cfg.RoomURL == "" { return auth.Credentials{}, auth.ErrRoomIDRequired