Commit 40e0c16

mo <mo.khan@gmail.com>
2017-11-12 00:10:59
start to define API for logout.
1 parent a22c0f7
Changed files (7)
airport/app/controllers/sessions_controller.rb
@@ -5,8 +5,8 @@ class SessionsController < ApplicationController
   def new
     @saml_request = authentication_request
     @relay_state = JSON.generate(redirect_to: '/')
-    @uri = URI.parse(idp_metadata.single_sign_on_service_for(binding: :http_redirect)[:location])
-    @redirect_uri = redirect_url_for(@uri, @saml_request, @relay_state)
+    @post_uri = idp_metadata.single_sign_on_service_for(binding: :post)
+    @redirect_uri = redirect_url_for(@saml_request, @relay_state)
   end
 
   def create
@@ -17,11 +17,16 @@ class SessionsController < ApplicationController
     redirect_to dashboard_path
   end
 
+  def destroy
+    @uri = idp_metadata.single_logout_service_for(:post)
+    @logout_request = idp_metadata.build_logout_request.serialize
+  end
+
   private
 
-  def redirect_url_for(uri, saml_request, relay_state)
-    uri.to_s + '?' +
-      {
+  def redirect_url_for(saml_request, relay_state)
+    uri = idp_metadata.single_sign_on_service_for(binding: :http_redirect)
+    uri.to_s + '?' + {
       'SAMLRequest' => saml_request,
       'RelayState' => relay_state,
     }.map do |(x, y)|
@@ -30,7 +35,7 @@ class SessionsController < ApplicationController
   end
 
   def idp_metadata
-    Saml::Kit.configuration.registry.metadata_for(DEFAULT_IDP_ENTITY_ID)
+    Rails.configuration.x.idp_metadata
   end
 
   def authentication_request
airport/app/views/dashboard/show.html.erb
@@ -7,6 +7,7 @@
           <li> <%= attribute %> </li>
         <% end %>
       </ul>
+      <%= link_to "logout", session_path, method: :delete %>
     </div>
   </div>
 </div>
airport/app/views/sessions/new.html.erb
@@ -3,7 +3,7 @@
     <div class="col">
       <%= link_to "Log in to IDP via redirect", @redirect_uri %>
 
-      <%= form_tag @uri.to_s, method: :post do %>
+      <%= form_tag @post_uri.to_s, method: :post do %>
         <%= hidden_field_tag 'SAMLRequest', @saml_request %>
         <%= hidden_field_tag 'RelayState', @relay_state %>
         <%= submit_tag "Log In to IDP via POST" %>
airport/config/initializers/saml_kit.rb
@@ -1,6 +1,5 @@
-idp = nil
 Saml::Kit.configure do |configuration|
   configuration.issuer = ENV['ISSUER']
-  idp = configuration.registry.register_url("#{ENV['AUTHENTICATION_HOST']}/metadata")
+  Rails.configuration.x.idp_metadata =
+    configuration.registry.register_url("#{ENV['AUTHENTICATION_HOST']}/metadata")
 end
-DEFAULT_IDP_ENTITY_ID=idp.entity_id
airport/config/routes.rb
@@ -1,6 +1,6 @@
 Rails.application.routes.draw do
   get "dashboard", to: "dashboard#show", as: :dashboard
-  resource :session, only: [:new, :create]
+  resource :session, only: [:new, :create, :destroy]
   resource :metadata, only: [:show]
   resources :computers, only: [:index]
   root to: "sessions#new"
saml-kit/lib/saml/kit/identity_provider_metadata.rb
@@ -24,9 +24,10 @@ module Saml
 
       def single_sign_on_service_for(binding:)
         binding = Saml::Kit::Namespaces.binding_for(binding)
-        single_sign_on_services.find do |item|
+        result = single_sign_on_services.find do |item|
           item[:binding] == binding
         end
+        return result[:location] if result
       end
 
       def attributes
saml-kit/spec/saml/identity_provider_metadata_spec.rb
@@ -222,19 +222,19 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
   end
 
   describe "#single_sign_on_service_for" do
-    let(:url) { FFaker::Internet.http_url }
+    let(:post_url) { FFaker::Internet.http_url }
+    let(:redirect_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.add_single_sign_on_service(redirect_url, binding: :http_redirect)
+      builder.add_single_sign_on_service(post_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)
+      expect(subject.single_sign_on_service_for(binding: :post)).to eql(post_url)
+      expect(subject.single_sign_on_service_for(binding: :http_redirect)).to eql(redirect_url)
     end
 
     it 'returns nil if the binding cannot be found' do