authengine 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/README.md +86 -0
  5. data/Rakefile +31 -0
  6. data/app/assets/images/message_block/back.gif +0 -0
  7. data/app/assets/images/message_block/back_m.gif +0 -0
  8. data/app/assets/images/message_block/confirmation.gif +0 -0
  9. data/app/assets/images/message_block/confirmation_m.gif +0 -0
  10. data/app/assets/images/message_block/error.gif +0 -0
  11. data/app/assets/images/message_block/error_m.gif +0 -0
  12. data/app/assets/images/message_block/info.gif +0 -0
  13. data/app/assets/images/message_block/info_m.gif +0 -0
  14. data/app/assets/images/message_block/notice.gif +0 -0
  15. data/app/assets/images/message_block/notice_m.gif +0 -0
  16. data/app/assets/images/message_block/warn.gif +0 -0
  17. data/app/assets/images/message_block/warn_m.gif +0 -0
  18. data/app/assets/stylesheets/authengine.css +3 -0
  19. data/app/assets/stylesheets/message_block.css +45 -0
  20. data/app/controllers/authengine/accounts_controller.rb +56 -0
  21. data/app/controllers/authengine/action_roles_controller.rb +22 -0
  22. data/app/controllers/authengine/actions_controller.rb +17 -0
  23. data/app/controllers/authengine/roles_controller.rb +35 -0
  24. data/app/controllers/authengine/sessions_controller.rb +75 -0
  25. data/app/controllers/authengine/user_roles_controller.rb +55 -0
  26. data/app/controllers/authengine/useractions_controller.rb +17 -0
  27. data/app/controllers/authengine/users_controller.rb +137 -0
  28. data/app/helpers/application_helper.rb +2 -0
  29. data/app/helpers/authengine/users_helper.rb +11 -0
  30. data/app/helpers/roles_helper.rb +2 -0
  31. data/app/mailers/authengine/user_mailer.rb +53 -0
  32. data/app/models/action.rb +54 -0
  33. data/app/models/action_role.rb +29 -0
  34. data/app/models/authenticated_system.rb +179 -0
  35. data/app/models/authorized_system.rb +41 -0
  36. data/app/models/controller.rb +124 -0
  37. data/app/models/role.rb +71 -0
  38. data/app/models/session.rb +3 -0
  39. data/app/models/session_role.rb +17 -0
  40. data/app/models/user.rb +191 -0
  41. data/app/models/user_observer.rb +14 -0
  42. data/app/models/user_role.rb +4 -0
  43. data/app/models/useraction.rb +56 -0
  44. data/app/views/authengine/accounts/edit.html.erb +19 -0
  45. data/app/views/authengine/actions/create.html.erb +2 -0
  46. data/app/views/authengine/actions/destroy.html.erb +2 -0
  47. data/app/views/authengine/actions/edit.html.erb +80 -0
  48. data/app/views/authengine/actions/index.html.haml +26 -0
  49. data/app/views/authengine/actions/new.html.erb +2 -0
  50. data/app/views/authengine/actions/show.html.erb +8 -0
  51. data/app/views/authengine/actions/update.html.erb +11 -0
  52. data/app/views/authengine/admin/_show.html.haml +5 -0
  53. data/app/views/authengine/layouts/authengine.html.haml +9 -0
  54. data/app/views/authengine/roles/index.html.haml +12 -0
  55. data/app/views/authengine/roles/new.html.haml +15 -0
  56. data/app/views/authengine/roles/show.html.erb +8 -0
  57. data/app/views/authengine/sessions/new.html.haml +18 -0
  58. data/app/views/authengine/user_mailer/activation.html.erb +5 -0
  59. data/app/views/authengine/user_mailer/forgot_password.html.erb +3 -0
  60. data/app/views/authengine/user_mailer/message_to_admin.html.erb +2 -0
  61. data/app/views/authengine/user_mailer/reset_password.html.erb +1 -0
  62. data/app/views/authengine/user_mailer/signup_notification.html.erb +5 -0
  63. data/app/views/authengine/user_roles/edit.html.haml +10 -0
  64. data/app/views/authengine/user_roles/index.html.haml +14 -0
  65. data/app/views/authengine/user_roles/new.html.haml +8 -0
  66. data/app/views/authengine/useractions/_useraction.html.erb +6 -0
  67. data/app/views/authengine/useractions/index.html.erb +13 -0
  68. data/app/views/authengine/useractions/show.html.haml +14 -0
  69. data/app/views/authengine/useractions/update.html.erb +2 -0
  70. data/app/views/authengine/users/_no_privacy_policy.html.haml +1 -0
  71. data/app/views/authengine/users/_privacy_policy_example.html.haml +36 -0
  72. data/app/views/authengine/users/_user.html.haml +19 -0
  73. data/app/views/authengine/users/edit.html.haml +24 -0
  74. data/app/views/authengine/users/index.html.haml +10 -0
  75. data/app/views/authengine/users/new.html.haml +31 -0
  76. data/app/views/authengine/users/show.html.haml +19 -0
  77. data/app/views/authengine/users/signup.html.haml +52 -0
  78. data/authengine.gemspec +44 -0
  79. data/config/application.rb +1 -0
  80. data/config/routes.rb +43 -0
  81. data/db/migrate/20110320171029_create_authengine_tables.rb +90 -0
  82. data/db/migrate/20110924165900_add_parent_id_to_roles_table.rb +5 -0
  83. data/db/migrate/20110925202800_add_type_field_to_user_roles_table.rb +5 -0
  84. data/db/migrate/20111003074700_add_indexes_to_several_tables.rb +7 -0
  85. data/db/seeds.rb +7 -0
  86. data/lib/application_helper.rb +19 -0
  87. data/lib/authengine.rb +5 -0
  88. data/lib/authengine/engine.rb +44 -0
  89. data/lib/authengine/testing_support/factories/user_factory.rb +13 -0
  90. data/lib/authengine/version.rb +3 -0
  91. data/lib/rails/generators/authengine/authengine_generator.rb +160 -0
  92. data/lib/rails/generators/authengine/templates/initializer.rb +3 -0
  93. data/lib/rails/generators/authengine/templates/migration.rb +16 -0
  94. data/lib/rails/generators/authengine/templates/pre_populate_database.rb +20 -0
  95. data/lib/rails/generators/authengine/templates/schema.rb +69 -0
  96. data/lib/tasks/bootstrap.rake +29 -0
  97. data/spec/authengine_spec.rb +7 -0
  98. data/spec/dummy/.rspec +1 -0
  99. data/spec/dummy/Gemfile +3 -0
  100. data/spec/dummy/Rakefile +8 -0
  101. data/spec/dummy/app/assets/javascripts/jasmine_examples/Player.js +22 -0
  102. data/spec/dummy/app/assets/javascripts/jasmine_examples/Song.js +7 -0
  103. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  104. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  105. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  106. data/spec/dummy/config.ru +4 -0
  107. data/spec/dummy/config/application.rb +50 -0
  108. data/spec/dummy/config/boot.rb +10 -0
  109. data/spec/dummy/config/database.yml +22 -0
  110. data/spec/dummy/config/environment.rb +5 -0
  111. data/spec/dummy/config/environments/development.rb +26 -0
  112. data/spec/dummy/config/environments/production.rb +49 -0
  113. data/spec/dummy/config/environments/test.rb +35 -0
  114. data/spec/dummy/config/initializers/application.rb +1 -0
  115. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  116. data/spec/dummy/config/initializers/inflections.rb +10 -0
  117. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  118. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  119. data/spec/dummy/config/initializers/session_store.rb +8 -0
  120. data/spec/dummy/config/locales/en.yml +5 -0
  121. data/spec/dummy/config/routes.rb +3 -0
  122. data/spec/dummy/db/development.sqlite3 +0 -0
  123. data/spec/dummy/db/schema.rb +87 -0
  124. data/spec/dummy/lib/constants.rb +5 -0
  125. data/spec/dummy/log/development.log +117 -0
  126. data/spec/dummy/log/production.log +0 -0
  127. data/spec/dummy/log/server.log +0 -0
  128. data/spec/dummy/public/404.html +26 -0
  129. data/spec/dummy/public/422.html +26 -0
  130. data/spec/dummy/public/500.html +26 -0
  131. data/spec/dummy/public/favicon.ico +0 -0
  132. data/spec/dummy/public/javascripts/application.js +2 -0
  133. data/spec/dummy/public/javascripts/controls.js +965 -0
  134. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  135. data/spec/dummy/public/javascripts/effects.js +1123 -0
  136. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  137. data/spec/dummy/public/javascripts/rails.js +191 -0
  138. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  139. data/spec/dummy/script/rails +6 -0
  140. data/spec/dummy/spec/javascripts/helpers/.gitkeep +0 -0
  141. data/spec/dummy/spec/javascripts/helpers/SpecHelper.js +9 -0
  142. data/spec/dummy/spec/javascripts/jasmine_examples/PlayerSpec.js +58 -0
  143. data/spec/dummy/spec/javascripts/support/jasmine.yml +76 -0
  144. data/spec/generators/authengine_generator_spec.rb +11 -0
  145. data/spec/integration/navigation_spec.rb +9 -0
  146. data/spec/javascripts/spec.css +3 -0
  147. data/spec/javascripts/spec.js.coffee +2 -0
  148. data/spec/models/action_role_spec.rb +59 -0
  149. data/spec/models/authenticated_system_spec.rb +109 -0
  150. data/spec/models/role_spec.rb +38 -0
  151. data/spec/models/user_factory_spec.rb +7 -0
  152. data/spec/models/user_spec.rb +16 -0
  153. data/spec/requests/sessions_spec.rb +11 -0
  154. data/spec/spec_helper.rb +57 -0
  155. metadata +405 -0
@@ -0,0 +1,17 @@
1
+ class Authengine::UseractionsController < ApplicationController
2
+ layout 'authengine/layouts/authengine'
3
+
4
+ def show
5
+ eval("@useractions = Useraction#{params[:actionlog_id].to_i}.all.map{|u| u.becomes(Useraction)}")
6
+ @date = Useraction.date_of_index(params[:actionlog_id].to_i)
7
+ @sort_criteria = [ :created_at, :user_lastName ]
8
+ end
9
+
10
+ def index
11
+ dates = (0..4).to_a.inject({}) do |hash,index|
12
+ hash.merge!( index => Useraction.date_of_index(index) )
13
+ hash
14
+ end
15
+ @dates = dates.invert
16
+ end
17
+ end
@@ -0,0 +1,137 @@
1
+ # Besides the ususal REST actions, this controller contains show_self,
2
+ # edit_self and update_self actions.
3
+ # This permits access to be explicitly controlled via the
4
+ # check_permissions filter, distinguishing between actions on one's own
5
+ # model vs. actions on other users' models.
6
+ class Authengine::UsersController < ApplicationController
7
+ layout 'authengine/layouts/authengine'
8
+ #before_filter :not_logged_in_required, :only => [:new, :create]
9
+ #before_filter :login_required, :only => [:show, :edit, :update]
10
+ #before_filter :check_administrator_role, :only => [:index, :destroy, :enable]
11
+ #before_filter :user_or_current_user, :only => [:show, :edit, :update]
12
+
13
+ # activate is where a user with the correct activation code
14
+ # is redirected to, so they can enter passwords and login name
15
+ skip_before_filter :check_permissions, :only=>[:activate, :signup]
16
+
17
+ def index
18
+ @users = User.find(:all, :order=>"lastName, firstName")
19
+ end
20
+
21
+ def show
22
+ @user = User.find(params[:id])
23
+ end
24
+
25
+ def show_self
26
+ @user = current_user
27
+ render :template=>"users/show"
28
+ end
29
+
30
+ def new
31
+ @user = User.new
32
+ @user.user_roles.build
33
+ @roles = Role.all
34
+ end
35
+
36
+ # users may only be created by the administrator from the index page
37
+ def create
38
+ cookies.delete :auth_token
39
+ @user = User.new(params[:user])
40
+ @user.save!
41
+ redirect_to authengine_users_path
42
+ rescue ActiveRecord::RecordInvalid
43
+ flash[:error] = "There was a problem creating the user account."
44
+ @roles=Role.all
45
+ render :action => 'new'
46
+ end
47
+
48
+ def edit # edit a user profile with id given
49
+ @user = User.find(params[:id])
50
+ end
51
+
52
+ def edit_self # edit profile of current user
53
+ @user = current_user
54
+ render :template => 'users/edit'
55
+ end
56
+
57
+ # account was created by admin and now user is entering username/password
58
+ def activate
59
+ # TODO must remember to reset the session[:activation_code]
60
+ # looks as if setting current user (next line) was causing the user to be
61
+ # logged-in after activation
62
+ user = User.find_and_activate!(params[:activation_code])
63
+ if user.update_attributes(params[:user].slice(:login, :email, :password, :password_confirmation))
64
+ redirect_to root_path
65
+ else
66
+ flash[:warn] = user.errors.full_messages
67
+ redirect_to signup_authengine_user_path(user)
68
+ end
69
+ rescue User::ArgumentError
70
+ flash[:notice] = 'Activation code not found. Please ask the database administrator to create an account for you.'
71
+ redirect_to new_authengine_user_path
72
+ rescue User::ActivationCodeNotFound
73
+ flash[:notice] = 'Activation code not found. Please ask the database administrator to create an account for you.'
74
+ redirect_to new_authengine_user_path
75
+ rescue User::AlreadyActivated
76
+ flash[:notice] = 'Your account has already been activated. You can log in below.'
77
+ redirect_to login_path
78
+ end
79
+
80
+ def update_self
81
+ @user = User.find(current_user.id)
82
+ if @user.update_attributes(params[:user])
83
+ flash[:notice] = "Your profile has been updated"
84
+ redirect_to authengine_users_path
85
+ else
86
+ flash[:notice] = @user.errors.full_messages
87
+ render :action => 'edit'
88
+ end
89
+ end
90
+
91
+ def update
92
+ @user = User.find(params[:id])
93
+ if @user.update_attributes(params[:user])
94
+ flash[:notice] = "User updated"
95
+ redirect_to authengine_users_path
96
+ else
97
+ render :action => 'edit'
98
+ end
99
+ end
100
+
101
+ def destroy
102
+ @user = User.find(params[:id])
103
+ @user.destroy
104
+ redirect_to authengine_users_path
105
+ end
106
+
107
+ def disable
108
+ @user = User.find(params[:id])
109
+ unless @user.update_attribute(:enabled, false)
110
+ flash[:error] = "There was a problem disabling this user."
111
+ end
112
+ redirect_to authengine_users_path
113
+ end
114
+
115
+ def enable
116
+ @user = User.find(params[:id])
117
+ unless @user.update_attribute(:enabled, true)
118
+ flash[:error] = "There was a problem enabling this user."
119
+ end
120
+ redirect_to authengine_users_path
121
+ end
122
+
123
+ def signup
124
+ @user = User.find(params[:id])
125
+ end
126
+
127
+ protected
128
+
129
+ def user_or_current_user
130
+ if current_user.has_role?('administrator')
131
+ @user = User.find(params[:id])
132
+ else
133
+ @user = current_user
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,2 @@
1
+ ## Look in lib/application_helper.rb
2
+ ## I can't figure out how to get it included unless I put it that directory
@@ -0,0 +1,11 @@
1
+ module Authengine
2
+ module UsersHelper
3
+ #used in the edit template to create the correct link for saving
4
+ #this permits access control by having both "update self" action and
5
+ #an update action with id passed in url
6
+ def requested_user_or_self
7
+ @user == current_user ? update_self_authengine_user_url(@user) : authengine_user_url(@user, :method => :put)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ module RolesHelper
2
+ end
@@ -0,0 +1,53 @@
1
+ class Authengine::UserMailer < ActionMailer::Base
2
+ def signup_notification(user)
3
+ setup_email(user)
4
+ @subject += 'Please activate your new account'
5
+ @url = authengine_activate_url(:activation_code => user.activation_code)
6
+ mail( :to => @recipients,
7
+ :subject => @subject,
8
+ :date => @sent_on,
9
+ :from => @from
10
+ )
11
+ end
12
+
13
+ def activation(user)
14
+ setup_email(user)
15
+ @subject += 'Your account has been activated!'
16
+ @url = login_url
17
+ mail( :to => @recipients,
18
+ :subject => @subject,
19
+ :date => @sent_on,
20
+ :from => @from
21
+ )
22
+ end
23
+
24
+ def forgot_password(user)
25
+ setup_email(user)
26
+ @subject += 'You have requested to change your password'
27
+ @url = "http://#{SITE_URL}/authengine/reset_password/#{user.password_reset_code}"
28
+ end
29
+
30
+ def reset_password(user)
31
+ setup_email(user)
32
+ @subject += 'Your password has been reset.'
33
+ end
34
+
35
+ def message_to_admin(subject,body)
36
+ @admin = User.find_by_login('admin')
37
+ @recipients = @admin.email
38
+ @from = @admin.email
39
+ @subject = "#{APPLICATION_NAME || "database"} - "
40
+ @sent_on = Time.now
41
+ @subject += subject
42
+ @body = body
43
+ end
44
+
45
+ protected
46
+ def setup_email(user)
47
+ @recipients = "#{user.email}"
48
+ @from = "#{APPLICATION_NAME || "database"} Administrator<#{ADMIN_EMAIL}>"
49
+ @subject = "#{APPLICATION_NAME || "database"} - "
50
+ @sent_on = Time.now
51
+ @user = user
52
+ end
53
+ end
@@ -0,0 +1,54 @@
1
+ class Action < ActiveRecord::Base
2
+ belongs_to :controller
3
+
4
+ has_many :action_roles, :dependent=>:delete_all
5
+ has_many :roles, :through => :action_roles
6
+
7
+ # useractions are created in order to log actions performed by users, for recording in the log files
8
+ has_many :useractions
9
+ has_many :users, :through=>:useractions
10
+
11
+ delegate :controller_name, :to=>:controller
12
+
13
+ def <=>(other)
14
+ sort_field <=> other.sort_field
15
+ end
16
+
17
+ def sort_field
18
+ [controller_name, action_name]
19
+ end
20
+
21
+ def self.list
22
+ all_actions = Hash.new
23
+ all(:include=>:controller).each{|a|
24
+ all_actions[a.controller_name] ||= Hash.new
25
+ all_actions[a.controller_name][a.action_name] = a.id
26
+ }
27
+ all_actions
28
+ end
29
+
30
+ def self.update_table_for(cont,action_names)
31
+ remove_deleted_actions(cont, action_names)
32
+ add_new_actions(cont, action_names)
33
+ end
34
+
35
+ private
36
+ # passed-in a controller object and a list of action name strings parsed from the xx_controller.rb file
37
+ def self.remove_deleted_actions(cont, action_list)
38
+ # first see what actions are in the table but not in the action_list pulled from the passe-in controller file
39
+ controller_actions = cont.actions.map(&:action_name)
40
+ actions_to_delete = controller_actions.delete_if{|a_name| action_list.include?(a_name)}
41
+ # and delete them from the table
42
+ actions_to_delete.map! { |ad| find_by_controller_id_and_action_name(cont.id,ad).id }
43
+ destroy(actions_to_delete)
44
+ end
45
+
46
+ def self.add_new_actions(cont, action_list)
47
+ # then see what actions are in the action list pulled from the controllers, but not in the table
48
+ actions = cont.actions.map(&:action_name)
49
+ action_list.delete_if{ |al| actions.include?(al) }
50
+ # and add them to the table
51
+ action_list.each { |a| Action.create(:controller_id=>cont.id,:action_name=>a) } unless action_list.empty?
52
+ end
53
+
54
+ end
@@ -0,0 +1,29 @@
1
+ class ActionRole < ActiveRecord::Base
2
+ belongs_to :role
3
+ belongs_to :action
4
+
5
+ # this is the key database lookup for checking permissions
6
+ # returns true if there is at least one of the passed-in role ids
7
+ # which explicitly permits (i.e. the role has action_role associations)
8
+ # the specified controller and action
9
+ def self.permits_access_for(controller, action, role_ids)
10
+ joins([:role, :action => :controller ]).
11
+ where("roles.id" => role_ids).
12
+ where("actions.action_name" => action).
13
+ where("controllers.controller_name" => controller).
14
+ exists?
15
+ end
16
+
17
+ def self.assign_developer_access
18
+ developer_id = Role.developer_id
19
+ Action.all.each do |a|
20
+ find_or_create_by_action_id_and_role_id(a.id, developer_id)
21
+ end if developer_id
22
+ end
23
+
24
+ def self.bootstrap_access_for(role)
25
+ Action.all.each do |a|
26
+ find_or_create_by_action_id_and_role_id(a.id, role.id)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,179 @@
1
+ # AuthenticatedSystem is 'include'd in ActionController by the authengine engine
2
+ # see lib/authengine/engine.rb
3
+ module AuthenticatedSystem
4
+ protected
5
+ # Returns true or false if the user is logged in.
6
+ # Preloads @current_user with the user model if they're logged in.
7
+ def logged_in?
8
+ current_user != :false
9
+ end
10
+
11
+ # Accesses the current user from the session. Set it to :false if login fails
12
+ # so that future calls do not hit the database.
13
+ def current_user
14
+ @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie || :false)
15
+ end
16
+
17
+ # Store the given user id in the session.
18
+ def current_user=(new_user)
19
+ session[:user_id] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
20
+ @current_user = new_user || :false
21
+ end
22
+
23
+ # Check if the user is authorized
24
+ #
25
+ # Override this method in your controllers if you want to restrict access
26
+ # to only a few actions or if you want to check if the user
27
+ # has the correct rights.
28
+ #
29
+ # Example:
30
+ #
31
+ # # only allow nonbobs
32
+ # def authorized?
33
+ # current_user.login != "bob"
34
+ # end
35
+ def authorized?
36
+ logged_in?
37
+ end
38
+
39
+ # Filter method to enforce a login requirement.
40
+ #
41
+ # To require logins for all actions, use this in your controllers:
42
+ #
43
+ # before_filter :login_required
44
+ #
45
+ # To require logins for specific actions, use this in your controllers:
46
+ #
47
+ # before_filter :login_required, :only => [ :edit, :update ]
48
+ #
49
+ # To skip this in a subclassed controller:
50
+ #
51
+ # skip_before_filter :login_required
52
+ #
53
+ def login_required
54
+ authorized? || access_denied
55
+ end
56
+
57
+ def not_logged_in_required
58
+ !logged_in? || permission_denied
59
+ end
60
+
61
+ def check_role(role)
62
+ unless logged_in? && @current_user.has_role?(role)
63
+ if logged_in?
64
+ permission_denied
65
+ else
66
+ store_referer
67
+ access_denied
68
+ end
69
+ end
70
+ end
71
+
72
+ # Redirect as appropriate when an access request fails.
73
+ #
74
+ # The default action is to redirect to the login screen.
75
+ #
76
+ # Override this method in your controllers if you want to have special
77
+ # behavior in case the user is not authorized
78
+ # to access the requested action. For example, a popup window might
79
+ # simply close itself.
80
+ def access_denied
81
+ respond_to do |format|
82
+ format.html do
83
+ store_location
84
+ flash.now[:error] = "You must be logged in to access this feature."
85
+ logger.info "in access_denied: redirect to session::new"
86
+ redirect_to :controller => 'authengine/sessions', :action => 'new'
87
+ end
88
+ format.xml do
89
+ request_http_basic_authentication 'Web Password'
90
+ end
91
+ end
92
+ end
93
+
94
+ def permission_denied
95
+ # users will be redirected properly if they tried to access a
96
+ # resource they didn't have permission for.
97
+ # Its designed to redirect back to the last page they were on,
98
+ # unless that page is on another site or has
99
+ # the same address as the resource they're trying to access.
100
+ flash[:error] = "You don't have permission to complete that action."
101
+ respond_to do |format|
102
+ format.html do
103
+ domain_name = SITE_URL
104
+ http_referer = request.env["HTTP_REFERER"]
105
+
106
+ referer_domain = http_referer.match(/(http:\/\/)?([^\/]*)/)[2] unless http_referer.nil?
107
+ store_location
108
+ store_referer
109
+
110
+ if http_referer.nil?
111
+ session[:refer_to] = nil
112
+ redirect_to root_path
113
+ elsif referer_domain != domain_name # came from another site, go to root path
114
+ session[:refer_to] = nil
115
+ redirect_to root_path
116
+ elsif http_referer.match(session[:return_to]) #requesting the same page again go to root path
117
+ redirect_to root_path
118
+ else # go back to previous page
119
+ redirect_to_referer_or_default(root_path)
120
+ end
121
+ end
122
+ format.xml do
123
+ headers["Status"] = "Unauthorized"
124
+ headers["WWW-Authenticate"] = %(Basic realm="Web Password")
125
+ render :text => "You don't have permission to complete this action.", :status => '401 Unauthorized'
126
+ end
127
+ end
128
+ end
129
+
130
+ # Store the URI of the current request in the session.
131
+ # We can return to this location by calling #redirect_back_or_default.
132
+ def store_location
133
+ session[:return_to] = request.fullpath
134
+ end
135
+
136
+ def store_referer
137
+ session[:refer_to] = request.env["HTTP_REFERER"]
138
+ end
139
+
140
+ # Redirect to the URI stored by the most recent store_location call or
141
+ # to the passed default.
142
+ def redirect_back_or_default(default)
143
+ redirect_to(session[:return_to] || default)
144
+ session[:return_to] = nil
145
+ end
146
+
147
+ def redirect_to_referer_or_default(default)
148
+ redirect_to(session[:refer_to] || default)
149
+ session[:refer_to] = nil
150
+ end
151
+
152
+ # Inclusion hook to make #current_user and #logged_in?
153
+ # available as ActionView helper methods.
154
+ def self.included(base)
155
+ base.send :helper_method, :current_user, :logged_in? if base.respond_to? :helper_method
156
+ end
157
+
158
+ # Called from #current_user. First attempt to login by the user id stored in the session.
159
+ def login_from_session
160
+ self.current_user = User.find(session[:user_id]) if session[:user_id]
161
+ end
162
+
163
+ # Called from #current_user. Now, attempt to login by basic authentication information.
164
+ def login_from_basic_auth
165
+ authenticate_with_http_basic do |username, password|
166
+ self.current_user = User.authenticate(username, password)
167
+ end
168
+ end
169
+
170
+ # Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
171
+ def login_from_cookie
172
+ user = cookies[:auth_token] && User.find_by_remember_token(cookies[:auth_token])
173
+ if user && user.remember_token?
174
+ user.remember_me
175
+ cookies[:auth_token] = { :value => user.remember_token, :expires => user.remember_token_expires_at }
176
+ self.current_user = user
177
+ end
178
+ end
179
+ end