File: configuration.rb

package info (click to toggle)
ruby-activeldap 4.0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,524 kB
  • ctags: 1,815
  • sloc: ruby: 17,656; makefile: 15
file content (187 lines) | stat: -rw-r--r-- 5,520 bytes parent folder | download
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
require "English"
require "cgi"
require 'uri'
begin
  require 'uri/ldaps'
rescue LoadError
  module URI
    class LDAPS < LDAP
      DEFAULT_PORT = 636
    end
    @@schemes['LDAPS'] = LDAPS
  end
end

module ActiveLdap
  # Configuration
  #
  # Configuration provides the default settings required for
  # ActiveLdap to work with your LDAP server. All of these
  # settings can be passed in at initialization time.
  module Configuration
    def self.included(base)
      base.extend(ClassMethods)
    end

    DEFAULT_CONFIG = {}
    DEFAULT_CONFIG[:host] = '127.0.0.1'
    DEFAULT_CONFIG[:port] = nil
    DEFAULT_CONFIG[:method] = :plain  # :ssl, :tls, :plain allowed

    DEFAULT_CONFIG[:bind_dn] = nil
    DEFAULT_CONFIG[:password_block] = nil
    DEFAULT_CONFIG[:password] = nil
    DEFAULT_CONFIG[:store_password] = true
    DEFAULT_CONFIG[:allow_anonymous] = true
    DEFAULT_CONFIG[:sasl_quiet] = true
    DEFAULT_CONFIG[:try_sasl] = false
    DEFAULT_CONFIG[:sasl_options] = nil
    # See http://www.iana.org/assignments/sasl-mechanisms
    DEFAULT_CONFIG[:sasl_mechanisms] = ["GSSAPI", "DIGEST-MD5",
                                        "CRAM-MD5", "EXTERNAL"]

    DEFAULT_CONFIG[:retry_limit] = 1
    DEFAULT_CONFIG[:retry_wait] = 1
    DEFAULT_CONFIG[:timeout] = 0 # in seconds; 0 <= Never timeout
    # Whether or not to retry on timeouts
    DEFAULT_CONFIG[:retry_on_timeout] = true
    DEFAULT_CONFIG[:follow_referrals] = true

    DEFAULT_CONFIG[:logger] = nil

    module ClassMethods
      @@defined_configurations = {}

      def default_configuration
        DEFAULT_CONFIG.dup
      end

      def ensure_configuration(config=nil)
        if config.nil?
          if defined?(LDAP_ENV)
            config = LDAP_ENV
          elsif defined?(Rails)
            config = Rails.env
          else
            config = {}
          end
        end

        if config.is_a?(Symbol) or config.is_a?(String)
          _config = configurations[config.to_s]
          unless _config
            raise ConnectionError,
                  _("%s connection is not configured") % config
          end
          config = _config
        end

        config
      end

      def configuration(key=nil)
        @@defined_configurations[key || active_connection_name]
      end

      def define_configuration(key, config)
        @@defined_configurations[key] = config
      end

      def defined_configurations
        @@defined_configurations
      end

      def remove_configuration_by_configuration(config)
        @@defined_configurations.delete_if {|key, value| value == config}
      end

      CONNECTION_CONFIGURATION_KEYS = [:uri, :base, :adapter]
      def remove_connection_related_configuration(config)
        config.reject do |key, value|
          CONNECTION_CONFIGURATION_KEYS.include?(key)
        end
      end

      def merge_configuration(user_configuration, target=self)
        configuration = default_configuration
        prepare_configuration(user_configuration).each do |key, value|
          case key
          when :base
            # Scrub before inserting
            target.base = value.gsub(/['}{#]/, '')
          when :scope, :ldap_scope
            if key == :ldap_scope
              message = _(":ldap_scope configuration option is deprecated. " \
                          "Use :scope instead.")
              ActiveSupport::Deprecation.warn(message)
            end
            target.scope = value
            configuration[:scope] = value
          else
            configuration[key] = value
          end
        end
        configuration
      end

      def prepare_configuration(configuration)
        configuration = configuration.symbolize_keys
        uri = configuration.delete(:uri)
        return configuration unless uri

        begin
          uri = URI.parse(uri)
        rescue URI::InvalidURIError
          raise ConfigurationError.new(_("invalid URI: %s") % uri)
        end
        unless uri.is_a?(URI::LDAP)
          raise ConfigurationError.new(_("not a LDAP URI: %s") % uri.to_s)
        end

        merger = URIConfigurationMerger.new(uri)
        merger.merge(configuration)
      end

      class URIConfigurationMerger
        def initialize(uri)
          @uri = uri
        end

        def merge(configuration)
          uri_configuration = {:port => @uri.port}
          uri_configuration[:host] = @uri.host if @uri.host
          uri_configuration[:base] = @uri.dn if @uri.dn
          extensions = parse_extensions
          bindname_extension = extensions["bindname"]
          if bindname_extension
            uri_configuration[:bind_dn] = bindname_extension[:value]
            uri_configuration[:allow_anonymous] = !bindname_extension[:critical]
          end
          uri_configuration[:scope] = @uri.scope if @uri.scope
          uri_configuration[:method] = :ssl if @uri.is_a?(URI::LDAPS)
          uri_configuration.merge(configuration)
        end

        private
        def parse_extensions
          extensions = {}
          (@uri.extensions || "").split(",").collect do |extension|
            name, value = extension.split("=", 2)
            case name
            when /\A!/
              critical = true
              name = $POSTMATCH
            else
              critical = false
            end
            extensions[name] = {
              :critical => critical,
              :value => CGI.unescape(value || ""),
            }
          end
          extensions
        end
      end
    end
  end
end