Welcome to mirror list, hosted at ThFree Co, Russian Federation.

logout_request.rb « cas3 « strategies « omniauth « lib « omniauth-cas3 « gems « vendor - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 72978227edb330fcfd7538d43706da139536287b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
module OmniAuth
  module Strategies
    class CAS3
      class LogoutRequest
        def initialize(strategy, request)
          @strategy, @request = strategy, request
        end

        def call(options = {})
          @options = options

          begin
            result = single_sign_out_callback.call(*logout_request)
          rescue StandardError => err
            return @strategy.fail! :logout_request, err
          else
            result = [200,{},'OK'] if result == true || result.nil?
          ensure
            return unless result

            # TODO: Why does ActionPack::Response return [status,headers,body]
            # when Rack::Response#new wants [body,status,headers]? Additionally,
            # why does Rack::Response differ in argument order from the usual
            # Rack-like [status,headers,body] array?
            return Rack::Response.new(result[2],result[0],result[1]).finish
          end
        end

      private

        def logout_request
          @logout_request ||= begin
            saml = parse_and_ensure_namespaces(@request.params['logoutRequest'])
            ns = saml.collect_namespaces
            name_id = saml.xpath('//saml:NameID', ns).text
            sess_idx = saml.xpath('//samlp:SessionIndex', ns).text
            inject_params(name_id:name_id, session_index:sess_idx)
            @request
          end
        end

        def parse_and_ensure_namespaces(logout_request_xml)
          doc = Nokogiri.parse(logout_request_xml)
          ns = doc.collect_namespaces
          if ns.include?('xmlns:samlp') && ns.include?('xmlns:saml')
            doc
          else
            add_namespaces(doc)
          end
        end

        def add_namespaces(logout_request_doc)
          root = logout_request_doc.root
          root.add_namespace('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol')
          root.add_namespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion\\')

          # In order to add namespaces properly we need to re-parse the document
          Nokogiri.parse(logout_request_doc.to_s)
        end

        def inject_params(new_params)
          new_params.each do |key, val|
            @request.update_param(key, val)
          end
        end

        def single_sign_out_callback
          @options[:on_single_sign_out]
        end
      end
    end
  end
end