diff options
| author | mo khan <mo@mokhan.ca> | 2025-03-05 11:43:07 -0700 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-03-05 11:43:07 -0700 |
| commit | 20e152182f7137ae2c7f512d0cab1b3c846a4677 (patch) | |
| tree | 9c7a0ca1e52abc1d9fd2a77ec0c3b3b6166c4dd0 /bin/sp | |
| parent | 502228f90f6e3e7b03d2c3165a9b8b8f00e29dce (diff) | |
refactor: extract scheme and provide the appropriate nameid for saml transaction
Diffstat (limited to 'bin/sp')
| -rwxr-xr-x | bin/sp | 163 |
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 |
