blue_light_special_heroku_fork 0.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +95 -0
  3. data/Rakefile +95 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/blue_light_special/impersonations_controller.rb +44 -0
  6. data/app/controllers/blue_light_special/passwords_controller.rb +88 -0
  7. data/app/controllers/blue_light_special/sessions_controller.rb +70 -0
  8. data/app/controllers/blue_light_special/users_controller.rb +48 -0
  9. data/app/models/blue_light_special_mailer.rb +19 -0
  10. data/app/models/deliver_change_password_job.rb +19 -0
  11. data/app/models/deliver_welcome_job.rb +17 -0
  12. data/app/models/generic_mailer.rb +22 -0
  13. data/app/models/impersonation.rb +26 -0
  14. data/app/models/mimi_mailer.rb +21 -0
  15. data/app/views/blue_light_special_mailer/change_password.html.erb +9 -0
  16. data/app/views/impersonations/index.html.erb +5 -0
  17. data/app/views/passwords/edit.html.erb +23 -0
  18. data/app/views/passwords/new.html.erb +15 -0
  19. data/app/views/sessions/new.html.erb +48 -0
  20. data/app/views/users/_form.html.erb +21 -0
  21. data/app/views/users/edit.html.erb +6 -0
  22. data/app/views/users/new.html.erb +6 -0
  23. data/app/views/users/show.html.erb +8 -0
  24. data/generators/blue_light_special/USAGE +1 -0
  25. data/generators/blue_light_special/blue_light_special_generator.rb +78 -0
  26. data/generators/blue_light_special/lib/insert_commands.rb +33 -0
  27. data/generators/blue_light_special/lib/rake_commands.rb +22 -0
  28. data/generators/blue_light_special/templates/README +20 -0
  29. data/generators/blue_light_special/templates/application.html.erb +50 -0
  30. data/generators/blue_light_special/templates/blue_light_special.rb +25 -0
  31. data/generators/blue_light_special/templates/blue_light_special.yml +45 -0
  32. data/generators/blue_light_special/templates/factories.rb +23 -0
  33. data/generators/blue_light_special/templates/migrations/create_users.rb +24 -0
  34. data/generators/blue_light_special/templates/migrations/update_users.rb +44 -0
  35. data/generators/blue_light_special/templates/style.css +31 -0
  36. data/generators/blue_light_special/templates/user.rb +3 -0
  37. data/generators/blue_light_special/templates/xd_receiver.html +10 -0
  38. data/generators/blue_light_special/templates/xd_receiver_ssl.html +10 -0
  39. data/generators/blue_light_special_admin/USAGE +1 -0
  40. data/generators/blue_light_special_admin/blue_light_special_admin_generator.rb +30 -0
  41. data/generators/blue_light_special_admin/lib/insert_commands.rb +33 -0
  42. data/generators/blue_light_special_admin/templates/README +16 -0
  43. data/generators/blue_light_special_admin/templates/app/controllers/admin/admin_controller.rb +14 -0
  44. data/generators/blue_light_special_admin/templates/app/controllers/admin/users_controller.rb +52 -0
  45. data/generators/blue_light_special_admin/templates/app/views/admin/users/_form.html.erb +25 -0
  46. data/generators/blue_light_special_admin/templates/app/views/admin/users/edit.html.erb +6 -0
  47. data/generators/blue_light_special_admin/templates/app/views/admin/users/index.html.erb +7 -0
  48. data/generators/blue_light_special_admin/templates/app/views/admin/users/new.html.erb +6 -0
  49. data/generators/blue_light_special_admin/templates/app/views/admin/users/show.html.erb +10 -0
  50. data/generators/blue_light_special_admin/templates/test/integration/admin/users_test.rb +201 -0
  51. data/generators/blue_light_special_tests/USAGE +1 -0
  52. data/generators/blue_light_special_tests/blue_light_special_tests_generator.rb +21 -0
  53. data/generators/blue_light_special_tests/templates/README +58 -0
  54. data/generators/blue_light_special_tests/templates/test/integration/edit_profile_test.rb +35 -0
  55. data/generators/blue_light_special_tests/templates/test/integration/facebook_test.rb +61 -0
  56. data/generators/blue_light_special_tests/templates/test/integration/impersonation_test.rb +39 -0
  57. data/generators/blue_light_special_tests/templates/test/integration/password_reset_test.rb +128 -0
  58. data/generators/blue_light_special_tests/templates/test/integration/sign_in_test.rb +66 -0
  59. data/generators/blue_light_special_tests/templates/test/integration/sign_out_test.rb +28 -0
  60. data/generators/blue_light_special_tests/templates/test/integration/sign_up_test.rb +47 -0
  61. data/lib/blue_light_special.rb +7 -0
  62. data/lib/blue_light_special/authentication.rb +138 -0
  63. data/lib/blue_light_special/configuration.rb +34 -0
  64. data/lib/blue_light_special/extensions/errors.rb +6 -0
  65. data/lib/blue_light_special/extensions/rescue.rb +5 -0
  66. data/lib/blue_light_special/routes.rb +55 -0
  67. data/lib/blue_light_special/user.rb +247 -0
  68. data/rails/init.rb +4 -0
  69. data/shoulda_macros/blue_light_special.rb +244 -0
  70. data/test/controllers/passwords_controller_test.rb +184 -0
  71. data/test/controllers/sessions_controller_test.rb +129 -0
  72. data/test/controllers/users_controller_test.rb +57 -0
  73. data/test/models/blue_light_special_mailer_test.rb +52 -0
  74. data/test/models/impersonation_test.rb +25 -0
  75. data/test/models/user_test.rb +213 -0
  76. data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
  77. data/test/rails_root/app/controllers/application_controller.rb +6 -0
  78. data/test/rails_root/app/helpers/application_helper.rb +5 -0
  79. data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
  80. data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
  81. data/test/rails_root/config/boot.rb +110 -0
  82. data/test/rails_root/config/environment.rb +22 -0
  83. data/test/rails_root/config/environments/development.rb +19 -0
  84. data/test/rails_root/config/environments/production.rb +1 -0
  85. data/test/rails_root/config/environments/test.rb +37 -0
  86. data/test/rails_root/config/initializers/inflections.rb +10 -0
  87. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  88. data/test/rails_root/config/initializers/requires.rb +13 -0
  89. data/test/rails_root/config/initializers/time_formats.rb +4 -0
  90. data/test/rails_root/config/routes.rb +9 -0
  91. data/test/rails_root/public/dispatch.rb +10 -0
  92. data/test/rails_root/script/create_project.rb +52 -0
  93. data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
  94. data/test/test_helper.rb +21 -0
  95. metadata +187 -0
@@ -0,0 +1,50 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" xml:lang="en-US" lang="en-US" xmlns:fb="http://www.facebook.com/2008/fbml">
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
5
+ <title><%= yield(:title) %></title>
6
+ <meta name="description" content="<%= yield(:description) %>" />
7
+ <meta name="keywords" content="<%= yield(:keywords) %>" />
8
+ <meta name="robots" content="INDEX,FOLLOW" />
9
+
10
+ <%= stylesheet_link_tag "style" %>
11
+ <!--[if IE 6]>
12
+ <%= stylesheet_link_tag "ie6-style" %>
13
+ <![endif]-->
14
+
15
+ <%- if request.ssl? -%>
16
+ <%= javascript_include_tag 'https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' %>
17
+ <%- else -%>
18
+ <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' %>
19
+ <%- end -%>
20
+ <%= javascript_include_tag 'application' %>
21
+ </head>
22
+ <body>
23
+
24
+ <% if signed_in? %>
25
+ <% if impersonating? %>
26
+ Impersonating <%= current_user.name %>
27
+ | <%= link_to 'Stop impersonating', impersonation_path, :method => :delete %>
28
+ <% else %>
29
+ Welcome, <%= current_user.name %>
30
+ | <%= link_to 'Sign out', sign_out_path %>
31
+ <% end %>
32
+
33
+ <% if current_user.admin? %>
34
+ | <%= link_to 'Admin', impersonations_path %>
35
+ <% end %>
36
+
37
+ | <%= link_to 'My Profile', user_path(current_user) %>
38
+ <% else %>
39
+ <%= link_to 'Sign in', sign_in_path %> |
40
+ <%= link_to 'Sign up', sign_up_path %>
41
+ <% end %>
42
+
43
+ <div id="flash">
44
+ <%- flash.each do |key, value| -%>
45
+ <div class="<%= key %>_flash"><%=h value %></div>
46
+ <%- end -%>
47
+ </div>
48
+ <%= yield %>
49
+ </body>
50
+ </html>
@@ -0,0 +1,25 @@
1
+ require 'yaml'
2
+
3
+ begin
4
+ configuration = YAML.load_file("#{Rails.root}/config/blue_light_special.yml")[Rails.env]
5
+ configuration = HashWithIndifferentAccess.new(configuration)
6
+
7
+ BlueLightSpecial.configure do |config|
8
+ config.mailer_sender = configuration[:mailer_sender]
9
+ config.impersonation_hash = configuration[:impersonation_hash]
10
+ config.use_facebook_connect = configuration[:use_facebook_connect]
11
+ config.use_delayed_job = configuration[:use_delayed_job]
12
+ config.facebook_api_key = configuration[:facebook_api_key]
13
+ config.facebook_secret_key = configuration[:facebook_secret_key]
14
+ end
15
+
16
+ if configuration[:madmimi_username].present? && configuration[:madmimi_api_key].present?
17
+ MadMimiMailer.api_settings = {
18
+ :username => configuration[:madmimi_username],
19
+ :api_key => configuration[:madmimi_api_key]
20
+ }
21
+ else
22
+ end
23
+ rescue LoadError
24
+ puts "The /config/blue_light_special.yml file is missing or broken."
25
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # The mailer_sender is set as the reply address for all notification emails.
3
+ #
4
+ # Set madmimi_username and madmimi_api_key to your MadMimi account username
5
+ # and API key.
6
+ #
7
+ # The impersonation_hash is used to secure user impersonations. Set it to
8
+ # a long, random hash.
9
+ #
10
+ # To turn on Facebook Connect, set use_facebook_connect to true.
11
+ #
12
+ # If you are using Facebook Connect, you'll need to provide your
13
+ # application's API and secret keys from your Facebook application
14
+ # settings at http://facebook.com/developers.
15
+ #
16
+
17
+ development:
18
+ mailer_sender: donotreply@example.com
19
+ madmimi_username:
20
+ madmimi_api_key:
21
+ impersonation_hash:
22
+ use_facebook_connect: false
23
+ use_delayed_job: true
24
+ facebook_api_key:
25
+ facebook_secret_key:
26
+
27
+ test:
28
+ mailer_sender: donotreply@example.com
29
+ madmimi_username:
30
+ madmimi_api_key:
31
+ impersonation_hash:
32
+ use_facebook_connect: false
33
+ use_delayed_job: true
34
+ facebook_api_key:
35
+ facebook_secret_key:
36
+
37
+ production:
38
+ mailer_sender: donotreply@example.com
39
+ madmimi_username:
40
+ madmimi_api_key:
41
+ impersonation_hash:
42
+ use_facebook_connect: false
43
+ use_delayed_job: true
44
+ facebook_api_key:
45
+ facebook_secret_key:
@@ -0,0 +1,23 @@
1
+ Factory.sequence :email do |n|
2
+ "user#{n}@example.com"
3
+ end
4
+
5
+ Factory.sequence :facebook_id do |n|
6
+ n
7
+ end
8
+
9
+ Factory.define :user do |user|
10
+ user.email { Factory.next :email }
11
+ user.first_name { "Factory" }
12
+ user.last_name { "User" }
13
+ user.password { "password" }
14
+ user.password_confirmation { "password" }
15
+ end
16
+
17
+ Factory.define :admin_user, :parent => :user do |admin|
18
+ admin.role 'admin'
19
+ end
20
+
21
+ Factory.define :facebook_user, :parent => :user do |user|
22
+ user.facebook_uid { Factory.next :facebook_id }
23
+ end
@@ -0,0 +1,24 @@
1
+ class BlueLightSpecialCreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table(:users) do |t|
4
+ t.string :email, :limit => 100
5
+ t.string :first_name, :limit => 50
6
+ t.string :last_name, :limit => 50
7
+ t.string :role, :limit => 50
8
+ t.string :encrypted_password, :limit => 128
9
+ t.string :salt, :limit => 128
10
+ t.string :remember_token, :limit => 128
11
+ t.string :facebook_uid, :limit => 50
12
+ t.string :password_reset_token, :limit => 128
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :users, :email
17
+ add_index :users, :remember_token
18
+ add_index :users, :facebook_uid
19
+ end
20
+
21
+ def self.down
22
+ drop_table :users
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ class BlueLightSpecialUpdateUsers<%= schema_version_constant %> < ActiveRecord::Migration
2
+ def self.up
3
+ <%
4
+ existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name }
5
+ columns = [
6
+ [:email, 't.string :email, :limit => 100'],
7
+ [:first_name, 't.string :first_name, :limit => 50'],
8
+ [:last_name, 't.string :last_name, :limit => 50'],
9
+ [:role, 't.string :role, :limit => 50'],
10
+ [:encrypted_password, 't.string :encrypted_password, :limit => 128'],
11
+ [:salt, 't.string :salt, :limit => 128'],
12
+ [:remember_token, 't.string :remember_token, :limit => 128'],
13
+ [:facebook_uid, 't.string :facebook_uid, :limit => 50'],
14
+ [:password_reset_token, 't.string :password_reset_token, :limit => 128']
15
+ ].delete_if {|c| existing_columns.include?(c.first.to_s)}
16
+ -%>
17
+ change_table(:users) do |t|
18
+ <% columns.each do |c| -%>
19
+ <%= c.last %>
20
+ <% end -%>
21
+ end
22
+
23
+ <%
24
+ existing_indexes = ActiveRecord::Base.connection.indexes(:users)
25
+ index_names = existing_indexes.collect { |each| each.name }
26
+ new_indexes = [
27
+ [:index_users_on_email, 'add_index :users, :email'],
28
+ [:index_users_on_remember_token, 'add_index :users, :remember_token'],
29
+ [:index_users_on_facebook_uid, 'add_index :users, :facebook_uid']
30
+ ].delete_if { |each| index_names.include?(each.first.to_s) }
31
+ -%>
32
+ <% new_indexes.each do |each| -%>
33
+ <%= each.last %>
34
+ <% end -%>
35
+ end
36
+
37
+ def self.down
38
+ change_table(:users) do |t|
39
+ <% unless columns.empty? -%>
40
+ t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
41
+ <% end -%>
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ /* Flash messages */
2
+
3
+ .notice_flash,
4
+ .failure_flash,
5
+ .success_flash {
6
+ border: 1px solid;
7
+ padding: 3px;
8
+ padding:15px 10px;
9
+ background-repeat: no-repeat;
10
+ background-position: 10px center;
11
+ margin-bottom: 10px;
12
+ font-weight: bold;
13
+ width: 60%;
14
+ margin-left: auto;
15
+ margin-right: auto;
16
+ }
17
+
18
+ .notice_flash {
19
+ color: #00529B;
20
+ background-color: #BDE5F8;
21
+ }
22
+
23
+ .failure_flash {
24
+ color: #D8000C;
25
+ background-color: #FFBABA;
26
+ }
27
+
28
+ .success_flash {
29
+ color: #4F8A10;
30
+ background-color: #DFF2BF;
31
+ }
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ include BlueLightSpecial::User
3
+ end
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" >
4
+ <head>
5
+ <title>Cross-Domain Receiver Page</title>
6
+ </head>
7
+ <body>
8
+ <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.debug.js" type="text/javascript"></script>
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" >
4
+ <head>
5
+ <title>Cross-Domain Receiver Page</title>
6
+ </head>
7
+ <body>
8
+ <script src="https://ssl.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
9
+ </body>
10
+ </html>
@@ -0,0 +1 @@
1
+ script/generate blue_light_special_admin
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
2
+
3
+ class BlueLightSpecialAdminGenerator < Rails::Generator::Base
4
+
5
+ def manifest
6
+ record do |m|
7
+ m.directory File.join("app", "controllers", "admin")
8
+ m.file "app/controllers/admin/admin_controller.rb", "app/controllers/admin/admin_controller.rb"
9
+ m.file "app/controllers/admin/users_controller.rb", "app/controllers/admin/users_controller.rb"
10
+
11
+ m.directory File.join("app", "views", "admin", "users")
12
+ ["app/views/admin/users/_form.html.erb",
13
+ "app/views/admin/users/edit.html.erb",
14
+ "app/views/admin/users/index.html.erb",
15
+ "app/views/admin/users/new.html.erb",
16
+ "app/views/admin/users/show.html.erb"].each do |file|
17
+ m.file file, file
18
+ end
19
+
20
+ m.directory File.join("test", "integration", "admin")
21
+ m.file "test/integration/admin/users_test.rb", "test/integration/admin/users_test.rb"
22
+
23
+ m.insert_into "config/routes.rb",
24
+ "map.namespace :admin do |admin|\n admin.resources :users\n end"
25
+
26
+ m.readme "README"
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,33 @@
1
+ # Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
2
+
3
+ Rails::Generator::Commands::Base.class_eval do
4
+ def file_contains?(relative_destination, line)
5
+ File.read(destination_path(relative_destination)).include?(line)
6
+ end
7
+ end
8
+
9
+ Rails::Generator::Commands::Create.class_eval do
10
+ def insert_into(file, line)
11
+ logger.insert "#{line} into #{file}"
12
+ unless options[:pretend] || file_contains?(file, line)
13
+ gsub_file file, /^(class|module|.*Routing).*$/ do |match|
14
+ "#{match}\n #{line}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Rails::Generator::Commands::Destroy.class_eval do
21
+ def insert_into(file, line)
22
+ logger.remove "#{line} from #{file}"
23
+ unless options[:pretend]
24
+ gsub_file file, "\n #{line}", ''
25
+ end
26
+ end
27
+ end
28
+
29
+ Rails::Generator::Commands::List.class_eval do
30
+ def insert_into(file, line)
31
+ logger.insert "#{line} into #{file}"
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+
2
+ *******************************************************************************
3
+
4
+ Next:
5
+
6
+ 1. Add a link somewhere in your app to /admin/users for admins to access the
7
+ list of users.
8
+
9
+ 2. Any other admin controllers should inherit from Admin::AdminController.
10
+ This will ensure that only users who have the 'admin' role are allowed
11
+ to access the admin controllers.
12
+
13
+ 3. Manually set an 'admin' role on at least one user, or you won't be able
14
+ to access the admin area.
15
+
16
+ *******************************************************************************
@@ -0,0 +1,14 @@
1
+ class Admin::AdminController < ApplicationController
2
+
3
+ before_filter :authenticate
4
+ before_filter :check_role
5
+
6
+
7
+ private
8
+
9
+
10
+ def check_role
11
+ redirect_to root_url unless current_user.admin?
12
+ end
13
+
14
+ end
@@ -0,0 +1,52 @@
1
+ class Admin::UsersController < Admin::AdminController
2
+
3
+ def index
4
+ @users = User.all
5
+ end
6
+
7
+ def show
8
+ @user = User.find(params[:id])
9
+ end
10
+
11
+ def new
12
+ @user = User.new
13
+ end
14
+
15
+ def create
16
+ @user = User.new(params[:user])
17
+ @user.role = params[:user][:role]
18
+ if @user.save
19
+ flash[:notice] = "Created #{@user.name}"
20
+ redirect_to admin_user_url(@user)
21
+ else
22
+ render :action => 'new'
23
+ end
24
+ end
25
+
26
+ def edit
27
+ @user = User.find(params[:id])
28
+ end
29
+
30
+ def update
31
+ @user = User.find(params[:id])
32
+ @user.role = params[:user][:role]
33
+ if @user.update_attributes(params[:user])
34
+ flash[:notice] = "Updated #{@user.name}"
35
+ redirect_to admin_user_url(@user)
36
+ else
37
+ render :action => 'edit'
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ @user = User.find(params[:id])
43
+ if @user != current_user
44
+ @user.destroy
45
+ flash[:notice] = "Deleted #{@user.name}"
46
+ else
47
+ flash[:error] = "Cannot delete yourself"
48
+ end
49
+ redirect_to admin_users_url
50
+ end
51
+
52
+ end
@@ -0,0 +1,25 @@
1
+ <%= form.error_messages %>
2
+ <p class="text_field">
3
+ <%= form.label :first_name %>
4
+ <%= form.text_field :first_name %>
5
+ </p>
6
+ <p class="text_field">
7
+ <%= form.label :last_name %>
8
+ <%= form.text_field :last_name %>
9
+ </p>
10
+ <p class="text_field">
11
+ <%= form.label :email %>
12
+ <%= form.text_field :email %>
13
+ </p>
14
+ <p class="password_field">
15
+ <%= form.label :password %>
16
+ <%= form.password_field :password %>
17
+ </p>
18
+ <p class="password_field">
19
+ <%= form.label :password_confirmation, "Confirm password" %>
20
+ <%= form.password_field :password_confirmation %>
21
+ </p>
22
+ <p>
23
+ <%= form.label :role %>
24
+ <%= form.collection_select :role, ['', 'admin'], :to_s, :to_s %>
25
+ </p>