File: discovery_manager.rb

package info (click to toggle)
ruby-openid 2.9.2debian-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,300 kB
  • sloc: ruby: 17,952; javascript: 6,183; xml: 219; sh: 78; python: 30; makefile: 2
file content (150 lines) | stat: -rw-r--r-- 3,658 bytes parent folder | download | duplicates (4)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
module OpenID
  class Consumer

    # A set of discovered services, for tracking which providers have
    # been attempted for an OpenID identifier
    class DiscoveredServices
      attr_reader :current

      def initialize(starting_url, yadis_url, services)
        @starting_url = starting_url
        @yadis_url = yadis_url
        @services = services.dup
        @current = nil
      end

      def next
        @current = @services.shift
      end

      def for_url?(url)
        [@starting_url, @yadis_url].member?(url)
      end

      def started?
        !@current.nil?
      end

      def empty?
        @services.empty?
      end

      def to_session_value
        services = @services.map{|s| s.respond_to?(:to_session_value) ? s.to_session_value : s }
        current_val = @current.respond_to?(:to_session_value) ? @current.to_session_value : @current

        {
          'starting_url' => @starting_url,
          'yadis_url' => @yadis_url,
          'services' => services,
          'current' => current_val
        }
      end

      def ==(other)
        to_session_value == other.to_session_value
      end

      def self.from_session_value(value)
        return value unless value.is_a?(Hash)

        services = value['services'].map{|s| OpenID::OpenIDServiceEndpoint.from_session_value(s) }
        current = OpenID::OpenIDServiceEndpoint.from_session_value(value['current'])

        obj = self.new(value['starting_url'], value['yadis_url'], services)
        obj.instance_variable_set("@current", current)
        obj
      end
    end

    # Manages calling discovery and tracking which endpoints have
    # already been attempted.
    class DiscoveryManager
      def initialize(session, url, session_key_suffix=nil)
        @url = url

        @session = OpenID::Consumer::Session.new(session, DiscoveredServices)
        @session_key_suffix = session_key_suffix || 'auth'
      end

      def get_next_service
        manager = get_manager
        if !manager.nil? && manager.empty?
          destroy_manager
          manager = nil
        end

        if manager.nil?
          yadis_url, services = yield @url
          manager = create_manager(yadis_url, services)
        end

        if !manager.nil?
          service = manager.next
          store(manager)
        else
          service = nil
        end

        return service
      end

      def cleanup(force=false)
        manager = get_manager(force)
        if !manager.nil?
          service = manager.current
          destroy_manager(force)
        else
          service = nil
        end
        return service
      end

      protected

      def get_manager(force=false)
        manager = load
        if force || manager.nil? || manager.for_url?(@url)
          return manager
        else
          return nil
        end
      end

      def create_manager(yadis_url, services)
        manager = get_manager
        if !manager.nil?
          raise StandardError, "There is already a manager for #{yadis_url}"
        end
        if services.empty?
          return nil
        end
        manager = DiscoveredServices.new(@url, yadis_url, services)
        store(manager)
        return manager
      end

      def destroy_manager(force=false)
        if !get_manager(force).nil?
          destroy!
        end
      end

      def session_key
        'OpenID::Consumer::DiscoveredServices::' + @session_key_suffix
      end

      def store(manager)
        @session[session_key] = manager
      end

      def load
        @session[session_key]
      end

      def destroy!
        @session[session_key] = nil
      end
    end
  end
end