jwt_auth_cognito 0.3.0 → 1.0.0.pre.beta.1
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/bitbucket-pipelines.yml +12 -5
- data/lib/jwt_auth_cognito/jwt_validator.rb +168 -19
- data/lib/jwt_auth_cognito/version.rb +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: 4b2b634f054c3fc1bfda6e0e63ffca5138547b23b11eff699faf23152491764a
|
4
|
+
data.tar.gz: df5e63158c0ac35b9530dc09ce74cf207a08897a8480c1aa5bcb1b9c177bd6e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 034cd66eeb8c72a3446f32a74f1f73b17e78c4c24f566c2bbaacb017568d4e73faee63c9c53c4aecd658b11ee472d8912a9e87da1695a869590210b8c820b2ae
|
7
|
+
data.tar.gz: f00152cc1067ebda1630768f93ab7fb5053372c13e67b94ef08f6cdc5fde421e008c326c6ea454d0839b71b525dbf1daf16a94aa14fbb759ceb07dd150cd9477
|
data/bitbucket-pipelines.yml
CHANGED
@@ -125,12 +125,11 @@ pipelines:
|
|
125
125
|
# Tags stable (X.Y.Z)
|
126
126
|
"v[0-9]*.[0-9]*.[0-9]*":
|
127
127
|
- step:
|
128
|
-
name: Deploy Estable
|
129
|
-
trigger: manual # Requiere confirmación manual
|
128
|
+
name: Tests y Build para Deploy Estable
|
130
129
|
caches:
|
131
130
|
- bundler
|
132
131
|
script:
|
133
|
-
- echo "🚨
|
132
|
+
- echo "🚨 Preparando versión estable para deploy"
|
134
133
|
- bundle install
|
135
134
|
- echo "Tests completos y exhaustivos..."
|
136
135
|
- bundle exec rspec
|
@@ -140,6 +139,16 @@ pipelines:
|
|
140
139
|
- bundle audit check --update || echo "Bundle audit no disponible, continuando..."
|
141
140
|
- echo "Building gem final..."
|
142
141
|
- gem build jwt_auth_cognito.gemspec
|
142
|
+
- echo "Build completado - Listo para deploy manual"
|
143
|
+
artifacts:
|
144
|
+
- "*.gem"
|
145
|
+
- step:
|
146
|
+
name: Deploy Estable a RubyGems
|
147
|
+
trigger: manual # Requiere confirmación manual para el deploy
|
148
|
+
caches:
|
149
|
+
- bundler
|
150
|
+
script:
|
151
|
+
- echo "🚨 DEPLOY DE PRODUCCIÓN - Versión estable"
|
143
152
|
- echo "Configurando credenciales RubyGems..."
|
144
153
|
- mkdir -p ~/.gem
|
145
154
|
- 'echo ":rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials'
|
@@ -147,8 +156,6 @@ pipelines:
|
|
147
156
|
- echo "Publicando version ESTABLE a RubyGems..."
|
148
157
|
- gem push *.gem
|
149
158
|
- echo "VERSION ESTABLE PUBLICADA EXITOSAMENTE"
|
150
|
-
artifacts:
|
151
|
-
- "*.gem"
|
152
159
|
|
153
160
|
# Tags alpha (X.Y.Z-alpha.N) - Solo para testing
|
154
161
|
"v*-alpha.*":
|
@@ -27,14 +27,24 @@ module JwtAuthCognito
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
# ========== 🚀 MAIN VALIDATION METHOD ==========
|
31
|
+
|
32
|
+
# Main validation method - use this for most cases
|
33
|
+
# Intelligently validates tokens with all features:
|
34
|
+
# - JWT validation (basic or secure)
|
35
|
+
# - API key validation (if provided)
|
36
|
+
# - Blacklist checking
|
37
|
+
# - Automatic appId verification
|
38
|
+
# - User data enrichment (if enabled)
|
39
|
+
def validate(token, options = {})
|
35
40
|
@config.validate!
|
36
41
|
|
37
|
-
|
42
|
+
api_key = options[:api_key]
|
43
|
+
force_secure = options[:force_secure] || false
|
44
|
+
enrich_user_data = options.fetch(:enrich_user_data, true)
|
45
|
+
require_app_access = options[:require_app_access] || false
|
46
|
+
|
47
|
+
# Step 1: Validate API key if provided
|
38
48
|
api_key_data = nil
|
39
49
|
if api_key && @config.enable_api_key_validation && @api_key_validator
|
40
50
|
api_key_result = @api_key_validator.validate_api_key(api_key)
|
@@ -43,26 +53,129 @@ module JwtAuthCognito
|
|
43
53
|
api_key_data = api_key_result[:key_data]
|
44
54
|
end
|
45
55
|
|
46
|
-
# Check blacklist first
|
56
|
+
# Step 2: Check blacklist first
|
47
57
|
return { valid: false, error: 'Token has been revoked' } if @blacklist_service.is_blacklisted?(token)
|
48
58
|
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
# Step 3: Validate JWT token
|
60
|
+
validation_mode = force_secure ? :secure : @config.validation_mode
|
61
|
+
token_result = case validation_mode
|
62
|
+
when :secure
|
63
|
+
validate_token_secure(token, options)
|
64
|
+
when :basic
|
65
|
+
validate_token_basic(token, options)
|
66
|
+
else
|
67
|
+
raise ConfigurationError, "Invalid validation_mode: #{validation_mode}"
|
68
|
+
end
|
69
|
+
|
70
|
+
return token_result unless token_result[:valid] && token_result[:payload]
|
71
|
+
|
72
|
+
# Step 4: Verify appId access if API key has one
|
73
|
+
if api_key_data
|
74
|
+
app_validation = verify_app_access(api_key_data, token_result[:payload], require_app_access)
|
75
|
+
return app_validation unless app_validation[:valid]
|
76
|
+
end
|
58
77
|
|
59
|
-
#
|
60
|
-
|
78
|
+
# Step 5: Enrich with user data if requested
|
79
|
+
enriched_result = token_result.dup
|
80
|
+
enriched_result[:api_key] = api_key_data if api_key_data
|
81
|
+
|
82
|
+
if enrich_user_data && @config.enable_user_data_retrieval && @user_data_service
|
83
|
+
user_id = token_result[:payload]['sub']
|
84
|
+
if user_id
|
85
|
+
begin
|
86
|
+
user_data = @user_data_service.get_comprehensive_user_data(user_id)
|
87
|
+
enriched_result[:user_permissions] = user_data['permissions']
|
88
|
+
enriched_result[:user_organizations] = user_data['organizations']
|
89
|
+
enriched_result[:applications] = user_data['applications']
|
90
|
+
rescue StandardError => e
|
91
|
+
ErrorUtils.log_error(e, 'User data retrieval failed')
|
92
|
+
# Continue with basic validation if user data service fails
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
61
96
|
|
62
|
-
|
97
|
+
enriched_result
|
98
|
+
end
|
99
|
+
|
100
|
+
# ========== SIMPLIFIED PUBLIC API ==========
|
101
|
+
|
102
|
+
# Quick validation for simple use cases
|
103
|
+
# Just validates the JWT token (includes blacklist check)
|
104
|
+
def validate_token(token, options = {})
|
105
|
+
result = validate(token, options.merge(enrich_user_data: false))
|
106
|
+
{
|
107
|
+
valid: result[:valid],
|
108
|
+
payload: result[:payload],
|
109
|
+
sub: result[:sub],
|
110
|
+
username: result[:username],
|
111
|
+
token_use: result[:token_use],
|
112
|
+
error: result[:error]
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
# Validate with API key (automatic appId verification)
|
117
|
+
# Use this when you have an API key and want automatic security
|
118
|
+
def validate_with_api_key(token, api_key, options = {})
|
119
|
+
validate(token, options.merge(api_key: api_key))
|
120
|
+
end
|
121
|
+
|
122
|
+
# Validate with strict appId requirement
|
123
|
+
# Use this when you MUST ensure user has access to a specific app
|
124
|
+
def validate_with_app_access(token, api_key, options = {})
|
125
|
+
validate(token, options.merge(api_key: api_key, require_app_access: true))
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get enriched validation (user data included)
|
129
|
+
# Use this when you need user permissions, organizations, apps
|
130
|
+
def validate_enriched(token, api_key = nil, options = {})
|
131
|
+
validate(token, options.merge(api_key: api_key, enrich_user_data: true))
|
132
|
+
end
|
133
|
+
|
134
|
+
# ========== LEGACY METHODS (DEPRECATED) ==========
|
135
|
+
|
136
|
+
# @deprecated Use validate() or validate_with_api_key() instead
|
137
|
+
def validate_token_with_api_key(token, api_key = nil, options = {})
|
138
|
+
puts 'WARNING: validate_token_with_api_key is deprecated. Use validate() or validate_with_api_key() instead.'
|
139
|
+
result = validate(token, options.merge(api_key: api_key, enrich_user_data: false))
|
140
|
+
{
|
141
|
+
valid: result[:valid],
|
142
|
+
payload: result[:payload],
|
143
|
+
sub: result[:sub],
|
144
|
+
username: result[:username],
|
145
|
+
token_use: result[:token_use],
|
146
|
+
api_key: result[:api_key],
|
147
|
+
error: result[:error]
|
148
|
+
}
|
63
149
|
end
|
64
150
|
|
151
|
+
# @deprecated Use validate_with_app_access() instead
|
152
|
+
def validate_token_with_app_id(token, api_key, options = {})
|
153
|
+
puts 'WARNING: validate_token_with_app_id is deprecated. Use validate_with_app_access() instead.'
|
154
|
+
validate_with_app_access(token, api_key, options.merge(enrich_user_data: false))
|
155
|
+
end
|
156
|
+
|
157
|
+
# @deprecated Use validate() instead
|
158
|
+
def validate_token_enhanced(token, api_key = nil, options = {})
|
159
|
+
puts 'WARNING: validate_token_enhanced is deprecated. Use validate() instead.'
|
160
|
+
result = validate(token, options.merge(api_key: api_key, enrich_user_data: false))
|
161
|
+
{
|
162
|
+
valid: result[:valid],
|
163
|
+
payload: result[:payload],
|
164
|
+
sub: result[:sub],
|
165
|
+
username: result[:username],
|
166
|
+
token_use: result[:token_use],
|
167
|
+
api_key: result[:api_key],
|
168
|
+
error: result[:error]
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
# @deprecated Use validate_enriched() instead
|
65
173
|
def validate_token_enriched(token, api_key = nil, options = {})
|
174
|
+
puts 'WARNING: validate_token_enriched is deprecated. Use validate_enriched() instead.'
|
175
|
+
validate_enriched(token, api_key, options)
|
176
|
+
end
|
177
|
+
|
178
|
+
def old_validate_token_enriched(token, api_key = nil, options = {})
|
66
179
|
# First, perform standard token validation
|
67
180
|
basic_result = validate_token_with_api_key(token, api_key, options)
|
68
181
|
|
@@ -299,5 +412,41 @@ module JwtAuthCognito
|
|
299
412
|
|
300
413
|
raise ValidationError, "Token missing required scopes: #{missing_scopes.join(', ')}"
|
301
414
|
end
|
415
|
+
|
416
|
+
def verify_app_access(api_key_data, payload, require_app_access)
|
417
|
+
app_id = api_key_data['appId'] || api_key_data['metadata']&.[]('appId')
|
418
|
+
|
419
|
+
return { valid: false, error: 'API key is not associated with an application' } if !app_id && require_app_access
|
420
|
+
|
421
|
+
return { valid: true } unless app_id
|
422
|
+
|
423
|
+
user_id = payload['sub']
|
424
|
+
return { valid: false, error: 'Token missing user ID (sub claim)' } unless user_id
|
425
|
+
|
426
|
+
verify_user_app_access(user_id, app_id, require_app_access)
|
427
|
+
end
|
428
|
+
|
429
|
+
def verify_user_app_access(user_id, app_id, require_app_access)
|
430
|
+
if require_app_access && (!@config.enable_user_data_retrieval || !@user_data_service)
|
431
|
+
return { valid: false,
|
432
|
+
error: 'User data service not available for application access verification' }
|
433
|
+
end
|
434
|
+
|
435
|
+
return { valid: true } unless @config.enable_user_data_retrieval && @user_data_service
|
436
|
+
|
437
|
+
begin
|
438
|
+
user_applications = @user_data_service.get_user_applications(user_id)
|
439
|
+
has_access = user_applications.any? { |app| app['appId'] == app_id }
|
440
|
+
|
441
|
+
return { valid: false, error: "User does not have access to application #{app_id}" } unless has_access
|
442
|
+
|
443
|
+
{ valid: true }
|
444
|
+
rescue StandardError => e
|
445
|
+
return { valid: false, error: 'Could not verify application access' } if require_app_access
|
446
|
+
|
447
|
+
ErrorUtils.log_error(e, 'User application access verification failed')
|
448
|
+
{ valid: true } # Continue with basic validation if user data service fails
|
449
|
+
end
|
450
|
+
end
|
302
451
|
end
|
303
452
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_auth_cognito
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Optimal
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-ssm
|
@@ -237,9 +237,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
237
237
|
version: 2.7.0
|
238
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
239
|
requirements:
|
240
|
-
- - "
|
240
|
+
- - ">"
|
241
241
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
242
|
+
version: 1.3.1
|
243
243
|
requirements: []
|
244
244
|
rubygems_version: 3.3.27
|
245
245
|
signing_key:
|