authem 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +6 -0
  7. data/Appraisals +12 -0
  8. data/CHANGELOG.md +42 -0
  9. data/Gemfile +10 -0
  10. data/README.markdown +15 -1
  11. data/Rakefile +11 -5
  12. data/authem.gemspec +25 -0
  13. data/gemfiles/rails_4.0.gemfile +16 -0
  14. data/gemfiles/rails_4.1.gemfile +15 -0
  15. data/lib/authem.rb +4 -10
  16. data/lib/authem/controller.rb +50 -0
  17. data/lib/authem/errors/ambigous_role.rb +8 -0
  18. data/lib/authem/errors/unknown_role.rb +7 -0
  19. data/lib/authem/railtie.rb +12 -0
  20. data/lib/authem/role.rb +62 -0
  21. data/lib/authem/session.rb +41 -0
  22. data/lib/authem/support.rb +129 -0
  23. data/lib/authem/token.rb +5 -5
  24. data/lib/authem/user.rb +27 -13
  25. data/lib/authem/version.rb +1 -1
  26. data/lib/generators/authem/session/session_generator.rb +12 -0
  27. data/lib/generators/authem/session/templates/create_sessions.rb +15 -0
  28. data/lib/generators/authem/user/templates/create_table_migration.rb +22 -0
  29. data/lib/generators/authem/user/templates/model.rb +11 -0
  30. data/lib/generators/authem/user/user_generator.rb +13 -0
  31. data/spec/controller_spec.rb +413 -0
  32. data/spec/session_spec.rb +52 -0
  33. data/spec/spec_helper.rb +4 -0
  34. data/spec/support/active_record.rb +45 -0
  35. data/spec/support/i18n.rb +1 -0
  36. data/spec/support/time.rb +1 -0
  37. data/spec/token_spec.rb +10 -0
  38. data/spec/user_spec.rb +115 -0
  39. metadata +42 -112
  40. data/lib/authem/base_user.rb +0 -54
  41. data/lib/authem/config.rb +0 -21
  42. data/lib/authem/controller_support.rb +0 -51
  43. data/lib/authem/sorcery_user.rb +0 -24
  44. data/lib/generators/authem/model/model_generator.rb +0 -23
@@ -0,0 +1,52 @@
1
+ require "spec_helper"
2
+
3
+ describe Authem::Session do
4
+ class User < ActiveRecord::Base
5
+ self.table_name = :users
6
+ end
7
+
8
+ let(:user){ User.create(email: "joe@example.com") }
9
+ let(:role){ :user }
10
+
11
+ it "generates secure token on creation" do
12
+ expect(Authem::Token).to receive(:generate).and_return("a secure token")
13
+ model = described_class.create(role: role, subject: user)
14
+ expect(model.token).to eq("a secure token")
15
+ end
16
+
17
+ it "set expires_at attribute according to ttl" do
18
+ model = described_class.create(role: role, subject: user, ttl: 30.minutes)
19
+ expect(model.expires_at).to be_within(1.second).of(30.minutes.from_now)
20
+ end
21
+
22
+ it "uses default ttl if value is not provided" do
23
+ model = described_class.create(role: role, subject: user)
24
+ expect(model.expires_at).to be_within(1.second).of(30.days.from_now)
25
+ end
26
+
27
+ context "scopes" do
28
+ def create_session_with_expiration(expires_at)
29
+ described_class.create(
30
+ role: role,
31
+ subject: user,
32
+ expires_at: expires_at
33
+ )
34
+ end
35
+
36
+ let!(:expired_session){ create_session_with_expiration(1.day.ago) }
37
+ let!(:active_session){ create_session_with_expiration(1.week.from_now) }
38
+ let(:active_scope){ described_class.active }
39
+ let(:expired_scope){ described_class.expired }
40
+
41
+ specify ".active filters out expired sessions" do
42
+ expect(active_scope).to include(active_session)
43
+ expect(active_scope).not_to include(expired_session)
44
+ end
45
+
46
+ specify ".expired filters out active sessions" do
47
+ expect(expired_scope).to include(expired_session)
48
+ expect(expired_scope).not_to include(active_session)
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,4 @@
1
+ require "bundler/setup"
2
+ require "authem"
3
+
4
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each(&method(:require))
@@ -0,0 +1,45 @@
1
+ require "active_record"
2
+
3
+ ActiveRecord::Migration.verbose = false
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ adapter: "sqlite3",
7
+ database: ":memory:"
8
+ )
9
+
10
+ class CreateUsersMigration < ActiveRecord::Migration
11
+ def up
12
+ create_table :users do |t|
13
+ t.string :email
14
+ t.string :password_digest
15
+ t.string :password_reset_token
16
+ end
17
+ end
18
+ end
19
+
20
+ class CreateSessionsMigration < ActiveRecord::Migration
21
+ def up
22
+ create_table :authem_sessions do |t|
23
+ t.string :role, null: false
24
+ t.references :subject, null: false, polymorphic: true
25
+ t.string :token, null: false
26
+ t.datetime :expires_at, null: false
27
+ t.integer :ttl, null: false
28
+ t.timestamps
29
+ end
30
+ end
31
+ end
32
+
33
+ RSpec.configure do |config|
34
+ config.before :suite do
35
+ CreateUsersMigration.new.up
36
+ CreateSessionsMigration.new.up
37
+ end
38
+
39
+ config.around do |example|
40
+ ActiveRecord::Base.transaction do
41
+ example.run
42
+ raise ActiveRecord::Rollback
43
+ end
44
+ end
45
+ end
@@ -0,0 +1 @@
1
+ I18n.enforce_available_locales = false
@@ -0,0 +1 @@
1
+ Time.zone_default = ActiveSupport::TimeZone["UTC"]
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+
3
+ describe Authem::Token do
4
+ context ".generate" do
5
+ subject{ described_class.generate }
6
+ it "generates a secure token 60 chars long" do
7
+ expect(subject.length).to eq(60)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,115 @@
1
+ require "spec_helper"
2
+
3
+ describe Authem::User do
4
+
5
+ class TestUser < ActiveRecord::Base
6
+ self.table_name = :users
7
+ include Authem::User
8
+
9
+
10
+ def self.create(email: "joe@example.com", password: "password")
11
+ super(
12
+ email: email,
13
+ password: password,
14
+ password_confirmation: password
15
+ )
16
+ end
17
+ end
18
+
19
+ it "downcases email" do
20
+ record = TestUser.new
21
+ record.email = "JOE@EXAMPLE.COM"
22
+ expect(record.email).to eq("joe@example.com")
23
+ end
24
+
25
+ subject(:user){ TestUser.create }
26
+
27
+ context "#authenticate" do
28
+ it "returns record if password is correct" do
29
+ expect(user.authenticate("password")).to eq(user)
30
+ end
31
+
32
+ it "returns false if password is incorrect" do
33
+ expect(user.authenticate("notright")).to be_falsy
34
+ end
35
+
36
+ it "returns false if password is nil" do
37
+ expect(user.authenticate(nil)).to be_falsy
38
+ end
39
+ end
40
+
41
+ context "#password_reset_token" do
42
+ it "generates token on record creation" do
43
+ expect(user.password_reset_token).to be_present
44
+ end
45
+ end
46
+
47
+ context "#reset_password" do
48
+ it "changes the password if on successful update" do
49
+ expect{ user.reset_password "123", "123" }.to change{ user.reload.password_digest }
50
+ end
51
+
52
+ it "regenerates password reset token on successful update" do
53
+ expect{ user.reset_password "123", "123" }.to change{ user.reload.password_reset_token }
54
+ end
55
+
56
+ it "does not change password on error" do
57
+ expect{ user.reset_password "123", "321" }.not_to change{ user.reload.password_digest }
58
+ expect{ user.reset_password "123", "" }.not_to change{ user.reload.password_digest }
59
+ expect{ user.reset_password nil, "321" }.not_to change{ user.reload.password_digest }
60
+ expect{ user.reset_password nil, nil }.not_to change{ user.reload.password_digest }
61
+ end
62
+
63
+ it "does not change password reset token on error" do
64
+ expect{ user.reset_password "123", "321" }.not_to change{ user.reload.password_reset_token }
65
+ expect{ user.reset_password "123", "" }.not_to change{ user.reload.password_reset_token }
66
+ expect{ user.reset_password nil, "321" }.not_to change{ user.reload.password_reset_token }
67
+ expect{ user.reset_password nil, nil }.not_to change{ user.reload.password_reset_token }
68
+ end
69
+
70
+ it "returns true if when password change is successful" do
71
+ expect(user.reset_password("123", "123")).to be_truthy
72
+ end
73
+
74
+ it "returns false when confirmation does not match" do
75
+ expect(user.reset_password("123", "321")).to be_falsy
76
+ end
77
+
78
+ it "adds an error when confirmation does not match" do
79
+ user.reset_password("123", "321")
80
+ expect(user.errors).to include(:password_confirmation)
81
+ end
82
+
83
+ it "adds and error when password is blank" do
84
+ user.reset_password(nil, "")
85
+ expect(user.errors).to include(:password)
86
+ end
87
+
88
+ it "returns false when password is blank" do
89
+ expect(user.reset_password("", "")).to be_falsy
90
+ end
91
+ end
92
+
93
+ context "validations" do
94
+ it "allows properly formatted emails" do
95
+ record = TestUser.create(email: "joe@example.com")
96
+ expect(record.errors).not_to include(:email)
97
+ end
98
+
99
+ it "validates email presence" do
100
+ record = TestUser.create(email: nil)
101
+ expect(record.errors).to include(:email)
102
+ end
103
+
104
+ it "validates email format" do
105
+ record = TestUser.create(email: "joe-at-example-com")
106
+ expect(record.errors).to include(:email)
107
+ end
108
+
109
+ it "validates email uniqueness" do
110
+ TestUser.create email: "joe@example.com"
111
+ record = TestUser.create(email: "JOE@EXAMPLE.COM")
112
+ expect(record.errors).to include(:email)
113
+ end
114
+ end
115
+ end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authem
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Elliott
8
+ - Pavel Pravosud
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-04-29 00:00:00.000000000 Z
12
+ date: 2014-06-09 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
@@ -28,147 +29,76 @@ dependencies:
28
29
  name: railties
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ">="
32
+ - - "~>"
32
33
  - !ruby/object:Gem::Version
33
34
  version: '4.0'
34
35
  type: :runtime
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
- - - ">="
39
+ - - "~>"
39
40
  - !ruby/object:Gem::Version
40
41
  version: '4.0'
41
42
  - !ruby/object:Gem::Dependency
42
43
  name: bcrypt
43
44
  requirement: !ruby/object:Gem::Requirement
44
45
  requirements:
45
- - - ">="
46
+ - - "~>"
46
47
  - !ruby/object:Gem::Version
47
48
  version: '3.1'
48
49
  type: :runtime
49
50
  prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '3.1'
55
- - !ruby/object:Gem::Dependency
56
- name: actionpack
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '4.0'
62
- type: :development
63
- prerelease: false
64
51
  version_requirements: !ruby/object:Gem::Requirement
65
52
  requirements:
66
53
  - - "~>"
67
54
  - !ruby/object:Gem::Version
68
- version: '4.0'
69
- - !ruby/object:Gem::Dependency
70
- name: activerecord
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '4.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '4.0'
83
- - !ruby/object:Gem::Dependency
84
- name: database_cleaner
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: sqlite3
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: pry
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- description: Authem provides a simple solution for email-based authentication.
55
+ version: '3.1'
56
+ description: Authem provides a simple solution for email-based authentication
154
57
  email:
155
- - paul@hashrocket.com
58
+ - paul@codingfrontier.com
59
+ - pavel@pravosud.com
156
60
  executables: []
157
61
  extensions: []
158
62
  extra_rdoc_files: []
159
63
  files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - ".ruby-gemset"
67
+ - ".ruby-version"
68
+ - ".travis.yml"
69
+ - Appraisals
70
+ - CHANGELOG.md
71
+ - Gemfile
160
72
  - LICENSE
161
73
  - README.markdown
162
74
  - Rakefile
75
+ - authem.gemspec
76
+ - gemfiles/rails_4.0.gemfile
77
+ - gemfiles/rails_4.1.gemfile
163
78
  - lib/authem.rb
164
- - lib/authem/base_user.rb
165
- - lib/authem/config.rb
166
- - lib/authem/controller_support.rb
167
- - lib/authem/sorcery_user.rb
79
+ - lib/authem/controller.rb
80
+ - lib/authem/errors/ambigous_role.rb
81
+ - lib/authem/errors/unknown_role.rb
82
+ - lib/authem/railtie.rb
83
+ - lib/authem/role.rb
84
+ - lib/authem/session.rb
85
+ - lib/authem/support.rb
168
86
  - lib/authem/token.rb
169
87
  - lib/authem/user.rb
170
88
  - lib/authem/version.rb
171
- - lib/generators/authem/model/model_generator.rb
89
+ - lib/generators/authem/session/session_generator.rb
90
+ - lib/generators/authem/session/templates/create_sessions.rb
91
+ - lib/generators/authem/user/templates/create_table_migration.rb
92
+ - lib/generators/authem/user/templates/model.rb
93
+ - lib/generators/authem/user/user_generator.rb
94
+ - spec/controller_spec.rb
95
+ - spec/session_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/support/active_record.rb
98
+ - spec/support/i18n.rb
99
+ - spec/support/time.rb
100
+ - spec/token_spec.rb
101
+ - spec/user_spec.rb
172
102
  homepage: https://github.com/paulelliott/authem
173
103
  licenses:
174
104
  - MIT
@@ -181,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
111
  requirements:
182
112
  - - ">="
183
113
  - !ruby/object:Gem::Version
184
- version: 1.9.3
114
+ version: 2.0.0
185
115
  required_rubygems_version: !ruby/object:Gem::Requirement
186
116
  requirements:
187
117
  - - ">="