Commit 75713bb

mo <mo@mokhan.ca>
2017-11-07 21:03:33
parse login url from IDP metadata.
1 parent 376f92c
airport/app/controllers/sessions_controller.rb
@@ -3,9 +3,9 @@ class SessionsController < ApplicationController
   skip_before_action :authenticate!
 
   def new
-    uri = URI.parse(Rails.configuration.x.authentication_host)
-    uri.path += "/session/new"
-    redirect_to uri.to_s + '?' + query_params
+    metadata = Saml::Kit.configuration.registry.metadata_for(DEFAULT_IDP_ENTITY_ID)
+    @uri = URI.parse(metadata.single_sign_on_service_for(binding: :http_redirect)[:location])
+    redirect_to @uri.to_s + '?' + query_params
   end
 
   def create
airport/app/views/sessions/new.html.erb
@@ -0,0 +1,9 @@
+<div class="container">
+  <div class="row">
+    <div class="col">
+      <%= form_tag url: "" do %>
+        <% submit_tag "Log In to IDP" %>
+      <% end %>
+    </div>
+  </div>
+</div>
airport/config/initializers/configuration.rb
@@ -1,1 +1,1 @@
-Rails.application.config.x.authentication_host = ENV['AUTHENTICATION_HOST']
+#Rails.application.config.x.authentication_host = ENV['AUTHENTICATION_HOST']
airport/config/initializers/saml_kit.rb
@@ -1,4 +1,5 @@
+DEFAULT_IDP_ENTITY_ID="#{ENV['AUTHENTICATION_HOST']}/metadata"
 Saml::Kit.configure do |configuration|
   configuration.issuer = ENV['ISSUER']
-  configuration.registry.register_url("#{ENV['AUTHENTICATION_HOST']}/metadata")
+  configuration.registry.register_url(DEFAULT_IDP_ENTITY_ID)
 end
airport/spec/controllers/sessions_controller_spec.rb
@@ -9,7 +9,7 @@ describe SessionsController do
     it 'generates a saml request and redirects to the auth host' do
       travel_to 1.seconds.from_now
       allow(Saml::Kit::Request).to receive(:encode).and_return(saml_request)
-      allow(Rails.configuration.x).to receive(:authentication_host).and_return(auth_host)
+      #allow(Rails.configuration.x).to receive(:authentication_host).and_return(auth_host)
 
       get :new
 
airport/.env
@@ -1,2 +1,2 @@
-AUTHENTICATION_HOST=http://localhost:4000/
+AUTHENTICATION_HOST=http://localhost:4000
 ISSUER=airport.dev
saml-kit/lib/saml/kit/identity_provider_metadata.rb
@@ -12,6 +12,13 @@ module Saml
         end
       end
 
+      def single_sign_on_service_for(binding:)
+        binding = Saml::Kit::Namespaces.binding_for(binding)
+        single_sign_on_services.find do |item|
+          item[:binding] == binding
+        end
+      end
+
       def attributes
         find_all("/md:EntityDescriptor/md:#{name}/saml:Attribute").map do |item|
           {
saml-kit/lib/saml/kit/namespaces.rb
@@ -25,8 +25,10 @@ module Saml
       def self.binding_for(binding)
         if :post == binding
           Namespaces::POST
-        else
+        elsif :http_redirect == binding
           Namespaces::HTTP_REDIRECT
+        else
+          nil
         end
       end
     end
saml-kit/spec/saml/identity_provider_metadata_spec.rb
@@ -221,4 +221,25 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
       expect(subject.errors[:base]).to include("invalid signature.")
     end
   end
+
+  describe "#single_sign_on_service_for" do
+    let(:url) { FFaker::Internet.http_url }
+
+    subject do
+      builder = Saml::Kit::IdentityProviderMetadata::Builder.new
+      builder.add_single_sign_on_service(FFaker::Internet.http_url, binding: :http_redirect)
+      builder.add_single_sign_on_service(url, binding: :post)
+      builder.build
+    end
+
+    it 'returns the binding that matches the requested' do
+      result = subject.single_sign_on_service_for(binding: :post)
+      expect(result[:binding]).to eql(Saml::Kit::Namespaces::POST)
+      expect(result[:location]).to eql(url)
+    end
+
+    it 'returns nil if the binding cannot be found' do
+      expect(subject.single_sign_on_service_for(binding: :soap)).to be_nil
+    end
+  end
 end