Class: Kward::RPC::AuthManager
- Inherits:
-
Object
- Object
- Kward::RPC::AuthManager
- Defined in:
- lib/kward/rpc/auth_manager.rb
Overview
RPC authentication manager for provider status, login, and logout requests.
Defined Under Namespace
Classes: Login
Instance Method Summary collapse
-
#initialize(server:, oauth_factory: -> { OpenAIOAuth.new }, github_oauth_factory: -> { GithubOAuth.new }, anthropic_oauth_factory: -> { AnthropicOAuth.new }, config_manager: ConfigManager.new) ⇒ AuthManager
constructor
A new instance of AuthManager.
- #login_status(login_id:) ⇒ Object
- #login_with_api_key(provider_id:, api_key:) ⇒ Object
- #login_with_oauth(provider_id:, timeout_seconds: 120) ⇒ Object
- #logout_provider(provider_id:) ⇒ Object
- #providers ⇒ Object
- #start_oauth_login(provider_id:, oauth:, timeout_seconds: 120) ⇒ Object
- #start_openai_login(timeout_seconds: 120) ⇒ Object
- #status ⇒ Object
- #submit_openai_code(login_id:, code:) ⇒ Object
Constructor Details
#initialize(server:, oauth_factory: -> { OpenAIOAuth.new }, github_oauth_factory: -> { GithubOAuth.new }, anthropic_oauth_factory: -> { AnthropicOAuth.new }, config_manager: ConfigManager.new) ⇒ AuthManager
Returns a new instance of AuthManager.
17 18 19 20 21 22 23 24 25 |
# File 'lib/kward/rpc/auth_manager.rb', line 17 def initialize(server:, oauth_factory: -> { OpenAIOAuth.new }, github_oauth_factory: -> { GithubOAuth.new }, anthropic_oauth_factory: -> { AnthropicOAuth.new }, config_manager: ConfigManager.new) @server = server @oauth_factory = oauth_factory @github_oauth_factory = github_oauth_factory @anthropic_oauth_factory = anthropic_oauth_factory @config_manager = config_manager @logins = {} @mutex = Mutex.new end |
Instance Method Details
#login_status(login_id:) ⇒ Object
118 119 120 |
# File 'lib/kward/rpc/auth_manager.rb', line 118 def login_status(login_id:) login_payload(fetch_login(login_id)) end |
#login_with_api_key(provider_id:, api_key:) ⇒ Object
46 47 48 49 50 |
# File 'lib/kward/rpc/auth_manager.rb', line 46 def login_with_api_key(provider_id:, api_key:) provider_id = provider_id.to_s @config_manager.set_api_key(provider_id, api_key) { providerId: provider_id, message: "Saved API key for #{provider_name(provider_id)}." } end |
#login_with_oauth(provider_id:, timeout_seconds: 120) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/kward/rpc/auth_manager.rb', line 69 def login_with_oauth(provider_id:, timeout_seconds: 120) provider_id = provider_id.to_s case provider_id when "openai" start_oauth_login(provider_id: "openai", oauth: @oauth_factory.call, timeout_seconds: timeout_seconds) when "anthropic" start_oauth_login(provider_id: "anthropic", oauth: @anthropic_oauth_factory.call, timeout_seconds: timeout_seconds) when "github" raise "GitHub OAuth is supported in the CLI with `ruby lib/main.rb login github`, but RPC browser login is not implemented yet." else raise "Unsupported OAuth provider: #{provider_id}" end end |
#logout_provider(provider_id:) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/kward/rpc/auth_manager.rb', line 52 def logout_provider(provider_id:) provider_id = provider_id.to_s case provider_id when "openai" logout_openai { providerId: provider_id, message: "Logged out of OpenAI." } when "anthropic" logout_anthropic { providerId: provider_id, message: "Logged out of Anthropic." } when "openrouter" @config_manager.delete_key("openrouter_api_key") { providerId: provider_id, message: "Logged out of OpenRouter." } else raise "Unsupported auth provider: #{provider_id}" end end |
#providers ⇒ Object
42 43 44 |
# File 'lib/kward/rpc/auth_manager.rb', line 42 def providers { providers: [openai_provider, anthropic_provider, openrouter_provider, github_provider] } end |
#start_oauth_login(provider_id:, oauth:, timeout_seconds: 120) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/kward/rpc/auth_manager.rb', line 87 def start_oauth_login(provider_id:, oauth:, timeout_seconds: 120) flow = oauth.start_login_flow pkce = flow.fetch(:pkce) state = flow.fetch(:state) server = flow.fetch(:server) redirect_uri = flow.fetch(:redirect_uri) url = flow.fetch(:authorization_url) login = Login.new( id: SecureRandom.uuid, provider_id: provider_id, oauth: oauth, pkce: pkce, state: state, server: server, redirect_uri: redirect_uri, status: "pending" ) @mutex.synchronize { @logins[login.id] = login } login.thread = Thread.new { wait_for_callback(login, timeout_seconds: timeout_seconds.to_i <= 0 ? 120 : timeout_seconds.to_i) } { providerId: provider_id, loginId: login.id, authorizationUrl: url, redirectUri: redirect_uri, status: login.status } end |
#start_openai_login(timeout_seconds: 120) ⇒ Object
83 84 85 |
# File 'lib/kward/rpc/auth_manager.rb', line 83 def start_openai_login(timeout_seconds: 120) start_oauth_login(provider_id: "openai", oauth: @oauth_factory.call, timeout_seconds: timeout_seconds) end |
#status ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/kward/rpc/auth_manager.rb', line 27 def status oauth = @oauth_factory.call config = stored_config { openaiOAuth: oauth.logged_in?, openaiAccountId: oauth.respond_to?(:account_id) ? oauth.account_id : nil, openrouterApiKey: !ENV["OPENROUTER_API_KEY"].to_s.empty? || !config["openrouter_api_key"].to_s.empty?, openaiAccessToken: !ENV["OPENAI_ACCESS_TOKEN"].to_s.empty?, anthropicOAuth: @anthropic_oauth_factory.call.logged_in?, githubOAuth: @github_oauth_factory.call.logged_in? } rescue StandardError => e { openaiOAuth: false, error: e. } end |
#submit_openai_code(login_id:, code:) ⇒ Object
109 110 111 112 113 114 115 116 |
# File 'lib/kward/rpc/auth_manager.rb', line 109 def submit_openai_code(login_id:, code:) login = fetch_login(login_id) raise "Login is not pending" unless login.status == "pending" code = login.oauth.(code.to_s, expected_state: login.state) complete_login(login, code) login_payload(login) end |