/lib/authenticated_system.rb

https://gitlab.com/micro/noosfero · Ruby · 160 lines · 108 code · 10 blank · 42 comment · 12 complexity · 5d2beccaab680f979d2360a2c7ed0a93 MD5 · raw file

  1. module AuthenticatedSystem
  2. protected
  3. def self.included base
  4. if base < ActionController::Base
  5. base.around_filter :user_set_current
  6. base.before_filter :login_from_cookie
  7. end
  8. # Inclusion hook to make #current_user and #logged_in?
  9. # available as ActionView helper methods.
  10. base.helper_method :current_user, :logged_in?
  11. end
  12. # Returns true or false if the user is logged in.
  13. # Preloads @current_user with the user model if they're logged in.
  14. def logged_in?
  15. current_user != nil
  16. end
  17. # Accesses the current user from the session.
  18. def current_user
  19. @current_user ||= begin
  20. id = session[:user]
  21. user = User.where(id: id).first if id
  22. user.session = session if user
  23. User.current = user
  24. user
  25. end
  26. end
  27. # Store the given user in the session.
  28. def current_user=(new_user)
  29. if new_user.nil?
  30. session.delete(:user)
  31. else
  32. session[:user] = new_user.id
  33. new_user.session = session
  34. new_user.register_login
  35. end
  36. @current_user = User.current = new_user
  37. end
  38. # See impl. from http://stackoverflow.com/a/2513456/670229
  39. def user_set_current
  40. User.current = current_user
  41. yield
  42. ensure
  43. # to address the thread variable leak issues in Puma/Thin webserver
  44. User.current = nil
  45. end
  46. # Check if the user is authorized.
  47. #
  48. # Override this method in your controllers if you want to restrict access
  49. # to only a few actions or if you want to check if the user
  50. # has the correct rights.
  51. #
  52. # Example:
  53. #
  54. # # only allow nonbobs
  55. # def authorize?
  56. # current_user.login != "bob"
  57. # end
  58. def authorized?
  59. true
  60. end
  61. # Filter method to enforce a login requirement.
  62. #
  63. # To require logins for all actions, use this in your controllers:
  64. #
  65. # before_filter :login_required
  66. #
  67. # To require logins for specific actions, use this in your controllers:
  68. #
  69. # before_filter :login_required, :only => [ :edit, :update ]
  70. #
  71. # To skip this in a subclassed controller:
  72. #
  73. # skip_before_filter :login_required
  74. #
  75. def login_required
  76. username, passwd = get_auth_data
  77. if username && passwd
  78. self.current_user ||= User.authenticate(username, passwd) || nil
  79. end
  80. if logged_in? && authorized?
  81. true
  82. else
  83. if params[:require_login_popup]
  84. render :json => { :require_login_popup => true }
  85. else
  86. access_denied
  87. end
  88. end
  89. end
  90. # Redirect as appropriate when an access request fails.
  91. #
  92. # The default action is to redirect to the login screen.
  93. #
  94. # Override this method in your controllers if you want to have special
  95. # behavior in case the user is not authorized
  96. # to access the requested action. For example, a popup window might
  97. # simply close itself.
  98. def access_denied
  99. respond_to do |accepts|
  100. accepts.html do
  101. if request.xhr?
  102. render :text => _('Access denied'), :status => 401
  103. else
  104. store_location
  105. redirect_to :controller => '/account', :action => 'login'
  106. end
  107. end
  108. accepts.xml do
  109. headers["Status"] = "Unauthorized"
  110. headers["WWW-Authenticate"] = %(Basic realm="Web Password")
  111. render :text => "Could't authenticate you", :status => '401 Unauthorized'
  112. end
  113. end
  114. false
  115. end
  116. # Store the URI of the current request in the session.
  117. #
  118. # We can return to this location by calling #redirect_back_or_default.
  119. def store_location(location = request.url)
  120. session[:return_to] = location
  121. end
  122. # Redirect to the URI stored by the most recent store_location call or
  123. # to the passed default.
  124. def redirect_back_or_default(default)
  125. if session[:return_to]
  126. redirect_to(session.delete(:return_to))
  127. else
  128. redirect_to(default)
  129. end
  130. end
  131. # When called with before_filter :login_from_cookie will check for an :auth_token
  132. # cookie and log the user back in if apropriate
  133. def login_from_cookie
  134. return if cookies[:auth_token].blank? or logged_in?
  135. user = User.where(remember_token: cookies[:auth_token]).first
  136. self.current_user = user if user and user.remember_token?
  137. end
  138. private
  139. @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
  140. # gets BASIC auth info
  141. def get_auth_data
  142. auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
  143. auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
  144. return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
  145. end
  146. end