knock 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OWQzZTFhZmNhYTg2YjZmZDhmMzkyZjRkYzRiMTg0ZmE0MTVhOGE1MA==
4
+ MzVhZjdkMGZhZTMxMWVmYTU1MTRiMTU1OWM4ZTdhZTAyYmEzZWZiNw==
5
5
  data.tar.gz: !binary |-
6
- OWRjZDEyZmY3MDk0MTYzM2QwMmM0NDQxYTJjOGEwZWM2ZjBmMjBjYQ==
6
+ YWYwZTAzM2EwY2MxMzU4Nzg3N2ZmNzkwY2Y5NzhlOWZiOTFiMzVlMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZmRkZjFjOGViZTJhNjhmNWFlZmQ5ZGIwMzI2MjQ5YjRiOWI5ZWY3MGRjN2Rj
10
- ZmE5NjY3YzVlNTE1MDAxYmNlOThhYmZkMzBlMjY0ZDI1MmNmYjMzYWY3ODc5
11
- MDZkNjZhYjM5M2EzY2FjMzczNTYyN2Y0MTM5MmMwMTIxZTRjMmE=
9
+ MjhlOTdhZTBkNTE0NjQzMjBjYWE4M2JlMDA1YjI3ODgyZjFkYzhhYThjOWQ3
10
+ NGQ1ZjllMzBmZjUzZTdmYjRhYTcyYzQ3MDM4YzAxODNlNzkxMzg2MDlkZGVl
11
+ ODI4ZTE2N2YwMDE1OWViMGIzOGI0ZDQ5ODU5YzU3ODc1ZTc2NWU=
12
12
  data.tar.gz: !binary |-
13
- M2RlNjA2ZTFjOTdkMDZlMTllNjA1MzViZjIzODNhYTNlZWM2MjNlNjVjZWJi
14
- NzdkNDk5YzIzMWViNzEzMjRhZjEwMjNmNWNmMTZmNjA1NDhlMzU4NDM0NzZk
15
- ZmM2NzA3MzQ5MzVkZDA2NzBkMjljMzY5ZmVjOWZiNWZhOTgxY2E=
13
+ MGJjNjQyOWQ3YzA2ZTU0MzY4ZTI3MGFlY2E0ZDdkMjZhNDJjNmI1YTEzMmZi
14
+ ZDQ3NDA2NGM2YzA1MTc1M2I4MmI2MThjMzc4MTYzZTQwNzA3MGJkYTJkNWFl
15
+ ZjBjZDk3OGRmMWFkNWY5OTA0NWRlYzhmY2EzM2YxMjdmY2I2YzM=
@@ -6,11 +6,13 @@ module Knock
6
6
 
7
7
  def initialize payload: {}, token: nil
8
8
  if token.present?
9
- @payload, _ = JWT.decode token, key, true, verify_claims
9
+ @payload, _ = JWT.decode token, decode_key, true, options
10
10
  @token = token
11
11
  else
12
12
  @payload = payload
13
- @token = JWT.encode(claims.merge(payload), key, 'HS256')
13
+ @token = JWT.encode claims.merge(payload),
14
+ secret_key,
15
+ Knock.token_signature_algorithm
14
16
  end
15
17
  end
16
18
 
@@ -19,10 +21,20 @@ module Knock
19
21
  end
20
22
 
21
23
  private
22
- def key
24
+ def secret_key
23
25
  Knock.token_secret_signature_key.call
24
26
  end
25
27
 
28
+ def decode_key
29
+ Knock.token_public_key || secret_key
30
+ end
31
+
32
+ def options
33
+ verify_claims.merge({
34
+ algorithm: Knock.token_signature_algorithm
35
+ })
36
+ end
37
+
26
38
  def claims
27
39
  {
28
40
  exp: Knock.token_lifetime.from_now.to_i,
@@ -32,7 +44,7 @@ module Knock
32
44
 
33
45
  def verify_claims
34
46
  {
35
- aud: Knock.token_audience, verify_claims: Knock.token_audience.present?
47
+ aud: Knock.token_audience, verify_aud: Knock.token_audience.present?
36
48
  }
37
49
  end
38
50
  end
@@ -18,8 +18,10 @@ Knock.setup do |config|
18
18
  ## AuthTokenController parameters. It also uses the same variable to enforce
19
19
  ## permitted values in the controller.
20
20
  ##
21
+ ## You must raise ActiveRecord::RecordNotFound if the resource cannot be retrieved.
22
+ ##
21
23
  ## Default:
22
- # self.current_user_from_handle = -> (handle) { User.find_by! Knock.handle_attr => handle }
24
+ # config.current_user_from_handle = -> (handle) { User.find_by! Knock.handle_attr => handle }
23
25
 
24
26
  ## Current user retrieval when validating token
25
27
  ## --------------------------------------------
@@ -28,6 +30,8 @@ Knock.setup do |config|
28
30
  ## By default, it assumes you have a model called `User` and that
29
31
  ## the user_id is stored in the 'sub' claim.
30
32
  ##
33
+ ## You must raise ActiveRecord::RecordNotFound if the resource cannot be retrieved.
34
+ ##
31
35
  ## Default:
32
36
  # config.current_user_from_token = -> (claims) { User.find claims['sub'] }
33
37
 
@@ -44,7 +48,7 @@ Knock.setup do |config|
44
48
  ## Audience claim
45
49
  ## --------------
46
50
  ##
47
- ## Configure the audience claim to indentify the recipients that the token
51
+ ## Configure the audience claim to identify the recipients that the token
48
52
  ## is intended for.
49
53
  ##
50
54
  ## Default:
@@ -53,6 +57,13 @@ Knock.setup do |config|
53
57
  ## If using Auth0, uncomment the line below
54
58
  # config.token_audience = -> { Rails.application.secrets.auth0_client_id }
55
59
 
60
+ ## Signature algorithm
61
+ ## -------------------
62
+ ##
63
+ ## Configure the algorithm used to encode the token
64
+ ##
65
+ ## Default:
66
+ # config.token_signature_algorithm = 'HS256'
56
67
 
57
68
  ## Signature key
58
69
  ## -------------
@@ -65,4 +76,11 @@ Knock.setup do |config|
65
76
  ## If using Auth0, uncomment the line below
66
77
  # config.token_secret_signature_key = -> { JWT.base64url_decode Rails.application.secrets.auth0_client_secret }
67
78
 
79
+ ## Public key
80
+ ## ----------
81
+ ##
82
+ ## Configure the public key used to decode tokens, if required.
83
+ ##
84
+ ## Default:
85
+ # config.token_public_key = nil
68
86
  end
data/lib/knock.rb CHANGED
@@ -6,10 +6,10 @@ module Knock
6
6
  self.handle_attr = :email
7
7
 
8
8
  mattr_accessor :current_user_from_handle
9
- self.current_user_from_handle = -> (handle) { User.find_by! Knock.handle_attr => handle }
9
+ self.current_user_from_handle = -> handle { User.find_by! Knock.handle_attr => handle }
10
10
 
11
11
  mattr_accessor :current_user_from_token
12
- self.current_user_from_token = -> (claims) { User.find claims['sub'] }
12
+ self.current_user_from_token = -> claims { User.find claims['sub'] }
13
13
 
14
14
  mattr_accessor :token_lifetime
15
15
  self.token_lifetime = 1.day
@@ -17,9 +17,15 @@ module Knock
17
17
  mattr_accessor :token_audience
18
18
  self.token_audience = nil
19
19
 
20
+ mattr_accessor :token_signature_algorithm
21
+ self.token_signature_algorithm = 'HS256'
22
+
20
23
  mattr_accessor :token_secret_signature_key
21
24
  self.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
22
25
 
26
+ mattr_accessor :token_public_key
27
+ self.token_public_key = nil
28
+
23
29
  # Default way to setup Knock. Run `rails generate knock:install` to create
24
30
  # a fresh initializer with all configuration values.
25
31
  def self.setup
@@ -1,12 +1,16 @@
1
1
  module Knock::Authenticable
2
- attr_reader :current_user
2
+ def current_user
3
+ @current_user ||= begin
4
+ token = params[:token] ||
5
+ request.headers['Authorization'].match(/^Bearer (.*)$/)[1]
3
6
 
4
- def authenticate
5
- begin
6
- token = request.headers['Authorization'].split(' ').last
7
- @current_user = Knock::AuthToken.new(token: token).current_user
7
+ Knock::AuthToken.new(token: token).current_user
8
8
  rescue
9
- head :unauthorized
9
+ nil
10
10
  end
11
11
  end
12
+
13
+ def authenticate
14
+ head :unauthorized unless current_user
15
+ end
12
16
  end
data/lib/knock/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Knock
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -0,0 +1,9 @@
1
+ class CurrentUsersController < ApplicationController
2
+ def show
3
+ if current_user
4
+ head :ok
5
+ else
6
+ head :not_found
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,5 @@
1
1
  Rails.application.routes.draw do
2
2
  resources :protected_resources
3
+ resource :current_user
3
4
  mount Knock::Engine => "/knock"
4
5
  end
Binary file
@@ -1,78 +1,146 @@
1
-  (2.9ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "password_digest" varchar NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
2
-  (1.4ms) CREATE TABLE "schema_migrations" ("version" varchar NOT NULL)
1
+  (4.5ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar NOT NULL, "password_digest" varchar NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
2
+  (1.6ms) CREATE TABLE "schema_migrations" ("version" varchar NOT NULL)
3
3
   (0.1ms) select sqlite_version(*)
4
-  (1.3ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
4
+  (1.6ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
5
5
   (0.1ms) SELECT version FROM "schema_migrations"
6
-  (1.0ms) INSERT INTO "schema_migrations" (version) VALUES ('20150713101607')
6
+  (1.5ms) INSERT INTO "schema_migrations" (version) VALUES ('20150713101607')
7
7
  ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
8
8
   (0.1ms) begin transaction
9
9
  Fixture Delete (0.2ms) DELETE FROM "users"
10
- Fixture Insert (0.1ms) INSERT INTO "users" ("email", "password_digest", "created_at", "updated_at", "id") VALUES ('one@example.net', '$2a$04$0mPmVn/CmWZkmHf15VY.JuVDRXH5EhKuCzFpsKH7.ySvtGWM4WLhW', '2015-07-23 14:58:31', '2015-07-23 14:58:31', 980190962)
11
- Fixture Insert (0.1ms) INSERT INTO "users" ("email", "password_digest", "created_at", "updated_at", "id") VALUES ('two@example.net', '$2a$04$h2eMNW1pZXYVkPzhnOGg3efpsw7/ENPysgUpdAi4o8u0K.wu/omDG', '2015-07-23 14:58:31', '2015-07-23 14:58:31', 298486374)
12
-  (45.0ms) commit transaction
10
+ Fixture Insert (0.1ms) INSERT INTO "users" ("email", "password_digest", "created_at", "updated_at", "id") VALUES ('one@example.net', '$2a$04$8Yam9pqovA3weu3n/l1Z4eJ7SP/xFw2yESJoXUcpqk89Fqn3mpY7C', '2016-01-02 04:04:33', '2016-01-02 04:04:33', 980190962)
11
+ Fixture Insert (0.1ms) INSERT INTO "users" ("email", "password_digest", "created_at", "updated_at", "id") VALUES ('two@example.net', '$2a$04$pPSRVhAc5Awe4myXaw6EF.Xn.hJ/mWlUGSUA5UfiGbmm4l6O5QJ9u', '2016-01-02 04:04:33', '2016-01-02 04:04:33', 298486374)
12
+  (1.7ms) commit transaction
13
+  (0.1ms) begin transaction
14
+ ------------------------------------------------------
15
+ Knock::AuthTokenControllerTest: test_responds_with_201
16
+ ------------------------------------------------------
17
+ User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
18
+ Processing by Knock::AuthTokenController#create as HTML
19
+ Parameters: {"auth"=>{"email"=>"one@example.net", "password"=>"[FILTERED]"}}
20
+ User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
21
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
22
+ Completed 201 Created in 7ms (Views: 0.3ms | ActiveRecord: 0.3ms)
23
+  (0.1ms) rollback transaction
24
+  (0.1ms) begin transaction
25
+ -----------------------------------------------------------------------------
26
+ Knock::AuthTokenControllerTest: test_responds_with_404_if_user_does_not_exist
27
+ -----------------------------------------------------------------------------
28
+ Processing by Knock::AuthTokenController#create as HTML
29
+ Parameters: {"auth"=>{"email"=>"wrong@example.net", "password"=>"[FILTERED]"}}
30
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "wrong@example.net"]]
31
+ Completed 404 Not Found in 1ms (ActiveRecord: 0.1ms)
32
+  (0.1ms) rollback transaction
33
+  (0.1ms) begin transaction
34
+ -----------------------------------------------------------------------------
35
+ Knock::AuthTokenControllerTest: test_responds_with_404_if_password_is_invalid
36
+ -----------------------------------------------------------------------------
37
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
38
+ Processing by Knock::AuthTokenController#create as HTML
39
+ Parameters: {"auth"=>{"email"=>"one@example.net", "password"=>"[FILTERED]"}}
40
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
41
+ Completed 404 Not Found in 2ms (ActiveRecord: 0.1ms)
42
+  (0.1ms) rollback transaction
43
+  (0.1ms) begin transaction
44
+ -------------------------------------------------------------------------
45
+ Knock::AuthTokenTest: test_verify_audience_when_token_audience_is_present
46
+ -------------------------------------------------------------------------
47
+  (0.1ms) rollback transaction
48
+  (0.1ms) begin transaction
49
+ -------------------------------------------------
50
+ Knock::AuthTokenTest: test_encode_tokens_with_RSA
51
+ -------------------------------------------------
52
+  (0.1ms) rollback transaction
53
+  (0.1ms) begin transaction
54
+ -------------------------------------------
55
+ Knock::AuthTokenTest: test_verify_algorithm
56
+ -------------------------------------------
57
+  (0.1ms) rollback transaction
58
+  (0.1ms) begin transaction
59
+ ----------------------------------------------------
60
+ Knock::AuthTokenTest: test_decode_RSA_encoded_tokens
61
+ ----------------------------------------------------
62
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
63
+  (0.1ms) rollback transaction
64
+  (0.1ms) begin transaction
65
+ -------------------------------------------------------------------------------------------
66
+ ProtectedResourcesControllerTest: test_responds_with_unauthorized_with_invalid_token_in_url
67
+ -------------------------------------------------------------------------------------------
68
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
69
+ Processing by ProtectedResourcesController#index as HTML
70
+ Parameters: {"token"=>"invalid"}
71
+ Filter chain halted as :authenticate rendered or redirected
72
+ Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)
73
+  (0.1ms) rollback transaction
13
74
   (0.1ms) begin transaction
14
75
  -----------------------------------------------------------------
15
76
  ProtectedResourcesControllerTest: test_responds_with_unauthorized
16
77
  -----------------------------------------------------------------
78
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
79
+ Processing by ProtectedResourcesController#index as HTML
80
+ Filter chain halted as :authenticate rendered or redirected
81
+ Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)
82
+  (0.1ms) rollback transaction
83
+  (0.1ms) begin transaction
84
+ ----------------------------------------------------------------------------------------------
85
+ ProtectedResourcesControllerTest: test_responds_with_unauthorized_with_invalid_token_in_header
86
+ ----------------------------------------------------------------------------------------------
87
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
17
88
  Processing by ProtectedResourcesController#index as HTML
18
89
  Filter chain halted as :authenticate rendered or redirected
19
90
  Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)
20
91
   (0.1ms) rollback transaction
21
92
   (0.1ms) begin transaction
22
- -----------------------------------------------------------------------------
23
- ProtectedResourcesControllerTest: test_responds_with_success_if_authenticated
24
- -----------------------------------------------------------------------------
25
- User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
93
+ ------------------------------------------------------------------------------
94
+ ProtectedResourcesControllerTest: test_responds_with_success_with_token_in_url
95
+ ------------------------------------------------------------------------------
96
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
26
97
  Processing by ProtectedResourcesController#index as HTML
98
+ Parameters: {"token"=>"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NTE3OTM4NzQsImF1ZCI6bnVsbCwic3ViIjo5ODAxOTA5NjJ9.o7HWlffQZN6ss8gZk4Nyl70T8TXpNFoVhr3lBZ5Jvnc"}
27
99
  User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
28
- Completed 200 OK in 2ms (ActiveRecord: 0.1ms)
100
+ Completed 200 OK in 1ms (ActiveRecord: 0.1ms)
29
101
   (0.1ms) rollback transaction
30
-  (0.0ms) begin transaction
102
+  (0.1ms) begin transaction
31
103
  ------------------------------------------------------------------------------
32
104
  ProtectedResourcesControllerTest: test_has_a_current_user_after_authentication
33
105
  ------------------------------------------------------------------------------
34
106
  User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
35
107
  Processing by ProtectedResourcesController#index as HTML
36
- User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
37
- Completed 200 OK in 0ms (ActiveRecord: 0.0ms)
108
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
109
+ Completed 200 OK in 1ms (ActiveRecord: 0.1ms)
38
110
   (0.1ms) rollback transaction
39
111
   (0.1ms) begin transaction
40
- ------------------------------------------------------
41
- Knock::AuthTokenControllerTest: test_responds_with_201
42
- ------------------------------------------------------
112
+ ---------------------------------------------------------------------------------------
113
+ ProtectedResourcesControllerTest: test_responds_with_success_with_valid_token_in_header
114
+ ---------------------------------------------------------------------------------------
43
115
  User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
44
- Processing by Knock::AuthTokenController#create as HTML
45
- Parameters: {"auth"=>{"email"=>"one@example.net", "password"=>"[FILTERED]"}}
46
- User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
47
- User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
48
- Completed 201 Created in 3ms (Views: 0.2ms | ActiveRecord: 0.2ms)
49
-  (0.1ms) rollback transaction
50
-  (0.1ms) begin transaction
51
- -----------------------------------------------------------------------------
52
- Knock::AuthTokenControllerTest: test_responds_with_404_if_password_is_invalid
53
- -----------------------------------------------------------------------------
116
+ Processing by ProtectedResourcesController#index as HTML
54
117
  User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
55
- Processing by Knock::AuthTokenController#create as HTML
56
- Parameters: {"auth"=>{"email"=>"one@example.net", "password"=>"[FILTERED]"}}
57
- User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "one@example.net"]]
58
- Completed 404 Not Found in 2ms (ActiveRecord: 0.1ms)
59
-  (0.1ms) rollback transaction
60
-  (0.0ms) begin transaction
61
- -----------------------------------------------------------------------------
62
- Knock::AuthTokenControllerTest: test_responds_with_404_if_user_does_not_exist
63
- -----------------------------------------------------------------------------
64
- Processing by Knock::AuthTokenController#create as HTML
65
- Parameters: {"auth"=>{"email"=>"wrong@example.net", "password"=>"[FILTERED]"}}
66
- User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "wrong@example.net"]]
67
- Completed 404 Not Found in 1ms (ActiveRecord: 0.1ms)
118
+ Completed 200 OK in 1ms (ActiveRecord: 0.1ms)
68
119
   (0.1ms) rollback transaction
69
120
   (0.1ms) begin transaction
70
- ---------------------------------------
71
- KnockTest: test_setup_block_yields_self
72
- ---------------------------------------
73
-  (0.0ms) rollback transaction
121
+ --------------------------------------------------
122
+ CurrentUsersControllerTest: test_responds_with_200
123
+ --------------------------------------------------
124
+ User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
125
+ Processing by CurrentUsersController#show as HTML
126
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
127
+ Completed 200 OK in 1ms (ActiveRecord: 0.1ms)
128
+  (0.1ms) rollback transaction
74
129
   (0.1ms) begin transaction
130
+ ---------------------------------------------------------------------------
131
+ CurrentUsersControllerTest: test_responds_with_404_if_user_is_not_logged_in
132
+ ---------------------------------------------------------------------------
133
+ User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 980190962]]
134
+ Processing by CurrentUsersController#show as HTML
135
+ Completed 404 Not Found in 0ms (ActiveRecord: 0.0ms)
136
+  (0.1ms) rollback transaction
137
+  (0.1ms) begin transaction
75
138
  ----------------------------------------------------------------
76
139
  InstallGeneratorTest: test_Assert_all_files_are_properly_created
77
140
  ----------------------------------------------------------------
78
-  (0.1ms) rollback transaction
141
+  (0.1ms) rollback transaction
142
+  (0.1ms) begin transaction
143
+ ---------------------------------------
144
+ KnockTest: test_setup_block_yields_self
145
+ ---------------------------------------
146
+  (0.1ms) rollback transaction
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class CurrentUsersControllerTest < ActionController::TestCase
4
+ setup do
5
+ @user = users(:one)
6
+ @token = Knock::AuthToken.new(payload: { sub: @user.id }).token
7
+ end
8
+
9
+ def authenticate token: @token
10
+ @request.env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
11
+ end
12
+
13
+ test "responds with 404 if user is not logged in" do
14
+ get :show
15
+ assert_response :not_found
16
+ end
17
+
18
+ test "responds with 200" do
19
+ authenticate
20
+ get :show
21
+ assert_response :success
22
+ end
23
+ end
@@ -1,10 +1,13 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ProtectedResourcesControllerTest < ActionController::TestCase
4
- def authenticate
4
+ def setup
5
5
  @user = users(:one)
6
6
  @token = Knock::AuthToken.new(payload: { sub: @user.id }).token
7
- @request.env['HTTP_AUTHORIZATION'] = "Bearer #{@token}"
7
+ end
8
+
9
+ def authenticate token: @token
10
+ @request.env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
8
11
  end
9
12
 
10
13
  test "responds with unauthorized" do
@@ -12,12 +15,28 @@ class ProtectedResourcesControllerTest < ActionController::TestCase
12
15
  assert_response :unauthorized
13
16
  end
14
17
 
15
- test "responds with success if authenticated" do
18
+ test "responds with success with valid token in header" do
16
19
  authenticate
17
20
  get :index
18
21
  assert_response :success
19
22
  end
20
23
 
24
+ test "responds with unauthorized with invalid token in header" do
25
+ authenticate token: "invalid"
26
+ get :index
27
+ assert_response :unauthorized
28
+ end
29
+
30
+ test "responds with success with token in url" do
31
+ get :index, token: @token
32
+ assert_response :success
33
+ end
34
+
35
+ test "responds with unauthorized with invalid token in url" do
36
+ get :index, token: "invalid"
37
+ assert_response :unauthorized
38
+ end
39
+
21
40
  test "has a current_user after authentication" do
22
41
  authenticate
23
42
  get :index
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+ require 'jwt'
3
+
4
+ module Knock
5
+ class AuthTokenTest < ActiveSupport::TestCase
6
+ test "verify algorithm" do
7
+ Knock.token_signature_algorithm = 'RS256'
8
+ key = Knock.token_secret_signature_key.call
9
+
10
+ token = JWT.encode({sub: '1'}, key, 'HS256')
11
+
12
+ assert_raises(JWT::IncorrectAlgorithm) {
13
+ AuthToken.new(token: token)
14
+ }
15
+ end
16
+
17
+ test "decode RSA encoded tokens" do
18
+ user = users(:one)
19
+ rsa_private = OpenSSL::PKey::RSA.generate 2048
20
+ Knock.token_public_key = rsa_private.public_key
21
+ Knock.token_signature_algorithm = 'RS256'
22
+
23
+ token = JWT.encode({sub: user.id}, rsa_private, 'RS256')
24
+
25
+ assert_nothing_raised { AuthToken.new(token: token) }
26
+ end
27
+
28
+ test "encode tokens with RSA" do
29
+ rsa_private = OpenSSL::PKey::RSA.generate 2048
30
+ Knock.token_secret_signature_key = -> { rsa_private }
31
+ Knock.token_signature_algorithm = 'RS256'
32
+
33
+ token = AuthToken.new(payload: {sub: '1'}).token
34
+
35
+ payload, header = JWT.decode token, rsa_private.public_key, true
36
+ assert_equal payload['sub'], '1'
37
+ assert_equal header['alg'], 'RS256'
38
+ end
39
+
40
+ test "verify audience when token_audience is present" do
41
+ Knock.token_audience = 'bar'
42
+ key = Knock.token_secret_signature_key.call
43
+
44
+ token = JWT.encode({sub: 'foo'}, key, 'HS256')
45
+
46
+ assert_raises(JWT::InvalidAudError) {
47
+ AuthToken.new token: token
48
+ }
49
+ end
50
+ end
51
+ end
data/test/test_helper.rb CHANGED
@@ -21,3 +21,18 @@ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
21
21
  ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
22
22
  ActiveSupport::TestCase.fixtures :all
23
23
  end
24
+
25
+ # Make sure knock global configuration is reset before every tests
26
+ # to avoid order dependent failures.
27
+ class ActiveSupport::TestCase
28
+ setup :reset_knock_configuration
29
+
30
+ private
31
+
32
+ def reset_knock_configuration
33
+ Knock.token_signature_algorithm = 'HS256'
34
+ Knock.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
35
+ Knock.token_public_key = nil
36
+ Knock.token_audience = nil
37
+ end
38
+ end
@@ -18,8 +18,10 @@ Knock.setup do |config|
18
18
  ## AuthTokenController parameters. It also uses the same variable to enforce
19
19
  ## permitted values in the controller.
20
20
  ##
21
+ ## You must raise ActiveRecord::RecordNotFound if the resource cannot be retrieved.
22
+ ##
21
23
  ## Default:
22
- # self.current_user_from_handle = -> (handle) { User.find_by! Knock.handle_attr => handle }
24
+ # config.current_user_from_handle = -> (handle) { User.find_by! Knock.handle_attr => handle }
23
25
 
24
26
  ## Current user retrieval when validating token
25
27
  ## --------------------------------------------
@@ -28,6 +30,8 @@ Knock.setup do |config|
28
30
  ## By default, it assumes you have a model called `User` and that
29
31
  ## the user_id is stored in the 'sub' claim.
30
32
  ##
33
+ ## You must raise ActiveRecord::RecordNotFound if the resource cannot be retrieved.
34
+ ##
31
35
  ## Default:
32
36
  # config.current_user_from_token = -> (claims) { User.find claims['sub'] }
33
37
 
@@ -44,7 +48,7 @@ Knock.setup do |config|
44
48
  ## Audience claim
45
49
  ## --------------
46
50
  ##
47
- ## Configure the audience claim to indentify the recipients that the token
51
+ ## Configure the audience claim to identify the recipients that the token
48
52
  ## is intended for.
49
53
  ##
50
54
  ## Default:
@@ -53,6 +57,13 @@ Knock.setup do |config|
53
57
  ## If using Auth0, uncomment the line below
54
58
  # config.token_audience = -> { Rails.application.secrets.auth0_client_id }
55
59
 
60
+ ## Signature algorithm
61
+ ## -------------------
62
+ ##
63
+ ## Configure the algorithm used to encode the token
64
+ ##
65
+ ## Default:
66
+ # config.token_signature_algorithm = 'HS256'
56
67
 
57
68
  ## Signature key
58
69
  ## -------------
@@ -65,4 +76,11 @@ Knock.setup do |config|
65
76
  ## If using Auth0, uncomment the line below
66
77
  # config.token_secret_signature_key = -> { JWT.base64url_decode Rails.application.secrets.auth0_client_secret }
67
78
 
79
+ ## Public key
80
+ ## ----------
81
+ ##
82
+ ## Configure the public key used to decode tokens, if required.
83
+ ##
84
+ ## Default:
85
+ # config.token_public_key = nil
68
86
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnaud MESUREUR
@@ -9,20 +9,20 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-07-23 00:00:00.000000000 Z
12
+ date: 2016-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - ! '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: '4.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '4.2'
28
28
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,7 @@ files:
93
93
  - test/dummy/app/assets/javascripts/application.js
94
94
  - test/dummy/app/assets/stylesheets/application.css
95
95
  - test/dummy/app/controllers/application_controller.rb
96
+ - test/dummy/app/controllers/current_users_controller.rb
96
97
  - test/dummy/app/controllers/protected_resources_controller.rb
97
98
  - test/dummy/app/helpers/application_helper.rb
98
99
  - test/dummy/app/models/user.rb
@@ -128,12 +129,14 @@ files:
128
129
  - test/dummy/public/422.html
129
130
  - test/dummy/public/500.html
130
131
  - test/dummy/public/favicon.ico
132
+ - test/dummy/test/controllers/current_users_controller_test.rb
131
133
  - test/dummy/test/controllers/protected_resources_controller_test.rb
132
134
  - test/dummy/test/fixtures/users.yml
133
135
  - test/dummy/test/models/user_test.rb
134
136
  - test/fixtures/users.yml
135
137
  - test/generators/install_generator_test.rb
136
138
  - test/knock_test.rb
139
+ - test/model/knock/auth_token_test.rb
137
140
  - test/test_helper.rb
138
141
  - test/tmp/config/initializers/knock.rb
139
142
  homepage: https://github.com/nsarno/knock
@@ -167,6 +170,7 @@ test_files:
167
170
  - test/dummy/app/assets/javascripts/application.js
168
171
  - test/dummy/app/assets/stylesheets/application.css
169
172
  - test/dummy/app/controllers/application_controller.rb
173
+ - test/dummy/app/controllers/current_users_controller.rb
170
174
  - test/dummy/app/controllers/protected_resources_controller.rb
171
175
  - test/dummy/app/helpers/application_helper.rb
172
176
  - test/dummy/app/models/user.rb
@@ -202,11 +206,13 @@ test_files:
202
206
  - test/dummy/public/422.html
203
207
  - test/dummy/public/500.html
204
208
  - test/dummy/public/favicon.ico
209
+ - test/dummy/test/controllers/current_users_controller_test.rb
205
210
  - test/dummy/test/controllers/protected_resources_controller_test.rb
206
211
  - test/dummy/test/fixtures/users.yml
207
212
  - test/dummy/test/models/user_test.rb
208
213
  - test/fixtures/users.yml
209
214
  - test/generators/install_generator_test.rb
210
215
  - test/knock_test.rb
216
+ - test/model/knock/auth_token_test.rb
211
217
  - test/test_helper.rb
212
218
  - test/tmp/config/initializers/knock.rb