cops 0.2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +113 -0
  3. data/Rakefile +95 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/blue_light_special/confirmations_controller.rb +76 -0
  6. data/app/controllers/blue_light_special/impersonations_controller.rb +44 -0
  7. data/app/controllers/blue_light_special/passwords_controller.rb +93 -0
  8. data/app/controllers/blue_light_special/sessions_controller.rb +76 -0
  9. data/app/controllers/blue_light_special/users_controller.rb +85 -0
  10. data/app/models/blue_light_special_mailer.rb +28 -0
  11. data/app/models/deliver_change_password_job.rb +19 -0
  12. data/app/models/deliver_welcome_job.rb +17 -0
  13. data/app/models/generic_mailer.rb +31 -0
  14. data/app/models/impersonation.rb +26 -0
  15. data/app/models/mimi_mailer.rb +30 -0
  16. data/app/views/generic_mailer/change_password.html.erb +9 -0
  17. data/app/views/generic_mailer/confirmation.html.erb +5 -0
  18. data/app/views/generic_mailer/welcome.html.erb +1 -0
  19. data/app/views/impersonations/index.html.erb +5 -0
  20. data/app/views/passwords/edit.html.erb +23 -0
  21. data/app/views/passwords/new.html.erb +15 -0
  22. data/app/views/sessions/new.html.erb +48 -0
  23. data/app/views/users/_form.html.erb +21 -0
  24. data/app/views/users/edit.html.erb +6 -0
  25. data/app/views/users/new.html.erb +6 -0
  26. data/app/views/users/show.html.erb +8 -0
  27. data/generators/blue_light_special/USAGE +1 -0
  28. data/generators/blue_light_special/blue_light_special_generator.rb +78 -0
  29. data/generators/blue_light_special/lib/insert_commands.rb +33 -0
  30. data/generators/blue_light_special/lib/rake_commands.rb +22 -0
  31. data/generators/blue_light_special/templates/README +20 -0
  32. data/generators/blue_light_special/templates/application.html.erb +50 -0
  33. data/generators/blue_light_special/templates/blue_light_special.rb +25 -0
  34. data/generators/blue_light_special/templates/blue_light_special.yml +45 -0
  35. data/generators/blue_light_special/templates/factories.rb +23 -0
  36. data/generators/blue_light_special/templates/migrations/create_users.rb +24 -0
  37. data/generators/blue_light_special/templates/migrations/update_users.rb +44 -0
  38. data/generators/blue_light_special/templates/style.css +31 -0
  39. data/generators/blue_light_special/templates/user.rb +3 -0
  40. data/generators/blue_light_special/templates/xd_receiver.html +10 -0
  41. data/generators/blue_light_special/templates/xd_receiver_ssl.html +10 -0
  42. data/generators/blue_light_special_admin/USAGE +1 -0
  43. data/generators/blue_light_special_admin/blue_light_special_admin_generator.rb +30 -0
  44. data/generators/blue_light_special_admin/lib/insert_commands.rb +33 -0
  45. data/generators/blue_light_special_admin/templates/README +16 -0
  46. data/generators/blue_light_special_admin/templates/app/controllers/admin/admin_controller.rb +14 -0
  47. data/generators/blue_light_special_admin/templates/app/controllers/admin/users_controller.rb +52 -0
  48. data/generators/blue_light_special_admin/templates/app/views/admin/users/_form.html.erb +25 -0
  49. data/generators/blue_light_special_admin/templates/app/views/admin/users/edit.html.erb +6 -0
  50. data/generators/blue_light_special_admin/templates/app/views/admin/users/index.html.erb +7 -0
  51. data/generators/blue_light_special_admin/templates/app/views/admin/users/new.html.erb +6 -0
  52. data/generators/blue_light_special_admin/templates/app/views/admin/users/show.html.erb +10 -0
  53. data/generators/blue_light_special_admin/templates/test/integration/admin/users_test.rb +201 -0
  54. data/generators/blue_light_special_tests/USAGE +1 -0
  55. data/generators/blue_light_special_tests/blue_light_special_tests_generator.rb +21 -0
  56. data/generators/blue_light_special_tests/templates/README +58 -0
  57. data/generators/blue_light_special_tests/templates/test/integration/edit_profile_test.rb +35 -0
  58. data/generators/blue_light_special_tests/templates/test/integration/facebook_test.rb +61 -0
  59. data/generators/blue_light_special_tests/templates/test/integration/impersonation_test.rb +39 -0
  60. data/generators/blue_light_special_tests/templates/test/integration/password_reset_test.rb +128 -0
  61. data/generators/blue_light_special_tests/templates/test/integration/sign_in_test.rb +66 -0
  62. data/generators/blue_light_special_tests/templates/test/integration/sign_out_test.rb +28 -0
  63. data/generators/blue_light_special_tests/templates/test/integration/sign_up_test.rb +47 -0
  64. data/lib/blue_light_special/authentication.rb +138 -0
  65. data/lib/blue_light_special/configuration.rb +34 -0
  66. data/lib/blue_light_special/extensions/errors.rb +6 -0
  67. data/lib/blue_light_special/extensions/rescue.rb +5 -0
  68. data/lib/blue_light_special/routes.rb +62 -0
  69. data/lib/blue_light_special/user.rb +279 -0
  70. data/lib/blue_light_special.rb +7 -0
  71. data/rails/init.rb +4 -0
  72. data/shoulda_macros/blue_light_special.rb +244 -0
  73. data/test/controllers/passwords_controller_test.rb +184 -0
  74. data/test/controllers/sessions_controller_test.rb +129 -0
  75. data/test/controllers/users_controller_test.rb +57 -0
  76. data/test/models/blue_light_special_mailer_test.rb +52 -0
  77. data/test/models/impersonation_test.rb +25 -0
  78. data/test/models/user_test.rb +213 -0
  79. data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
  80. data/test/rails_root/app/controllers/application_controller.rb +6 -0
  81. data/test/rails_root/app/helpers/application_helper.rb +5 -0
  82. data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
  83. data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
  84. data/test/rails_root/config/boot.rb +110 -0
  85. data/test/rails_root/config/environment.rb +22 -0
  86. data/test/rails_root/config/environments/development.rb +19 -0
  87. data/test/rails_root/config/environments/production.rb +1 -0
  88. data/test/rails_root/config/environments/test.rb +37 -0
  89. data/test/rails_root/config/initializers/inflections.rb +10 -0
  90. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  91. data/test/rails_root/config/initializers/requires.rb +13 -0
  92. data/test/rails_root/config/initializers/time_formats.rb +4 -0
  93. data/test/rails_root/config/routes.rb +9 -0
  94. data/test/rails_root/public/dispatch.rb +10 -0
  95. data/test/rails_root/script/create_project.rb +52 -0
  96. data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
  97. data/test/test_helper.rb +21 -0
  98. metadata +212 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Envy Labs LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,113 @@
1
+ = Blue Light Special
2
+
3
+ Blue Light Special is a derivative from Thoughtbot's
4
+ {Clearance}[http://github.com/thoughtbot/clearance] gem. It's a highly
5
+ opinionated starting point for many of our projects at Envy Labs.
6
+
7
+ In addition to the basic email and password authentication provided by
8
+ Clearance, a default Blue Light Special installation includes:
9
+
10
+ * optional support for authenticating with Facebook Connect, using {mini_fb}[http://github.com/appoxy/mini_fb]
11
+
12
+ * a simple role system with built-in support for admin users
13
+
14
+ * the ability for an admin to impersonate any other user
15
+
16
+ * use of {MadMimi}[http://madmimi.com/r/b8599b9343f82e3bc30984ca4f3fea3f] for sending notification emails
17
+
18
+ * {delayed_job}[http://github.com/tobi/delayed_job] for sending emails in the background
19
+
20
+ * a basic application layout and stylesheet
21
+
22
+ == Setup
23
+
24
+ After installing the Blue Light Special gem, require it in your Rails app and run
25
+ the blue_light_special generator.
26
+
27
+ In your config/environment.rb:
28
+
29
+ config.gem 'blue_light_special'
30
+
31
+ Run the generators and migrate your database:
32
+
33
+ script/generate blue_light_special
34
+ script/generate delayed_job
35
+ rake db:migrate
36
+
37
+ You'll also want to take a look at Blue Light Special's configuration options
38
+ in config/blue_light_special.yml.
39
+
40
+ == Tests
41
+
42
+ Blue Light Special can optionally generate integration tests that cover all
43
+ of its basic features. These tests require {shoulda}[http://github.com/thoughtbot/shoulda],
44
+ {factory_girl}[http://github.com/thoughtbot/factory_girl], {webrat}[http://github.com/brynary/webrat],
45
+ and {fakeweb}[http://github.com/chrisk/fakeweb]. To install the tests:
46
+
47
+ script/generate blue_light_special_tests
48
+
49
+ After the generator runs, you'll see instructions for updating
50
+ test/test_helper.rb to include some helper methods that the tests require.
51
+ You can also use these helper methods in your own integration tests whenever
52
+ you need to sign a user in or out.
53
+
54
+ == Administration Interface
55
+
56
+ The final Blue Light Special generator builds a very simple administration
57
+ interface for your app. This allows admins to manage and impersonate users,
58
+ and it can be used as a starting point for building a more elaborate admin
59
+ interface. If you'd like to generate the admin interface, run:
60
+
61
+ script/generate blue_light_special_admin
62
+
63
+ This will generate your user admin controller and its integration test.
64
+
65
+ == Mad Mimi
66
+
67
+ If you'd like an overview of Mad Mimi, check out the third part of
68
+ {this screencast}[http://railslab.newrelic.com/2009/10/23/episode-21-on-the-edge-part-3].
69
+ In order to get Blue Light Special working with Mad Mimi, you'll need to sign
70
+ up for an account at {madmimi.com}[http://madmimi.com/r/b8599b9343f82e3bc30984ca4f3fea3f].
71
+
72
+ Your Mad Mimi account needs API access, so be sure to enable that during the signup
73
+ process. The support people at Mad Mimi will manually authorize your account for
74
+ API access. This usually happens within a few hours after you've signed up. Until
75
+ your account is authorized, you'll see HTTP errors when your Rails app attempts to
76
+ send email.
77
+
78
+ After you've signed up and your API access has been approved, all you'll need to do is
79
+ put your Mad Mimi username and API key in config/blue_light_special.yml.
80
+
81
+ == Facebook Connect
82
+
83
+ To set up Facebook Connect, go to the {Facebook developer page}[http://facebook.com/developers]
84
+ and create a new Facebook app. Since you're only using this app for Facebook Connect,
85
+ you can leave most of the fields blank. Be sure to give your app a name, and then
86
+ head over to the Connect settings and set the Connect URL to point at your Rails app.
87
+ In the Advanced section, you'll need to set Email Domain to the domain from which you'll
88
+ be sending email messages.
89
+
90
+ After you've finished setting up your Facebook app, grab its API key and secret key
91
+ and put them in config/blue_light_special.yml.
92
+
93
+ == To Build the Gem ==
94
+ gem build cops.gemspec
95
+
96
+ sudo gem install cops.gem
97
+
98
+ gem yank cops -v 0.2.0.1
99
+
100
+ == Differences from Blue Light Special ==
101
+ 1. MimiMailer was made optional. In some cases, like deploying on heroku, you won't want to use MimiMailer templates, but instead regular mailer templates. Cops does not use MimiMailer unless you've setup your login info for that service.
102
+ 2. DelayedJob is now optional. You can turn off the use of delayed job, again in the case of deploying to Heroku for example where you do not want to pay the extra fees of using a background worker. In this case emails will be sent immediately and not queued.
103
+ 3. The welcome email is not only suppressed if the email is already confirmed, but is also not sent if the user connects via Facebook. Since Facebook returns the email already, which presumably Facebook has already confirmed, Cops marks the user as already confirmed.
104
+ 4. Cops adds back into BlueLightSpecial, the email confirmation from Clearance. This is only used for non-facebook connect users
105
+ 5. Added flash notice on creation of user
106
+ 6. Using redirect_back_or in all cases so app using Cops gem has an option of where to send the user
107
+ 7. Added a facebook_logout method that facebook can call via its Post-Remove Callback, to remove user from app
108
+ 8. Changed to user can still log in even though they haven't confirmed their email (they just aren't active)
109
+ 9. The change password function was using the confirmation token instead of the password reset token in several spots
110
+
111
+ == Copyright
112
+
113
+ Copyright (c) 2010 Envy Labs LLC. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,95 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "blue_light_special"
9
+ gem.summary = %Q{Rails authentication by email and password}
10
+ gem.description = %Q{Rails authentication by email and password with integrated dependencies to MadMimi. Also provides administrative user impersonation.}
11
+ gem.email = "nate@envylabs.com"
12
+ gem.homepage = "http://github.com/envylabs/blue_light_special"
13
+ gem.authors = ["Nathaniel Bibler", "Mark Kendall", "Caike Souza"]
14
+ gem.files = FileList["[A-Z]*", "{app,config,generators,lib,shoulda_macros,rails}/**/*"]
15
+
16
+ gem.add_dependency "mini_fb", '=0.2.2'
17
+ gem.add_dependency "delayed_job", '=1.8.4'
18
+ gem.add_dependency "mad_mimi_mailer", '=0.0.7'
19
+
20
+ gem.add_development_dependency "shoulda", ">= 0"
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
25
+ end
26
+
27
+ namespace :test do
28
+ Rake::TestTask.new(:basic => ["check_dependencies",
29
+ "generator:cleanup",
30
+ "generator:blue_light_special",
31
+ "generator:blue_light_special_tests",
32
+ "generator:blue_light_special_admin"]) do |task|
33
+ task.libs << "lib"
34
+ task.libs << "test"
35
+ task.pattern = "test/{controllers,models}/*_test.rb"
36
+ task.verbose = false
37
+ end
38
+ end
39
+
40
+ generators = %w(blue_light_special blue_light_special_tests blue_light_special_admin)
41
+
42
+ namespace :generator do
43
+ desc "Cleans up the test app before running the generator"
44
+ task :cleanup do
45
+ FileList["test/rails_root/db/**/*"].each do |each|
46
+ FileUtils.rm_rf(each)
47
+ end
48
+
49
+ FileUtils.rm_rf("test/rails_root/vendor/plugins/blue_light_special")
50
+ FileUtils.mkdir_p("test/rails_root/vendor/plugins")
51
+ blue_light_special_root = File.expand_path(File.dirname(__FILE__))
52
+ system("ln -s \"#{blue_light_special_root}\" test/rails_root/vendor/plugins/blue_light_special")
53
+ end
54
+
55
+ desc "Run the blue_light_special generator"
56
+ task :blue_light_special do
57
+ system "cd test/rails_root && ./script/generate blue_light_special -f && ./script/generate delayed_job && rake gems:unpack && rake db:migrate db:test:prepare"
58
+ end
59
+
60
+ desc "Run the blue_light_special tests generator"
61
+ task :blue_light_special_tests do
62
+ system "cd test/rails_root && ./script/generate blue_light_special_tests -f"
63
+ end
64
+
65
+ desc "Run the blue_light_special admin generator"
66
+ task :blue_light_special_admin do
67
+ system "cd test/rails_root && ./script/generate blue_light_special_admin -f"
68
+ end
69
+
70
+ end
71
+
72
+ begin
73
+ require 'rcov/rcovtask'
74
+ Rcov::RcovTask.new do |test|
75
+ test.libs << 'test'
76
+ test.pattern = 'test/**/test_*.rb'
77
+ test.verbose = true
78
+ end
79
+ rescue LoadError
80
+ task :rcov do
81
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
82
+ end
83
+ end
84
+
85
+ task :default => ['test:basic']
86
+
87
+ require 'rake/rdoctask'
88
+ Rake::RDocTask.new do |rdoc|
89
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
90
+
91
+ rdoc.rdoc_dir = 'rdoc'
92
+ rdoc.title = "BlueLightSpecial #{version}"
93
+ rdoc.rdoc_files.include('README*')
94
+ rdoc.rdoc_files.include('lib/**/*.rb')
95
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,76 @@
1
+ class BlueLightSpecial::ConfirmationsController < ApplicationController
2
+ unloadable
3
+
4
+ skip_before_filter :authenticate, :only => [:new, :create]
5
+ before_filter :redirect_signed_in_confirmed_user, :only => [:new, :create]
6
+ before_filter :redirect_signed_out_confirmed_user, :only => [:new, :create]
7
+ before_filter :forbid_missing_token, :only => [:new, :create]
8
+ before_filter :forbid_non_existent_user, :only => [:new, :create]
9
+
10
+ filter_parameter_logging :token
11
+
12
+ def new
13
+ create
14
+ end
15
+
16
+ def create
17
+ @user = ::User.find_by_id_and_confirmation_token(
18
+ params[:user_id], params[:token])
19
+ @user.confirm_email!
20
+
21
+ sign_in(@user)
22
+ flash_success_after_create
23
+ redirect_to(url_after_create)
24
+ end
25
+
26
+ private
27
+
28
+ def redirect_signed_in_confirmed_user
29
+ user = ::User.find_by_id(params[:user_id])
30
+ if user && user.email_confirmed? && current_user == user
31
+ flash_success_after_create
32
+ redirect_to(url_after_create)
33
+ end
34
+ end
35
+
36
+ def redirect_signed_out_confirmed_user
37
+ user = ::User.find_by_id(params[:user_id])
38
+ if user && user.email_confirmed? && signed_out?
39
+ flash_already_confirmed
40
+ redirect_to(url_already_confirmed)
41
+ end
42
+ end
43
+
44
+ def forbid_missing_token
45
+ if params[:token].blank?
46
+ raise ActionController::Forbidden, "missing token"
47
+ end
48
+ end
49
+
50
+ def forbid_non_existent_user
51
+ unless ::User.find_by_id_and_confirmation_token(
52
+ params[:user_id], params[:token])
53
+ raise ActionController::Forbidden, "non-existent user"
54
+ end
55
+ end
56
+
57
+ def flash_success_after_create
58
+ flash[:success] = translate(:confirmed_email,
59
+ :scope => [:clearance, :controllers, :confirmations],
60
+ :default => "Confirmed email and signed in.")
61
+ end
62
+
63
+ def flash_already_confirmed
64
+ flash[:success] = translate(:already_confirmed_email,
65
+ :scope => [:clearance, :controllers, :confirmations],
66
+ :default => "Already confirmed email. Please sign in.")
67
+ end
68
+
69
+ def url_after_create
70
+ '/'
71
+ end
72
+
73
+ def url_already_confirmed
74
+ sign_in_url
75
+ end
76
+ end
@@ -0,0 +1,44 @@
1
+ class BlueLightSpecial::ImpersonationsController < ApplicationController
2
+ before_filter :authenticate
3
+ before_filter :check_role, :except => :destroy
4
+
5
+
6
+ def index
7
+ @users = User.all
8
+ render :template => 'impersonations/index'
9
+ end
10
+
11
+ def create
12
+ user = User.find(params[:user_id])
13
+ if user == current_user
14
+ flash[:failure] = "Cannot impersonate yourself"
15
+ redirect_to root_url
16
+ else
17
+ session[:admin_user_id] = current_user.id
18
+ session[:impersonation_hash] = Impersonation.hash_for(current_user.id)
19
+ sign_in(user)
20
+ redirect_to root_url
21
+ end
22
+ end
23
+
24
+ def destroy
25
+ if Impersonation.valid_hash?(session[:admin_user_id], session[:impersonation_hash])
26
+ old_user = current_user
27
+ admin_user = User.find(session[:admin_user_id])
28
+ session[:admin_user_id] = nil
29
+ session[:impersonation_hash] = nil
30
+ sign_in(admin_user)
31
+ redirect_to impersonations_url
32
+ else
33
+ deny_access
34
+ end
35
+ end
36
+
37
+
38
+ private
39
+
40
+
41
+ def check_role
42
+ raise ActionController::Forbidden, "disallowed" unless current_user.admin?
43
+ end
44
+ end
@@ -0,0 +1,93 @@
1
+ class BlueLightSpecial::PasswordsController < ApplicationController
2
+ unloadable
3
+
4
+ skip_before_filter :authenticate, :only => [:new, :create, :edit, :update]
5
+ before_filter :forbid_missing_token, :only => [:edit, :update]
6
+ before_filter :forbid_non_existent_user, :only => [:edit, :update]
7
+ filter_parameter_logging :password, :password_confirmation
8
+
9
+ def new
10
+ render :template => 'passwords/new'
11
+ end
12
+
13
+ def create
14
+ if user = ::User.find_by_email(params[:password][:email])
15
+ user.forgot_password!
16
+ if user.password_reset_token.present?
17
+ if BlueLightSpecial.configuration.use_delayed_job
18
+ Delayed::Job.enqueue DeliverChangePasswordJob.new(user)
19
+ else
20
+ BlueLightSpecialMailer.deliver_change_password(user)
21
+ end
22
+ flash_notice_after_create
23
+ redirect_to(url_after_create)
24
+ else
25
+ flash[:notice] = 'Your password was not able to be recovered. You may never have finished registration.'
26
+ render :template => 'passwords/new'
27
+ end
28
+ else
29
+ flash_failure_after_create
30
+ render :template => 'passwords/new'
31
+ end
32
+ end
33
+
34
+ def edit
35
+ @user = ::User.find_by_id_and_password_reset_token(
36
+ params[:user_id], params[:token])
37
+ render :template => 'passwords/edit'
38
+ end
39
+
40
+ def update
41
+ @user = ::User.find_by_id_and_password_reset_token(
42
+ params[:user_id], params[:token])
43
+
44
+ if @user.update_password(params[:user][:password],
45
+ params[:user][:password_confirmation])
46
+ sign_in(@user)
47
+ flash_success_after_update
48
+ redirect_to(url_after_update)
49
+ else
50
+ render :template => 'passwords/edit'
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def forbid_missing_token
57
+ if params[:token].blank?
58
+ raise ActionController::Forbidden, "missing token"
59
+ end
60
+ end
61
+
62
+ def forbid_non_existent_user
63
+ unless ::User.find_by_id_and_password_reset_token(
64
+ params[:user_id], params[:token])
65
+ raise ActionController::Forbidden, "non-existent user"
66
+ end
67
+ end
68
+
69
+ def flash_notice_after_create
70
+ flash[:notice] = translate(:deliver_change_password,
71
+ :scope => [:blue_light_special, :controllers, :passwords],
72
+ :default => "You will receive an email within the next few minutes. " <<
73
+ "It contains instructions for changing your password.")
74
+ end
75
+
76
+ def flash_failure_after_create
77
+ flash.now[:failure] = translate(:unknown_email,
78
+ :scope => [:blue_light_special, :controllers, :passwords],
79
+ :default => "Unknown email.")
80
+ end
81
+
82
+ def url_after_create
83
+ sign_in_url
84
+ end
85
+
86
+ def flash_success_after_update
87
+ flash[:success] = translate(:signed_in, :default => "Signed in.")
88
+ end
89
+
90
+ def url_after_update
91
+ '/'
92
+ end
93
+ end
@@ -0,0 +1,76 @@
1
+ class BlueLightSpecial::SessionsController < ApplicationController
2
+ unloadable
3
+
4
+ skip_before_filter :authenticate, :only => [:new, :create, :destroy]
5
+ protect_from_forgery :except => :create
6
+ filter_parameter_logging :password
7
+
8
+ def new
9
+ render :template => 'sessions/new'
10
+ end
11
+
12
+ def create
13
+ @user = if params[:session]
14
+ ::User.authenticate(params[:session][:email], params[:session][:password])
15
+ else
16
+ ::User.find_facebook_user(cookies[BlueLightSpecial.configuration.facebook_api_key + "_session_key"],
17
+ cookies[BlueLightSpecial.configuration.facebook_api_key + "_user"])
18
+ end
19
+
20
+ if @user.nil?
21
+ flash_failure_after_create
22
+ render :template => 'sessions/new', :status => :unauthorized
23
+ else
24
+ if @user.email_confirmed?
25
+ flash_success_after_create
26
+ else
27
+ ::BlueLightSpecialMailer.deliver_confirmation(@user)
28
+ flash_notice_after_create
29
+ end
30
+ sign_in(@user)
31
+ reset_session
32
+ redirect_back_or(url_after_create)
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ if BlueLightSpecial.configuration.use_facebook_connect
38
+ cookies[BlueLightSpecial.configuration.facebook_api_key + "_user"] = nil
39
+ cookies[BlueLightSpecial.configuration.facebook_api_key + "_session_key"] = nil
40
+ end
41
+ sign_out
42
+ flash_success_after_destroy
43
+ redirect_to(url_after_destroy)
44
+ end
45
+
46
+ private
47
+
48
+ def flash_failure_after_create
49
+ flash.now[:failure] = translate(:bad_email_or_password,
50
+ :scope => [:blue_light_special, :controllers, :sessions],
51
+ :default => "Bad email or password.")
52
+ end
53
+
54
+ def flash_success_after_create
55
+ flash[:success] = translate(:signed_in, :default => "Signed in.")
56
+ end
57
+
58
+ def flash_notice_after_create
59
+ flash[:notice] = translate(:unconfirmed_email,
60
+ :scope => [:blue_light_special, :controllers, :sessions],
61
+ :default => "User has not confirmed email. " <<
62
+ "Confirmation email will be resent.")
63
+ end
64
+
65
+ def url_after_create
66
+ '/'
67
+ end
68
+
69
+ def flash_success_after_destroy
70
+ flash[:success] = translate(:signed_out, :default => "Signed out.")
71
+ end
72
+
73
+ def url_after_destroy
74
+ sign_in_url
75
+ end
76
+ end
@@ -0,0 +1,85 @@
1
+ class BlueLightSpecial::UsersController < ApplicationController
2
+ unloadable
3
+
4
+ skip_before_filter :authenticate, :only => [:new, :create, :facebook_remove]
5
+ before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in?
6
+ filter_parameter_logging :password
7
+ # Before Filter on *only* the 'uninstalled' method
8
+ before_filter :verify_uninstall_signature, :only => [:facebook_remove]
9
+
10
+ def facebook_remove
11
+ @fb_uid = params[:fb_sig_user]
12
+ if @fb_uid.present?
13
+ # From here on it will be app specific -- given the facebook uid, destroy the user, like...
14
+ @user = User.find_by_facebook_uid(@fb_uid)
15
+ @user.destroy if @user
16
+ end
17
+ render :nothing => true; return
18
+ end
19
+
20
+ def show
21
+ @user = current_user
22
+ render :template => 'users/show'
23
+ end
24
+
25
+ def new
26
+ @user = ::User.new(params[:user])
27
+ render :template => 'users/new'
28
+ end
29
+
30
+ def create
31
+ @user = ::User.new params[:user]
32
+ if @user.save
33
+ sign_in(@user)
34
+ flash[:notice] = 'You have successfully signed up.'
35
+ redirect_back_or(url_after_create)
36
+ else
37
+ render :template => 'users/new'
38
+ end
39
+ end
40
+
41
+ def edit
42
+ @user = current_user
43
+ render :template => 'users/edit'
44
+ end
45
+
46
+ def update
47
+ @user = current_user
48
+ if @user.update_attributes(params[:user])
49
+ flash[:success] = 'Your profile has been updated.'
50
+ redirect_back_or(user_path(@user))
51
+ else
52
+ render :template => 'users/edit'
53
+ end
54
+ end
55
+
56
+ protected
57
+ def verify_uninstall_signature
58
+ signature = ''
59
+ keys = params.keys.sort
60
+ keys.each do |key|
61
+ next if key == 'fb_sig'
62
+ next unless key.include?('fb_sig')
63
+ key_name = key.gsub('fb_sig_', '')
64
+ signature += key_name
65
+ signature += '='
66
+ signature += params[key]
67
+ end
68
+ signature += BlueLightSpecial.configuration.facebook_secret_key
69
+ calculated_sig = Digest::MD5.hexdigest(signature)
70
+ #logger.info "\nUNINSTALL :: Signature (fb_sig param from facebook) :: #{params[:fb_sig]}"
71
+ #logger.info "\nUNINSTALL :: Signature String (pre-hash) :: #{signature}"
72
+ #logger.info "\nUNINSTALL :: MD5 Hashed Sig :: #{calculated_sig}"
73
+ if calculated_sig != params[:fb_sig]
74
+ #logger.warn "\n\nUNINSTALL :: WARNING :: expected signatures did not match\n\n" return false else
75
+ #logger.warn "\n\nUNINSTALL :: SUCCESS!! Signatures matched.\n"
76
+ end
77
+ return true
78
+ end
79
+
80
+ private
81
+
82
+ def url_after_create
83
+ root_url
84
+ end
85
+ end
@@ -0,0 +1,28 @@
1
+ class BlueLightSpecialMailer
2
+
3
+ def self.deliver_change_password(user)
4
+ if MadMimiMailer.api_settings.present? && MadMimiMailer.api_settings[:username].present? && MadMimiMailer.api_settings[:api_key].present?
5
+ MimiMailer.deliver_mimi_change_password(user)
6
+ else
7
+ GenericMailer.deliver_change_password(user)
8
+ end
9
+ end
10
+
11
+ def self.deliver_welcome(user)
12
+ if MadMimiMailer.api_settings.present? && MadMimiMailer.api_settings[:username].present? && MadMimiMailer.api_settings[:api_key].present?
13
+ MimiMailer.deliver_welcome(user)
14
+ else
15
+ GenericMailer.deliver_welcome(user)
16
+ end
17
+ end
18
+
19
+ def self.deliver_confirmation(user)
20
+ if MadMimiMailer.api_settings.present? && MadMimiMailer.api_settings[:username].present? && MadMimiMailer.api_settings[:api_key].present?
21
+ MimiMailer.deliver_confirmation(user)
22
+ else
23
+ GenericMailer.deliver_confirmation(user)
24
+ end
25
+ end
26
+
27
+
28
+ end
@@ -0,0 +1,19 @@
1
+ ##
2
+ # Delivers the BlueLightSpecial.deliver_mimi_change_password to the requested
3
+ # User by +id+ as an asynchronous process.
4
+ #
5
+ class DeliverChangePasswordJob
6
+
7
+ attr_reader :user_id
8
+
9
+ def initialize(user_id)
10
+ @user_id = user_id.kind_of?(User) ? user_id.id : user_id
11
+ end
12
+
13
+ def perform
14
+ if user = User.find_by_id(@user_id)
15
+ BlueLightSpecialMailer.deliver_change_password(user)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # Delivers the UserMailer.deliver_mimi_welcome to the requested User by +id+
3
+ # as an asynchronous process.
4
+ #
5
+ class DeliverWelcomeJob
6
+
7
+ def initialize(user_id)
8
+ @user_id = user_id
9
+ end
10
+
11
+ def perform
12
+ if user = User.find_by_id(@user_id)
13
+ BlueLightSpecialMailer.deliver_welcome(user)
14
+ end
15
+ end
16
+
17
+ end