blue_light_special_heroku_fork 0.2.0.1

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 (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>