Module: Legion::Extensions::Github::OAuth::Runners::Auth
Constant Summary
Helpers::Client::CREDENTIAL_RESOLVERS
Helpers::TokenCache::TOKEN_BUFFER_SECONDS
Instance Method Summary
collapse
-
#authorize_url(client_id:, redirect_uri:, scope:, state:, code_challenge:, code_challenge_method: 'S256') ⇒ Object
-
#exchange_code(client_id:, code:, redirect_uri:, code_verifier:, client_secret: nil) ⇒ Object
-
#generate_pkce ⇒ Object
-
#oauth_connection(client_id: nil, client_secret: nil) ⇒ Object
-
#poll_device_code(client_id:, device_code:, interval: 5, timeout: 300) ⇒ Object
-
#refresh_token(client_id:, refresh_token:, client_secret: nil) ⇒ Object
-
#request_device_code(client_id:, scope: 'repo') ⇒ Object
-
#revoke_token(client_id:, client_secret:, access_token:) ⇒ Object
#connection, #gh_cli_token_output, #max_fallback_retries, #on_rate_limit, #on_scope_authorized, #on_scope_denied, #resolve_broker_app, #resolve_credential, #resolve_env, #resolve_gh_cli, #resolve_next_credential, #resolve_settings_app, #resolve_settings_delegated, #resolve_settings_pat, #resolve_vault_app, #resolve_vault_delegated, #resolve_vault_pat
#credential_fingerprint, #invalidate_scope, #mark_rate_limited, #rate_limited?, #register_scope, #scope_status
#fetch_token, #mark_rate_limited, #rate_limited?, #store_token
Instance Method Details
#authorize_url(client_id:, redirect_uri:, scope:, state:, code_challenge:, code_challenge_method: 'S256') ⇒ Object
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 25
def authorize_url(client_id:, redirect_uri:, scope:, state:,
code_challenge:, code_challenge_method: 'S256', **)
params = URI.encode_www_form(
client_id: client_id, redirect_uri: redirect_uri,
scope: scope, state: state,
code_challenge: code_challenge,
code_challenge_method: code_challenge_method
)
{ result: "https://github.com/login/oauth/authorize?#{params}" }
end
|
#exchange_code(client_id:, code:, redirect_uri:, code_verifier:, client_secret: nil) ⇒ Object
36
37
38
39
40
41
42
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 36
def exchange_code(client_id:, code:, redirect_uri:, code_verifier:, client_secret: nil, **)
body = { client_id: client_id, code: code,
redirect_uri: redirect_uri, code_verifier: code_verifier }
body[:client_secret] = client_secret if client_secret
response = oauth_connection.post('/login/oauth/access_token', body)
{ result: response.body }
end
|
#generate_pkce ⇒ Object
17
18
19
20
21
22
23
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 17
def generate_pkce(**)
verifier = SecureRandom.urlsafe_base64(32)
challenge = ::Base64.urlsafe_encode64(
OpenSSL::Digest::SHA256.digest(verifier), padding: false
)
{ result: { verifier: verifier, challenge: challenge, challenge_method: 'S256' } }
end
|
#oauth_connection(client_id: nil, client_secret: nil) ⇒ Object
93
94
95
96
97
98
99
100
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 93
def oauth_connection(client_id: nil, client_secret: nil, **)
Faraday.new(url: 'https://github.com') do |conn|
conn.request :json
conn.response :json, content_type: /\bjson$/
conn.['Accept'] = 'application/json'
conn.request :authorization, :basic, client_id, client_secret if client_id && client_secret
end
end
|
#poll_device_code(client_id:, device_code:, interval: 5, timeout: 300) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 59
def poll_device_code(client_id:, device_code:, interval: 5, timeout: 300, **)
deadline = Time.now + timeout
current_interval = interval
loop do
response = oauth_connection.post('/login/oauth/access_token', {
client_id: client_id,
device_code: device_code,
grant_type: 'urn:ietf:params:oauth:grant-type:device_code'
})
body = response.body
return { result: body } if body[:access_token]
error_key = body[:error]
case error_key
when 'authorization_pending'
return { error: 'timeout', description: "Device code flow timed out after #{timeout}s" } if Time.now > deadline
sleep(current_interval) unless current_interval.zero?
when 'slow_down'
current_interval += 5
sleep(current_interval) unless current_interval.zero?
else
return { error: error_key, description: body[:error_description] }
end
end
end
|
#refresh_token(client_id:, refresh_token:, client_secret: nil) ⇒ Object
44
45
46
47
48
49
50
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 44
def refresh_token(client_id:, refresh_token:, client_secret: nil, **)
body = { client_id: client_id, refresh_token: refresh_token,
grant_type: 'refresh_token' }
body[:client_secret] = client_secret if client_secret
response = oauth_connection.post('/login/oauth/access_token', body)
{ result: response.body }
end
|
#request_device_code(client_id:, scope: 'repo') ⇒ Object
52
53
54
55
56
57
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 52
def request_device_code(client_id:, scope: 'repo', **)
response = oauth_connection.post('/login/device/code', {
client_id: client_id, scope: scope
})
{ result: response.body }
end
|
#revoke_token(client_id:, client_secret:, access_token:) ⇒ Object
87
88
89
90
91
|
# File 'lib/legion/extensions/github/oauth/runners/auth.rb', line 87
def revoke_token(client_id:, client_secret:, access_token:, **)
conn = oauth_connection(client_id: client_id, client_secret: client_secret)
response = conn.delete("/applications/#{client_id}/token", { access_token: access_token })
{ result: response.status == 204 }
end
|