cops 0.2.0.6
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.
- data/LICENSE +20 -0
- data/README.rdoc +113 -0
- data/Rakefile +95 -0
- data/VERSION +1 -0
- data/app/controllers/blue_light_special/confirmations_controller.rb +76 -0
- data/app/controllers/blue_light_special/impersonations_controller.rb +44 -0
- data/app/controllers/blue_light_special/passwords_controller.rb +93 -0
- data/app/controllers/blue_light_special/sessions_controller.rb +76 -0
- data/app/controllers/blue_light_special/users_controller.rb +85 -0
- data/app/models/blue_light_special_mailer.rb +28 -0
- data/app/models/deliver_change_password_job.rb +19 -0
- data/app/models/deliver_welcome_job.rb +17 -0
- data/app/models/generic_mailer.rb +31 -0
- data/app/models/impersonation.rb +26 -0
- data/app/models/mimi_mailer.rb +30 -0
- data/app/views/generic_mailer/change_password.html.erb +9 -0
- data/app/views/generic_mailer/confirmation.html.erb +5 -0
- data/app/views/generic_mailer/welcome.html.erb +1 -0
- data/app/views/impersonations/index.html.erb +5 -0
- data/app/views/passwords/edit.html.erb +23 -0
- data/app/views/passwords/new.html.erb +15 -0
- data/app/views/sessions/new.html.erb +48 -0
- data/app/views/users/_form.html.erb +21 -0
- data/app/views/users/edit.html.erb +6 -0
- data/app/views/users/new.html.erb +6 -0
- data/app/views/users/show.html.erb +8 -0
- data/generators/blue_light_special/USAGE +1 -0
- data/generators/blue_light_special/blue_light_special_generator.rb +78 -0
- data/generators/blue_light_special/lib/insert_commands.rb +33 -0
- data/generators/blue_light_special/lib/rake_commands.rb +22 -0
- data/generators/blue_light_special/templates/README +20 -0
- data/generators/blue_light_special/templates/application.html.erb +50 -0
- data/generators/blue_light_special/templates/blue_light_special.rb +25 -0
- data/generators/blue_light_special/templates/blue_light_special.yml +45 -0
- data/generators/blue_light_special/templates/factories.rb +23 -0
- data/generators/blue_light_special/templates/migrations/create_users.rb +24 -0
- data/generators/blue_light_special/templates/migrations/update_users.rb +44 -0
- data/generators/blue_light_special/templates/style.css +31 -0
- data/generators/blue_light_special/templates/user.rb +3 -0
- data/generators/blue_light_special/templates/xd_receiver.html +10 -0
- data/generators/blue_light_special/templates/xd_receiver_ssl.html +10 -0
- data/generators/blue_light_special_admin/USAGE +1 -0
- data/generators/blue_light_special_admin/blue_light_special_admin_generator.rb +30 -0
- data/generators/blue_light_special_admin/lib/insert_commands.rb +33 -0
- data/generators/blue_light_special_admin/templates/README +16 -0
- data/generators/blue_light_special_admin/templates/app/controllers/admin/admin_controller.rb +14 -0
- data/generators/blue_light_special_admin/templates/app/controllers/admin/users_controller.rb +52 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/_form.html.erb +25 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/edit.html.erb +6 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/index.html.erb +7 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/new.html.erb +6 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/show.html.erb +10 -0
- data/generators/blue_light_special_admin/templates/test/integration/admin/users_test.rb +201 -0
- data/generators/blue_light_special_tests/USAGE +1 -0
- data/generators/blue_light_special_tests/blue_light_special_tests_generator.rb +21 -0
- data/generators/blue_light_special_tests/templates/README +58 -0
- data/generators/blue_light_special_tests/templates/test/integration/edit_profile_test.rb +35 -0
- data/generators/blue_light_special_tests/templates/test/integration/facebook_test.rb +61 -0
- data/generators/blue_light_special_tests/templates/test/integration/impersonation_test.rb +39 -0
- data/generators/blue_light_special_tests/templates/test/integration/password_reset_test.rb +128 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_in_test.rb +66 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_out_test.rb +28 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_up_test.rb +47 -0
- data/lib/blue_light_special/authentication.rb +138 -0
- data/lib/blue_light_special/configuration.rb +34 -0
- data/lib/blue_light_special/extensions/errors.rb +6 -0
- data/lib/blue_light_special/extensions/rescue.rb +5 -0
- data/lib/blue_light_special/routes.rb +62 -0
- data/lib/blue_light_special/user.rb +279 -0
- data/lib/blue_light_special.rb +7 -0
- data/rails/init.rb +4 -0
- data/shoulda_macros/blue_light_special.rb +244 -0
- data/test/controllers/passwords_controller_test.rb +184 -0
- data/test/controllers/sessions_controller_test.rb +129 -0
- data/test/controllers/users_controller_test.rb +57 -0
- data/test/models/blue_light_special_mailer_test.rb +52 -0
- data/test/models/impersonation_test.rb +25 -0
- data/test/models/user_test.rb +213 -0
- data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
- data/test/rails_root/app/controllers/application_controller.rb +6 -0
- data/test/rails_root/app/helpers/application_helper.rb +5 -0
- data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
- data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
- data/test/rails_root/config/boot.rb +110 -0
- data/test/rails_root/config/environment.rb +22 -0
- data/test/rails_root/config/environments/development.rb +19 -0
- data/test/rails_root/config/environments/production.rb +1 -0
- data/test/rails_root/config/environments/test.rb +37 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/requires.rb +13 -0
- data/test/rails_root/config/initializers/time_formats.rb +4 -0
- data/test/rails_root/config/routes.rb +9 -0
- data/test/rails_root/public/dispatch.rb +10 -0
- data/test/rails_root/script/create_project.rb +52 -0
- data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
- data/test/test_helper.rb +21 -0
- metadata +212 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class GenericMailer < ActionMailer::Base
|
|
2
|
+
|
|
3
|
+
def change_password(user)
|
|
4
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
5
|
+
recipients user.email
|
|
6
|
+
subject I18n.t(:change_password,
|
|
7
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
8
|
+
:default => "Change your password")
|
|
9
|
+
body :url => edit_user_password_url(user,
|
|
10
|
+
:token => user.password_reset_token,
|
|
11
|
+
:escape => false)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def welcome(user)
|
|
15
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
16
|
+
recipients user.email
|
|
17
|
+
subject I18n.t(:welcome,
|
|
18
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
19
|
+
:default => "Welcome")
|
|
20
|
+
body :user => user
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def confirmation(user)
|
|
24
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
25
|
+
recipients user.email
|
|
26
|
+
subject I18n.t(:confirmation,
|
|
27
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
28
|
+
:default => "Account confirmation")
|
|
29
|
+
body :user => user
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Impersonation
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Returns a hash based on the given id.
|
|
5
|
+
#
|
|
6
|
+
def self.hash_for(id)
|
|
7
|
+
raise(ArgumentError, "Must provide an id") unless id
|
|
8
|
+
generate_hash(id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Returns +true+ if the given hash is valid for the given id.
|
|
13
|
+
#
|
|
14
|
+
def self.valid_hash?(id, hash)
|
|
15
|
+
hash == generate_hash(id)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def self.generate_hash(id)
|
|
23
|
+
Digest::MD5.hexdigest("----#{id}-----#{BlueLightSpecial.configuration.impersonation_hash}-----")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class MimiMailer < MadMimiMailer
|
|
2
|
+
|
|
3
|
+
def mimi_change_password(user)
|
|
4
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
5
|
+
recipients user.email
|
|
6
|
+
subject I18n.t(:change_password,
|
|
7
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
8
|
+
:default => "Change your password")
|
|
9
|
+
body :url => edit_user_password_url(user,
|
|
10
|
+
:token => user.password_reset_token,
|
|
11
|
+
:escape => false)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def mimi_welcome(user)
|
|
15
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
16
|
+
recipients user.email
|
|
17
|
+
subject I18n.t(:welcome,
|
|
18
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
19
|
+
:default => "Welcome")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def confirmation(user)
|
|
23
|
+
from BlueLightSpecial.configuration.mailer_sender
|
|
24
|
+
recipients user.email
|
|
25
|
+
subject I18n.t(:confirmation,
|
|
26
|
+
:scope => [:blue_light_special, :models, :blue_light_special_mailer],
|
|
27
|
+
:default => "Account confirmation")
|
|
28
|
+
body :user => user
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Someone, hopefully you, has requested that we send you a link to change your password.
|
|
2
|
+
|
|
3
|
+
Here's the link:
|
|
4
|
+
|
|
5
|
+
<%= edit_user_password_url(@user,
|
|
6
|
+
:token => @user.confirmation_token,
|
|
7
|
+
:escape => false) %>
|
|
8
|
+
|
|
9
|
+
If you didn't request this, ignore this email. Don't worry. Your password hasn't been changed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Welcome
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<h2>Change your password</h2>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
Your password has been reset. Choose a new password below.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<%= error_messages_for :user %>
|
|
8
|
+
|
|
9
|
+
<% form_for(:user,
|
|
10
|
+
:url => user_password_path(@user, :token => @user.password_reset_token),
|
|
11
|
+
:html => { :method => :put }) do |form| %>
|
|
12
|
+
<div class="password_field">
|
|
13
|
+
<%= form.label :password, "Choose password" %>
|
|
14
|
+
<%= form.password_field :password %>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="password_field">
|
|
17
|
+
<%= form.label :password_confirmation, "Confirm password" %>
|
|
18
|
+
<%= form.password_field :password_confirmation %>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="submit_field">
|
|
21
|
+
<%= form.submit "Save this password", :disable_with => "Please wait..." %>
|
|
22
|
+
</div>
|
|
23
|
+
<% end %>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<h2>Change your password</h2>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
We will email you a link to change your password.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<% form_for :password, :url => passwords_path do |form| %>
|
|
8
|
+
<div class="text_field">
|
|
9
|
+
<%= form.label :email, "Email address" %>
|
|
10
|
+
<%= form.text_field :email %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="submit_field">
|
|
13
|
+
<%= form.submit "Reset password", :disable_with => "Please wait..." %>
|
|
14
|
+
</div>
|
|
15
|
+
<% end %>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<%- if BlueLightSpecial.configuration.use_facebook_connect -%>
|
|
2
|
+
<%- if request.ssl? -%>
|
|
3
|
+
<%= javascript_include_tag 'https://ssl.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US' %>
|
|
4
|
+
<%- else -%>
|
|
5
|
+
<%= javascript_include_tag 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US' %>
|
|
6
|
+
<%- end -%>
|
|
7
|
+
<script>
|
|
8
|
+
function facebook_onlogin() {
|
|
9
|
+
document.location.href = "<%= fb_connect_path %>";
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
<%- end -%>
|
|
13
|
+
|
|
14
|
+
<h2>Sign in</h2>
|
|
15
|
+
|
|
16
|
+
<% form_for :session, :url => session_path do |form| %>
|
|
17
|
+
<div class="text_field">
|
|
18
|
+
<%= form.label :email %>
|
|
19
|
+
<%= form.text_field :email %>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="text_field">
|
|
22
|
+
<%= form.label :password %>
|
|
23
|
+
<%= form.password_field :password %>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="submit_field">
|
|
26
|
+
<%= form.submit "Sign in", :disable_with => "Please wait..." %>
|
|
27
|
+
<%- if BlueLightSpecial.configuration.use_facebook_connect -%>
|
|
28
|
+
or <fb:login-button onlogin="facebook_onlogin();" length="long" v="2" size="large"></fb:login-button>
|
|
29
|
+
<%- end -%>
|
|
30
|
+
</div>
|
|
31
|
+
<% end %>
|
|
32
|
+
|
|
33
|
+
<ul>
|
|
34
|
+
<li>
|
|
35
|
+
<%= link_to "Sign up", sign_up_path %>
|
|
36
|
+
</li>
|
|
37
|
+
<li>
|
|
38
|
+
<%= link_to "Forgot password?", new_password_path %>
|
|
39
|
+
</li>
|
|
40
|
+
</ul>
|
|
41
|
+
|
|
42
|
+
<%- if BlueLightSpecial.configuration.use_facebook_connect -%>
|
|
43
|
+
<script type="text/javascript">
|
|
44
|
+
FB.init("<%= BlueLightSpecial.configuration.facebook_api_key %>", "xd_receiver.html", {
|
|
45
|
+
permsToRequestOnConnect : "email",
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
<%- end -%>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<%= form.error_messages %>
|
|
2
|
+
<p class="text_field">
|
|
3
|
+
<%= form.label :email %>
|
|
4
|
+
<%= form.text_field :email %>
|
|
5
|
+
</p>
|
|
6
|
+
<p class="text_field">
|
|
7
|
+
<%= form.label :first_name %>
|
|
8
|
+
<%= form.text_field :first_name %>
|
|
9
|
+
</p>
|
|
10
|
+
<p class="text_field">
|
|
11
|
+
<%= form.label :last_name %>
|
|
12
|
+
<%= form.text_field :last_name %>
|
|
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>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
script/generate blue_light_special
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
|
|
3
|
+
|
|
4
|
+
class BlueLightSpecialGenerator < Rails::Generator::Base
|
|
5
|
+
|
|
6
|
+
def manifest
|
|
7
|
+
record do |m|
|
|
8
|
+
m.directory File.join("config", "initializers")
|
|
9
|
+
m.file "blue_light_special.rb", "config/initializers/blue_light_special.rb"
|
|
10
|
+
m.file "blue_light_special.yml", "config/blue_light_special.yml"
|
|
11
|
+
|
|
12
|
+
m.directory File.join("app", "views", "layouts")
|
|
13
|
+
m.file "application.html.erb", "app/views/layouts/application.html.erb"
|
|
14
|
+
|
|
15
|
+
m.directory File.join("public", "stylesheets")
|
|
16
|
+
m.file "style.css", "public/stylesheets/style.css"
|
|
17
|
+
|
|
18
|
+
m.file "xd_receiver.html", "public/xd_receiver.html"
|
|
19
|
+
m.file "xd_receiver_ssl.html", "public/xd_receiver_ssl.html"
|
|
20
|
+
|
|
21
|
+
m.insert_into "app/controllers/application_controller.rb",
|
|
22
|
+
"include BlueLightSpecial::Authentication"
|
|
23
|
+
|
|
24
|
+
user_model = "app/models/user.rb"
|
|
25
|
+
if File.exists?(user_model)
|
|
26
|
+
m.insert_into user_model, "include BlueLightSpecial::User"
|
|
27
|
+
else
|
|
28
|
+
m.directory File.join("app", "models")
|
|
29
|
+
m.file "user.rb", user_model
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
m.insert_into "config/routes.rb",
|
|
33
|
+
"BlueLightSpecial::Routes.draw(map)"
|
|
34
|
+
|
|
35
|
+
m.directory File.join("test", "factories")
|
|
36
|
+
m.file "factories.rb", "test/factories/user.rb"
|
|
37
|
+
|
|
38
|
+
m.migration_template "migrations/#{migration_source_name}.rb",
|
|
39
|
+
'db/migrate',
|
|
40
|
+
:migration_file_name => "blue_light_special_#{migration_target_name}"
|
|
41
|
+
|
|
42
|
+
m.readme "README"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def schema_version_constant
|
|
47
|
+
if upgrading_blue_light_special_again?
|
|
48
|
+
"To#{schema_version.gsub('_', '')}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def migration_source_name
|
|
55
|
+
if ActiveRecord::Base.connection.table_exists?(:users)
|
|
56
|
+
'update_users'
|
|
57
|
+
else
|
|
58
|
+
'create_users'
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def migration_target_name
|
|
63
|
+
if upgrading_blue_light_special_again?
|
|
64
|
+
"update_users_to_#{schema_version}"
|
|
65
|
+
else
|
|
66
|
+
'create_users'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def schema_version
|
|
71
|
+
IO.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip.gsub(/[^\d]/, '_')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def upgrading_blue_light_special_again?
|
|
75
|
+
ActiveRecord::Base.connection.table_exists?(:users)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
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|.*Routes).*$/ 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,22 @@
|
|
|
1
|
+
Rails::Generator::Commands::Create.class_eval do
|
|
2
|
+
def rake_db_migrate
|
|
3
|
+
logger.rake "db:migrate"
|
|
4
|
+
unless system("rake db:migrate")
|
|
5
|
+
logger.rake "db:migrate failed. Rolling back"
|
|
6
|
+
command(:destroy).invoke!
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
|
12
|
+
def rake_db_migrate
|
|
13
|
+
logger.rake "db:rollback"
|
|
14
|
+
system "rake db:rollback"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Rails::Generator::Commands::List.class_eval do
|
|
19
|
+
def rake_db_migrate
|
|
20
|
+
logger.rake "db:migrate"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
*******************************************************************************
|
|
3
|
+
|
|
4
|
+
Next:
|
|
5
|
+
|
|
6
|
+
1. Configure default url options for the mailer to generate URLs in emails.
|
|
7
|
+
In production.rb it must be the actual host your application is deployed to.
|
|
8
|
+
In config/environments/test.rb and config/environments/development.rb:
|
|
9
|
+
|
|
10
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
|
11
|
+
|
|
12
|
+
2. If you haven't already, be sure you have delayed_jobs setup and configured:
|
|
13
|
+
|
|
14
|
+
./script/generate delayed_job
|
|
15
|
+
|
|
16
|
+
3. Migrate:
|
|
17
|
+
|
|
18
|
+
rake db:migrate
|
|
19
|
+
|
|
20
|
+
*******************************************************************************
|
|
@@ -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
|
+
}
|