socialcast_ldap_integration 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ require "net/ldap"
2
+
3
+ module Socialcast
4
+ module LdapIntegration
5
+
6
+ NULL_FILTER = ::Net::LDAP::Filter.pres("objectclass")
7
+
8
+ def self.config
9
+ @@config
10
+ end
11
+
12
+ def self.config=(config)
13
+ @@config = config
14
+ end
15
+
16
+ def self.available?
17
+ return false unless self.config
18
+ return self.config['connections'].all? do |connection|
19
+ ['searcher_username', 'searcher_password', 'filter_string', 'base', 'host', 'port', 'ssl', 'map'].all? { |field| !connection[field].to_s.blank? } && self.required_fields.all? { |field| !connection['map'][field].blank? }
20
+ end
21
+ end
22
+
23
+ def self.scheduled?
24
+ self.config['enableLdapSchedule']
25
+ end
26
+
27
+ def self.mirror_lazily?
28
+ return true unless self.available?
29
+ !self.config['lazy_mirroring']
30
+ end
31
+
32
+ def self.schedule
33
+ config = Socialcast::LdapIntegration.config
34
+ cron_line = nil
35
+ if config['enableLdapSchedule']
36
+ case config['schedule']['checkFreq']
37
+ when 'Hourly'
38
+ cron_line = "0 */#{config['schedule']['hourInterval'].to_i} * * *"
39
+ when 'Daily'
40
+ cron_line = "0 #{config['schedule']['timeHour']} * * *"
41
+ when 'Weekly'
42
+ cron_line = "0 #{config['schedule']['timeHour']} * * #{config['schedule']['timeDay'].to_i + 1}"
43
+ end
44
+ end
45
+
46
+ return cron_line
47
+ end
48
+
49
+ # Connects to the Directory servers specified in the configuration.
50
+ #
51
+ # Supported Options:
52
+ # [:config] One or more LDAP connection specifications to connect to, overrides those in LdapIntegration.config
53
+ #
54
+ # Yields:
55
+ # - Connected and authenticated Net::LDAP object
56
+ # - Connection settings for the connection
57
+ def self.connect(options={})
58
+ raise ArgumentError.new("connect requires a block, see connect_to") unless block_given?
59
+ config = options[:config] ? [options[:config]] : Socialcast::LdapIntegration.config['connections']
60
+ config.each do |connection_options|
61
+ ldap = connect_to(connection_options)
62
+ yield(ldap, connection_options)
63
+ end
64
+ nil
65
+ end
66
+
67
+ def self.connect_to(connection_options)
68
+ searcher_username = connection_options['searcher_username']
69
+ searcher_password = connection_options['searcher_password']
70
+ base = connection_options['base']
71
+ host = connection_options['host']
72
+ port = connection_options['port']
73
+ ssl = connection_options['ssl']
74
+
75
+ ldap = Net::LDAP.new :host => host, :port => port, :base => base
76
+ ldap.auth searcher_username, searcher_password
77
+
78
+ return ldap
79
+ end
80
+
81
+ # Supported options
82
+ # [:filter] A string representing the search filter to use instead of the default search filter. Overrides any :auxiliary_filter option.
83
+ # [:auxiliary_filter] A string representing a search filter to use in addition to the defualt search filter. The two filters will be combined
84
+ # using a logical AND.
85
+ # [:limit] A number representing the maxmimum number of records to return, defaults to unlimited.
86
+ def self.search(options={})
87
+ options.reverse_merge! :connect_options => {}
88
+ Socialcast::LdapIntegration.connect(options.delete(:connect_options) || {}) do |ldap, connection|
89
+ ldap_search_options = self.construct_filter_for_search(connection, options.delete(:filter), options.delete(:auxiliary_filter))
90
+ ldap_search_options[:size] = options[:limit] if options.has_key?(:limit)
91
+ ldap.search(ldap_search_options) do |entry|
92
+ yield(entry, connection) if block_given?
93
+ end
94
+ end
95
+ end
96
+
97
+ # Supported options:
98
+ # [:identifying_field] the field which is being used to look up the user. Should probably be 'company_login' or 'email'.
99
+ # Defaults to 'company_login'
100
+ def self.authenticated?(identifier, password, options = {})
101
+ return false if password.blank?
102
+ identifying_field = options.reverse_merge!({:identifying_field => 'company_login'}).delete(:identifying_field)
103
+
104
+ Socialcast::LdapIntegration.connect do |ldap, connection|
105
+ connection_options = {}
106
+ connection_options.reverse_merge! options
107
+ base = connection['base']
108
+ host = connection['host']
109
+ port = connection['port']
110
+ map = connection['map']
111
+ connection_options.reverse_merge! :host => host, :port => port, :base => base, :filter => "#{map[identifying_field]}=#{identifier}", :password => password
112
+ return true if !ldap.bind_as(connection_options).blank?
113
+ end
114
+ return false
115
+ end
116
+
117
+ # Returns true if LDAP will manage the user field with the given name
118
+ def self.mirroring_field?(field)
119
+ string_field = field.to_s
120
+ self.available? && (["password", "email"].include?(string_field))
121
+ end
122
+
123
+
124
+ def self.fetch_account_info(identifier, options = {})
125
+ identifying_field = options.delete(:identifying_field) || 'company_login'
126
+ matched_account = nil
127
+
128
+ self.connect do |ldap, connection|
129
+ map = connection['map']
130
+ ldap.search(self.construct_filter_for_search(connection, nil, "#{map[identifying_field]}=#{identifier}")) do |entry, connection|
131
+ matched_account = entry
132
+ end
133
+ if matched_account
134
+ mapped_account_info = HashWithIndifferentAccess.new
135
+ map.each_pair do |sc_field, ldap_field|
136
+ mapped_account_info[sc_field] = matched_account[ldap_field].first unless ldap_field.blank?
137
+ end
138
+ return mapped_account_info
139
+ end
140
+ end
141
+ nil
142
+ end
143
+
144
+ protected
145
+ def self.construct_filter_for_search(connection, filter_options=nil, auxiliary_filter=nil)
146
+ unless filter_options
147
+ search_filter = connection['filter_string'].blank? ? NULL_FILTER : Net::LDAP::Filter.construct(connection['filter_string'])
148
+ search_filter = search_filter & Net::LDAP::Filter.construct(auxiliary_filter) if auxiliary_filter
149
+ return {:filter => search_filter}
150
+ end
151
+ {:filter => filter_options}
152
+ end
153
+ def self.required_fields
154
+ ['email', 'company_login']
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,5 @@
1
+ module Socialcast
2
+ module LdapIntegration
3
+ VERSION = "1.1.5"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: socialcast_ldap_integration
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 5
10
+ version: 1.1.5
11
+ platform: ruby
12
+ authors:
13
+ - Mitch Williams
14
+ - Sean Cashin
15
+ - Socialcast Inc.
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-02-15 00:00:00 -08:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: scashin133-net-ldap
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - "="
30
+ - !ruby/object:Gem::Version
31
+ hash: 19
32
+ segments:
33
+ - 0
34
+ - 1
35
+ - 4
36
+ version: 0.1.4
37
+ type: :runtime
38
+ version_requirements: *id001
39
+ description: "BLAH. "
40
+ email:
41
+ - mitch@socialcast.com
42
+ - sean@socialcast.com
43
+ - support@socialcast.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files: []
49
+
50
+ files:
51
+ - lib/socialcast/ldap_integration/version.rb
52
+ - lib/socialcast/ldap_integration.rb
53
+ has_rdoc: true
54
+ homepage: http://github.com/socialcast/socialcast_ldap_integration
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options: []
59
+
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project: socialcast_ldap_integration
83
+ rubygems_version: 1.4.2
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Provides support for connecting to and traversing LDAP trees.
87
+ test_files: []
88
+