summaryrefslogtreecommitdiff
path: root/bin/sp
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-03-05 11:43:07 -0700
committermo khan <mo@mokhan.ca>2025-03-05 11:43:07 -0700
commit20e152182f7137ae2c7f512d0cab1b3c846a4677 (patch)
tree9c7a0ca1e52abc1d9fd2a77ec0c3b3b6166c4dd0 /bin/sp
parent502228f90f6e3e7b03d2c3165a9b8b8f00e29dce (diff)
refactor: extract scheme and provide the appropriate nameid for saml transaction
Diffstat (limited to 'bin/sp')
-rwxr-xr-xbin/sp163
1 files changed, 0 insertions, 163 deletions
diff --git a/bin/sp b/bin/sp
deleted file mode 100755
index f570dab2..00000000
--- a/bin/sp
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env ruby
-
-require "bundler/inline"
-
-gemfile do
- source "https://rubygems.org"
-
- gem "base64", "~> 0.1"
- gem "erb", "~> 4.0"
- gem "net-hippie", "~> 1.0"
- gem "rack", "~> 3.0"
- gem "rackup", "~> 2.0"
- gem "saml-kit", "~> 1.0"
- gem "webrick", "~> 1.0"
-end
-
-class OnDemandRegistry < Saml::Kit::DefaultRegistry
- def metadata_for(entity_id)
- found = super(entity_id)
- return found if found
-
- register_url(entity_id, verify_ssl: false)
- super(entity_id)
- end
-end
-
-Saml::Kit.configure do |x|
- x.entity_id = "http://localhost:8283/metadata.xml"
- x.registry = OnDemandRegistry.new
- x.logger = Logger.new("/dev/stderr")
-end
-
-class ServiceProvider
- def initialize
- @storage = {}
- end
-
- # Download IDP Metadata
- #
- # GET /metadata.xml
- def metadata
- xml = Saml::Kit::Metadata.build_xml do |builder|
- builder.embed_signature = false
- builder.contact_email = 'hi@example.com'
- builder.organization_name = "Acme, Inc"
- builder.organization_url = "https://example.com"
- builder.build_service_provider do |x|
- x.name_id_formats = [Saml::Kit::Namespaces::EMAIL_ADDRESS]
- x.add_assertion_consumer_service("http://localhost:8283/assertions", binding: :http_post)
- end
- end
-
- [200, { 'Content-Type' => "application/samlmetadata+xml" }, [xml]]
- end
-
- def call(env)
- path = env['PATH_INFO']
- case env['REQUEST_METHOD']
- when 'GET'
- case path
- when "/metadata.xml"
- return metadata
- when "/openid/new"
- return redirect_to("http://localhost:8282/oauth/authorize?client_id=service-provider&state=example&redirect_uri=http://localhost:8283/oauth/callback&response_type=code&response_mode=query&scope=openid")
- when "/oauth/callback"
- return oauth_callback(Rack::Request.new(env))
- else
- return saml_post_to_idp(Rack::Request.new(env))
- end
- when 'POST'
- case path
- when "/assertions"
- return saml_assertions(Rack::Request.new(env))
- else
- return not_found
- end
- end
- not_found
- end
-
- private
-
- def not_found
- [404, { 'X-Backend-Server' => 'SP' }, []]
- end
-
- def redirect_to(location)
- [302, { 'Location' => location }, []]
- end
-
- def oauth_callback(request)
- response = Net::Hippie.default_client.post(
- "http://localhost:8282/oauth/token",
- headers: { 'Authorization' => Net::Hippie.basic_auth('client_id', 'secret') },
- body: {
- grant_type: "authorization_code",
- code: request.params['code'],
- code_verifier: "not_implemented"
- }
- )
- [200, { "Content-Type" => "application/json" }, [JSON.pretty_generate(request.params.merge(JSON.parse(response.body)))]]
- end
-
- def saml_post_to_idp(request)
- idp = Saml::Kit.registry.metadata_for('http://localhost:8282/metadata.xml')
- relay_state = Base64.strict_encode64(JSON.generate(redirect_to: '/dashboard'))
-
- @saml_builder = nil
- uri, saml_params = idp.login_request_for(binding: :http_post, relay_state: relay_state) do |builder|
- @saml_builder = builder
- end
-
- template = <<~ERB
- <!doctype html>
- <html>
- <head><title></title></head>
- <body style="background-color: pink;">
- <h2>Sending SAML Request (SP -> IdP)</h2>
- <textarea readonly="readonly" disabled="disabled" cols=225 rows=6><%=- @saml_builder.to_xml(pretty: true) -%></textarea>
-
- <form action="<%= uri %>" method="post">
- <%- saml_params.each do |(key, value)| -%>
- <input type="hidden" name="<%= key %>" value="<%= value %>" />
- <%- end -%>
- <input type="submit" value="Submit" />
- </form>
- </body>
- </html>
- ERB
- html = ERB.new(template, trim_mode: '-').result(binding)
- [200, { 'Content-Type' => "text/html" }, [html]]
- end
-
- def saml_assertions(request)
- sp = Saml::Kit.registry.metadata_for('http://localhost:8283/metadata.xml')
- saml_binding = sp.assertion_consumer_service_for(binding: :http_post)
- saml_response = saml_binding.deserialize(request.params)
- raise saml_response.errors unless saml_response.valid?
-
- template = <<~ERB
- <!doctype html>
- <html>
- <head><title></title></head>
- <body style="background-color: pink;">
- <h2>Received SAML Response</h2>
- <textarea readonly="readonly" disabled="disabled" cols=220 rows=40><%=- saml_response.to_xml(pretty: true) -%></textarea>
- </body>
- </html>
- ERB
- erb = ERB.new(template, trim_mode: '-')
- html = erb.result(binding)
- [200, { 'Content-Type' => "text/html" }, [html]]
- end
-end
-
-if __FILE__ == $0
- app = Rack::Builder.new do
- use Rack::Reloader
- run ServiceProvider.new
- end.to_app
-
- Rackup::Server.start(app: app, Port: ENV.fetch('PORT', 8283).to_i)
-end