Commit 53a7bd1

mo khan <mo@mokhan.ca>
2025-03-18 20:25:16
refactor: extract an OAuth::Client class to all the generation of dynamic client registration
1 parent a255f98
Changed files (1)
bin
bin/ui
@@ -38,20 +38,45 @@ Saml::Kit.configure do |x|
   x.logger = Logger.new("/dev/stderr")
 end
 
-class UI
-  def metadata
-    xml = Saml::Kit::Metadata.build_xml do |builder|
-      builder.embed_signature = false
-      builder.contact_email = 'ui@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("#{$scheme}://#{$host}/saml/assertions", binding: :http_post)
+module OAuth
+  class Client
+    attr_reader :client_id, :client_secret, :http
+
+    def initialize(client_id, client_secret)
+      @client_id = client_id
+      @client_secret = client_secret
+      @http = Net::Hippie::Client.new(headers: ::Net::Hippie::Client::DEFAULT_HEADERS.merge({
+        'Authorization' => Net::Hippie.basic_auth(client_id, client_secret),
+      }))
+    end
+
+    def authorize_uri
+      "http://#{$idp_host}/oauth/authorize?client_id=#{client_id}&state=example&redirect_uri=#{$scheme}://#{$host}/oauth/callback&response_type=code&response_mode=query&scope=openid"
+    end
+
+    def with_http
+      http.with_retry do |client|
+        yield client
       end
     end
 
-    [200, { 'Content-Type' => "application/samlmetadata+xml" }, [xml]]
+    def exchange(grant_type:, code:)
+      with_http do |client|
+        client.post("http://#{$idp_host}/oauth/token", body: {
+          grant_type: grant_type,
+          code: code,
+          code_verifier: "not_implemented"
+        })
+      end
+    end
+  end
+end
+
+class UI
+  attr_reader :oauth_client
+
+  def initialize(oauth_client)
+    @oauth_client = oauth_client
   end
 
   def call(env)
@@ -62,7 +87,7 @@ class UI
       when "/oauth/callback"
         return oauth_callback(Rack::Request.new(env))
       when "/oidc/new"
-        return redirect_to("http://#{$idp_host}/oauth/authorize?client_id=service-provider&state=example&redirect_uri=#{$scheme}://#{$host}/oauth/callback&response_type=code&response_mode=query&scope=openid")
+        return redirect_to(oauth_client.authorize_uri)
       when "/saml/metadata.xml"
         return metadata
       when "/saml/new"
@@ -83,6 +108,22 @@ class UI
 
   private
 
+  def metadata
+    xml = Saml::Kit::Metadata.build_xml do |builder|
+      builder.embed_signature = false
+      builder.contact_email = 'ui@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("#{$scheme}://#{$host}/saml/assertions", binding: :http_post)
+      end
+    end
+
+    [200, { 'Content-Type' => "application/samlmetadata+xml" }, [xml]]
+  end
+
+
   def not_found
     [404, { 'X-Backend-Server' => 'UI' }, []]
   end
@@ -96,18 +137,7 @@ class UI
   end
 
   def oauth_callback(request)
-    client = Net::Hippie::Client.new
-    response = client.with_retry do |x|
-      client.post(
-        "http://#{$idp_host}/oauth/token",
-        headers: { 'Authorization' => Net::Hippie.basic_auth('client_id', 'secret') },
-        body: {
-          grant_type: "authorization_code",
-          code: request.params['code'],
-          code_verifier: "not_implemented"
-        }
-      )
-    end
+    response = oauth_client.exchange(grant_type: "authorization_code", code: request.params['code'])
     [response.code, response.header, [response.body]]
   end
 
@@ -170,7 +200,7 @@ if __FILE__ == $0
     use Rack::Reloader
     use Rack::Session::Cookie, { domain: $host.split(":", 2)[0], path: "/", secret: SecureRandom.hex(64) }
 
-    run UI.new
+    run UI.new(::OAuth::Client.new('client_id', 'client_secret'))
   end.to_app
 
   Rackup::Server.start(app: app, Port: $port)