authpwn_rails 0.16.2 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -6
- data/Gemfile +7 -8
- data/Gemfile.lock +97 -113
- data/Gemfile.rails4 +8 -9
- data/{Gemfile.rails3 → Gemfile.rails41} +6 -7
- data/Gemfile.rails42 +17 -0
- data/README.rdoc +1 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/app/models/credentials/email.rb +15 -37
- data/app/models/credentials/omni_auth_uid.rb +96 -0
- data/app/models/credentials/password.rb +0 -5
- data/app/models/tokens/base.rb +11 -38
- data/authpwn_rails.gemspec +35 -33
- data/lib/authpwn_rails/credential_model.rb +1 -5
- data/lib/authpwn_rails/generators/all_generator.rb +3 -1
- data/lib/authpwn_rails/generators/templates/001_create_users.rb +3 -3
- data/lib/authpwn_rails/generators/templates/003_create_credentials.rb +7 -7
- data/lib/authpwn_rails/generators/templates/credentials.yml +13 -13
- data/lib/authpwn_rails/generators/templates/omniauth_initializer.rb +13 -0
- data/lib/authpwn_rails/generators/templates/session_controller_test.rb +22 -0
- data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.html.erb +3 -3
- data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.text.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session_mailer/reset_password_email.html.erb +3 -3
- data/lib/authpwn_rails/generators/templates/session_mailer/reset_password_email.text.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session_mailer.rb +1 -1
- data/lib/authpwn_rails/generators/templates/session_mailer_test.rb +14 -4
- data/lib/authpwn_rails/generators/templates/user.rb +40 -5
- data/lib/authpwn_rails/http_basic.rb +6 -5
- data/lib/authpwn_rails/routes.rb +20 -7
- data/lib/authpwn_rails/session.rb +1 -1
- data/lib/authpwn_rails/session_controller.rb +48 -12
- data/lib/authpwn_rails/session_mailer.rb +13 -14
- data/lib/authpwn_rails/session_model.rb +4 -24
- data/lib/authpwn_rails/user_extensions/email_field.rb +5 -21
- data/lib/authpwn_rails/user_extensions/password_field.rb +0 -4
- data/lib/authpwn_rails/user_model.rb +46 -12
- data/lib/authpwn_rails.rb +0 -2
- data/test/cookie_controller_test.rb +1 -7
- data/test/credentials/omni_auth_uid_credential_test.rb +141 -0
- data/test/helpers/action_controller.rb +2 -8
- data/test/helpers/db_setup.rb +8 -16
- data/test/helpers/routes.rb +35 -30
- data/test/helpers/test_order.rb +3 -0
- data/test/http_basic_controller_test.rb +7 -18
- data/test/routes_test.rb +19 -10
- data/test/session_controller_api_test.rb +181 -30
- data/test/session_controller_test.rb +6 -0
- data/test/session_mailer_api_test.rb +18 -13
- data/test/session_mailer_test.rb +6 -0
- data/test/test_helper.rb +3 -3
- data/test/user_test.rb +54 -7
- metadata +65 -64
- data/app/models/credentials/facebook.rb +0 -63
- data/lib/authpwn_rails/facebook_session.rb +0 -33
- data/lib/authpwn_rails/user_extensions/facebook_fields.rb +0 -63
- data/test/credentials/facebook_credential_test.rb +0 -64
- data/test/facebook_controller_test.rb +0 -65
- data/test/user_extensions/facebook_fields_test.rb +0 -61
data/app/models/tokens/base.rb
CHANGED
@@ -1,19 +1,5 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
|
-
# :nodoc: Backport urlsafe_base64 to 1.8.7.
|
4
|
-
unless SecureRandom.respond_to? :urlsafe_base64
|
5
|
-
SecureRandom.class_eval do
|
6
|
-
# :nodoc: lifted from 1.9.3 securerandom.rb, line 190
|
7
|
-
def self.urlsafe_base64(n=nil, padding=false)
|
8
|
-
s = [random_bytes(n)].pack("m*")
|
9
|
-
s.delete!("\n")
|
10
|
-
s.tr!("+/", "-_")
|
11
|
-
s.delete!("=") if !padding
|
12
|
-
s
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
3
|
# :namespace
|
18
4
|
module Tokens
|
19
5
|
|
@@ -45,30 +31,17 @@ class Base < ::Credential
|
|
45
31
|
credential ? credential.authenticate : :invalid
|
46
32
|
end
|
47
33
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
#
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# tokens (e.g., email or Facebook OAuth token) will be required,
|
60
|
-
# so we pre-fetch them.
|
61
|
-
Credential.where(name: code).includes(user: :credentials).
|
62
|
-
where(Credential.arel_table[:type].matches('Tokens::%')).
|
63
|
-
references(:credential)
|
64
|
-
end
|
65
|
-
rescue NameError
|
66
|
-
# Rails 3.
|
67
|
-
|
68
|
-
def self.with_code(code)
|
69
|
-
Credential.where(name: code).includes(user: :credentials).
|
70
|
-
where(Credential.arel_table[:type].matches('Tokens::%'))
|
71
|
-
end
|
34
|
+
# Scope that uses a secret code.
|
35
|
+
def self.with_code(code)
|
36
|
+
# NOTE 1: The where query must be performed off the root type, otherwise
|
37
|
+
# Rails will try to guess the right values for the 'type' column,
|
38
|
+
# and will sometimes get them wrong.
|
39
|
+
# NOTE 2: After using this method, it's likely that the user's other
|
40
|
+
# tokens (e.g., email or Facebook OAuth token) will be required,
|
41
|
+
# so we pre-fetch them.
|
42
|
+
Credential.where(name: code).includes(user: :credentials).
|
43
|
+
where(Credential.arel_table[:type].matches('Tokens::%')).
|
44
|
+
references(:credential)
|
72
45
|
end
|
73
46
|
|
74
47
|
# Authenticates a user using this token.
|
data/authpwn_rails.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: authpwn_rails 0.17.0 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "authpwn_rails"
|
8
|
-
s.version = "0.
|
9
|
+
s.version = "0.17.0"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Victor Costan"]
|
12
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-11-07"
|
13
15
|
s.description = "Works with Facebook."
|
14
16
|
s.email = "victor@costan.us"
|
15
17
|
s.extra_rdoc_files = [
|
@@ -22,15 +24,16 @@ Gem::Specification.new do |s|
|
|
22
24
|
".travis.yml",
|
23
25
|
"Gemfile",
|
24
26
|
"Gemfile.lock",
|
25
|
-
"Gemfile.rails3",
|
26
27
|
"Gemfile.rails4",
|
28
|
+
"Gemfile.rails41",
|
29
|
+
"Gemfile.rails42",
|
27
30
|
"LICENSE",
|
28
31
|
"README.rdoc",
|
29
32
|
"Rakefile",
|
30
33
|
"VERSION",
|
31
34
|
"app/helpers/session_helper.rb",
|
32
35
|
"app/models/credentials/email.rb",
|
33
|
-
"app/models/credentials/
|
36
|
+
"app/models/credentials/omni_auth_uid.rb",
|
34
37
|
"app/models/credentials/password.rb",
|
35
38
|
"app/models/tokens/base.rb",
|
36
39
|
"app/models/tokens/email_verification.rb",
|
@@ -45,13 +48,13 @@ Gem::Specification.new do |s|
|
|
45
48
|
"lib/authpwn_rails/current_user.rb",
|
46
49
|
"lib/authpwn_rails/engine.rb",
|
47
50
|
"lib/authpwn_rails/expires.rb",
|
48
|
-
"lib/authpwn_rails/facebook_session.rb",
|
49
51
|
"lib/authpwn_rails/generators/all_generator.rb",
|
50
52
|
"lib/authpwn_rails/generators/templates/001_create_users.rb",
|
51
53
|
"lib/authpwn_rails/generators/templates/003_create_credentials.rb",
|
52
54
|
"lib/authpwn_rails/generators/templates/credential.rb",
|
53
55
|
"lib/authpwn_rails/generators/templates/credentials.yml",
|
54
56
|
"lib/authpwn_rails/generators/templates/initializer.rb",
|
57
|
+
"lib/authpwn_rails/generators/templates/omniauth_initializer.rb",
|
55
58
|
"lib/authpwn_rails/generators/templates/session.rb",
|
56
59
|
"lib/authpwn_rails/generators/templates/session/forbidden.html.erb",
|
57
60
|
"lib/authpwn_rails/generators/templates/session/home.html.erb",
|
@@ -76,19 +79,17 @@ Gem::Specification.new do |s|
|
|
76
79
|
"lib/authpwn_rails/session_model.rb",
|
77
80
|
"lib/authpwn_rails/test_extensions.rb",
|
78
81
|
"lib/authpwn_rails/user_extensions/email_field.rb",
|
79
|
-
"lib/authpwn_rails/user_extensions/facebook_fields.rb",
|
80
82
|
"lib/authpwn_rails/user_extensions/password_field.rb",
|
81
83
|
"lib/authpwn_rails/user_model.rb",
|
82
84
|
"test/cookie_controller_test.rb",
|
83
85
|
"test/credentials/email_credential_test.rb",
|
84
86
|
"test/credentials/email_verification_token_test.rb",
|
85
|
-
"test/credentials/
|
87
|
+
"test/credentials/omni_auth_uid_credential_test.rb",
|
86
88
|
"test/credentials/one_time_token_credential_test.rb",
|
87
89
|
"test/credentials/password_credential_test.rb",
|
88
90
|
"test/credentials/password_reset_token_test.rb",
|
89
91
|
"test/credentials/session_uid_token_test.rb",
|
90
92
|
"test/credentials/token_crendential_test.rb",
|
91
|
-
"test/facebook_controller_test.rb",
|
92
93
|
"test/fixtures/bare_session/forbidden.html.erb",
|
93
94
|
"test/fixtures/bare_session/home.html.erb",
|
94
95
|
"test/fixtures/bare_session/new.html.erb",
|
@@ -104,66 +105,67 @@ Gem::Specification.new do |s|
|
|
104
105
|
"test/helpers/rails.rb",
|
105
106
|
"test/helpers/rails_undo.rb",
|
106
107
|
"test/helpers/routes.rb",
|
108
|
+
"test/helpers/test_order.rb",
|
107
109
|
"test/helpers/view_helpers.rb",
|
108
110
|
"test/http_basic_controller_test.rb",
|
109
111
|
"test/initializer_test.rb",
|
110
112
|
"test/routes_test.rb",
|
111
113
|
"test/session_controller_api_test.rb",
|
114
|
+
"test/session_controller_test.rb",
|
112
115
|
"test/session_mailer_api_test.rb",
|
116
|
+
"test/session_mailer_test.rb",
|
113
117
|
"test/session_test.rb",
|
114
118
|
"test/test_extensions_test.rb",
|
115
119
|
"test/test_helper.rb",
|
116
120
|
"test/user_extensions/email_field_test.rb",
|
117
|
-
"test/user_extensions/facebook_fields_test.rb",
|
118
121
|
"test/user_extensions/password_field_test.rb",
|
119
122
|
"test/user_test.rb"
|
120
123
|
]
|
121
124
|
s.homepage = "http://github.com/pwnall/authpwn_rails"
|
122
125
|
s.licenses = ["MIT"]
|
123
|
-
s.
|
124
|
-
s.
|
125
|
-
s.summary = "User authentication for Rails 3 and 4 applications."
|
126
|
+
s.rubygems_version = "2.2.2"
|
127
|
+
s.summary = "User authentication for Rails 4 applications."
|
126
128
|
|
127
129
|
if s.respond_to? :specification_version then
|
128
130
|
s.specification_version = 4
|
129
131
|
|
130
132
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
131
|
-
s.add_runtime_dependency(%q<
|
132
|
-
s.
|
133
|
-
s.add_development_dependency(%q<bundler>, [">= 1.3.5"])
|
133
|
+
s.add_runtime_dependency(%q<rails>, [">= 4.0.9"])
|
134
|
+
s.add_development_dependency(%q<bundler>, [">= 1.7.3"])
|
134
135
|
s.add_development_dependency(%q<mocha>, [">= 0.14.0"])
|
135
|
-
s.add_development_dependency(%q<jeweler>, [">=
|
136
|
+
s.add_development_dependency(%q<jeweler>, [">= 2.0.1"])
|
136
137
|
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
137
|
-
s.add_development_dependency(%q<mysql2>, [">= 0.3.
|
138
|
-
s.add_development_dependency(%q<
|
139
|
-
s.add_development_dependency(%q<
|
138
|
+
s.add_development_dependency(%q<mysql2>, [">= 0.3.16"])
|
139
|
+
s.add_development_dependency(%q<omniauth>, [">= 1.2.2"])
|
140
|
+
s.add_development_dependency(%q<pg>, [">= 0.17.1"])
|
141
|
+
s.add_development_dependency(%q<sqlite3>, [">= 1.3.9"])
|
140
142
|
s.add_development_dependency(%q<rubysl>, [">= 0"])
|
141
143
|
s.add_development_dependency(%q<rubysl-bundler>, [">= 0"])
|
142
144
|
s.add_development_dependency(%q<rubysl-rake>, [">= 0"])
|
143
145
|
else
|
144
|
-
s.add_dependency(%q<
|
145
|
-
s.add_dependency(%q<
|
146
|
-
s.add_dependency(%q<bundler>, [">= 1.3.5"])
|
146
|
+
s.add_dependency(%q<rails>, [">= 4.0.9"])
|
147
|
+
s.add_dependency(%q<bundler>, [">= 1.7.3"])
|
147
148
|
s.add_dependency(%q<mocha>, [">= 0.14.0"])
|
148
|
-
s.add_dependency(%q<jeweler>, [">=
|
149
|
+
s.add_dependency(%q<jeweler>, [">= 2.0.1"])
|
149
150
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
150
|
-
s.add_dependency(%q<mysql2>, [">= 0.3.
|
151
|
-
s.add_dependency(%q<
|
152
|
-
s.add_dependency(%q<
|
151
|
+
s.add_dependency(%q<mysql2>, [">= 0.3.16"])
|
152
|
+
s.add_dependency(%q<omniauth>, [">= 1.2.2"])
|
153
|
+
s.add_dependency(%q<pg>, [">= 0.17.1"])
|
154
|
+
s.add_dependency(%q<sqlite3>, [">= 1.3.9"])
|
153
155
|
s.add_dependency(%q<rubysl>, [">= 0"])
|
154
156
|
s.add_dependency(%q<rubysl-bundler>, [">= 0"])
|
155
157
|
s.add_dependency(%q<rubysl-rake>, [">= 0"])
|
156
158
|
end
|
157
159
|
else
|
158
|
-
s.add_dependency(%q<
|
159
|
-
s.add_dependency(%q<
|
160
|
-
s.add_dependency(%q<bundler>, [">= 1.3.5"])
|
160
|
+
s.add_dependency(%q<rails>, [">= 4.0.9"])
|
161
|
+
s.add_dependency(%q<bundler>, [">= 1.7.3"])
|
161
162
|
s.add_dependency(%q<mocha>, [">= 0.14.0"])
|
162
|
-
s.add_dependency(%q<jeweler>, [">=
|
163
|
+
s.add_dependency(%q<jeweler>, [">= 2.0.1"])
|
163
164
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
164
|
-
s.add_dependency(%q<mysql2>, [">= 0.3.
|
165
|
-
s.add_dependency(%q<
|
166
|
-
s.add_dependency(%q<
|
165
|
+
s.add_dependency(%q<mysql2>, [">= 0.3.16"])
|
166
|
+
s.add_dependency(%q<omniauth>, [">= 1.2.2"])
|
167
|
+
s.add_dependency(%q<pg>, [">= 0.17.1"])
|
168
|
+
s.add_dependency(%q<sqlite3>, [">= 1.3.9"])
|
167
169
|
s.add_dependency(%q<rubysl>, [">= 0"])
|
168
170
|
s.add_dependency(%q<rubysl-bundler>, [">= 0"])
|
169
171
|
s.add_dependency(%q<rubysl-rake>, [">= 0"])
|
@@ -20,13 +20,9 @@ module CredentialModel
|
|
20
20
|
|
21
21
|
# Secret information associated with the token.
|
22
22
|
validates :key, length: { in: 1..2.kilobytes, allow_nil: true }
|
23
|
-
|
24
|
-
if ActiveRecord::Base.respond_to? :mass_assignment_sanitizer=
|
25
|
-
attr_accessible
|
26
|
-
end
|
27
23
|
end
|
28
24
|
|
29
|
-
#
|
25
|
+
# Class methods on models that include Authpwn::CredentialModel.
|
30
26
|
module ClassMethods
|
31
27
|
|
32
28
|
end # module Authpwn::FacebookTokenModel::ClassMethods
|
@@ -66,9 +66,11 @@ class AllGenerator < Rails::Generators::Base
|
|
66
66
|
'reset_password_email.text.erb')
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
69
|
+
def create_initializers
|
70
70
|
copy_file 'initializer.rb',
|
71
71
|
File.join('config', 'initializers', 'authpwn.rb')
|
72
|
+
copy_file 'omniauth_initializer.rb',
|
73
|
+
File.join('config', 'initializers', 'authpwn_omniauth.rb')
|
72
74
|
end
|
73
75
|
end # class Authpwn::AllGenerator
|
74
76
|
|
@@ -3,9 +3,9 @@ class CreateUsers < ActiveRecord::Migration
|
|
3
3
|
create_table :users do |t|
|
4
4
|
t.string :exuid, limit: 32, null: false
|
5
5
|
|
6
|
-
t.timestamps
|
7
|
-
end
|
6
|
+
t.timestamps null: false
|
8
7
|
|
9
|
-
|
8
|
+
t.index :exuid, unique: true
|
9
|
+
end
|
10
10
|
end
|
11
11
|
end
|
@@ -8,13 +8,13 @@ class CreateCredentials < ActiveRecord::Migration
|
|
8
8
|
t.timestamp :updated_at, null: false
|
9
9
|
|
10
10
|
t.binary :key, limit: 2.kilobytes, null: true
|
11
|
-
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
# All the credentials (maybe of a specific type) belonging to a user.
|
13
|
+
t.index [:user_id, :type], unique: false
|
14
|
+
# A specific credential, to find out what user it belongs to.
|
15
|
+
t.index [:type, :name], unique: true
|
16
|
+
# Expired credentials (particularly useful for tokens).
|
17
|
+
t.index [:type, :updated_at], unique: false
|
18
|
+
end
|
19
19
|
end
|
20
20
|
end
|
@@ -20,19 +20,6 @@ john_password:
|
|
20
20
|
user: john
|
21
21
|
key: <%= Credentials::Password.hash_password('password', '1234').inspect %>
|
22
22
|
|
23
|
-
# Test account vic.tor@costan.us
|
24
|
-
jane_facebook:
|
25
|
-
user: jane
|
26
|
-
type: Credentials::Facebook
|
27
|
-
name: 1011950666
|
28
|
-
key: AAAEj8jKX2a8BAA4kNheRhOs6SlECVcZCE9o5pPKMytOjjoiNAoZBGZAwuL4KrrxXWesfJRhzDZCJiqrcQG3UdjRRNtyMJQMZD
|
29
|
-
|
30
|
-
john_facebook:
|
31
|
-
user: john
|
32
|
-
type: Credentials::Facebook
|
33
|
-
name: 702659
|
34
|
-
key: 702659|ffffffffffffffffffffffff-702659|ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
35
|
-
|
36
23
|
jane_token:
|
37
24
|
user: jane
|
38
25
|
type: Tokens::OneTime
|
@@ -69,3 +56,16 @@ jane_session_token:
|
|
69
56
|
key: <%= { :browser_ip => '18.70.0.160',
|
70
57
|
:browser_ua => 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1'
|
71
58
|
}.to_yaml.inspect %>
|
59
|
+
|
60
|
+
john_omniauth_developer:
|
61
|
+
user: john
|
62
|
+
type: Credentials::OmniAuthUid
|
63
|
+
name: developer,john@gmail.com
|
64
|
+
key: "0"
|
65
|
+
|
66
|
+
jane_omniauth_developer:
|
67
|
+
user: jane
|
68
|
+
type: Credentials::OmniAuthUid
|
69
|
+
name: developer,jane@gmail.com
|
70
|
+
key: "1"
|
71
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# See the OmniAuth documentation for the contents of this file.
|
2
|
+
#
|
3
|
+
# https://github.com/intridea/omniauth
|
4
|
+
# https://github.com/intridea/omniauth/wiki
|
5
|
+
|
6
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
7
|
+
provider :developer unless Rails.env.production?
|
8
|
+
|
9
|
+
# provider :twitter, Rails.application.secrets.twitter_api_key,
|
10
|
+
# Rails.application.secrets.twitter_api_secret
|
11
|
+
end
|
12
|
+
|
13
|
+
OmniAuth.config.logger = Rails.logger
|
@@ -5,6 +5,7 @@ class SessionControllerTest < ActionController::TestCase
|
|
5
5
|
@user = users(:jane)
|
6
6
|
@email_credential = credentials(:jane_email)
|
7
7
|
@password_credential = credentials(:jane_password)
|
8
|
+
@omniauth_credential = credentials(:jane_omniauth_developer)
|
8
9
|
end
|
9
10
|
|
10
11
|
test "user home page" do
|
@@ -118,4 +119,25 @@ class SessionControllerTest < ActionController::TestCase
|
|
118
119
|
|
119
120
|
assert_redirected_to new_session_url
|
120
121
|
end
|
122
|
+
|
123
|
+
test "OmniAuth failure" do
|
124
|
+
get :omniauth_failure
|
125
|
+
|
126
|
+
assert_redirected_to new_session_url
|
127
|
+
end
|
128
|
+
|
129
|
+
test "OmniAuth login via developer strategy and good account" do
|
130
|
+
old_token = credentials(:jane_session_token)
|
131
|
+
old_token.updated_at = Time.now - 1.year
|
132
|
+
old_token.save!
|
133
|
+
|
134
|
+
request.env['omniauth.auth'] = {
|
135
|
+
'provider' => @omniauth_credential.provider,
|
136
|
+
'uid' => @omniauth_credential.uid }
|
137
|
+
post :omniauth, provider: @omniauth_credential.provider
|
138
|
+
assert_equal @user, session_current_user, 'session'
|
139
|
+
assert_redirected_to session_url
|
140
|
+
assert_nil Tokens::Base.with_code(old_token.code).first,
|
141
|
+
'old session not purged'
|
142
|
+
end
|
121
143
|
end
|
data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.html.erb
CHANGED
@@ -6,14 +6,14 @@
|
|
6
6
|
<p>
|
7
7
|
You are receiving this e-mail because someone (hopefully you) registered
|
8
8
|
an account at
|
9
|
-
<%= link_to @host, root_url(:
|
9
|
+
<%= link_to @host, root_url(host: @host, protocol: @protocol) %>
|
10
10
|
using your e-mail address.
|
11
11
|
</p>
|
12
12
|
|
13
13
|
<p>
|
14
14
|
Please go
|
15
|
-
<%= link_to 'here', token_session_url(@token, :
|
16
|
-
:
|
15
|
+
<%= link_to 'here', token_session_url(@token, host: @host,
|
16
|
+
protocol: @protocol) %>
|
17
17
|
to confirm your e-mail address.
|
18
18
|
</p>
|
19
19
|
|
data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.text.erb
CHANGED
@@ -5,7 +5,7 @@ You are receiving this e-mail because someone (hopefully you) registered an
|
|
5
5
|
account at <%= @host %> using your e-mail address.
|
6
6
|
|
7
7
|
Please go to the address below to confirm your e-mail address.
|
8
|
-
<%= token_session_url @token, :
|
8
|
+
<%= token_session_url @token, host: @host, protocol: @protocol %>
|
9
9
|
|
10
10
|
If you haven't registered an account, please ignore this e-mail. Someone most
|
11
11
|
likely mistyped their e-mail.
|
@@ -6,14 +6,14 @@
|
|
6
6
|
<p>
|
7
7
|
You are receiving this e-mail because someone (hopefully you) requested a
|
8
8
|
password reset for your
|
9
|
-
<%= link_to @host, root_url(:
|
9
|
+
<%= link_to @host, root_url(host: @host, protocol: @protocol) %>
|
10
10
|
account.
|
11
11
|
</p>
|
12
12
|
|
13
13
|
<p>
|
14
14
|
Please go
|
15
|
-
<%= link_to 'here', token_session_url(@token, :
|
16
|
-
:
|
15
|
+
<%= link_to 'here', token_session_url(@token, host: @host,
|
16
|
+
protocol: @protocol) %>
|
17
17
|
to reset your password.
|
18
18
|
</p>
|
19
19
|
|
@@ -5,7 +5,7 @@ You are receiving this e-mail because someone (hopefully you) requested a
|
|
5
5
|
password reset for your <%= @host %> account.
|
6
6
|
|
7
7
|
Please go to the address below to reset your password.
|
8
|
-
<%= token_session_url @token, :
|
8
|
+
<%= token_session_url @token, host: @host, protocol: @protocol %>
|
9
9
|
|
10
10
|
If you haven't requested a password reset, please ignore this e-mail. Someone
|
11
11
|
most likely mistyped their e-mail.
|
@@ -21,6 +21,6 @@ class SessionMailer < ActionMailer::Base
|
|
21
21
|
%Q|"#{server_hostname} staff" <admin@#{server_hostname}>|
|
22
22
|
end
|
23
23
|
|
24
|
-
# You shouldn't extend the session
|
24
|
+
# You shouldn't extend the session mailer, so you can benefit from future
|
25
25
|
# features. But, if you must, you can do it here.
|
26
26
|
end
|
@@ -10,8 +10,13 @@ class SessionMailerTest < ActionMailer::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
test 'email verification email' do
|
13
|
-
|
14
|
-
|
13
|
+
email_draft = SessionMailer.email_verification_email @verification_token,
|
14
|
+
@root_url
|
15
|
+
if email_draft.respond_to? :deliver_now
|
16
|
+
email = email_draft.deliver_now # Rails 4.2+
|
17
|
+
else
|
18
|
+
email = email_draft.deliver # Rails 4.0 and 4.1
|
19
|
+
end
|
15
20
|
assert !ActionMailer::Base.deliveries.empty?
|
16
21
|
|
17
22
|
assert_equal 'test.host e-mail verification', email.subject
|
@@ -23,8 +28,13 @@ class SessionMailerTest < ActionMailer::TestCase
|
|
23
28
|
end
|
24
29
|
|
25
30
|
test 'password reset email' do
|
26
|
-
|
27
|
-
|
31
|
+
email_draft = SessionMailer.reset_password_email @reset_email,
|
32
|
+
@reset_token, @root_url
|
33
|
+
if email_draft.respond_to? :deliver_now
|
34
|
+
email = email_draft.deliver_now # Rails 4.2+
|
35
|
+
else
|
36
|
+
email = email_draft.deliver # Rails 4.0 and 4.1
|
37
|
+
end
|
28
38
|
assert !ActionMailer::Base.deliveries.empty?
|
29
39
|
|
30
40
|
assert_equal 'test.host password reset', email.subject
|
@@ -6,15 +6,50 @@ class User < ActiveRecord::Base
|
|
6
6
|
# include Authpwn::UserExtensions::EmailField
|
7
7
|
# Virtual password attribute, with confirmation validation.
|
8
8
|
# include Authpwn::UserExtensions::PasswordField
|
9
|
-
# Convenience Facebook accessors.
|
10
|
-
# include Authpwn::UserExtensions::FacebookFields
|
11
9
|
|
12
|
-
# Change this
|
10
|
+
# Change this to customize user lookup in the e-mail/password signin process.
|
13
11
|
#
|
14
12
|
# For example, to implement Facebook / Twitter's ability to log in using
|
15
13
|
# either an e-mail address or a username, look up the user by the username,
|
16
|
-
#
|
17
|
-
|
14
|
+
# create a new Session with the e-mail and password, and pass it to super
|
15
|
+
#
|
16
|
+
# @param [Session] signin the information entered in the sign-in form
|
17
|
+
# @return [User, Symbol] the authenticated user, or a symbol indicating the
|
18
|
+
# reason why the authentication failed
|
19
|
+
def self.authenticate_signin(signin)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
# Change this to customize user lookup in the OmniAuth signup process.
|
24
|
+
#
|
25
|
+
# This method is called when there is no Credential matching the OmniAuth
|
26
|
+
# information, but before {User#create_from_omniauth}. It is an opportunity
|
27
|
+
# to identify an existing user who uses a new sign-in method.
|
28
|
+
#
|
29
|
+
# The default implementation finds an user whose e-mail matches the 'email'
|
30
|
+
# value in the OmniAuth hash.
|
31
|
+
#
|
32
|
+
# @param [Hash] omniauth_hash the hash provided by OmniAuth
|
33
|
+
# @return [User] the user who should be signed in, or nil if no such user
|
34
|
+
# exists
|
35
|
+
def self.related_to_omniauth(omniauth_hash)
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
# Change this to customize on-demand user creation on OmniAuth signup.
|
40
|
+
#
|
41
|
+
# This method is called when there is no existing user matching the OmniAuth
|
42
|
+
# information, and is responsible for creating a user. It is an opportunity
|
43
|
+
# to collect the OmniAuth information to populate the user's account.
|
44
|
+
#
|
45
|
+
# The default implementation creates a user with the e-mail matching the
|
46
|
+
# 'email' key in the OmniAuth hash. If no e-mail key is present, no User is
|
47
|
+
# created.
|
48
|
+
#
|
49
|
+
# @param [Hash] omniauth_hash the hash provided by OmniAuth
|
50
|
+
# @return [User] a saved User, or nil if the OmniAuth sign-in information
|
51
|
+
# should not be used to create a user
|
52
|
+
def self.create_from_omniauth(omniauth_hash)
|
18
53
|
super
|
19
54
|
end
|
20
55
|
|
@@ -2,14 +2,14 @@ require 'action_controller'
|
|
2
2
|
|
3
3
|
# :nodoc: adds authenticates_using_http_basic
|
4
4
|
class ActionController::Base
|
5
|
-
# Keeps track of the currently authenticated user via the session.
|
5
|
+
# Keeps track of the currently authenticated user via the session.
|
6
6
|
#
|
7
7
|
# Assumes the existence of a User model. A bare ActiveModel model will do the
|
8
8
|
# trick. Model instances must implement id, and the model class must implement
|
9
9
|
# find_by_id.
|
10
10
|
def self.authenticates_using_http_basic(options = {})
|
11
11
|
include Authpwn::HttpBasicControllerInstanceMethods
|
12
|
-
before_filter :authenticate_using_http_basic, options
|
12
|
+
before_filter :authenticate_using_http_basic, options
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -29,17 +29,18 @@ module HttpBasicControllerInstanceMethods
|
|
29
29
|
def authenticate_using_http_basic
|
30
30
|
return if current_user
|
31
31
|
authenticate_with_http_basic do |email, password|
|
32
|
-
|
32
|
+
signin = Session.new email: email, password: password
|
33
|
+
auth = User.authenticate_signin signin
|
33
34
|
self.current_user = auth unless auth.kind_of? Symbol
|
34
35
|
end
|
35
36
|
end
|
36
37
|
private :authenticate_using_http_basic
|
37
|
-
|
38
|
+
|
38
39
|
# Inform the user that their request is forbidden.
|
39
40
|
#
|
40
41
|
# If a user is logged on, this renders the session/forbidden view with a HTTP
|
41
42
|
# 403 code.
|
42
|
-
#
|
43
|
+
#
|
43
44
|
# If no user is logged in, a HTTP 403 code is returned, together with an
|
44
45
|
# HTTP Authentication header causing the user-agent (browser) to initiate
|
45
46
|
# http basic authentication.
|
data/lib/authpwn_rails/routes.rb
CHANGED
@@ -10,17 +10,22 @@ module Routes
|
|
10
10
|
module MapperMixin
|
11
11
|
# Draws the routes for a session controller.
|
12
12
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
13
|
+
# @param [Object] options
|
14
|
+
# @option options [String] controller the name of the controller; defaults to
|
15
|
+
# "session" for SessionController
|
16
|
+
# @option options [String] paths the prefix of the route paths; defaults to
|
17
|
+
# the controller name
|
18
|
+
# @option options [String] method_names the root of name used in the path
|
19
|
+
# methods; defaults to "session", which will generate names like
|
20
|
+
# session_path, new_session_path, and token_session_path
|
21
|
+
# @option options [String] omniauth_path_prefix the prefix of the OmniAuth
|
22
|
+
# route paths; defaults to '/auth'; this option should equal
|
23
|
+
# OmniAuth.config.path_prefix
|
20
24
|
def authpwn_session(options = {})
|
21
25
|
controller = options[:controller] || 'session'
|
22
26
|
paths = options[:paths] || controller
|
23
27
|
methods = options[:method_names] || 'session'
|
28
|
+
oa_prefix = options[:omniauth_path_prefix] || '/auth'
|
24
29
|
|
25
30
|
get "/#{paths}/token/:code", controller: controller, action: 'token',
|
26
31
|
as: :"token_#{methods}"
|
@@ -40,6 +45,14 @@ module MapperMixin
|
|
40
45
|
post "/#{paths}/reset_password", controller: controller,
|
41
46
|
action: 'reset_password',
|
42
47
|
as: "reset_password_#{methods}"
|
48
|
+
|
49
|
+
match "#{oa_prefix}/:provider/callback", via: [:get, :post],
|
50
|
+
controller: controller,
|
51
|
+
action: 'omniauth',
|
52
|
+
as: "omniauth_#{methods}"
|
53
|
+
get "#{oa_prefix}/failure", controller: controller,
|
54
|
+
action: 'omniauth_failure',
|
55
|
+
as: "omniauth_failure_#{methods}"
|
43
56
|
end
|
44
57
|
end
|
45
58
|
|
@@ -45,7 +45,7 @@ module ControllerInstanceMethods
|
|
45
45
|
end
|
46
46
|
if user
|
47
47
|
session[:authpwn_suid] = Tokens::SessionUid.random_for(user,
|
48
|
-
request.remote_ip, request.user_agent).suid
|
48
|
+
request.remote_ip, request.user_agent || 'N/A').suid
|
49
49
|
else
|
50
50
|
session.delete :authpwn_suid
|
51
51
|
end
|