gamora 0.8.0 → 0.9.0

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: d898db3b0a39bb00099a8912953f6dcdfda11cddbb38eccfe72a798986a4dbb9
4
- data.tar.gz: 943a549def5cc2b014fe7200cb72cfdfd00acef025b2db74731cce0eecfa5927
3
+ metadata.gz: 6fff76821e79e75149f4d407303a9b52dac3b68ac711ffc38ac4e8d517ab7225
4
+ data.tar.gz: 4f5d52c9ef04b8d1219ca84a28fe25d3bb0dad677d97edc7c863d3c039a9e8d4
5
5
  SHA512:
6
- metadata.gz: a71915324e16d094db423133defdfa83f21a4451eb32ac468d4d2be35eb0768493e6cba8ed48c2efea746f4219e406751159c3d5eac500fe3e52f1e7c94c99d9
7
- data.tar.gz: 86a1b5282d7bfc407264f971bc3f5ba2c6f756028d5afdb857e069ede7cc9787c9ad4b291b9e4fcf9365bc9a4f4e26e977a3b13f4a870b1c32c0b24bd6ba95e4
6
+ metadata.gz: eaec688075667ad6184c0567aa2637480a1781e50e5a7bb9448ba27f0b39cc969f42d83374afb5c1c2a5ccc1a339cfc95c553e71492e1e0de65a836f247bde45
7
+ data.tar.gz: a7d1eadca9cd826bcb13f22c01e332324199877fd9e43285e3daae60a6b3ce29102f3beeccfb20db200563d7a6a90c8ae7dfe25d4097e9cb6fd8a2762ef9f0bb
@@ -15,9 +15,15 @@ module Gamora
15
15
  }.freeze
16
16
 
17
17
  def authenticate_user!
18
+ return authentication_failed! unless access_token.present?
19
+
20
+ token_data = introspect_access_token(access_token)
21
+ return authentication_failed! unless valid_token_data?(token_data)
22
+
18
23
  claims = resource_owner_claims(access_token)
19
- assign_current_user_from_claims(claims) if claims.present?
20
- validate_authentication!
24
+ return authentication_failed! unless claims.present?
25
+
26
+ assign_current_user_from_claims(claims)
21
27
  end
22
28
 
23
29
  def current_user
@@ -26,21 +32,29 @@ module Gamora
26
32
 
27
33
  private
28
34
 
29
- def validate_authentication!
35
+ def access_token
30
36
  raise NotImplementedError
31
37
  end
32
38
 
33
- def access_token
39
+ def authentication_failed!
34
40
  raise NotImplementedError
35
41
  end
36
42
 
37
- def user_authentication_failed!
38
- raise NotImplementedError
43
+ def valid_token_data?(token_data)
44
+ token_data[:active] && whitelisted_client?(token_data[:client_id])
45
+ end
46
+
47
+ def whitelisted_client?(client_id)
48
+ whitelisted_clients.include?(client_id)
49
+ end
50
+
51
+ def whitelisted_clients
52
+ Configuration.whitelisted_clients | [Configuration.client_id]
39
53
  end
40
54
 
41
55
  def assign_current_user_from_claims(claims)
42
- attrs = user_attributes_from_claims(claims)
43
- @current_user = User.new(attrs)
56
+ attributes = user_attributes_from_claims(claims)
57
+ @current_user = User.new(attributes)
44
58
  end
45
59
 
46
60
  def user_attributes_from_claims(claims)
@@ -48,27 +62,29 @@ module Gamora
48
62
  end
49
63
 
50
64
  def resource_owner_claims(access_token)
51
- return {} if access_token.blank?
52
-
53
- resource_owner_claims!(access_token)
54
- end
65
+ cache_key = cache_key(:userinfo, access_token)
66
+ expires_in = Configuration.userinfo_cache_expires_in
55
67
 
56
- def resource_owner_claims!(access_token)
57
- Rails.cache.fetch(cache_key(access_token), cache_options) do
68
+ Rails.cache.fetch(cache_key, { expires_in: expires_in }) do
58
69
  oauth_client.userinfo(access_token)
59
70
  end
60
71
  end
61
72
 
62
- def oauth_client
63
- Client.from_config
73
+ def introspect_access_token(access_token)
74
+ cache_key = cache_key(:introspect, access_token)
75
+ expires_in = Configuration.introspect_cache_expires_in
76
+
77
+ Rails.cache.fetch(cache_key, { expires_in: expires_in }) do
78
+ oauth_client.introspect(access_token)
79
+ end
64
80
  end
65
81
 
66
- def cache_options
67
- { expires_in: Configuration.userinfo_cache_expires_in }
82
+ def cache_key(context, access_token)
83
+ "gamora:#{context}:#{Digest::SHA256.hexdigest(access_token)}"
68
84
  end
69
85
 
70
- def cache_key(access_token)
71
- "userinfo:#{Digest::SHA256.hexdigest(access_token)}"
86
+ def oauth_client
87
+ Client.from_config
72
88
  end
73
89
  end
74
90
  end
@@ -7,12 +7,6 @@ module Gamora
7
7
 
8
8
  private
9
9
 
10
- def validate_authentication!
11
- return if current_user.present?
12
-
13
- user_authentication_failed!
14
- end
15
-
16
10
  def access_token
17
11
  pattern = /^Bearer /
18
12
  header = request.headers["Authorization"]
@@ -21,7 +15,7 @@ module Gamora
21
15
  header.gsub(pattern, "")
22
16
  end
23
17
 
24
- def user_authentication_failed!
18
+ def authentication_failed!
25
19
  render json: { error: "Access token invalid" }, status: :unauthorized
26
20
  end
27
21
  end
@@ -11,18 +11,12 @@ module Gamora
11
11
 
12
12
  private
13
13
 
14
- def validate_authentication!
15
- return if current_user.present?
16
-
17
- session["gamora.origin"] = request.original_url
18
- user_authentication_failed!
19
- end
20
-
21
14
  def access_token
22
15
  session[:access_token]
23
16
  end
24
17
 
25
- def user_authentication_failed!
18
+ def authentication_failed!
19
+ session["gamora.origin"] = request.original_url
26
20
  redirect_to gamora.authentication_path
27
21
  end
28
22
  end
data/lib/gamora/client.rb CHANGED
@@ -20,13 +20,25 @@ module Gamora
20
20
  token_method: Configuration.token_method,
21
21
  redirect_uri: Configuration.redirect_uri,
22
22
  userinfo_url: Configuration.userinfo_url,
23
- authorize_url: Configuration.authorize_url
23
+ authorize_url: Configuration.authorize_url,
24
+ introspect_url: Configuration.introspect_url
24
25
  }
25
26
  end
26
27
  end
27
28
 
28
29
  def userinfo(access_token)
29
- response = userinfo_request(access_token)
30
+ params = userinfo_params(access_token)
31
+ opts = request_options(params)
32
+ response = request(:post, options[:userinfo_url], opts)
33
+ JSON.parse(response.body).symbolize_keys
34
+ rescue OAuth2::Error
35
+ {}
36
+ end
37
+
38
+ def introspect(access_token)
39
+ params = introspect_params(access_token)
40
+ opts = request_options(params)
41
+ response = request(:post, options[:introspect_url], opts)
30
42
  JSON.parse(response.body).symbolize_keys
31
43
  rescue OAuth2::Error
32
44
  {}
@@ -34,15 +46,22 @@ module Gamora
34
46
 
35
47
  private
36
48
 
37
- def userinfo_request(access_token)
38
- opts = userinfo_request_options(access_token)
39
- request(:post, options[:userinfo_url], opts)
49
+ def request_options(params)
50
+ {
51
+ body: params.to_json,
52
+ headers: { "Content-Type": "application/json" }
53
+ }
40
54
  end
41
55
 
42
- def userinfo_request_options(access_token)
56
+ def userinfo_params(access_token)
57
+ { access_token: access_token }
58
+ end
59
+
60
+ def introspect_params(access_token)
43
61
  {
44
- body: { access_token: access_token }.to_json,
45
- headers: { "Content-Type": "application/json" }
62
+ token: access_token,
63
+ client_id: Configuration.client_id,
64
+ client_secret: Configuration.client_secret
46
65
  }
47
66
  end
48
67
  end
@@ -6,8 +6,9 @@ module Gamora
6
6
  mattr_accessor :client_secret, default: nil
7
7
  mattr_accessor :site, default: nil
8
8
  mattr_accessor :token_url, default: "/oauth2/token"
9
- mattr_accessor :authorize_url, default: "/oauth2/authorize"
10
9
  mattr_accessor :userinfo_url, default: "/oauth2/userinfo"
10
+ mattr_accessor :authorize_url, default: "/oauth2/authorize"
11
+ mattr_accessor :introspect_url, default: "/oauth2/introspect"
11
12
  mattr_accessor :token_method, default: :post
12
13
  mattr_accessor :redirect_uri, default: nil
13
14
  mattr_accessor :default_scope, default: "openid profile email"
@@ -16,7 +17,9 @@ module Gamora
16
17
  mattr_accessor :default_branding, default: "amco"
17
18
  mattr_accessor :default_theme, default: "default"
18
19
  mattr_accessor :ui_locales, default: -> { I18n.locale }
19
- mattr_accessor :userinfo_cache_expires_in, default: 0.seconds
20
+ mattr_accessor :userinfo_cache_expires_in, default: 1.minute
21
+ mattr_accessor :introspect_cache_expires_in, default: 0.seconds
22
+ mattr_accessor :whitelisted_clients, default: []
20
23
 
21
24
  def setup
22
25
  yield(self) if block_given?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gamora
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -8,8 +8,9 @@ Gamora.setup do |config|
8
8
 
9
9
  # ===> Optional OAuth2 configuration options and its defaults.
10
10
  # config.token_url = "/oauth2/token"
11
- # config.authorize_url = "/oauth2/authorize"
12
11
  # config.userinfo_url = "/oauth2/userinfo"
12
+ # config.authorize_url = "/oauth2/authorize"
13
+ # config.introspect_url = "/oauth2/introspect"
13
14
  # config.token_method = :post
14
15
  # config.redirect_uri = nil
15
16
  # config.default_scope = "openid profile email"
@@ -18,5 +19,7 @@ Gamora.setup do |config|
18
19
  # config.default_branding = "amco"
19
20
  # config.default_theme = "default"
20
21
  # config.ui_locales = -> { I18n.locale }
21
- # config.userinfo_cache_expires_in = 0.seconds
22
+ # config.userinfo_cache_expires_in = 1.minute
23
+ # config.introspect_cache_expires_in = 0.seconds
24
+ # config.whitelisted_clients = []
22
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gamora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Gutiérrez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-21 00:00:00.000000000 Z
11
+ date: 2023-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2