authorio 0.8.4 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78659edadab6ff85d24828c318525bac7b62b4a76b9905e0a1d819ec266f9d46
4
- data.tar.gz: 817fe77d1c1fd89e68df07a594725997d598e0f0027210d083762da50cb447fd
3
+ metadata.gz: e4cd85ad8ec9b0e70f4d276f7c600d5cc3ebab5b04f0f0313da9f6151e78d680
4
+ data.tar.gz: 7ec85565cc8fb4ea711836ab8069f7062929d13af6f1520809095bdee7c859b9
5
5
  SHA512:
6
- metadata.gz: 8205bfe7bc6798f560da3f56b19f26822653d6f6fb8baac925be38a713f871e1faf90f0492ea25187124cd98db928a7d875da47b53faf14afe1efc6418498dbd
7
- data.tar.gz: 3c772c7777f016316911f36573f5d2982ca27a40edb18dcac16782fb380021971feaeea4271adebe411101b39a9bb544d3f27f88dec93d72aae6f0e5adc483fd
6
+ metadata.gz: 845bc518d44332a7e71eabd020da0f450979dcf35ec35539850ee40b931c270c7c89f6205fa021b27b78b86c07fbcd1b36354c49c79c28d6e5d2b8ea501aad00
7
+ data.tar.gz: ca1f67ba7804bd630ce55713cfd1c3f2b542f04781583ec165073c1ad0eea829bef439d362af9e302e530da8ccc650736b00039b1151e7559b1cb8b8cdcc64b2
@@ -50,7 +50,7 @@ div.authorio-auth {
50
50
  margin: 0.1em;
51
51
  }
52
52
 
53
- .authorio-auth .auth-btn-row .auth-btn:last-child {
53
+ .authorio-auth .auth-btn-row .btn-success {
54
54
  float: right;
55
55
  }
56
56
 
@@ -2,9 +2,6 @@
2
2
 
3
3
  module Authorio
4
4
  class AuthController < AuthorioController
5
- require 'uri'
6
- require 'digest'
7
-
8
5
  # These API-only endpoints are protected by code challenge and do not need CSRF protextion
9
6
  protect_from_forgery with: :exception, except: %i[send_profile issue_token]
10
7
 
@@ -31,22 +28,19 @@ module Authorio
31
28
  def authorize_user
32
29
  redirect_to session[:client_id] and return if params[:commit] == 'Cancel'
33
30
 
34
- user = authenticate_user_from_session_or_password
35
- write_session_cookie(user) if auth_user_params[:remember_me]
36
- redirect_to_client(user)
31
+ @user = authenticate_user_from_session_or_password
32
+ write_session_cookie(@user) if auth_user_params[:remember_me]
33
+ create_auth_request
34
+ redirect_to_client
37
35
  end
38
36
 
39
37
  def send_profile
40
- @request = validate_request Request.find_by! code: params[:code]
41
- rescue Exceptions::InvalidGrant, ActiveRecord::RecordNotFound => e
42
- render oauth_error 'invalid_grant', e.message
38
+ @auth_request = find_auth_request or (render validation_failed and return)
43
39
  end
44
40
 
45
41
  def issue_token
46
- @request = validate_request Request.find_by! code: params[:code]
47
- @token = Token.create_from_request(@request)
48
- rescue Exceptions::InvalidGrant, ActiveRecord::RecordNotFound => e
49
- render oauth_error 'invalid_grant', e.message
42
+ @auth_request = find_auth_request or (render validation_failed and return)
43
+ @token = Token.create_from_request(@auth_request)
50
44
  end
51
45
 
52
46
  def verify_token
@@ -61,14 +55,10 @@ module Authorio
61
55
 
62
56
  def auth_interface_params
63
57
  @auth_interface_params ||= begin
64
- required = %w[client_id redirect_uri state code_challenge]
65
- permitted = %w[me scope code_challenge_method response_type action controller]
66
- missing = required - params.keys
67
- raise ::ActionController::ParameterMissing, missing unless missing.empty?
68
-
69
- unpermitted = params.keys - required - permitted
70
- raise ::ActionController::UnpermittedParameters, unpermitted unless unpermitted.empty?
71
-
58
+ required = %w[client_id redirect_uri state]
59
+ permitted = %w[me scope code_challenge_method response_type code_challenge dummy]
60
+ params.require(required)
61
+ params.permit(permitted + required)
72
62
  params.permit!
73
63
  end
74
64
  end
@@ -86,27 +76,26 @@ module Authorio
86
76
  oauth_error('invalid_token', 'The access token has expired', :unauthorized)
87
77
  end
88
78
 
89
- def code_challenge_failed?
90
- # For now, if original request did not have code challenge, then we pass by default
91
- return unless session[:code_challenge]
92
-
93
- sha256 = Digest::SHA256.hexdigest params[:code_verifier]
94
- Base64.urlsafe_encode64(sha256) != session[:code_challenge]
79
+ def validation_failed
80
+ oauth_error('invalid_grant', 'validation failed')
95
81
  end
96
82
 
97
- def validate_request(request)
98
- raise Exceptions::InvalidGrant, 'validation failed' if request.invalid?(params) || code_challenge_failed?
83
+ def find_auth_request
84
+ auth_request = Request.find_by code: params[:code]
85
+ auth_request&.validate_oauth params
86
+ end
99
87
 
100
- request
88
+ def create_auth_request
89
+ @auth_req = Request.create(client: session[:client_id],
90
+ redirect_uri: session[:redirect_uri],
91
+ code_challenge: (session[:code_challenge] if session.key? :code_challenge),
92
+ scope: (scope_params[:scope].join(' ') if params.key? :scope),
93
+ authorio_user: @user)
101
94
  end
102
95
 
103
- def redirect_to_client(user)
104
- auth_req = Request.create(client: session[:client_id],
105
- redirect_uri: session[:redirect_uri],
106
- scope: (scope_params[:scope].join(' ') if params.key? :scope),
107
- authorio_user: user)
108
- redirect_params = { code: auth_req.code, state: session[:state] }
109
- redirect_to "#{auth_req.redirect_uri}?#{redirect_params.to_query}"
96
+ def redirect_to_client
97
+ redirect_params = { code: @auth_req.code, state: session[:state] }
98
+ redirect_to "#{@auth_req.redirect_uri}?#{redirect_params.to_query}"
110
99
  end
111
100
 
112
101
  def authenticate_user_from_session_or_password
@@ -16,10 +16,20 @@ module Authorio
16
16
  self.client = value
17
17
  end
18
18
 
19
- def invalid?(params)
20
- redirect_uri != params[:redirect_uri] ||
21
- client != params[:client_id] ||
22
- created_at < Time.now - 10.minutes
19
+ def validate_oauth(params)
20
+ redirect_uri == params[:redirect_uri] &&
21
+ client == params[:client_id] &&
22
+ created_at > 10.minutes.ago &&
23
+ code_challenge_matches(params[:code_verifier]) &&
24
+ self
25
+ end
26
+
27
+ def code_challenge_matches(verifier)
28
+ # For now, if original request did not have code challenge, then we pass by default
29
+ return true if code_challenge.blank?
30
+
31
+ sha256 = Digest::SHA256.digest verifier
32
+ Base64.urlsafe_encode64(sha256).sub(/=*$/, '') == code_challenge
23
33
  end
24
34
 
25
35
  def self.user_scope_description(scope)
@@ -38,8 +48,7 @@ module Authorio
38
48
 
39
49
  USER_SCOPE_DESCRIPTION = {
40
50
  profile: 'View basic profile information',
41
- email: 'View your email address',
42
- offline_access: 'Keep you logged in permanently (until revoked)'
51
+ email: 'View your email address'
43
52
  }.freeze
44
53
  end
45
54
  end
@@ -4,4 +4,4 @@ json.access_token @token.auth_token
4
4
  json.expires_in Authorio.configuration.token_expiration
5
5
  json.token_type 'Bearer'
6
6
  json.scope @token.scope
7
- json.partial! 'authorio/users/profile', request: @request
7
+ json.partial! 'authorio/users/profile', request: @auth_request
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.me profile_url(request.authorio_user)
4
- if request.scope&.include? 'profile'
3
+ json.me profile_url(@auth_request.authorio_user)
4
+ if @auth_request.scope&.include? 'profile'
5
5
  json.profile do
6
- json.name(request.authorio_user.full_name)
7
- json.call(request.authorio_user, :url, :photo)
8
- json.email(request.authorio_user.email) if request.scope.include?('email')
6
+ json.name(@auth_request.authorio_user.full_name)
7
+ json.call(@auth_request.authorio_user, :url, :photo)
8
+ json.email(@auth_request.authorio_user.email) if @auth_request.scope.include?('email')
9
9
  end
10
10
  end
@@ -33,9 +33,9 @@
33
33
  <% end %>
34
34
  <% end -%>
35
35
  <div class='auth-btn-row'>
36
+ <%= form.submit("Sign in", class: 'btn btn-success auth-btn') %>
36
37
  <% if cancel %>
37
38
  <%= form.submit("Cancel", class: 'btn btn-default auth-btn') %>
38
39
  <% end %>
39
- <%= form.submit("Sign in", class: 'btn btn-success auth-btn') %>
40
40
  </div>
41
41
  <% end %>
@@ -0,0 +1,5 @@
1
+ class AddCodeChallengeToRequests < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :authorio_requests, :code_challenge, :string
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Authorio
4
- VERSION = '0.8.4'
4
+ VERSION = '0.8.5'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authorio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Meckler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-25 00:00:00.000000000 Z
11
+ date: 2021-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -157,6 +157,7 @@ files:
157
157
  - db/migrate/20210726164625_create_authorio_sessions.rb
158
158
  - db/migrate/20210801184120_add_profile_to_users.rb
159
159
  - db/migrate/20210817010101_change_path_to_username_in_users.rb
160
+ - db/migrate/20210831155106_add_code_challenge_to_requests.rb
160
161
  - lib/authorio.rb
161
162
  - lib/authorio/configuration.rb
162
163
  - lib/authorio/engine.rb
@@ -187,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
188
  - !ruby/object:Gem::Version
188
189
  version: '0'
189
190
  requirements: []
190
- rubygems_version: 3.2.11
191
+ rubygems_version: 3.1.6
191
192
  signing_key:
192
193
  specification_version: 4
193
194
  summary: Indieauth Authentication endpoint for Rails