godfat-rubycas-server 0.8.0.20090918

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.
Files changed (84) hide show
  1. data/CHANGELOG.txt +1 -0
  2. data/History.txt +273 -0
  3. data/LICENSE.txt +504 -0
  4. data/Manifest.txt +83 -0
  5. data/PostInstall.txt +3 -0
  6. data/README.rdoc +26 -0
  7. data/Rakefile +115 -0
  8. data/bin/rubycas-server +13 -0
  9. data/bin/rubycas-server-ctl +9 -0
  10. data/config.example.yml +555 -0
  11. data/config.ru +38 -0
  12. data/config/hoe.rb +78 -0
  13. data/config/requirements.rb +15 -0
  14. data/custom_views.example.rb +11 -0
  15. data/lib/casserver.rb +58 -0
  16. data/lib/casserver/authenticators/active_directory_ldap.rb +11 -0
  17. data/lib/casserver/authenticators/authlogic_crypto_providers/aes256.rb +43 -0
  18. data/lib/casserver/authenticators/authlogic_crypto_providers/bcrypt.rb +92 -0
  19. data/lib/casserver/authenticators/authlogic_crypto_providers/md5.rb +34 -0
  20. data/lib/casserver/authenticators/authlogic_crypto_providers/sha1.rb +35 -0
  21. data/lib/casserver/authenticators/authlogic_crypto_providers/sha512.rb +50 -0
  22. data/lib/casserver/authenticators/base.rb +48 -0
  23. data/lib/casserver/authenticators/client_certificate.rb +46 -0
  24. data/lib/casserver/authenticators/google.rb +54 -0
  25. data/lib/casserver/authenticators/ldap.rb +147 -0
  26. data/lib/casserver/authenticators/ntlm.rb +88 -0
  27. data/lib/casserver/authenticators/open_id.rb +22 -0
  28. data/lib/casserver/authenticators/sql.rb +119 -0
  29. data/lib/casserver/authenticators/sql_authlogic.rb +92 -0
  30. data/lib/casserver/authenticators/sql_encrypted.rb +92 -0
  31. data/lib/casserver/authenticators/sql_md5.rb +19 -0
  32. data/lib/casserver/authenticators/sql_rest_auth.rb +71 -0
  33. data/lib/casserver/authenticators/test.rb +19 -0
  34. data/lib/casserver/cas.rb +322 -0
  35. data/lib/casserver/conf.rb +75 -0
  36. data/lib/casserver/controllers.rb +463 -0
  37. data/lib/casserver/load_picnic.rb +19 -0
  38. data/lib/casserver/localization.rb +82 -0
  39. data/lib/casserver/models.rb +265 -0
  40. data/lib/casserver/postambles.rb +174 -0
  41. data/lib/casserver/utils.rb +30 -0
  42. data/lib/casserver/version.rb +9 -0
  43. data/lib/casserver/views.rb +249 -0
  44. data/lib/rubycas-server.rb +1 -0
  45. data/lib/rubycas-server/version.rb +1 -0
  46. data/po/de_DE/rubycas-server.po +119 -0
  47. data/po/es_ES/rubycas-server.po +115 -0
  48. data/po/fr_FR/rubycas-server.po +116 -0
  49. data/po/ja_JP/rubycas-server.po +118 -0
  50. data/po/pl_PL/rubycas-server.po +115 -0
  51. data/po/pt_BR/rubycas-server.po +115 -0
  52. data/po/ru_RU/rubycas-server.po +110 -0
  53. data/po/rubycas-server.pot +104 -0
  54. data/public/themes/cas.css +121 -0
  55. data/public/themes/notice.png +0 -0
  56. data/public/themes/ok.png +0 -0
  57. data/public/themes/simple/bg.png +0 -0
  58. data/public/themes/simple/login_box_bg.png +0 -0
  59. data/public/themes/simple/logo.png +0 -0
  60. data/public/themes/simple/theme.css +28 -0
  61. data/public/themes/urbacon/bg.png +0 -0
  62. data/public/themes/urbacon/login_box_bg.png +0 -0
  63. data/public/themes/urbacon/logo.png +0 -0
  64. data/public/themes/urbacon/theme.css +33 -0
  65. data/public/themes/warning.png +0 -0
  66. data/resources/init.d.sh +58 -0
  67. data/script/console +10 -0
  68. data/script/destroy +14 -0
  69. data/script/generate +14 -0
  70. data/script/txt2html +82 -0
  71. data/setup.rb +1585 -0
  72. data/tasks/deployment.rake +34 -0
  73. data/tasks/environment.rake +7 -0
  74. data/tasks/localization.rake +11 -0
  75. data/tasks/website.rake +17 -0
  76. data/vendor/isaac_0.9.1/LICENSE +26 -0
  77. data/vendor/isaac_0.9.1/README +78 -0
  78. data/vendor/isaac_0.9.1/TODO +3 -0
  79. data/vendor/isaac_0.9.1/VERSIONS +3 -0
  80. data/vendor/isaac_0.9.1/crypt/ISAAC.rb +171 -0
  81. data/vendor/isaac_0.9.1/isaac.gemspec +39 -0
  82. data/vendor/isaac_0.9.1/setup.rb +596 -0
  83. data/vendor/isaac_0.9.1/test/TC_ISAAC.rb +76 -0
  84. metadata +200 -0
@@ -0,0 +1,75 @@
1
+
2
+ conf_defaults = {
3
+ :maximum_unused_login_ticket_lifetime => 5.minutes,
4
+ :maximum_unused_service_ticket_lifetime => 5.minutes, # CAS Protocol Spec, sec. 3.2.1 (recommended expiry time)
5
+ :maximum_session_lifetime => 1.month, # all tickets are deleted after this period of time
6
+ :log => {:file => 'casserver.log', :level => 'DEBUG'},
7
+ :uri_path => "/"
8
+ }
9
+
10
+ if $CONF
11
+ $CONF.merge_defaults(conf_defaults)
12
+ else
13
+ unless $APP_NAME && $APP_ROOT
14
+ raise "Can't load the RubyCAS-Server configuration because $APP_NAME and/or $APP_ROOT are not defined."
15
+ end
16
+
17
+ require 'picnic/conf'
18
+ $CONF = Picnic::Conf.new(conf_defaults)
19
+ $CONF.load_from_file($APP_NAME, $APP_ROOT)
20
+ end
21
+
22
+ $AUTH = []
23
+
24
+ unless $CONF[:authenticator]
25
+ err = "
26
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27
+
28
+ You have not yet defined an authenticator for your CAS server!
29
+ Please consult the documentation and make the necessary changes to
30
+ your config file.
31
+
32
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
33
+ "
34
+ raise Picnic::Conf::Error, err
35
+ end
36
+
37
+ begin
38
+ # attempt to instantiate the authenticator
39
+ if $CONF[:authenticator].instance_of? Array
40
+ $CONF[:authenticator].each { |authenticator| $AUTH << authenticator[:class].constantize}
41
+ else
42
+ $AUTH << $CONF[:authenticator][:class].constantize
43
+ end
44
+ rescue NameError
45
+ if $CONF[:authenticator].instance_of? Array
46
+ $CONF[:authenticator].each do |authenticator|
47
+ if !authenticator[:source].nil?
48
+ # config.yml explicitly names source file
49
+ require authenticator[:source]
50
+ else
51
+ # the authenticator class hasn't yet been loaded, so lets try to load it from the casserver/authenticators directory
52
+ auth_rb = authenticator[:class].underscore.gsub('cas_server/', '')
53
+ require 'casserver/'+auth_rb
54
+ end
55
+ $AUTH << authenticator[:class].constantize
56
+ end
57
+ else
58
+ if $CONF[:authenticator][:source]
59
+ # config.yml explicitly names source file
60
+ require $CONF[:authenticator][:source]
61
+ else
62
+ # the authenticator class hasn't yet been loaded, so lets try to load it from the casserver/authenticators directory
63
+ auth_rb = $CONF[:authenticator][:class].underscore.gsub('cas_server/', '')
64
+ require 'casserver/'+auth_rb
65
+ end
66
+
67
+ $AUTH << $CONF[:authenticator][:class].constantize
68
+ end
69
+ end
70
+
71
+ $CONF[:static] = {
72
+ :urls => "/themes",
73
+ :root => "#{$APP_ROOT}/public"
74
+ }
75
+
@@ -0,0 +1,463 @@
1
+ # The #.#.# comments (e.g. "2.1.3") refer to section numbers in the CAS protocol spec
2
+ # under http://www.ja-sig.org/products/cas/overview/protocol/index.html
3
+
4
+ require 'casserver/cas'
5
+
6
+ module CASServer::Controllers
7
+
8
+ # 2.1
9
+ class Login < R '/', '/login'
10
+ include CASServer::CAS
11
+
12
+ # 2.1.1
13
+ def get
14
+ CASServer::Utils::log_controller_action(self.class, input)
15
+
16
+ # make sure there's no caching
17
+ headers['Pragma'] = 'no-cache'
18
+ headers['Cache-Control'] = 'no-store'
19
+ headers['Expires'] = (Time.now - 1.year).rfc2822
20
+
21
+ # optional params
22
+ @service = clean_service_url(input['service'])
23
+ @renew = input['renew']
24
+ @gateway = input['gateway'] == 'true' || input['gateway'] == '1'
25
+
26
+ if tgc = cookies['tgt']
27
+ tgt, tgt_error = validate_ticket_granting_ticket(tgc)
28
+ end
29
+
30
+ if tgt and !tgt_error
31
+ @message = {:type => 'notice',
32
+ :message => _("You are currently logged in as '%s'. If this is not you, please log in below.") % tgt.username }
33
+ end
34
+
35
+ if input['redirection_loop_intercepted']
36
+ @message = {:type => 'mistake',
37
+ :message => _("The client and server are unable to negotiate authentication. Please try logging in again later.")}
38
+ end
39
+
40
+ begin
41
+ if @service
42
+ if !@renew && tgt && !tgt_error
43
+ st = generate_service_ticket(@service, tgt.username, tgt)
44
+ service_with_ticket = service_uri_with_ticket(@service, st)
45
+ $LOG.info("User '#{tgt.username}' authenticated based on ticket granting cookie. Redirecting to service '#{@service}'.")
46
+ return redirect(service_with_ticket, :status => 303) # response code 303 means "See Other" (see Appendix B in CAS Protocol spec)
47
+ elsif @gateway
48
+ $LOG.info("Redirecting unauthenticated gateway request to service '#{@service}'.")
49
+ return redirect(@service, :status => 303)
50
+ end
51
+ elsif @gateway
52
+ $LOG.error("This is a gateway request but no service parameter was given!")
53
+ @message = {:type => 'mistake',
54
+ :message => _("The server cannot fulfill this gateway request because no service parameter was given.")}
55
+ end
56
+ rescue URI::InvalidURIError
57
+ $LOG.error("The service '#{@service}' is not a valid URI!")
58
+ @message = {:type => 'mistake',
59
+ :message => _("The target service your browser supplied appears to be invalid. Please contact your system administrator for help.")}
60
+ end
61
+
62
+ lt = generate_login_ticket
63
+
64
+ $LOG.debug("Rendering login form with lt: #{lt}, service: #{@service}, renew: #{@renew}, gateway: #{@gateway}")
65
+
66
+ @lt = lt.ticket
67
+
68
+ #$LOG.debug(env)
69
+
70
+ # If the 'onlyLoginForm' parameter is specified, we will only return the
71
+ # login form part of the page. This is useful for when you want to
72
+ # embed the login form in some external page (as an IFRAME, or otherwise).
73
+ # The optional 'submitToURI' parameter can be given to explicitly set the
74
+ # action for the form, otherwise the server will try to guess this for you.
75
+ if input.has_key? 'onlyLoginForm'
76
+ if @env['HTTP_HOST']
77
+ guessed_login_uri = "http#{@env['HTTPS'] && @env['HTTPS'] == 'on' ? 's' : ''}://#{@env['REQUEST_URI']}#{self / '/login'}"
78
+ else
79
+ guessed_login_uri = nil
80
+ end
81
+
82
+ @form_action = input['submitToURI'] || guessed_login_uri
83
+
84
+ if @form_action
85
+ render :login_form
86
+ else
87
+ @status = 500
88
+ _("Could not guess the CAS login URI. Please supply a submitToURI parameter with your request.")
89
+ end
90
+ else
91
+ render :login
92
+ end
93
+ end
94
+
95
+ # 2.2
96
+ def post
97
+ CASServer::Utils::log_controller_action(self.class, input)
98
+
99
+ # 2.2.1 (optional)
100
+ @service = clean_service_url(input['service'])
101
+
102
+ # 2.2.2 (required)
103
+ @username = input['username']
104
+ @password = input['password']
105
+ @lt = input['lt']
106
+
107
+ # Remove leading and trailing widespace from username.
108
+ @username.strip! if @username
109
+
110
+ if @username && $CONF[:downcase_username]
111
+ $LOG.debug("Converting username #{@username.inspect} to lowercase because 'downcase_username' option is enabled.")
112
+ @username.downcase!
113
+ end
114
+
115
+ if error = validate_login_ticket(@lt)
116
+ @message = {:type => 'mistake', :message => error}
117
+ # generate another login ticket to allow for re-submitting the form
118
+ @lt = generate_login_ticket.ticket
119
+ @status = 401
120
+ return render(:login)
121
+ end
122
+
123
+ # generate another login ticket to allow for re-submitting the form after a post
124
+ @lt = generate_login_ticket.ticket
125
+
126
+ $LOG.debug("Logging in with username: #{@username}, lt: #{@lt}, service: #{@service}, auth: #{$AUTH}")
127
+
128
+ credentials_are_valid = false
129
+ extra_attributes = {}
130
+ successful_authenticator = nil
131
+ begin
132
+ auth_index = 0
133
+ $AUTH.each do |auth_class|
134
+ auth = auth_class.new
135
+
136
+ auth.configure($CONF.authenticator[auth_index].merge(:auth_index => auth_index))
137
+
138
+ credentials_are_valid = auth.validate(
139
+ :username => @username,
140
+ :password => @password,
141
+ :service => @service,
142
+ :request => @env
143
+ )
144
+ if credentials_are_valid
145
+ extra_attributes.merge!(auth.extra_attributes) unless auth.extra_attributes.blank?
146
+ successful_authenticator = auth
147
+ break
148
+ end
149
+
150
+ auth_index += 1
151
+ end
152
+ rescue CASServer::AuthenticatorError => e
153
+ $LOG.error(e)
154
+ @message = {:type => 'mistake', :message => e.to_s}
155
+ return render(:login)
156
+ end
157
+
158
+ if credentials_are_valid
159
+ $LOG.info("Credentials for username '#{@username}' successfully validated using #{successful_authenticator.class.name}.")
160
+ $LOG.debug("Authenticator provided additional user attributes: #{extra_attributes.inspect}") unless extra_attributes.blank?
161
+
162
+ # 3.6 (ticket-granting cookie)
163
+ tgt = generate_ticket_granting_ticket(@username, extra_attributes)
164
+ setup_cookie_tgt(tgt)
165
+
166
+ if @service.blank?
167
+ $LOG.info("Successfully authenticated user '#{@username}' at '#{tgt.client_hostname}'. No service param was given, so we will not redirect.")
168
+ @message = {:type => 'confirmation', :message => _("You have successfully logged in.")}
169
+ else
170
+ @st = generate_service_ticket(@service, @username, tgt)
171
+ begin
172
+ service_with_ticket = service_uri_with_ticket(@service, @st)
173
+
174
+ $LOG.info("Redirecting authenticated user '#{@username}' at '#{@st.client_hostname}' to service '#{@service}'")
175
+ return redirect(service_with_ticket, :status => 303) # response code 303 means "See Other" (see Appendix B in CAS Protocol spec)
176
+ rescue URI::InvalidURIError
177
+ $LOG.error("The service '#{@service}' is not a valid URI!")
178
+ @message = {:type => 'mistake',
179
+ :message => _("The target service your browser supplied appears to be invalid. Please contact your system administrator for help.")}
180
+ end
181
+ end
182
+ else
183
+ $LOG.warn("Invalid credentials given for user '#{@username}'")
184
+ @message = {:type => 'mistake', :message => _("Incorrect username or password.")}
185
+ @status = 401
186
+ end
187
+
188
+ render :login
189
+
190
+ private
191
+ def setup_cookie_tgt tgt
192
+ expires = if $CONF.maximum_session_lifetime
193
+ $CONF.maximum_session_lifetime.to_i.from_now
194
+ else
195
+ nil
196
+ end
197
+
198
+ cookies['tgt'] = if expires
199
+ expiry_info = " It will expire on #{expires}."
200
+
201
+ { :value => tgt.to_s,
202
+ :expires => expires }
203
+
204
+ else
205
+ expiry_info = " It will not expire."
206
+
207
+ tgt.to_s
208
+ end
209
+
210
+ $LOG.debug("Ticket granting cookie '#{cookies['tgt'].inspect}' granted to #{@username.inspect}. #{expiry_info}")
211
+ end
212
+ end
213
+ end
214
+
215
+ # 2.3
216
+ class Logout < R '/logout'
217
+ include CASServer::CAS
218
+
219
+ # 2.3.1
220
+ def get
221
+ CASServer::Utils::log_controller_action(self.class, input)
222
+
223
+ # The behaviour here is somewhat non-standard. Rather than showing just a blank
224
+ # "logout" page, we take the user back to the login page with a "you have been logged out"
225
+ # message, allowing for an opportunity to immediately log back in. This makes it
226
+ # easier for the user to log out and log in as someone else.
227
+ @service = clean_service_url(input['service'] || input['destination'])
228
+ @continue_url = input['url']
229
+
230
+ @gateway = input['gateway'] == 'true' || input['gateway'] == '1'
231
+
232
+ tgt = CASServer::Models::TicketGrantingTicket.find_by_ticket(cookies['tgt'])
233
+
234
+ cookies.delete 'tgt'
235
+
236
+ if tgt
237
+ CASServer::Models::TicketGrantingTicket.transaction do
238
+ $LOG.debug("Deleting Service/Proxy Tickets for '#{tgt}' for user '#{tgt.username}'")
239
+ tgt.granted_service_tickets.each do |st|
240
+ send_logout_notification_for_service_ticket(st) if $CONF.enable_single_sign_out
241
+ # TODO: Maybe we should do some special handling if send_logout_notification_for_service_ticket fails?
242
+ # (the above method returns false if the POST results in a non-200 HTTP response).
243
+ $LOG.debug "Deleting #{st.class.name.demodulize} #{st.ticket.inspect} for service #{st.service}."
244
+ st.destroy
245
+ end
246
+
247
+ pgts = CASServer::Models::ProxyGrantingTicket.find(:all,
248
+ :conditions => [CASServer::Models::Base.connection.quote_table_name(CASServer::Models::ServiceTicket.table_name)+".username = ?", tgt.username],
249
+ :include => :service_ticket)
250
+ pgts.each do |pgt|
251
+ $LOG.debug("Deleting Proxy-Granting Ticket '#{pgt}' for user '#{pgt.service_ticket.username}'")
252
+ pgt.destroy
253
+ end
254
+
255
+ $LOG.debug("Deleting #{tgt.class.name.demodulize} '#{tgt}' for user '#{tgt.username}'")
256
+ tgt.destroy
257
+ end
258
+
259
+ $LOG.info("User '#{tgt.username}' logged out.")
260
+ else
261
+ $LOG.warn("User tried to log out without a valid ticket-granting ticket.")
262
+ end
263
+
264
+ @message = {:type => 'confirmation', :message => _("You have successfully logged out.")}
265
+
266
+ @message[:message] +=_(" Please click on the following link to continue:") if @continue_url
267
+
268
+ @lt = generate_login_ticket
269
+
270
+ if @gateway && @service
271
+ redirect(@service, :status => 303)
272
+ elsif @continue_url
273
+ render :logout
274
+ else
275
+ render :login
276
+ end
277
+ end
278
+ end
279
+
280
+ # 2.4
281
+ class Validate < R '/validate'
282
+ include CASServer::CAS
283
+
284
+ # 2.4.1
285
+ def get
286
+ CASServer::Utils::log_controller_action(self.class, input)
287
+
288
+ # required
289
+ @service = clean_service_url(input['service'])
290
+ @ticket = input['ticket']
291
+ # optional
292
+ @renew = input['renew']
293
+
294
+ st, @error = validate_service_ticket(@service, @ticket)
295
+ @success = st && !@error
296
+
297
+ @username = st.username if @success
298
+
299
+ @status = CASServer::Controllers.response_status_from_error(@error) if @error
300
+
301
+ render :validate
302
+ end
303
+ end
304
+
305
+ # 2.5
306
+ class ServiceValidate < R '/serviceValidate'
307
+ include CASServer::CAS
308
+
309
+ # 2.5.1
310
+ def get
311
+ CASServer::Utils::log_controller_action(self.class, input)
312
+
313
+ # required
314
+ @service = clean_service_url(input['service'])
315
+ @ticket = input['ticket']
316
+ # optional
317
+ @pgt_url = input['pgtUrl']
318
+ @renew = input['renew']
319
+
320
+ st, @error = validate_service_ticket(@service, @ticket)
321
+ @success = st && !@error
322
+
323
+ if @success
324
+ @username = st.username
325
+ if @pgt_url
326
+ pgt = generate_proxy_granting_ticket(@pgt_url, st)
327
+ @pgtiou = pgt.iou if pgt
328
+ end
329
+ @extra_attributes = st.granted_by_tgt.extra_attributes || {}
330
+ end
331
+
332
+ @status = CASServer::Controllers.response_status_from_error(@error) if @error
333
+
334
+ render :service_validate
335
+ end
336
+ end
337
+
338
+ # 2.6
339
+ class ProxyValidate < R '/proxyValidate'
340
+ include CASServer::CAS
341
+
342
+ # 2.6.1
343
+ def get
344
+ CASServer::Utils::log_controller_action(self.class, input)
345
+
346
+ # required
347
+ @service = clean_service_url(input['service'])
348
+ @ticket = input['ticket']
349
+ # optional
350
+ @pgt_url = input['pgtUrl']
351
+ @renew = input['renew']
352
+
353
+ @proxies = []
354
+
355
+ t, @error = validate_proxy_ticket(@service, @ticket)
356
+ @success = t && !@error
357
+
358
+ @extra_attributes = {}
359
+ if @success
360
+ @username = t.username
361
+
362
+ if t.kind_of? CASServer::Models::ProxyTicket
363
+ @proxies << t.granted_by_pgt.service_ticket.service
364
+ end
365
+
366
+ if @pgt_url
367
+ pgt = generate_proxy_granting_ticket(@pgt_url, t)
368
+ @pgtiou = pgt.iou if pgt
369
+ end
370
+
371
+ @extra_attributes = t.granted_by_tgt.extra_attributes || {}
372
+ end
373
+
374
+ @status = CASServer::Controllers.response_status_from_error(@error) if @error
375
+
376
+ render :proxy_validate
377
+ end
378
+ end
379
+
380
+ class Proxy < R '/proxy'
381
+ include CASServer::CAS
382
+
383
+ # 2.7
384
+ def get
385
+ CASServer::Utils::log_controller_action(self.class, input)
386
+
387
+ # required
388
+ @ticket = input['pgt']
389
+ @target_service = input['targetService']
390
+
391
+ pgt, @error = validate_proxy_granting_ticket(@ticket)
392
+ @success = pgt && !@error
393
+
394
+ if @success
395
+ @pt = generate_proxy_ticket(@target_service, pgt)
396
+ end
397
+
398
+ @status = CASServer::Controllers.response_status_from_error(@error) if @error
399
+
400
+ render :proxy
401
+ end
402
+ end
403
+
404
+ # Controller for obtaining login tickets.
405
+ # This is useful when you want to build a custom login form located on a
406
+ # remote server. Your form will have to include a valid login ticket
407
+ # value, and this can be fetched from the CAS server using this controller'
408
+ # POST method.
409
+ class LoginTicketDispenser < R '/loginTicket'
410
+ include CASServer::CAS
411
+
412
+ def get
413
+ CASServer::Utils::log_controller_action(self.class, input)
414
+ $LOG.error("Tried to use login ticket dispenser with get method!")
415
+ @status = 422
416
+ _("To generate a login ticket, you must make a POST request.")
417
+ end
418
+
419
+ # Renders a page with a login ticket (and only the login ticket)
420
+ # in the response body.
421
+ def post
422
+ CASServer::Utils::log_controller_action(self.class, input)
423
+ lt = generate_login_ticket
424
+
425
+ $LOG.debug("Dispensing login ticket #{lt} to host #{(@env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR']).inspect}")
426
+
427
+ @lt = lt.ticket
428
+
429
+ @lt
430
+ end
431
+ end
432
+
433
+ # class Themes < R '/themes/(.+)'
434
+ # MIME_TYPES = {'.css' => 'text/css', '.js' => 'text/javascript',
435
+ # '.jpg' => 'image/jpeg'}
436
+ # PATH = $CONF.themes_dir || File.expand_path(File.dirname(__FILE__))+'/../themes'
437
+ #
438
+ # def get(path)
439
+ # headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain"
440
+ # unless path.include? ".." # prevent directory traversal attacks
441
+ # headers['X-Sendfile'] = "#{PATH}/#{path}"
442
+ # data = File.read(headers['X-Sendfile'])
443
+ # headers['Content-Length'] = data.size.to_s # Rack Camping adapter chokes without this
444
+ # return data
445
+ # else
446
+ # status = "403"
447
+ # "403 - Invalid path"
448
+ # end
449
+ # end
450
+ # end
451
+
452
+ def response_status_from_error(error)
453
+ case error.code.to_s
454
+ when /^INVALID_/, 'BAD_PGT'
455
+ 422
456
+ when 'INTERNAL_ERROR'
457
+ 500
458
+ else
459
+ 500
460
+ end
461
+ end
462
+ module_function :response_status_from_error
463
+ end