dangerzone 0.0.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/README.md +21 -11
  2. data/lib/dangerzone/dangerzone_generator.rb +73 -59
  3. data/lib/dangerzone/templates/controllers/application_controller.rb +5 -6
  4. data/lib/dangerzone/templates/controllers/create_accounts_controller.rb +11 -15
  5. data/lib/dangerzone/templates/controllers/reset_passwords_controller.rb +12 -16
  6. data/lib/dangerzone/templates/controllers/sessions_controller.rb +19 -16
  7. data/lib/dangerzone/templates/migration.rb +2 -4
  8. data/lib/dangerzone/templates/models/user.rb +38 -12
  9. data/lib/dangerzone/templates/routes.rb +1 -1
  10. data/lib/dangerzone/templates/spec/controllers/create_accounts_controller_spec.rb +179 -0
  11. data/lib/dangerzone/templates/spec/controllers/reset_passwords_controller_spec.rb +131 -0
  12. data/lib/dangerzone/templates/spec/controllers/sessions_controller_spec.rb +135 -0
  13. data/lib/dangerzone/templates/spec/factories/users_factory.rb +15 -0
  14. data/lib/dangerzone/templates/spec/models/user_spec.rb +172 -0
  15. data/lib/dangerzone/templates/spec/spec_helper.rb +36 -0
  16. data/lib/dangerzone/templates/views/create_accounts/check_your_email.html.erb +1 -1
  17. data/lib/dangerzone/templates/views/create_accounts/new.html.erb +1 -1
  18. data/lib/dangerzone/templates/views/layouts/_dangerzone_nav.html.erb +10 -0
  19. data/lib/dangerzone/templates/views/layouts/application.html.erb +18 -0
  20. data/lib/dangerzone/templates/views/reset_passwords/new.html.erb +1 -1
  21. data/lib/dangerzone/templates/views/reset_passwords/reset_password_form.html.erb +2 -1
  22. data/lib/dangerzone/templates/views/sessions/new.html.erb +2 -2
  23. metadata +41 -22
  24. data/dangerzone.gemspec +0 -18
  25. data/lib/.DS_Store +0 -0
  26. data/lib/dangerzone/.DS_Store +0 -0
  27. data/lib/dangerzone/templates/.DS_Store +0 -0
  28. data/lib/dangerzone/templates/views/.DS_Store +0 -0
  29. data/lib/dangerzone/templates/views/nav.html.erb +0 -10
data/README.md CHANGED
@@ -4,20 +4,30 @@
4
4
  Dangerzone handles sign-in, sign-out, creating new accounts, confirmation emails, reset password emails,
5
5
  and user authentification stuff that pretty much every web app needs.
6
6
 
7
- It's pretty much a really stripped down Devise. While Devise is designed for people with a lot of experience,
8
- Dangerzone is more for beginners. All of the files it generates and logic it appends are easy to find and
9
- explore (hopefully, anyway), so if you're new to Rails you can use Dangerzone to learn (also hopefully).
7
+ It's pretty much a really stripped down and above the board Devise. While Devise is designed for people with a
8
+ lot of experience, Dangerzone is more for beginners. All of the files it generates and logic it appends are
9
+ easy to find and explore (hopefully, anyway), so if you're new to Rails you can use Dangerzone to learn
10
+ (also hopefully).
10
11
 
11
12
  It's also for people who maybe have more experience and don't want to spend time writing all of this stuff
12
13
  out by hand but don't want to use Devise for whatever reason (ie those with some experience but still
13
14
  don't understand Devise)
14
15
 
16
+ At some point there'll be more options, like a version that's a bit more explicit in what it's doing and a version
17
+ with a ton of comments that explain what's going on ('this is a ternary operator' or 'methods that end with question marks
18
+ usually return true or false'). Also, a version where you can opt out of generating the specs.
19
+
15
20
  ## Dependencies
16
- You'll need these gems (and the gems that they depend on) to use Dangerzone:
21
+ You'll need these gems to use Dangerzone:
17
22
 
18
23
  * Rails 3.2
19
24
  * Bcrypt-ruby 3.0
20
- * Thor
25
+
26
+ Dangerzone also generates some specs and a factory for you. You'll need these gems if you actually want to use them.
27
+
28
+ * Rspec-rails 2.13
29
+ * Factory_Girl_Rails 4.2
30
+
21
31
 
22
32
  ## How to install
23
33
  You can do one of these in your command line (if you have the RubyGems command line stuff installed):
@@ -32,17 +42,16 @@ Alternatively, you can just add this to your app's GemFile:
32
42
  gem 'dangerzone'
33
43
  ```
34
44
 
35
- And then bundle or bundle install.
45
+ And then ```bundle``` or ```bundle install```.
36
46
 
37
47
  ## How to use
38
-
39
48
  First, add this to your Gemfile:
40
49
 
41
50
  ```ruby
42
51
  gem 'dangerzone'
43
52
  ```
44
53
 
45
- Then bundle or bundle install.
54
+ Then ```bundle``` or ````bundle install```.
46
55
 
47
56
  Then run this command from your app's root directory:
48
57
 
@@ -50,7 +59,7 @@ Then run this command from your app's root directory:
50
59
  rails generate dangerzone
51
60
  ```
52
61
 
53
- You can also put '```g```'' instead of '```generate```' if you're really in a hurry. Anyway, you should see something that
62
+ You can also put '```g```' instead of '```generate```' if you're really in a hurry. Anyway, you should see something that
54
63
  looks like this:
55
64
 
56
65
  ```ruby
@@ -65,7 +74,7 @@ looks like this:
65
74
  [etc...]
66
75
  ```
67
76
 
68
- Now, if you're in a fresh app, all you really have to do is ```rake db:migrate```
77
+ Now, if you're in a fresh app, all you really have to do is ```rake db:migrate```.
69
78
 
70
79
  Note: If you're adding Dangerzone to an existing app then things can be a bit more tricky. For instance,
71
80
  if you've changed your code in certain places Dangerzone may not edit the files correctly. It may
@@ -141,7 +150,8 @@ can add them to before\_filters)
141
150
  * app/views/create\_accounts/new.html.erb
142
151
  * app/views/create\_accounts/dangerzone.html.erb
143
152
  * app/views/dangerzone\_mailer/account\_confirmation\_email.html.erb
144
- * app/views/dangerzone\_mailer/account\_confirmation\_email.text.erb
153
+ * app/views/dangerzone\_mailer/account\_confirmation\_email.text
154
+ .erb
145
155
  * app/views/dangerzone\_mailer/reset\_password\_email.html.erb
146
156
  * app/views/dangerzone\_mailer/reset\_password\_email.text.erb
147
157
  * app/views/layouts/\_dangerzone\_nav.html.erb
@@ -3,114 +3,117 @@ class DangerzoneGenerator < Rails::Generators::Base
3
3
 
4
4
  source_root File.expand_path('../templates', __FILE__)
5
5
 
6
+ include Rails::Generators::Migration
7
+ # desc "add the migrations"
8
+
9
+ def self.next_migration_number(path)
10
+ unless @prev_migration_nr
11
+ @prev_migration_nr = Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
12
+ else
13
+ @prev_migration_nr += 1
14
+ end
15
+ @prev_migration_nr.to_s
16
+ end
17
+
18
+ def generate_the_create_users_migration_file
19
+ migration_template 'migration.rb', 'db/migrate/create_users_table_via_dangerzone.rb'
20
+ end
21
+
6
22
  def edit_the_routes_file
7
23
  routes = IO.read(get_directory + '/templates/routes.rb')
8
- line = "::Application.routes.draw do"
24
+ line = '::Application.routes.draw do'
9
25
  gsub_file 'config/routes.rb', /.+(#{Regexp.escape(line)})/mi do |match|
10
26
  "#{match}\n\n#{routes}\n"
11
27
  end
12
28
  end
13
29
 
14
30
  def get_rid_of_rails_default_index_page_in_index
15
- remove_file "public/index.html"
31
+ remove_file 'public/index.html'
32
+ end
33
+
34
+ def generate_user_model_file
35
+ copy_files_to_app_dir %w(user.rb), 'models'
16
36
  end
17
37
 
18
38
  def generate_the_nav_partial
19
- copy_file "views/nav.html.erb", "app/views/layouts/_dangerzone_nav.html.erb"
39
+ copy_files_to_app_dir %w(_dangerzone_nav.html.erb), 'views/layouts'
20
40
  end
21
41
 
22
42
  def add_nav_partial_and_notice_to_application_html_erb
23
43
  nav = "<%= render 'layouts/dangerzone_nav' %>\n\n<%= notice %>"
24
- line = "<body>"
44
+ line = '<body>'
25
45
  gsub_file 'app/views/layouts/application.html.erb', /(#{Regexp.escape(line)})/mi do |match|
26
46
  "#{match}\n#{nav}\n"
27
47
  end
28
48
  end
29
49
 
30
- def generate_user_model_file
31
- copy_file "models/user.rb", "app/models/user.rb"
32
- end
33
-
34
50
  def generate_the_controllers
35
- copy_file "controllers/create_accounts_controller.rb", "app/controllers/create_accounts_controller.rb"
36
- copy_file "controllers/reset_passwords_controller.rb", "app/controllers/reset_passwords_controller.rb"
37
- copy_file "controllers/sessions_controller.rb", "app/controllers/sessions_controller.rb"
51
+ file_names = %w(create_accounts_controller.rb reset_passwords_controller.rb sessions_controller.rb)
52
+ copy_files_to_app_dir file_names, 'controllers'
38
53
  end
39
54
 
40
55
  def add_methods_to_application_controller
41
56
  app_controller_methods = IO.read(get_directory + '/templates/controllers/application_controller.rb')
42
- line = "protect_from_forgery"
57
+ line = 'protect_from_forgery'
43
58
  gsub_file 'app/controllers/application_controller.rb', /.+(#{Regexp.escape(line)})/mi do |match|
44
59
  "#{match}\n\n#{app_controller_methods}\n"
45
60
  end
46
61
  end
47
62
 
63
+ def generate_spec_folder
64
+ empty_directory 'spec'
65
+ empty_directory 'spec/models'
66
+ empty_directory 'spec/factories'
67
+ empty_directory 'spec/controllers'
68
+ end
69
+
70
+ def generate_the_specs
71
+ copy_files_to_spec_dir %w(users_factory.rb), 'factories'
72
+ file_names = %w(create_accounts_controller_spec.rb reset_passwords_controller_spec.rb sessions_controller_spec.rb)
73
+ copy_files_to_spec_dir file_names, 'controllers'
74
+ copy_files_to_spec_dir %w(user_spec.rb), 'models'
75
+ copy_file 'spec/spec_helper.rb', 'spec/spec_helper.rb'
76
+ end
77
+
48
78
  def generate_mailer
49
- copy_file "mailers/dangerzone_mailer.rb", "app/mailers/dangerzone_mailer.rb"
79
+ copy_files_to_app_dir %w(dangerzone_mailer.rb), 'mailers'
50
80
  end
51
81
 
52
- def add_mailer_config_to_development
53
- comment = "# Via dangerzone: configures actionmailer to use localhost:3000 as its default url"
82
+ def add_mailer_config_to_development_and_test
83
+ comment = '# Via dangerzone: configures actionmailer to use localhost:3000 as its default url'
54
84
  config_stuff = "config.action_mailer.default_url_options = { :host => 'localhost:3000' }"
55
- line = "config.assets.debug = true"
85
+ line = 'config.assets.debug = true'
56
86
  gsub_file 'config/environments/development.rb', /.+(#{Regexp.escape(line)})/mi do |match|
57
87
  "#{match}\n\n #{comment}\n #{config_stuff}\n\n"
58
88
  end
59
- end
60
-
61
- def uncomment_bcrypt_in_gemfile
62
- uncommented = "gem 'bcrypt-ruby'"
63
- line = "# gem 'bcrypt-ruby'"
64
- gsub_file 'Gemfile', /(#{Regexp.escape(line)})/mi do |match|
65
- "#{uncommented}"
89
+ line = 'config.active_support.deprecation = :stderr'
90
+ gsub_file 'config/environments/test.rb', /.+(#{Regexp.escape(line)})/mi do |match|
91
+ "#{match}\n\n #{comment}\n #{config_stuff}\n\n"
66
92
  end
67
93
  end
68
94
 
69
95
  def generate_view_directories
70
- empty_directory "app/views/create_accounts"
71
- empty_directory "app/views/dangerzone_mailer"
72
- empty_directory "app/views/reset_passwords"
73
- empty_directory "app/views/sessions"
96
+ file_names = %w(create_accounts dangerzone_mailer reset_passwords sessions)
97
+ file_names.each { |f| empty_directory "app/views/#{f}" }
74
98
  end
75
99
 
76
100
  def fill_view_directories
77
- copy_file "views/create_accounts/check_your_email.html.erb", "app/views/create_accounts/check_your_email.html.erb"
78
- copy_file "views/create_accounts/new.html.erb", "app/views/create_accounts/new.html.erb"
79
- copy_file "views/create_accounts/dangerzone.html.erb", "app/views/create_accounts/dangerzone.html.erb"
80
-
81
- copy_file "views/dangerzone_mailer/account_confirmation_email.html.erb", "app/views/dangerzone_mailer/account_confirmation_email.html.erb"
82
- copy_file "views/dangerzone_mailer/account_confirmation_email.text.erb", "app/views/dangerzone_mailer/account_confirmation_email.text.erb"
83
- copy_file "views/dangerzone_mailer/reset_password_email.html.erb", "app/views/dangerzone_mailer/reset_password_email.html.erb"
84
- copy_file "views/dangerzone_mailer/reset_password_email.text.erb", "app/views/dangerzone_mailer/reset_password_email.text.erb"
85
-
86
- copy_file "views/reset_passwords/new.html.erb", "app/views/reset_passwords/new.html.erb"
87
- copy_file "views/reset_passwords/reset_password_form.html.erb", "app/views/reset_passwords/reset_password_form.html.erb"
88
-
89
- copy_file "views/sessions/new.html.erb", "app/views/sessions/new.html.erb"
90
- end
91
-
92
- include Rails::Generators::Migration
93
- desc "add the migrations"
94
-
95
- def self.next_migration_number(path)
96
- unless @prev_migration_nr
97
- @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
98
- else
99
- @prev_migration_nr += 1
100
- end
101
- @prev_migration_nr.to_s
102
- end
103
-
104
- def generate_the_users_migration_file
105
- migration_template "migration.rb", "db/migrate/create_users_table_via_dangerzone.rb"
101
+ file_names = %w(check_your_email.html.erb new.html.erb dangerzone.html.erb)
102
+ copy_files_to_app_dir(file_names, "views/create_accounts")
103
+ file_names = %w(account_confirmation_email.html.erb
104
+ account_confirmation_email.text.erb
105
+ reset_password_email.html.erb
106
+ reset_password_email.text.erb)
107
+ copy_files_to_app_dir(file_names, "views/dangerzone_mailer")
108
+ copy_files_to_app_dir(%w(new.html.erb reset_password_form.html.erb), 'views/reset_passwords')
109
+ copy_files_to_app_dir(%w(new.html.erb), 'views/sessions')
106
110
  end
107
111
 
108
112
  private
109
113
 
110
114
  def gsub_file(relative_destination, regexp, *args, &block)
111
- path = relative_destination
112
- content = File.read(path).gsub(regexp, *args, &block)
113
- File.open(path, 'wb') { |file| file.write(content) }
115
+ content = File.read(relative_destination).gsub(regexp, *args, &block)
116
+ File.open(relative_destination, 'wb') { |file| file.write(content) }
114
117
  end
115
118
 
116
119
  def get_directory
@@ -119,4 +122,15 @@ class DangerzoneGenerator < Rails::Generators::Base
119
122
  directory.join('/')
120
123
  end
121
124
 
125
+ def copy_files_to_app_dir(file_names, gem_path)
126
+ copy_files_to_specific_dir(file_names, gem_path, 'app')
127
+ end
128
+
129
+ def copy_files_to_spec_dir(file_names, gem_path)
130
+ file_names.each { |f| copy_file "spec/#{gem_path}/#{f}", "spec/#{gem_path}/#{f}" }
131
+ end
132
+
133
+ def copy_files_to_specific_dir(file_names, gem_path, directory)
134
+ file_names.each { |f| copy_file "#{gem_path}/#{f}", "#{directory}/#{gem_path}/#{f}" }
135
+ end
122
136
  end
@@ -1,11 +1,10 @@
1
+ private
2
+
1
3
  def current_user
2
- @current_user = User.find_by_remember_token(cookies[:remember_token])
3
- @current_user ||= User.find_by_id(session[:user_id])
4
- @current_user = nil if @current_user && request.remote_ip != @current_user.sign_in_ip
5
- @current_user
4
+ @current_user = User.find_by_id(session[:user_id]) || User.find_by_remember_token(cookies[:remember_token])
5
+ request.remote_ip == @current_user.try(:sign_in_ip) ? @current_user : @current_user ||= User.new(sign_in_ip: request.remote_ip)
6
6
  end
7
7
 
8
8
  def authorize_user
9
- redirect_to sign_in_url if current_user.nil?
9
+ redirect_to :sign_in if current_user.new_record?
10
10
  end
11
-
@@ -1,42 +1,38 @@
1
1
  class CreateAccountsController < ApplicationController
2
2
 
3
3
  def create
4
- session[:email] = params[:user][:email]
5
4
  @user = User.new(params[:user])
6
- @user.email = @user.email.downcase
7
- @user.remember_token = SecureRandom.urlsafe_base64
5
+ @user.confirmed = false
8
6
  if @user.update_reset_password_credentials
9
7
  DangerzoneMailer.account_confirmation_email(@user).deliver
10
- redirect_to check_your_email_url, notice: "Registration successful."
8
+ redirect_to :check_your_email, notice: "Registration successful."
11
9
  else
12
- redirect_to sign_up_url, notice: "Registration unsuccessful"
10
+ redirect_to :sign_up, notice: "Registration unsuccessful"
13
11
  end
14
12
  end
15
13
 
16
14
  def resend_confirmation_email
17
- @user = User.find_by_email(params[:email].downcase)
18
- if @user && !@user.confirmed
19
- @user.update_reset_password_credentials
15
+ @user = User.find_by_email(params[:email].try(:downcase))
16
+ if @user.try(:update_reset_password_credentials) && !@user.confirmed
20
17
  DangerzoneMailer.account_confirmation_email(@user).deliver
21
- redirect_to check_your_email_url, notice: "Resent confirmation email."
18
+ redirect_to :check_your_email, notice: 'Resent confirmation email.'
22
19
  else
23
- redirect_to check_your_email_url, notice: "Something went wrong."
20
+ redirect_to :check_your_email, notice: 'Unable to resend confirmation email.'
24
21
  end
25
22
  end
26
23
 
27
24
  def confirm
28
25
  @user = User.find_by_id(params[:id])
29
- if @user && (Time.now - @user.reset_password_sent_at) < 60.minutes && @user.reset_password_token == params[:reset_password_token]
26
+ if @user.try(:in_time?) && @user.token_matches?(params[:reset_password_token])
30
27
  reset_session
31
- @user.confirm(request.remote_ip)
28
+ @user.confirm!(request.remote_ip)
32
29
  session[:user_id] = @user.id
33
- redirect_to root_url, notice: "User confirmation successful."
30
+ redirect_to :root, notice: "User confirmation successful."
34
31
  else
35
- redirect_to sign_up_url, notice: "User confirmation unsuccessful."
32
+ redirect_to :sign_up, notice: "User confirmation unsuccessful."
36
33
  end
37
34
  end
38
35
 
39
36
  def new
40
37
  end
41
-
42
38
  end
@@ -1,43 +1,39 @@
1
1
  class ResetPasswordsController < ApplicationController
2
2
 
3
- def send_reset_password
4
- @user = User.find_by_email(params[:email].downcase)
5
- if @user.update_reset_password_credentials
3
+ def requested_reset_password
4
+ @user = User.find_by_email(params[:email].try(:downcase))
5
+ if @user.try(:update_reset_password_credentials)
6
6
  DangerzoneMailer.reset_password_email(@user).deliver
7
- redirect_to forgot_password_url, notice: "Reset password email successfully sent."
7
+ redirect_to :forgot_password, notice: "Reset password email successfully sent."
8
8
  else
9
- redirect_to forgot_password_url, notice: "Reset password email failed to send."
9
+ redirect_to :forgot_password, notice: "Reset password email failed to send."
10
10
  end
11
11
  end
12
12
 
13
13
  def reset_password_form
14
14
  @user = User.find_by_id(params[:id])
15
- if @user && (Time.now - @user.reset_password_sent_at) < 60.minutes && @user.reset_password_token == params[:reset_password_token]
16
- session[:reset_password_user_id] = @user.id
17
- else
18
- redirect_to forgot_password_url, notice: "There was a problem, try having the email resent to you."
15
+ unless @user.try(:in_time?) && @user.token_matches?(params[:reset_password_token])
16
+ redirect_to :forgot_password, notice: "There was a problem, try having the email resent to you."
19
17
  end
20
18
  end
21
19
 
22
20
  def update_password
23
- @user = User.find_by_id(session[:reset_password_user_id])
24
- if @user && (Time.now - @user.reset_password_sent_at) < 60.minutes
21
+ @user = User.find_by_id(params[:id])
22
+ if @user.try(:in_time?)
25
23
  @user.password = params[:password]
26
24
  @user.password_confirmation = params[:password_confirmation]
27
- @user.reset_password_token = SecureRandom.urlsafe_base64
28
25
  if @user.save
29
26
  reset_session
30
27
  session[:user_id] = @user.id
31
- redirect_to root_url, notice: "Password successfully updated."
28
+ redirect_to :root, notice: "Password successfully updated."
32
29
  else
33
- redirect_to send_reset_password_url, notice: "Update password unsuccessful."
30
+ redirect_to reset_password_form_path(@user.id, @user.reset_password_token), notice: "Update password unsuccessful: password confirmation did not match password."
34
31
  end
35
32
  else
36
- redirect_to send_reset_password_url, notice: "Update password unsuccessful."
33
+ redirect_to :forgot_password, notice: "Update password unsuccessful."
37
34
  end
38
35
  end
39
36
 
40
37
  def new
41
38
  end
42
-
43
39
  end
@@ -1,30 +1,33 @@
1
1
  class SessionsController < ApplicationController
2
2
 
3
3
  def create
4
- @user = User.find_by_email(params[:email].downcase)
5
- if @user && @user.authenticate(params[:password]) && @user.confirmed
6
- @user.sign_in_ip = request.remote_ip
7
- @user.sign_in_count = @user.sign_in_count + 1
8
- if params[:remember_me] == '1'
9
- @user.remember_token = SecureRandom.urlsafe_base64
10
- cookies.permanent[:remember_token] = @user.remember_token
11
- else
12
- session[:user_id] = @user.id
13
- end
14
- @user.save
15
- redirect_to root_url, :notice => "Sign-in successful."
4
+ clear_cookies
5
+ @user = User.find_by_email(params[:email].try(:downcase))
6
+ if @user.try(:sign_in!, request.remote_ip, params[:password])
7
+ set_cookies(params[:remember_me])
8
+ redirect_to :root, notice: "Sign-in successful."
16
9
  else
17
- redirect_to sign_in_url, :notice => "Sign-in unsuccessful."
10
+ redirect_to :sign_in, notice: "Sign-in unsuccessful."
18
11
  end
19
12
  end
20
13
 
21
14
  def destroy
22
- cookies.delete(:remember_token)
23
- reset_session
24
- redirect_to sign_in_url, :notice => "Sign-out successful."
15
+ clear_cookies
16
+ redirect_to :sign_in, notice: "Sign-out successful."
25
17
  end
26
18
 
27
19
  def new
20
+ redirect_to :root if session[:user_id] || cookies[:remember_token]
21
+ end
22
+
23
+ private
24
+
25
+ def set_cookies(remember_me)
26
+ remember_me.present? ? cookies.permanent[:remember_token] = @user.remember_token : session[:user_id] = @user.id
28
27
  end
29
28
 
29
+ def clear_cookies
30
+ cookies.delete(:remember_token)
31
+ reset_session
32
+ end
30
33
  end