authkit 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -3
  3. data/Rakefile +3 -2
  4. data/lib/authkit/version.rb +1 -1
  5. data/lib/generators/authkit/install_generator.rb +181 -35
  6. data/lib/generators/authkit/templates/app/controllers/application_controller.rb +6 -0
  7. data/lib/generators/authkit/templates/app/controllers/auths_controller.rb +144 -0
  8. data/lib/generators/authkit/templates/app/controllers/email_confirmation_controller.rb +1 -1
  9. data/lib/generators/authkit/templates/app/controllers/password_reset_controller.rb +7 -1
  10. data/lib/generators/authkit/templates/app/controllers/sessions_controller.rb +11 -2
  11. data/lib/generators/authkit/templates/app/controllers/signup_controller.rb +4 -2
  12. data/lib/generators/authkit/templates/app/controllers/upload_controller.rb +78 -0
  13. data/lib/generators/authkit/templates/app/controllers/users_controller.rb +2 -2
  14. data/lib/generators/authkit/templates/app/forms/signup.rb +57 -7
  15. data/lib/generators/authkit/templates/app/helpers/auths_helper.rb +26 -0
  16. data/lib/generators/authkit/templates/app/helpers/upload_helper.rb +118 -0
  17. data/lib/generators/authkit/templates/app/models/auth.rb +81 -0
  18. data/lib/generators/authkit/templates/app/models/avatar.rb +45 -0
  19. data/lib/generators/authkit/templates/app/models/user.rb +53 -26
  20. data/lib/generators/authkit/templates/app/views/auths/connect.html.erb +34 -0
  21. data/lib/generators/authkit/templates/app/views/password_change/show.html.erb +9 -9
  22. data/lib/generators/authkit/templates/app/views/password_reset/show.html.erb +6 -6
  23. data/lib/generators/authkit/templates/app/views/sessions/new.html.erb +25 -7
  24. data/lib/generators/authkit/templates/app/views/signup/new.html.erb +44 -32
  25. data/lib/generators/authkit/templates/app/views/users/complete.html.erb +39 -0
  26. data/lib/generators/authkit/templates/app/views/users/edit.html.erb +31 -31
  27. data/lib/generators/authkit/templates/app/workers/avatar_import_worker.rb +12 -0
  28. data/lib/generators/authkit/templates/config/initializers/filter_parameter_logging.rb +2 -2
  29. data/lib/generators/authkit/templates/config/initializers/omniauth.rb +59 -0
  30. data/lib/generators/authkit/templates/config/initializers/paperclip.rb +68 -0
  31. data/lib/generators/authkit/templates/db/migrate/add_authkit_fields_to_users.rb +8 -6
  32. data/lib/generators/authkit/templates/db/migrate/create_auths.rb +24 -0
  33. data/lib/generators/authkit/templates/db/migrate/create_avatars.rb +27 -0
  34. data/lib/generators/authkit/templates/lib/full_name_splitter.rb +111 -0
  35. data/lib/generators/authkit/templates/lib/username_format_validator.rb +11 -0
  36. data/lib/generators/authkit/templates/spec/controllers/application_controller_spec.rb +31 -38
  37. data/lib/generators/authkit/templates/spec/controllers/auths_controller_spec.rb +72 -0
  38. data/lib/generators/authkit/templates/spec/controllers/email_confirmation_controller_spec.rb +25 -27
  39. data/lib/generators/authkit/templates/spec/controllers/password_change_controller_spec.rb +30 -30
  40. data/lib/generators/authkit/templates/spec/controllers/password_reset_controller_spec.rb +20 -20
  41. data/lib/generators/authkit/templates/spec/controllers/sessions_controller_spec.rb +33 -33
  42. data/lib/generators/authkit/templates/spec/controllers/signup_controller_spec.rb +19 -19
  43. data/lib/generators/authkit/templates/spec/controllers/users_controller_spec.rb +21 -21
  44. data/lib/generators/authkit/templates/spec/factories/user.rb +3 -3
  45. data/lib/generators/authkit/templates/spec/forms/signup_spec.rb +32 -31
  46. data/lib/generators/authkit/templates/spec/models/auth_spec.rb +18 -0
  47. data/lib/generators/authkit/templates/spec/models/user_spec.rb +72 -78
  48. data/spec/rails_helper.rb +50 -0
  49. data/spec/spec_helper.rb +70 -13
  50. metadata +35 -17
  51. data/lib/generators/authkit/templates/spec/spec_helper.rb +0 -4
@@ -0,0 +1,45 @@
1
+ class Avatar < ActiveRecord::Base
2
+ # Avatar images are publicly available (you can share the URL and it won't
3
+ # expire, but you probably can't guess it). Also, the images should be
4
+ # cached on the client side as the path name includes a hash.
5
+ has_attached_file :attachment,
6
+ styles: {thumb: "200x200#"},
7
+ s3_permissions: 'public-read',
8
+ s3_headers: {"Cache-Control" => "max-age=#{1.year.to_i}", "Expires" => 1.year.from_now.httpdate}
9
+
10
+ before_validation :prepare_import
11
+ validates :attachment, attachment_presence: true, unless: :attachment_importing?
12
+ after_save :async_import
13
+
14
+ def as_json(options = {})
15
+ super({
16
+ methods: [:url]
17
+ }.merge(options))
18
+ end
19
+
20
+ def url
21
+ self.attachment.url(:thumb)
22
+ end
23
+
24
+ def import!
25
+ return false unless self.attachment_importing?
26
+ self.attachment_importing = false
27
+ if self.remote_url.present?
28
+ uri = URI.parse(self.remote_url)
29
+ self.attachment = uri
30
+ self.attachment_file_name = File.basename(URI.decode(uri.path))
31
+ end
32
+ self.save
33
+ end
34
+
35
+ protected
36
+
37
+ def prepare_import
38
+ return unless self.remote_url.present? && self.remote_url_changed?
39
+ self.attachment_importing = true
40
+ end
41
+
42
+ def async_import
43
+ AvatarImportWorker.perform_async(self.id) if self.attachment_importing?
44
+ end
45
+ end
@@ -1,37 +1,49 @@
1
1
  require 'email_format_validator'
2
-
2
+ require 'full_name_splitter'
3
+ <% if username? %>require 'username_format_validator'
4
+ <% end %>
3
5
  class User < ActiveRecord::Base
4
- has_secure_password
5
- has_one_time_password
6
+ <% if oauth? %>
7
+ has_many :auths
8
+ <% end %>
6
9
 
7
- # Uncomment if you are not using strong params (note, that email is only permitted on
8
- # signup and confirmation_email is only permitted on update):
9
- #
10
- # attr_accessible :username,
11
- # :email,
12
- # :confirmation_email,
13
- # :password,
14
- # :password_confirmation,
15
- # :time_zone,
16
- # :first_name,
17
- # :last_name,
18
- # :bio,
19
- # :website,
20
- # :phone_number
10
+ has_secure_password validations: false
11
+ has_one_time_password
21
12
 
22
13
  before_validation :downcase_email
23
14
  before_validation :set_confirmation_email
24
15
 
25
- # Whenever the password is set, validate (not only on create)
26
- validates :password, presence: true, confirmation: true, length: {minimum: 6}, if: :password_set?
27
- validates :username, presence: true, uniqueness: {case_sensitive: false}
28
- validates :email, email_format: true, presence: true, uniqueness: true
29
- validates :confirmation_email, email_format: true, presence: true
30
-
16
+ validates :password, confirmation: true, length: { minimum: 6 }, if: :has_password?
17
+ validates :email, email_format: true, uniqueness: { allow_nil: true }
18
+ validates :confirmation_email, email_format: true
19
+ <% if username? %>validates :username, username_format: true, uniqueness: { case_sensitive: false, allow_nil: true }
20
+ <% end %>
21
+ validates :password, presence: true, unless: :has_auth_or_skip_password_validation?
22
+ validates :email, presence: true, unless: :has_auth?
23
+ validates :confirmation_email, presence: true, unless: :has_auth?
24
+ <% if username? %>validates :username, presence: true, unless: :has_auth?
25
+ <% end %>
31
26
  # Confirm emails check for existing emails for uniqueness as a convenience
32
27
  validate :confirmation_email_uniqueness, if: :confirmation_email_set?
33
28
 
34
- def display_name
29
+ def suspended?
30
+ self.suspended_at.present?
31
+ end
32
+
33
+ def incomplete?
34
+ <% if username? %>username.blank? || <% end %>email.blank? || password_digest.blank?
35
+ end
36
+
37
+ def full_name=(value)
38
+ return if value.blank?
39
+
40
+ splitter = FullNameSplitter.new(value)
41
+ self.first_name = splitter.first_name
42
+ self.last_name = splitter.last_name
43
+ self.full_name
44
+ end
45
+
46
+ def full_name
35
47
  [first_name, last_name].compact.join(" ")
36
48
  end
37
49
 
@@ -141,7 +153,23 @@ class User < ActiveRecord::Base
141
153
 
142
154
  protected
143
155
 
144
- def password_set?
156
+ def has_auth?
157
+ <% if oauth? %>
158
+ self.auths.first.present?
159
+ <% else %>
160
+ false
161
+ <% end %>
162
+ end
163
+
164
+ def has_auth_or_skip_password_validation?
165
+ has_auth? || skip_password_validation?
166
+ end
167
+
168
+ def skip_password_validation?
169
+ self.password.blank? && self.password_digest.present?
170
+ end
171
+
172
+ def has_password?
145
173
  self.password.present?
146
174
  end
147
175
 
@@ -167,5 +195,4 @@ class User < ActiveRecord::Base
167
195
  def confirmation_email_uniqueness
168
196
  errors.add(:confirmation_email, :taken, value: email) if User.where('email = ?', confirmation_email).count > 0
169
197
  end
170
-
171
198
  end
@@ -0,0 +1,34 @@
1
+ <div class="providers">
2
+ <%% providers.each do |provider| %>
3
+ <a href="/auth/<%%= provider %>?connect=1" class="oauth <%%= provider %>"><i class="fa <%%= provider_font_awesome_icon(provider) %>"></i> <%%= provider_formatted_name(provider) %> Account</a>
4
+ <%% end %>
5
+ </div>
6
+
7
+ <table class="connected">
8
+ <%% current_user.auths.order('provider, id').each do |auth| %>
9
+ <tr class="auth <%%= auth.provider %>">
10
+ <td width="30">
11
+ <%% unless auth.image_url.blank? %>
12
+ <img src="<%%= auth.image_url %>" class="avatar">
13
+ <%% end %>
14
+ </td>
15
+ <td>
16
+ <span class="name"><%%= auth.name %></span>
17
+ <%%= link_to 'Disconnect', disconnect_url(auth) %>
18
+ </td>
19
+ <td align="center">
20
+ <span class="icon"><i class="fa <%%= provider_font_awesome_icon(auth.provider) %>"></i></span>
21
+ </td>
22
+ </li>
23
+ <%% end %>
24
+ <%% if current_user.auths.count == 0 %>
25
+ <tr>
26
+ <td colspan="3">You have not connected any social accounts</td>
27
+ </tr>
28
+ <%% end %>
29
+ </table>
30
+
31
+ <div class="agreement">
32
+ By connecting your account you are also agreeing to our<br />
33
+ <a href="<%%= terms_path %>" target="_blank">Terms &amp; Conditions</a> and <a href="<%%= privacy_path %>" target="_blank">Privacy Policy</a>
34
+ </div>
@@ -1,17 +1,17 @@
1
1
  <h1>Please enter a new password</h1>
2
2
 
3
- <%= form_tag(password_change_path, method: "post") do %>
4
- <%= hidden_field_tag :token, params[:token] %>
5
- <%= hidden_field_tag :email, params[:email] %>
3
+ <%%= form_tag(password_change_path, method: "post") do %>
4
+ <%%= hidden_field_tag :token, params[:token] %>
5
+ <%%= hidden_field_tag :email, params[:email] %>
6
6
 
7
7
  <div class="field">
8
- <%= label_tag "password" %>
9
- <%= password_field_tag "password" %>
8
+ <%%= label_tag "password" %>
9
+ <%%= password_field_tag "password" %>
10
10
  </div>
11
11
  <div class="field">
12
- <%= label_tag "password_confirmation" %>
13
- <%= password_field_tag "password_confirmation" %>
12
+ <%%= label_tag "password_confirmation" %>
13
+ <%%= password_field_tag "password_confirmation" %>
14
14
  </div>
15
15
 
16
- <%= submit_tag "Change" %>
17
- <% end %>
16
+ <%%= submit_tag "Change" %>
17
+ <%% end %>
@@ -1,12 +1,12 @@
1
1
  <h1>Reset your password</h1>
2
2
 
3
- <%= form_tag(password_reset_path, method: "post") do %>
4
- <%= hidden_field_tag :token, params[:token] %>
3
+ <%%= form_tag(password_reset_path, method: "post") do %>
4
+ <%%= hidden_field_tag :token, params[:token] %>
5
5
 
6
6
  <div class="field">
7
- <%= label_tag "email", "Email or username" %>
8
- <%= text_field_tag "email" %>
7
+ <%%= label_tag "email", "Email<% if username? %> or username<% end %>" %>
8
+ <%%= text_field_tag "email" %>
9
9
  </div>
10
10
 
11
- <%= submit_tag "Reset" %>
12
- <% end %>
11
+ <%%= submit_tag "Reset" %>
12
+ <%% end %>
@@ -1,17 +1,35 @@
1
1
  <h1>Sign In</h1>
2
2
 
3
- <%= form_tag(login_path, method: "post") do %>
3
+ <%%= form_tag(login_path, method: "post") do %>
4
4
  <div class="field">
5
- <%= label_tag "email", "Email or username" %>
6
- <%= text_field_tag "email" %>
5
+ <%%= label_tag "email", "Email<% if username? %> or username<% end %>" %>
6
+ <%%= text_field_tag "email" %>
7
7
  </div>
8
8
  <div class="field">
9
- <%= label_tag "password" %>
10
- <%= password_field_tag "password" %>
9
+ <%%= label_tag "password" %>
10
+ <%%= password_field_tag "password" %>
11
11
  </div>
12
12
  <div class="field">
13
- <%= check_box_tag :remember_me, "1", true %>
13
+ <%%= check_box_tag :remember_me, "1", true %>
14
14
  <label for="remember_me">Keep me signed in on this computer</label>
15
15
  </div>
16
- <%= submit_tag "Login" %>
16
+ <div class="login">
17
+ <%%= submit_tag "Login" %>
18
+ </div>
19
+
20
+ <div class="forgot">
21
+ <a href="/password/reset" class="forgot">Forgot your password?</a>
22
+ </div>
23
+ <%% end %>
24
+
25
+ <% if oauth? %>
26
+ <div class="or">
27
+ or sign in using a connected account
28
+ </div>
29
+
30
+ <div class="providers">
31
+ <%% providers.each do |provider| %>
32
+ <a href="/auth/<%%= provider %>?login=1" class="oauth <%%= provider %>"><i class="fa <%%= provider_font_awesome_icon(provider) %>"></i> <%%= provider_formatted_name(provider) %> Account</a>
33
+ <%% end %>
34
+ </div>
17
35
  <% end %>
@@ -1,62 +1,74 @@
1
1
  <h1>Sign Up</h1>
2
2
 
3
- <% if @signup.errors.any? %>
3
+ <% if oauth? %>
4
+ <div class="providers">
5
+ <%% providers.each do |provider| %>
6
+ <a href="/auth/<%%= provider %>?signup=1" class="oauth <%%= provider %>"><i class="fa <%%= provider_font_awesome_icon(provider) %>"></i> <%%= provider_formatted_name(provider) %> Account</a>
7
+ <%% end %>
8
+ </div>
9
+
10
+ <div class="or">
11
+ or sign up using your email
12
+ </div>
13
+ <% end %>
14
+
15
+ <%% if @signup.errors.any? %>
4
16
  <div id="error_explanation">
5
17
  <div class="alert alert-error">
6
- The form contains <%= pluralize(@signup.errors.count, "error") %>.
18
+ The form contains <%%= pluralize(@signup.errors.count, "error") %>.
7
19
  </div>
8
20
  <ul>
9
- <% @signup.errors.full_messages.each do |msg| %>
10
- <li>* <%= msg %></li>
11
- <% end %>
21
+ <%% @signup.errors.full_messages.each do |msg| %>
22
+ <li>* <%%= msg %></li>
23
+ <%% end %>
12
24
  </ul>
13
25
  </div>
14
- <% end %>
26
+ <%% end %>
15
27
 
16
- <%= form_for @signup, url: signup_path do |f| %>
28
+ <%%= form_for @signup, url: signup_path do |f| %>
17
29
  <div class="field">
18
- <%= f.label "first_name" %>
19
- <%= f.text_field "first_name" %>
30
+ <%%= f.label "first_name" %>
31
+ <%%= f.text_field "first_name" %>
20
32
  </div>
21
33
  <div class="field">
22
- <%= f.label "last_name" %>
23
- <%= f.text_field "last_name" %>
34
+ <%%= f.label "last_name" %>
35
+ <%%= f.text_field "last_name" %>
24
36
  </div>
25
37
  <div class="field">
26
- <%= f.label "bio" %>
27
- <%= f.text_area "bio" %>
38
+ <%%= f.label "bio" %>
39
+ <%%= f.text_area "bio" %>
28
40
  </div>
29
41
  <div class="field">
30
- <%= f.label "website" %>
31
- <%= f.text_field "website" %>
42
+ <%%= f.label "website" %>
43
+ <%%= f.text_field "website" %>
32
44
  </div>
33
45
  <div class="field">
34
- <%= f.label "phone_number" %>
35
- <%= f.text_field "phone_number" %>
46
+ <%%= f.label "phone_number" %>
47
+ <%%= f.text_field "phone_number" %>
36
48
  </div>
37
49
  <div class="field">
38
- <%= f.label "time_zone" %>
39
- <%= f.time_zone_select('time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)") %>
50
+ <%%= f.label "time_zone" %>
51
+ <%%= f.time_zone_select('time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)") %>
40
52
  </div>
41
53
  <div class="field">
42
- <%= f.label "email" %>
43
- <%= f.text_field "email" %>
54
+ <%%= f.label "email" %>
55
+ <%%= f.text_field "email" %>
44
56
  </div>
45
- <div class="field">
46
- <%= f.label "username" %>
47
- <%= f.text_field "username" %>
57
+ <% if username? %><div class="field">
58
+ <%%= f.label "username" %>
59
+ <%%= f.text_field "username" %>
48
60
  </div>
49
- <div class="field">
50
- <%= f.label "password" %>
51
- <%= f.password_field "password" %>
61
+ <% end %><div class="field">
62
+ <%%= f.label "password" %>
63
+ <%%= f.password_field "password" %>
52
64
  </div>
53
65
  <div class="field">
54
- <%= f.label "password_confirmation" %>
55
- <%= f.password_field "password_confirmation" %>
66
+ <%%= f.label "password_confirmation" %>
67
+ <%%= f.password_field "password_confirmation" %>
56
68
  </div>
57
69
  <div class="field">
58
- <%= check_box_tag :remember_me, "1", true %>
70
+ <%%= check_box_tag :remember_me, "1", true %>
59
71
  <label for="remember_me">Keep me signed in on this computer</label>
60
72
  </div>
61
- <%= f.submit "Sign up" %>
62
- <% end %>
73
+ <%%= f.submit "Sign up" %>
74
+ <%% end %>
@@ -0,0 +1,39 @@
1
+ <h1>One more step to complete your account</h1>
2
+
3
+ <%% if @user.errors.any? %>
4
+ <div id="error_explanation">
5
+ <div class="alert alert-error">
6
+ The form contains <%%= pluralize(@user.errors.count, "error") %>.
7
+ </div>
8
+ <ul>
9
+ <%% @user.errors.full_messages.each do |msg| %>
10
+ <li>* <%%= msg %></li>
11
+ <%% end %>
12
+ </ul>
13
+ </div>
14
+ <%% end %>
15
+
16
+ <%%= form_for @user do |f| %>
17
+ <div class="field">
18
+ <%%= f.label "first_name" %>
19
+ <%%= f.text_field "first_name" %>
20
+ </div>
21
+ <div class="field">
22
+ <%%= f.label "last_name" %>
23
+ <%%= f.text_field "last_name" %>
24
+ </div>
25
+ <div class="field">
26
+ <%%= f.label "email" %>
27
+ <%%= f.text_field "confirmation_email" %>
28
+ </div>
29
+ <div class="field">
30
+ <%%= f.label "password" %>
31
+ <%%= f.password_field "password" %>
32
+ </div>
33
+ <div class="field">
34
+ <%%= f.label "password_confirmation" %>
35
+ <%%= f.password_field "password_confirmation" %>
36
+ </div>
37
+ <%%= f.submit "Finish" %>
38
+ <%% end %>
39
+
@@ -1,58 +1,58 @@
1
1
  <h1>Account</h1>
2
2
 
3
- <% if @user.errors.any? %>
3
+ <%% if @user.errors.any? %>
4
4
  <div id="error_explanation">
5
5
  <div class="alert alert-error">
6
- The form contains <%= pluralize(@user.errors.count, "error") %>.
6
+ The form contains <%%= pluralize(@user.errors.count, "error") %>.
7
7
  </div>
8
8
  <ul>
9
- <% @user.errors.full_messages.each do |msg| %>
10
- <li>* <%= msg %></li>
11
- <% end %>
9
+ <%% @user.errors.full_messages.each do |msg| %>
10
+ <li>* <%%= msg %></li>
11
+ <%% end %>
12
12
  </ul>
13
13
  </div>
14
- <% end %>
14
+ <%% end %>
15
15
 
16
- <%= form_for @user do |f| %>
16
+ <%%= form_for @user do |f| %>
17
17
  <div class="field">
18
- <%= f.label "first_name" %>
19
- <%= f.text_field "first_name" %>
18
+ <%%= f.label "first_name" %>
19
+ <%%= f.text_field "first_name" %>
20
20
  </div>
21
21
  <div class="field">
22
- <%= f.label "last_name" %>
23
- <%= f.text_field "last_name" %>
22
+ <%%= f.label "last_name" %>
23
+ <%%= f.text_field "last_name" %>
24
24
  </div>
25
25
  <div class="field">
26
- <%= f.label "bio" %>
27
- <%= f.text_area "bio" %>
26
+ <%%= f.label "bio" %>
27
+ <%%= f.text_area "bio" %>
28
28
  </div>
29
29
  <div class="field">
30
- <%= f.label "website" %>
31
- <%= f.text_field "website" %>
30
+ <%%= f.label "website" %>
31
+ <%%= f.text_field "website" %>
32
32
  </div>
33
33
  <div class="field">
34
- <%= f.label "phone_number" %>
35
- <%= f.text_field "phone_number" %>
34
+ <%%= f.label "phone_number" %>
35
+ <%%= f.text_field "phone_number" %>
36
36
  </div>
37
37
  <div class="field">
38
- <%= f.label "time_zone" %>
39
- <%= f.time_zone_select('time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)") %>
38
+ <%%= f.label "time_zone" %>
39
+ <%%= f.time_zone_select('time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)") %>
40
40
  </div>
41
41
  <div class="field">
42
- <%= f.label "email" %>
43
- <%= f.text_field "confirmation_email" %>
42
+ <%%= f.label "email" %>
43
+ <%%= f.text_field "confirmation_email" %>
44
44
  </div>
45
- <div class="field">
46
- <%= f.label "username" %>
47
- <%= f.text_field "username" %>
45
+ <% if username? %><div class="field">
46
+ <%%= f.label "username" %>
47
+ <%%= f.text_field "username" %>
48
48
  </div>
49
- <div class="field">
50
- <%= f.label "password" %>
51
- <%= f.password_field "password" %>
49
+ <% end %><div class="field">
50
+ <%%= f.label "password" %>
51
+ <%%= f.password_field "password" %>
52
52
  </div>
53
53
  <div class="field">
54
- <%= f.label "password_confirmation" %>
55
- <%= f.password_field "password_confirmation" %>
54
+ <%%= f.label "password_confirmation" %>
55
+ <%%= f.password_field "password_confirmation" %>
56
56
  </div>
57
- <%= f.submit "Save" %>
58
- <% end %>
57
+ <%%= f.submit "Save" %>
58
+ <%% end %>