whimsy-asf 0.0.24 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
data/asf.version CHANGED
@@ -1 +1 @@
1
- 0.0.24
1
+ 0.0.25
@@ -2,38 +2,22 @@ require 'wunderbar'
2
2
  require 'ldap'
3
3
 
4
4
  module ASF
5
-
6
5
  # determine whether or not the LDAP API can be used
7
6
  def self.init_ldap
8
7
  @ldap = nil
9
8
 
10
- config = ASF::Config.get(:ldap)
9
+ host = ASF::LDAP.host
11
10
 
12
- unless config
13
- conf = '/etc/ldap/ldap.conf'
14
- if File.exist? conf
15
- config = File.read(conf)[/^uri\s+(ldaps?:\/\/\S+?:\d+)/i, 1]
16
- end
17
- end
18
-
19
- unless config
20
- # https://www.pingmybox.com/dashboard?location=304
21
- config = %w(ldaps://ldap1-us-west.apache.org:636
22
- ldaps://ldap1-eu-central.apache.org:636
23
- ldaps://ldap2-us-west.apache.org:636
24
- ldaps://ldap1-us-east.apache.org:636).sample
25
- end
26
-
27
- Wunderbar.info "Connecting to LDAP server: #{config}"
11
+ Wunderbar.info "Connecting to LDAP server: #{host}"
28
12
 
29
13
  begin
30
- uri = URI.parse(config)
14
+ uri = URI.parse(host)
31
15
  if uri.scheme == 'ldaps'
32
- @ldap = LDAP::SSLConn.new(uri.host, uri.port)
16
+ @ldap = ::LDAP::SSLConn.new(uri.host, uri.port)
33
17
  else
34
- @ldap = LDAP::Conn.new(uri.host, uri.port)
18
+ @ldap = ::LDAP::Conn.new(uri.host, uri.port)
35
19
  end
36
- rescue LDAP::ResultError=>re
20
+ rescue ::LDAP::ResultError=>re
37
21
  Wunderbar.error "Error binding to LDAP server: message: ["+ re.message + "]"
38
22
  end
39
23
  end
@@ -47,7 +31,7 @@ module ASF
47
31
  "#{[attrs].flatten.join(' ')}"
48
32
 
49
33
  begin
50
- result = @ldap.search2(base, LDAP::LDAP_SCOPE_ONELEVEL, filter, attrs)
34
+ result = @ldap.search2(base, ::LDAP::LDAP_SCOPE_ONELEVEL, filter, attrs)
51
35
  rescue
52
36
  result = []
53
37
  end
@@ -176,6 +160,10 @@ module ASF
176
160
  ASF::Member.status[name] or ASF.members.include? self
177
161
  end
178
162
 
163
+ def asf_committer?
164
+ ASF::Group.new('committers').include? self
165
+ end
166
+
179
167
  def banned?
180
168
  not attrs['loginShell'] or attrs['loginShell'].include? "/usr/bin/false"
181
169
  end
@@ -212,6 +200,15 @@ module ASF
212
200
  ASF.search_one(base, filter, 'cn').flatten.map {|cn| find(cn)}
213
201
  end
214
202
 
203
+ def include?(person)
204
+ filter = "(&(cn=#{name})(memberUid=#{person.name}))"
205
+ if ASF.search_one(base, filter, 'cn').empty?
206
+ return false
207
+ else
208
+ return true
209
+ end
210
+ end
211
+
215
212
  def members
216
213
  ASF.search_one(base, "cn=#{name}", 'memberUid').flatten.
217
214
  map {|uid| Person.find(uid)}
@@ -243,4 +240,57 @@ module ASF
243
240
  map {|uid| Person.find uid[/uid=(.*?),/,1]}
244
241
  end
245
242
  end
243
+
244
+ module LDAP
245
+ # select LDAP host
246
+ def self.host
247
+ # try whimsy config
248
+ host = ASF::Config.get(:ldap)
249
+
250
+ # check system configuration
251
+ unless host
252
+ conf = '/etc/ldap/ldap.conf'
253
+ if File.exist? conf
254
+ host = File.read(conf)[/^uri\s+(ldaps?:\/\/\S+?:\d+)/i, 1]
255
+ end
256
+ end
257
+
258
+ # if all else fails, pick one at random
259
+ unless host
260
+ # https://www.pingmybox.com/dashboard?location=304
261
+ host = %w(ldaps://ldap1-us-west.apache.org:636
262
+ ldaps://ldap1-eu-central.apache.org:636
263
+ ldaps://ldap2-us-west.apache.org:636
264
+ ldaps://ldap1-us-east.apache.org:636).sample
265
+ end
266
+
267
+ host
268
+ end
269
+
270
+ # query and extract cert from openssl output
271
+ def self.cert
272
+ host = LDAP.host[%r{//(.*?)(/|$)}, 1]
273
+ query = "openssl s_client -connect #{host} -showcerts"
274
+ output = `#{query} < /dev/null 2> /dev/null`
275
+ output[/^-+BEGIN.*?\n-+END[^\n]+\n/m]
276
+ end
277
+
278
+ # update /etc/ldap.conf. Usage:
279
+ # sudo ruby -r whimsy/asf -e "ASF::LDAP.configure"
280
+ def self.configure
281
+ if not File.exist? "/etc/ldap/asf-ldap-client.pem"
282
+ File.write "/etc/ldap/asf-ldap-client.pem", self.cert
283
+ end
284
+
285
+ ldap_conf = '/etc/ldap/ldap.conf'
286
+ content = File.read(ldap_conf)
287
+ unless content.include? 'asf-ldap-client.pem'
288
+ content.gsub!(/^TLS_CACERT/, '# TLS_CACERT')
289
+ content += "TLS_CACERT /etc/ldap/asf-ldap-client.pem\n"
290
+ content += "uri #{LDAP.host}\n"
291
+ content += "base dc=apache,dc=org\n"
292
+ File.write(ldap_conf, content)
293
+ end
294
+ end
295
+ end
246
296
  end
@@ -17,7 +17,7 @@ module ASF
17
17
  }
18
18
 
19
19
  # decode HTTP authorization, when present
20
- def self.decode(env, user)
20
+ def self.decode(env)
21
21
  class << env; attr_accessor :user, :password; end
22
22
 
23
23
  if env['HTTP_AUTHORIZATION']
@@ -25,25 +25,25 @@ module ASF
25
25
  env.user, env.password = Base64.decode64(env['HTTP_AUTHORIZATION'][
26
26
  /^Basic ([A-Za-z0-9+\/=]+)$/,1]).split(':',2)
27
27
  else
28
- env.user = user
28
+ env.user = env['REMOTE_USER'] ||= ENV['USER'] || Etc.getpwuid.name
29
29
  end
30
+
31
+ ASF::Person.new(env.user)
30
32
  end
31
33
 
32
34
  # Simply 'use' the following class in config.ru to limit access
33
35
  # to the application to ASF committers
34
36
  class Committers < Rack::Auth::Basic
35
37
  def initialize(app)
36
- super(app, "ASF Members and Officers", &proc {})
38
+ super(app, "ASF Committers", &proc {})
37
39
  end
38
40
 
39
41
  def call(env)
40
42
  authorized = ( ENV['RACK_ENV'] == 'test' )
41
43
 
42
- user = env['REMOTE_USER'] ||= ENV['USER'] || Etc.getpwuid.name
43
- authorized ||= ASF::Person.new(user)
44
+ authorized ||= ASF::Auth.decode(env).asf_committer?
44
45
 
45
46
  if authorized
46
- ASF::Auth.decode(env, user)
47
47
  @app.call(env)
48
48
  else
49
49
  unauthorized
@@ -61,21 +61,19 @@ module ASF
61
61
  def call(env)
62
62
  authorized = ( ENV['RACK_ENV'] == 'test' )
63
63
 
64
- user = env['REMOTE_USER'] ||= ENV['USER'] || Etc.getpwuid.name
65
- person = ASF::Person.new(user)
64
+ person = ASF::Auth.decode(env)
66
65
 
67
- authorized ||= DIRECTORS[user]
66
+ authorized ||= DIRECTORS[env.user]
68
67
  authorized ||= person.asf_member?
69
68
  authorized ||= ASF.pmc_chairs.include? person
70
69
 
71
70
  if not authorized
72
71
  accounting = ASF::Authorization.new('pit').
73
72
  find {|group, list| group=='accounting'}
74
- authorized = (accounting and accounting.last.include? user)
73
+ authorized = (accounting and accounting.last.include? env.user)
75
74
  end
76
75
 
77
76
  if authorized
78
- ASF::Auth.decode(env, user)
79
77
  @app.call(env)
80
78
  else
81
79
  unauthorized
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: whimsy-asf
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.24
5
+ version: 0.0.25
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sam Ruby