Commit 0436d46

mo khan <mo@mokhan.ca>
2025-03-26 21:27:30
feat: extract a layout helper for rendering html
1 parent 842a8ea
Changed files (1)
bin
bin/ui
@@ -11,7 +11,7 @@ gemfile do
   gem "rack", "~> 3.0"
   gem "rack-session", "~> 2.0"
   gem "rackup", "~> 2.0"
-  gem "saml-kit", "~> 1.0"
+  gem "saml-kit", "~> 1.0", git: "github.com:xlgmokha/saml-kit", branch: "main"
   gem "webrick", "~> 1.0"
 end
 
@@ -137,6 +137,21 @@ module HTTPHelpers
       [302, { 'Location' => "#{$scheme}://#{$host}#{location}" }, []]
     end
   end
+
+  def with_layout(bind)
+    template = <<~ERB
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <title></title>
+        </head>
+        <body style="background-color: pink;">
+          #{yield}
+        </body>
+      </html>
+    ERB
+    ERB.new(template, trim_mode: '-').result(bind)
+  end
 end
 
 class UI
@@ -154,29 +169,24 @@ class UI
     when Rack::GET
       case request.path
       when "/index.html"
-        template = <<~ERB
-          <!DOCTYPE html>
-          <html>
-            <head><title></title></head>
-            <body style="background-color: pink;">
-              <%- if current_user?(request) -%>
-                <a href="/groups.html">Groups</a>
-                <h1>Access Token</h1>
-                <pre><%= request.session[:access_token] %></pre>
-                <h1>ID Token</h1>
-                <pre><%= request.session[:id_token] %></pre>
-
-                <form action="/logout" method="post">
-                  <input type="submit" value="Logout" />
-                </form>
-              <%- else -%>
-                <a href="/saml/new">SAML Login</a>
-                <a href="/oidc/new">OIDC Login</a>
-              <%- end -%>
-            </body>
-          </html>
-        ERB
-        html = ERB.new(template, trim_mode: '-').result(binding)
+        html = with_layout(binding) do
+          <<~ERB
+            <%- if current_user?(request) -%>
+              <a href="/groups.html">Groups</a>
+              <h1>Access Token</h1>
+              <pre><%= request.session[:access_token] %></pre>
+              <h1>ID Token</h1>
+              <pre><%= request.session[:id_token] %></pre>
+
+              <form action="/logout" method="post">
+                <input type="submit" value="Logout" />
+              </form>
+            <%- else -%>
+              <a href="/saml/new">SAML Login</a>
+              <a href="/oidc/new">OIDC Login</a>
+            <%- end -%>
+          ERB
+        end
         return [200, { 'Content-Type' => "text/html" }, [html]]
       when "/groups.html"
         if current_user?(request)
@@ -269,13 +279,8 @@ class UI
     response = http.get("http://api.example.com:8080/groups.json")
     if response.code == "200"
       groups = JSON.parse(response.body, symbolize_names: true)
-      template = <<~ERB
-        <!DOCTYPE html>
-        <html>
-          <head>
-            <title></title>
-          </head>
-          <body style="background-color: pink;">
+      html = with_layout(binding) do
+        <<~ERB
             <a href="/index.html">Home</a>
             <a href="/groups.html">Groups</a>
             <form action="/logout" method="post">
@@ -303,10 +308,8 @@ class UI
               <%- end -%>
               </tbody>
             </table>
-          </body>
-        </html>
-      ERB
-      html = ERB.new(template, trim_mode: '-').result(binding)
+        ERB
+      end
       [200, { 'Content-Type' => "text/html" }, [html]]
     else
       [response.code, response.header, [response.body]]
@@ -322,35 +325,31 @@ class UI
     if response.code == "200"
       projects = JSON.parse(response.body, symbolize_names: true)
 
-      template = <<~ERB
-        <!DOCTYPE html>
-        <html>
-          <head>
-            <title></title>
-          </head>
-          <body style="background-color: pink;">
-            <a href="/index.html">Home</a>
-            <a href="/groups.html">Groups</a>
-            <table>
-              <thead>
-                <tr>
-                  <th>Name</th>
-                  <th>Group ID</th>
-                </tr>
-              </thead>
-              <tbody>
-              <%- projects.each do |project| -%>
-                <tr>
-                  <td><%= project[:name] %></td>
-                  <td><%= project[:group_id] %></td>
-                </tr>
-              <%- end -%>
-              </tbody>
-            </table>
-          </body>
-        </html>
-      ERB
-      html = ERB.new(template, trim_mode: '-').result(binding)
+      html = with_layout(binding) do
+        <<~ERB
+          <a href="/index.html">Home</a>
+          <a href="/groups.html">Groups</a>
+          <form action="/logout" method="post">
+            <input type="submit" value="Logout" />
+          </form>
+          <table>
+            <thead>
+              <tr>
+                <th>Name</th>
+                <th>Group ID</th>
+              </tr>
+            </thead>
+            <tbody>
+            <%- projects.each do |project| -%>
+              <tr>
+                <td><%= project[:name] %></td>
+                <td><%= project[:group_id] %></td>
+              </tr>
+            <%- end -%>
+            </tbody>
+          </table>
+        ERB
+      end
       [200, { 'Content-Type' => "text/html" }, [html]]
     else
       [response.code, response.header, [response.body]]
@@ -366,24 +365,19 @@ class UI
       @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 id="idp-form" action="<%= uri %>" method="post">
-            <%- saml_params.each do |(key, value)| -%>
-              <input type="hidden" name="<%= key %>" value="<%= value %>" />
-            <%- end -%>
-            <input id="submit-button" type="submit" value="Submit" />
-          </form>
-        </body>
-      </html>
-    ERB
-    html = ERB.new(template, trim_mode: '-').result(binding)
+    html = with_layout(binding) do
+      <<~ERB
+        <h2>Sending SAML Request (SP -> IdP)</h2>
+        <textarea readonly="readonly" disabled="disabled" cols=225 rows=6><%=- @saml_builder.to_xml(pretty: true) -%></textarea>
+
+        <form id="idp-form" action="<%= uri %>" method="post">
+          <%- saml_params.each do |(key, value)| -%>
+            <input type="hidden" name="<%= key %>" value="<%= value %>" />
+          <%- end -%>
+          <input id="submit-button" type="submit" value="Submit" />
+        </form>
+      ERB
+    end
     [200, { 'Content-Type' => "text/html" }, [html]]
   end
 
@@ -403,25 +397,18 @@ class UI
       request.session[:access_token] = tokens[:access_token]
       request.session[:refresh_token] = tokens[:access_token]
 
-      template = <<~ERB
-        <!doctype html>
-        <html>
-          <head>
-            <title></title>
-          </head>
-          <body style="background-color: pink;">
-            <a href="/index.html">Home</a>
-            <a href="/groups.html">Groups</a>
+      html = with_layout(binding) do
+        <<~ERB
+        <a href="/index.html">Home</a>
+        <a href="/groups.html">Groups</a>
 
-            <h2>Received SAML Response</h2>
-            <textarea readonly="readonly" disabled="disabled" cols=220 rows=40><%=- saml_response.to_xml(pretty: true) -%></textarea>
-            <pre id="raw-saml-response" style="display: none;"><%= request.params["SAMLResponse"] %></pre>
-            <pre id="xml-saml-assertion" style="display: none;"><%= saml_response.assertion.to_xml(pretty: true) %></pre>
-            <pre id="access-token" style="display: none;"><%= JSON.pretty_generate(request.session[:access_token]) %></pre>
-          </body>
-        </html>
-      ERB
-      html = ERB.new(template, trim_mode: '-').result(binding)
+        <h2>Received SAML Response</h2>
+        <textarea readonly="readonly" disabled="disabled" cols=220 rows=40><%=- saml_response.to_xml(pretty: true) -%></textarea>
+        <pre id="raw-saml-response" style="display: none;"><%= request.params["SAMLResponse"] %></pre>
+        <pre id="xml-saml-assertion" style="display: none;"><%= saml_response.assertion.to_xml(pretty: true) %></pre>
+        <pre id="access-token" style="display: none;"><%= JSON.pretty_generate(request.session[:access_token]) %></pre>
+        ERB
+      end
       [200, { 'Content-Type' => "text/html" }, [html]]
     else
       [response.code, response.header, [response.body]]