jwt_auth_cognito 1.0.0.pre.beta.11 → 1.0.0.pre.beta.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8069ccdfaed845402cd9053a2db66b2bc74359649de17ca2ce7ad010a939722
4
- data.tar.gz: 3ba1441f8016d8e2d5b1bca7913fd7700f0ae51c8470ab1e6f06a2e1a9640697
3
+ metadata.gz: b17cfc63543d51251188fa8645cf7f9235d741851fc33087bf781cb26ba21c07
4
+ data.tar.gz: c51dd33e95f2346794ad4d50578982e09ed0395b22e192d8a69e4a196ef8c687
5
5
  SHA512:
6
- metadata.gz: 897a6f309d17ba4f312e5b9b86a8daf4ab76050a6b5cd17543eaaf728c3ba242bc1ec34a8efb25f17395095cccf5225bf918850fb4f373ba0132311c3c0e84c7
7
- data.tar.gz: 785494e60e28e09a5b3343eaf9b2dfc0d9a70343cf8f56ddd81768b172c0753696a3b03df84f24510ba50687d9d7cb6af8a3bce72fad2331e88bc195d9dc73b5
6
+ metadata.gz: eb6034d5dcb76d9523e4dcf68e488899b2ee50eba313aba072b069a4a552d8cc331175d72dca2577b7f85b9e3b63720dbafe98a21d7cf10107da457cab281436
7
+ data.tar.gz: 7e5e07f954ca37e0ece2cfed27763426903623aafb3a2f37dd9fecf9c54a876ace20ec7e9e0fea7e8ea8117bc34af28ecd730af22c387a196b43b704a4a40925
@@ -59,6 +59,24 @@ module JwtAuthCognito
59
59
  @current_user_permissions ||= fetch_current_user_permissions
60
60
  end
61
61
 
62
+ # Raises ForbiddenError unless the user has the given permission over a specific resource.
63
+ # By convention reads the resource ID from params[:id]; override with resource_id: keyword arg.
64
+ #
65
+ # before_action -> { authorize_resource_permission!('fleet:vehicles:write') }, only: [:update]
66
+ # before_action -> { authorize_resource_permission!('fleet:vehicles:write', resource_id: params[:vehicle_id]) }
67
+ def authorize_resource_permission!(permission, resource_id: params[:id])
68
+ uid = jwt_user_id
69
+ aid = jwt_app_id
70
+ oid = jwt_org_id
71
+
72
+ raise JwtAuthCognito::ForbiddenError, 'Access denied' unless uid && aid && oid && resource_id
73
+
74
+ return if jwt_validator.check_resource_permission?(uid, aid, oid, resource_id.to_s, permission)
75
+
76
+ log_resource_permission_denied(permission, resource_id)
77
+ raise JwtAuthCognito::ForbiddenError, 'Access denied'
78
+ end
79
+
62
80
  private
63
81
 
64
82
  def fetch_current_user_permissions
@@ -114,5 +132,15 @@ module JwtAuthCognito
114
132
  "app_id=#{jwt_app_id} org_id=#{jwt_org_id}"
115
133
  )
116
134
  end
135
+
136
+ def log_resource_permission_denied(permission, resource_id)
137
+ return unless defined?(Rails)
138
+
139
+ Rails.logger.warn(
140
+ "[RESOURCE_PERMISSION_DENIED] user_id=#{jwt_user_id} " \
141
+ "permission=#{permission} resource_id=#{resource_id} " \
142
+ "app_id=#{jwt_app_id} org_id=#{jwt_org_id}"
143
+ )
144
+ end
117
145
  end
118
146
  end
@@ -270,6 +270,28 @@ module JwtAuthCognito
270
270
  @user_data_service.resolve_effective_permissions(user_id, app_id, org_id)
271
271
  end
272
272
 
273
+ # Get the permissions the user has over a specific resource instance (ReBAC).
274
+ # Returns { resource_type:, resource_id:, permissions:, mode: } or nil.
275
+ def get_resource_permissions(user_id, app_id, org_id, resource_type, resource_id)
276
+ return nil unless @user_data_service
277
+
278
+ result = @user_data_service.resolve_resource_permissions(user_id, app_id, org_id, resource_id)
279
+ return nil unless result
280
+
281
+ { resource_type: resource_type, resource_id: resource_id,
282
+ permissions: result[:permissions], mode: result[:mode] }
283
+ end
284
+
285
+ # Verify if the user has a specific permission over a concrete resource instance.
286
+ def check_resource_permission?(user_id, app_id, org_id, resource_id, permission)
287
+ return false unless @user_data_service
288
+
289
+ result = @user_data_service.resolve_resource_permissions(user_id, app_id, org_id, resource_id)
290
+ return false unless result
291
+
292
+ PermissionChecker.permission_in_list?(permission, result[:permissions])
293
+ end
294
+
273
295
  def is_token_expired?(token)
274
296
  payload = decode_token(token)
275
297
  return true if payload.is_a?(Hash) && payload[:error]
@@ -372,6 +372,35 @@ module JwtAuthCognito
372
372
  @cache_timestamps[key] = Time.now.to_i
373
373
  end
374
374
 
375
+ # Resolve permissions the user has over a specific resource instance (ReBAC).
376
+ # Applies resourceRestrictions per-permission: open mode if none configured.
377
+ # Returns nil if the user has no active membership in that org.
378
+ def resolve_resource_permissions(user_id, app_id, organization_id, resource_id)
379
+ effective = resolve_effective_permissions(user_id, app_id, organization_id)
380
+ return nil unless effective
381
+
382
+ raw = @redis_service.get("user:permissions:#{user_id}")
383
+ return nil unless raw
384
+
385
+ data = JSON.parse(raw)
386
+ restrictions = data.dig('permissions', app_id, organization_id, 'resourceRestrictions')
387
+ has_any_restriction = restrictions.is_a?(Hash) && !restrictions.empty?
388
+ mode = has_any_restriction ? 'restricted' : 'open'
389
+
390
+ allowed = effective.select do |perm|
391
+ if !restrictions.is_a?(Hash) || !restrictions.key?(perm)
392
+ true
393
+ else
394
+ restrictions[perm].is_a?(Array) && restrictions[perm].include?(resource_id)
395
+ end
396
+ end
397
+
398
+ { permissions: allowed, mode: mode }
399
+ rescue StandardError => e
400
+ puts "Error resolving resource permissions for #{user_id}:#{resource_id}: #{e.message}"
401
+ nil
402
+ end
403
+
375
404
  def compute_permissions_from_roles(app_id, organization_id, role_names)
376
405
  roles_data = get_app_roles(app_id, organization_id)
377
406
  return [] unless roles_data.is_a?(Hash)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JwtAuthCognito
4
- VERSION = '1.0.0-beta.11'
4
+ VERSION = '1.0.0-beta.12'
5
5
  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: 1.0.0.pre.beta.11
4
+ version: 1.0.0.pre.beta.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Optimal
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-02 00:00:00.000000000 Z
11
+ date: 2026-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ssm