challah 1.4.2 → 1.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 447489331d6bd86a5454685e67160b9299f4717c
4
- data.tar.gz: dced3cd2315e8382dd9b844b32851e53b2549b8e
3
+ metadata.gz: 5267d7f2cfbc84cb4a6af2c0d4a863ef8790a853
4
+ data.tar.gz: cbf3accdb5a30c551041e0b749ce3fd7a3f84eb7
5
5
  SHA512:
6
- metadata.gz: 443ee62005886d2eb46d9184239fd4bd27e8c70094ee118b0d2dabd3411e82618547c92fc21087258c176cbcbb11cc8725d7652fe565cb076b86c9a0e1af20bc
7
- data.tar.gz: 1e8aca0d48ec952a7050a0a13865099764b13eda8cea1b44e17f3d4e6e32690ee46bf81ffb5c3093bddc1cd047c4585b82eac22a708547210d7bc4e736270cd8
6
+ metadata.gz: 8849cba25a8264c34e120aa9c875040cac7aff7dc7a0f423b844098686f56544f66c973caaf089a018b5fd4bcbf7d7011ac972bb2124fb4ef888135eeea6b06b
7
+ data.tar.gz: d4c31ad4cc1301412bce1f6ebbeb3b1a5b6b79cb65ecfdbbe26041db09c8ac1eedd9b3e38839ce5ccee2855c5acd98f28bdbc299bf2b84f11b35d860202dd106
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## Challah 1.5.0
2
+
3
+ * Extract status enum to separate concern [PR #32](https://github.com/jdtornow/challah/pull/32) @philtr
4
+ * Add built-in support for authenticating using X-Auth-Token header for APIs
5
+
1
6
  ## Challah 1.4.2
2
7
 
3
8
  * Fix issue with duplicating models and audits [#28](https://github.com/jdtornow/challah/issues/28)
data/README.md CHANGED
@@ -8,9 +8,9 @@ Challah doesn't provide any fancy controllers or views that clutter your app or
8
8
 
9
9
  ## Requirements
10
10
 
11
- * Ruby 2.1.2+
11
+ * Ruby 2.2.2+
12
12
  * Bundler
13
- * Rails 5.0 (Recommended)
13
+ * Rails 4.2+ (5.0 Recommended)
14
14
 
15
15
  ## Installation
16
16
 
@@ -143,6 +143,50 @@ If necessary, the sessions controller which handles creating new sessions and si
143
143
  rails challah:unpack:signin
144
144
  ```
145
145
 
146
+ ## API Controllers
147
+
148
+ For apps that use JSON API controllers, Challah can be used to authenticate a user with a url parameter or an HTTP request header. This feature is disabled by default, so to use it you will need to change the `token_enabled` setting to `true`:
149
+
150
+ ```ruby
151
+ # in config/initializers/challah.rb
152
+ Challah.options[:token_enabled] = true
153
+ ```
154
+
155
+ Once enabled, this setting will allow the `api_key` for the user to be used to authenticate them via the `token` parameter, or `X-Auth-Token` HTTP header.
156
+
157
+ For example, the following request would authenticate a valid active user that has the `api_key` value of `abc123`:
158
+
159
+ ``` shell
160
+ curl -H "X-Auth-Token: abc123" \
161
+ -H 'Content-Type: application/json' \
162
+ http://localhost:3000/api/test.json
163
+ ```
164
+
165
+ Using the `token` param, you could write the same thing as:
166
+
167
+ ``` shell
168
+ curl -H 'Content-Type: application/json' \
169
+ http://localhost:3000/api/test.json?token=abc123
170
+ ```
171
+
172
+ If you'd like to change the HTTP header used to fetch the user's api key from, you can change it using the `token_header` setting:
173
+
174
+ ```ruby
175
+ # in config/initializers/challah.rb
176
+ Challah.options[:token_enabled] = true
177
+ Challah.options[:token_header] = "X-App-User"
178
+ ```
179
+
180
+ Then:
181
+
182
+ ``` shell
183
+ curl -H "X-App-User: abc123" \
184
+ -H 'Content-Type: application/json' \
185
+ http://localhost:3000/api/test.json
186
+ ```
187
+
188
+ _Note: Custom HTTP headers should always start with X-_
189
+
146
190
  ## ActionCable in Rails 5
147
191
 
148
192
  Challah works well with securing your ActionCable channels since Rails 5. Here is a sample `ApplicationCable::Connection` file to secure connections to a valid signed-in user:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.2
1
+ 1.5.0
data/lib/challah.rb CHANGED
@@ -15,7 +15,6 @@ module Challah
15
15
  autoload :Session, "challah/session"
16
16
  autoload :Signup, "challah/signup"
17
17
  autoload :Techniques, "challah/techniques"
18
- autoload :Techniques, "challah/techniques"
19
18
 
20
19
  autoload :EmailValidator, "challah/validators/email_validator"
21
20
  autoload :PasswordValidator, "challah/validators/password_validator"
@@ -32,6 +31,7 @@ module Challah
32
31
  autoload :UserFindable, "challah/concerns/user/findable"
33
32
  autoload :UserPasswordable, "challah/concerns/user/passwordable"
34
33
  autoload :UserProvideable, "challah/concerns/user/provideable"
34
+ autoload :UserStatusable, "challah/concerns/user/statusable"
35
35
  autoload :UserValidateable, "challah/concerns/user/validateable"
36
36
 
37
37
  # Configuration options
@@ -49,6 +49,8 @@ module Challah
49
49
  @options ||= {
50
50
  access_denied_view: "sessions/access_denied",
51
51
  api_key_enabled: false,
52
+ token_enabled: false,
53
+ token_header: "X-Auth-Token",
52
54
  cookie_prefix: "challah",
53
55
  email_validator: "challah/email",
54
56
  password_validator: PasswordValidator,
@@ -70,6 +72,7 @@ module Challah
70
72
  # Default registered authentication techiques.
71
73
  register_technique :api_key, ApiKeyTechnique
72
74
  register_technique :password, PasswordTechnique
75
+ register_technique :token, TokenTechnique
73
76
 
74
77
  # Set up plugin registering capability
75
78
  extend Plugins
@@ -7,40 +7,10 @@ module Challah
7
7
  attr_reader :password_confirmation
8
8
  attr_reader :password_updated
9
9
 
10
- begin
11
- if columns.map(&:name).include?("status")
12
- enum status: %w( active inactive )
13
- end
14
- rescue ActiveRecord::StatementInvalid => exception
15
- raise exception unless exception.message =~ /could not find table/i ||
16
- exception.message =~ /does not exist/i
17
- end
18
-
19
10
  before_save :ensure_user_tokens
20
11
  before_validation :normalize_user_email
21
12
  end
22
13
 
23
- # Fallback to pre-enum active column (pre challah 1.4)
24
- def active=(enabled)
25
- if self.class.columns.map(&:name).include?("status")
26
- self.status = (!!enabled ? :active : :inactive)
27
- else
28
- write_attribute(:active, !!enabled)
29
- end
30
- end
31
-
32
- def active?
33
- # enum-based status
34
- if self.class.columns.map(&:name).include?("status")
35
- read_attribute(:status).to_s == "active"
36
-
37
- # support for non-enum status column (pre challah 1.4)
38
- else
39
- !!read_attribute(:active)
40
- end
41
- end
42
- alias_method :active, :active?
43
-
44
14
  # First name and last name together
45
15
  def name
46
16
  "#{ first_name } #{ last_name }".strip
@@ -55,7 +25,7 @@ module Challah
55
25
  #
56
26
  # Override this method if you need to check for a particular configuration on each page request.
57
27
  def valid_session?
58
- active?
28
+ true
59
29
  end
60
30
 
61
31
  protected
@@ -0,0 +1,45 @@
1
+ module Challah
2
+ module UserStatusable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ begin
7
+ if columns.map(&:name).include?("status")
8
+ additional_statuses = Array(Challah.options[:additional_statuses])
9
+ enum status: [:active, :inactive, *additional_statuses]
10
+ end
11
+ rescue ActiveRecord::StatementInvalid => exception
12
+ raise exception unless exception.message =~ /could not find table/i ||
13
+ exception.message =~ /does not exist/i
14
+ end
15
+ end
16
+
17
+ # Fallback to pre-enum active column (pre challah 1.4)
18
+ def active=(enabled)
19
+ if self.class.columns.map(&:name).include?("status")
20
+ self.status = (!!enabled ? :active : :inactive)
21
+ else
22
+ write_attribute(:active, !!enabled)
23
+ end
24
+ end
25
+
26
+ def active?
27
+ # enum-based status
28
+ if self.class.columns.map(&:name).include?("status")
29
+ read_attribute(:status).to_s == "active"
30
+
31
+ # support for non-enum status column (pre challah 1.4)
32
+ else
33
+ !!read_attribute(:active)
34
+ end
35
+ end
36
+
37
+ def active
38
+ active?
39
+ end
40
+
41
+ def valid_session?
42
+ active?
43
+ end
44
+ end
45
+ end
@@ -8,6 +8,7 @@ module Challah
8
8
  include UserFindable
9
9
  include UserPasswordable
10
10
  include UserProvideable
11
+ include UserStatusable
11
12
 
12
13
  unless Challah.options[:skip_user_validations]
13
14
  include UserValidateable
@@ -53,7 +53,7 @@ module Challah
53
53
  nil
54
54
  end
55
55
 
56
- if store_user and store_user.active? and store_user.persistence_token == persistence_token
56
+ if store_user and store_user.valid_session? and store_user.persistence_token == persistence_token
57
57
  if store_user.valid_session?
58
58
  self.user = store_user
59
59
  @valid = true
@@ -90,7 +90,7 @@ module Challah
90
90
  # Returns true if this session has been authenticated and is ready to save.
91
91
  def valid?
92
92
  return @valid if @valid != nil
93
- return true if self.user and self.user.active?
93
+ return true if self.user and self.user.valid_session?
94
94
  authenticate!
95
95
  end
96
96
 
@@ -126,7 +126,7 @@ module Challah
126
126
  end
127
127
  end
128
128
 
129
- if user_record and user_record.active?
129
+ if user_record and user_record.valid_session?
130
130
  session.user = user_record
131
131
  session.persist = true
132
132
  end
@@ -1,5 +1,6 @@
1
- require 'challah/techniques/api_key_technique'
2
- require 'challah/techniques/password_technique'
1
+ require "challah/techniques/api_key_technique"
2
+ require "challah/techniques/password_technique"
3
+ require "challah/techniques/token_technique"
3
4
 
4
5
  module Challah
5
6
  # Techniques are used to allow different methods of authentication. By default, there are
@@ -23,7 +24,7 @@ module Challah
23
24
  # # was params[:secret] provided to the request
24
25
  # if @session.secret?
25
26
  # # does the params[:secret] value match our shared password?
26
- # if @session.secret == 'let-me-in'
27
+ # if @session.secret == "let-me-in"
27
28
  # # if the secret was correct, grab the username from params, and load the user
28
29
  # user = User.find_for_session(@session.username)
29
30
  # return user
@@ -16,7 +16,7 @@ module Challah
16
16
  unless @key.to_s.blank?
17
17
  user = user_model.find_by_api_key(@key)
18
18
 
19
- if user and user.active?
19
+ if user and user.valid_session?
20
20
  return user
21
21
  end
22
22
  end
@@ -33,4 +33,4 @@ module Challah
33
33
  end
34
34
 
35
35
  end
36
- end
36
+ end
@@ -1,5 +1,4 @@
1
1
  module Challah
2
-
3
2
  # Allows authentication by username and password.
4
3
  class PasswordTechnique
5
4
 
@@ -17,7 +16,7 @@ module Challah
17
16
  user = user_model.find_for_session(username)
18
17
 
19
18
  if user
20
- if user.active?
19
+ if user.valid_session?
21
20
  if user.authenticate(@password)
22
21
  return user
23
22
  end
@@ -51,5 +50,4 @@ module Challah
51
50
  @username
52
51
  end
53
52
  end
54
-
55
- end
53
+ end
@@ -0,0 +1,47 @@
1
+ module Challah
2
+ # Allows authentication with a token URL parameter or X-Auth-Token header.
3
+ # Useful for API-based authentication.
4
+ class TokenTechnique
5
+
6
+ attr_accessor :user_model
7
+
8
+ def initialize(session)
9
+ if session.request && session.request.headers[header_key]
10
+ @token = session.request.headers[header_key].to_s
11
+ else
12
+ @token = session.params[:token].to_s
13
+ end
14
+ end
15
+
16
+ def authenticate
17
+ # Token authorization functionality is only enabled with the :token_enabled option.
18
+ # This is turned off by default and must be manually enabled for security reasons.
19
+ return nil unless Challah.options[:token_enabled]
20
+
21
+ if user = user_model.where(api_key: token).first
22
+ if user.valid_session?
23
+ return user
24
+ end
25
+ end
26
+
27
+ nil
28
+ end
29
+
30
+ def header_key
31
+ Challah.options[:token_header] || "X-Auth-Token"
32
+ end
33
+
34
+ def persist?
35
+ false
36
+ end
37
+
38
+ def user_model
39
+ @user_model ||= Challah.user
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :token
45
+
46
+ end
47
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: challah
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Tornow
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-08-08 00:00:00.000000000 Z
13
+ date: 2017-01-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: highline
@@ -148,6 +148,7 @@ files:
148
148
  - lib/challah/concerns/user/findable.rb
149
149
  - lib/challah/concerns/user/passwordable.rb
150
150
  - lib/challah/concerns/user/provideable.rb
151
+ - lib/challah/concerns/user/statusable.rb
151
152
  - lib/challah/concerns/user/validateable.rb
152
153
  - lib/challah/concerns/userable.rb
153
154
  - lib/challah/controller.rb
@@ -165,6 +166,7 @@ files:
165
166
  - lib/challah/techniques.rb
166
167
  - lib/challah/techniques/api_key_technique.rb
167
168
  - lib/challah/techniques/password_technique.rb
169
+ - lib/challah/techniques/token_technique.rb
168
170
  - lib/challah/test.rb
169
171
  - lib/challah/validators/email_validator.rb
170
172
  - lib/challah/validators/password_validator.rb
@@ -192,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
194
  version: 1.8.11
193
195
  requirements: []
194
196
  rubyforge_project:
195
- rubygems_version: 2.4.5.1
197
+ rubygems_version: 2.5.2
196
198
  signing_key:
197
199
  specification_version: 4
198
200
  summary: Rails authentication and sessions