stytch 9.0.0 → 9.1.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 +4 -4
- data/.rubocop.yml +1 -1
- data/lib/stytch/errors.rb +7 -0
- data/lib/stytch/m2m.rb +49 -4
- data/lib/stytch/version.rb +1 -1
- data/stytch.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 833c91cba84e4cbbe5fd094bdf3d7ede5c0b351df7ebfab729fbaacdc181b14a
|
4
|
+
data.tar.gz: eccd3e064c0e2ba7bf0a7cbcc9f60b2aadaf25c0db70bee8c0c13646d30a6842
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c73c79869bb8e2bd29dac4307aa3dc4ba7b7a1c76eb1d5a780b29e2b62f2abcd2fe64244d654e37c99c160b8b5f1f6f762e02c59ea0510da034ebfb550c8d6ca
|
7
|
+
data.tar.gz: 07e99d0cd758a18aa37a20fe830ce7ba6ecfb19e9d6ec63a85870a12183b2da1ead1ec65315bee283d9f1b034f9f73be8b04aff9e5ff7fcd387867217cc92145
|
data/.rubocop.yml
CHANGED
data/lib/stytch/errors.rb
CHANGED
@@ -49,4 +49,11 @@ module Stytch
|
|
49
49
|
super(msg)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
class M2MPermissionError < StandardError
|
54
|
+
def initialize(has_scopes, required_scopes)
|
55
|
+
msg = "Missing at least one required scope from #{required_scopes} for M2M request with scopes #{has_scopes}"
|
56
|
+
super(msg)
|
57
|
+
end
|
58
|
+
end
|
52
59
|
end
|
data/lib/stytch/m2m.rb
CHANGED
@@ -96,6 +96,10 @@ module Stytch
|
|
96
96
|
# max_token_age::
|
97
97
|
# The maximum possible lifetime in seconds for the token to be valid.
|
98
98
|
# The type of this field is nilable +Integer+.
|
99
|
+
# scope_authorization_func::
|
100
|
+
# A function to check if the token has the required scopes. This defaults to a function that assumes
|
101
|
+
# scopes are either direct string matches or written in the form "action:resource". See the
|
102
|
+
# documentation for +perform_authorization_check+ for more information.
|
99
103
|
# == Returns:
|
100
104
|
# +nil+ if the token could not be validated, or an object with the following fields:
|
101
105
|
# scopes::
|
@@ -107,7 +111,12 @@ module Stytch
|
|
107
111
|
# custom_claims::
|
108
112
|
# A map of custom claims present in the token.
|
109
113
|
# The type of this field is +object+.
|
110
|
-
def authenticate_token(
|
114
|
+
def authenticate_token(
|
115
|
+
access_token:,
|
116
|
+
required_scopes: nil,
|
117
|
+
max_token_age: nil,
|
118
|
+
scope_authorization_func: method(:perform_authorization_check)
|
119
|
+
)
|
111
120
|
# Intentionally allow this to re-raise if authentication fails
|
112
121
|
decoded_jwt = authenticate_token_local(access_token)
|
113
122
|
|
@@ -119,14 +128,50 @@ module Stytch
|
|
119
128
|
resp = marshal_jwt_into_response(decoded_jwt)
|
120
129
|
|
121
130
|
unless required_scopes.nil?
|
122
|
-
|
123
|
-
|
124
|
-
|
131
|
+
is_authorized = scope_authorization_func.call(
|
132
|
+
has_scopes: resp['scopes'],
|
133
|
+
required_scopes: required_scopes
|
134
|
+
)
|
135
|
+
raise M2MPermissionError.new(resp['scopes'], required_scopes) unless is_authorized
|
125
136
|
end
|
126
137
|
|
127
138
|
resp
|
128
139
|
end
|
129
140
|
|
141
|
+
# Performs an authorization check against an M2M client and a set of required
|
142
|
+
# scopes. Returns true if the client has all the required scopes, false otherwise.
|
143
|
+
# A scope can match if the client has a wildcard resource or the specific resource.
|
144
|
+
# This function assumes that scopes are of the form "action:resource" or just
|
145
|
+
# "specific_scope". It is _also_ possible to represent scopes as "resource:action",
|
146
|
+
# but it is ultimately up to the developer to ensure consistency in the scopes format.
|
147
|
+
# Note that a scope of "*" will only match another literal "*" because wildcards are
|
148
|
+
# *not* supported in the prefix piece of a scope.
|
149
|
+
def perform_authorization_check(
|
150
|
+
has_scopes:,
|
151
|
+
required_scopes:
|
152
|
+
)
|
153
|
+
client_scopes = Hash.new { |hash, key| hash[key] = Set.new }
|
154
|
+
has_scopes.each do |scope|
|
155
|
+
action = scope
|
156
|
+
resource = '-'
|
157
|
+
action, resource = scope.split(':') if scope.include?(':')
|
158
|
+
client_scopes[action].add(resource)
|
159
|
+
end
|
160
|
+
|
161
|
+
required_scopes.each do |required_scope|
|
162
|
+
required_action = required_scope
|
163
|
+
required_resource = '-'
|
164
|
+
required_action, required_resource = required_scope.split(':') if required_scope.include?(':')
|
165
|
+
return false unless client_scopes.key?(required_action)
|
166
|
+
|
167
|
+
resources = client_scopes[required_action]
|
168
|
+
# The client can either have a wildcard resource or the specific resource
|
169
|
+
return false unless resources.include?('*') || resources.include?(required_resource)
|
170
|
+
end
|
171
|
+
|
172
|
+
true
|
173
|
+
end
|
174
|
+
|
130
175
|
# Parse a M2M token and verify the signature locally (without calling /authenticate in the API)
|
131
176
|
def authenticate_token_local(jwt)
|
132
177
|
issuer = 'stytch.com/' + @project_id
|
data/lib/stytch/version.rb
CHANGED
data/stytch.gemspec
CHANGED
@@ -30,6 +30,6 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency 'jwt', '>= 2.3.0'
|
31
31
|
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.11.0'
|
33
|
-
spec.add_development_dependency 'rubocop', '1.
|
33
|
+
spec.add_development_dependency 'rubocop', '1.64.1'
|
34
34
|
spec.add_development_dependency 'rubocop-rspec', '2.24.0'
|
35
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stytch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: 9.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stytch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -78,14 +78,14 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - '='
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 1.
|
81
|
+
version: 1.64.1
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - '='
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 1.
|
88
|
+
version: 1.64.1
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rubocop-rspec
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|