From 11d57c5cbe827d9029956ac5e52cac9082d46dee Mon Sep 17 00:00:00 2001 From: Jalyna Date: Mon, 5 Jun 2023 09:48:08 +0200 Subject: [PATCH] Support on person subjects when on behalf token is used (#387) --- CHANGELOG.md | 2 ++ lib/zaikio/jwt_auth.rb | 3 ++- test/zaikio/jwt_auth_test.rb | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 002db7e..50a7fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +* Support on behalf access tokens when `authorize_by_jwt_subject_type "Person"` + ## [2.5.0] - 2023-05-11 * Accept `zaikio.revoked_access_token` event when access token got revoked diff --git a/lib/zaikio/jwt_auth.rb b/lib/zaikio/jwt_auth.rb index 72a02a6..5bf07b3 100644 --- a/lib/zaikio/jwt_auth.rb +++ b/lib/zaikio/jwt_auth.rb @@ -192,7 +192,8 @@ def show_error_if_authorize_by_jwt_scopes_fails(token_data) def show_error_if_authorize_by_jwt_subject_type_fails(token_data) if !self.class.authorize_by_jwt_subject_type || - self.class.authorize_by_jwt_subject_type == token_data.subject_type + self.class.authorize_by_jwt_subject_type == token_data.subject_type || + (self.class.authorize_by_jwt_subject_type == "Person" && token_data.on_behalf_of_id) return end diff --git a/test/zaikio/jwt_auth_test.rb b/test/zaikio/jwt_auth_test.rb index f330b60..0e96073 100644 --- a/test/zaikio/jwt_auth_test.rb +++ b/test/zaikio/jwt_auth_test.rb @@ -130,6 +130,20 @@ def index end end +class PersonResourcesController < ApplicationController + include Zaikio::JWTAuth + + before_action :authenticate_by_jwt + + authorize_by_jwt_subject_type "Person" + + authorize_by_jwt_scopes :person + + def index + render plain: "hello" + end +end + class ResourcesControllerTest < ActionDispatch::IntegrationTest # rubocop:disable Metrics/ClassLength def setup Zaikio::JWTAuth.configure do |config| @@ -148,6 +162,7 @@ def setup end resources :other_app_resources resources :multi_app_resources + resources :person_resources end end @@ -199,6 +214,22 @@ def setup "https://docs.zaikio.com/guide/oauth/scopes.html"] }.to_json, response.body) end + test "forbidden if subject type is Person but organization token is passed" do + token = generate_token(sub: "Organization/abc", scope: ["test_app.person.r"]) + get "/person_resources", headers: { "Authorization" => "Bearer #{token}" } + assert_response :forbidden + assert_equal({ "errors" => ["unpermitted_subject", "Expected Subject Type: Person | Subject type from "\ + "Access Token: Organization - For more information check our docs: "\ + "https://docs.zaikio.com/guide/oauth/scopes.html"] }.to_json, response.body) + end + + test "allowed if subject type is Person but on behalf token is passed" do + token = generate_token(sub: "Person/def>Organization/abc", scope: ["test_app.person.r"]) + get "/person_resources", headers: { "Authorization" => "Bearer #{token}" } + assert_response :success + assert_equal "hello", response.body + end + test "forbidden if scope does not exist" do token = generate_token(scope: ["directory.person.r", "test_app.some.rw"]) get "/resources", headers: { "Authorization" => "Bearer #{token}" }