-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support local RBAC validation (#105)
- Loading branch information
1 parent
6d2bb65
commit 8bb3d8a
Showing
6 changed files
with
154 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# frozen_string_literal: true | ||
|
||
# !!! | ||
# WARNING: This file is autogenerated | ||
# Only modify code within MANUAL() sections | ||
# or your changes may be overwritten later! | ||
# !!! | ||
|
||
require_relative 'request_helper' | ||
|
||
module StytchB2B | ||
class RBAC | ||
include Stytch::RequestHelper | ||
|
||
def initialize(connection) | ||
@connection = connection | ||
end | ||
|
||
def policy | ||
query_params = {} | ||
request = request_with_query_params('/v1/b2b/rbac/policy', query_params) | ||
get_request(request) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'request_helper' | ||
|
||
module StytchB2B | ||
class PolicyCache | ||
def initialize(rbac_client:) | ||
@rbac_client = rbac_client | ||
@policy_last_update = 0 | ||
@cached_policy = nil | ||
end | ||
|
||
def reload_policy | ||
@cached_policy = rbac_client.get_policy | ||
@policy_last_update = Time.now.to_i | ||
end | ||
|
||
def get_policy(invalidate: false) | ||
reload_policy if invalidate || @cached_policy.nil? || @policy_last_update < Time.now.to_i - 300 | ||
@cached_policy | ||
end | ||
|
||
# Performs an authorization check against the project's policy and a set of roles. If the | ||
# check succeeds, this method will return. If the check fails, a PermissionError | ||
# will be raised. It's also possible for a TenancyError to be raised if the | ||
# subject_org_id does not match the authZ request organization_id. | ||
# authorization_check is an object with keys 'action', 'resource_id', and 'organization_id' | ||
def perform_authorization_check( | ||
subject_roles:, | ||
subject_org_id:, | ||
authorization_check: | ||
) | ||
raise TenancyError, subject_org_id if subject_org_id != authorization_check['organization_id'] | ||
|
||
policy = get_policy | ||
|
||
for role in policy['roles'] | ||
next unless subject_roles.include?(role['role_id']) | ||
|
||
for permission in role['permissions'] | ||
actions = permission['actions'] | ||
resource = permission['resource_id'] | ||
has_matching_action = actions.include?('*') || actions.include?(authorization_check['action']) | ||
has_matching_resource = resource == authorization_check['resource_id'] | ||
if has_matching_action && has_matching_resource | ||
# All good | ||
return | ||
end | ||
end | ||
end | ||
|
||
# If we get here, we didn't find a matching permission | ||
raise PermissionError, authorization_check | ||
end | ||
end | ||
end |