From ead90215e0b08090cf5218a3dabbcf5506758477 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 26 Mar 2025 11:26:06 -0600 Subject: feat: exchange a saml response for a token --- bin/ui | 75 ++++++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 22 deletions(-) (limited to 'bin') diff --git a/bin/ui b/bin/ui index 8dab9df1..e5eb5488 100755 --- a/bin/ui +++ b/bin/ui @@ -69,18 +69,32 @@ module OAuth ].join("?") end - def exchange(grant_type:, code:, code_verifier: "not_implemented") + def exchange(grant_type, params = {}) with_http do |client| - client.post(self[:token_endpoint], body: { - grant_type: grant_type, - code: code, - code_verifier: code_verifier, - }) + client.post(self[:token_endpoint], body: body_for(grant_type, params)) end end private + def body_for(grant_type, params) + case grant_type + when "authorization_code" + { + grant_type: grant_type, + code: params.fetch(:code), + code_verifier: params.fetch(:code_verifier, "not_implemented"), + } + when "urn:ietf:params:oauth:grant-type:saml2-bearer" + { + grant_type: grant_type, + assertion: params.fetch(:assertion), + } + else + raise NotImplementedError.new(grant_type) + end + end + def to_query(params = {}) params.map do |(key, value)| [key, value].join("=") @@ -221,7 +235,7 @@ class UI end def oauth_callback(request) - response = oauth_client.exchange(grant_type: "authorization_code", code: request.params['code']) + response = oauth_client.exchange("authorization_code", code: request.params['code']) if response.code == "200" tokens = JSON.parse(response.body, symbolize_names: true) request.session[:access_token] = tokens[:access_token] @@ -379,21 +393,38 @@ class UI saml_response = saml_binding.deserialize(request.params) raise saml_response.errors unless saml_response.valid? - template = <<~ERB - - - - - - -

Received SAML Response

- -
<%= request.params["SAMLResponse"] %>
- - - ERB - html = ERB.new(template, trim_mode: '-').result(binding) - [200, { 'Content-Type' => "text/html" }, [html]] + response = oauth_client.exchange( + "urn:ietf:params:oauth:grant-type:saml2-bearer", + assertion: request.params["SAMLResponse"], + ) + if response.code == "200" + tokens = JSON.parse(response.body, symbolize_names: true) + request.session[:access_token] = tokens[:access_token] + request.session[:id_token] = tokens[:id_token] + request.session[:refresh_token] = tokens[:access_token] + + template = <<~ERB + + + + + + +

Received SAML Response

+ +
<%= request.params["SAMLResponse"] %>
+
<%= JSON.pretty_generate(request.session[:access_token]) %>
+ + Home + Groups + + + ERB + html = ERB.new(template, trim_mode: '-').result(binding) + [200, { 'Content-Type' => "text/html" }, [html]] + else + [response.code, response.header, [response.body]] + end end end -- cgit v1.2.3