Skip to content

Commit

Permalink
✨ (oauth) Move introspect routes to doorkeeper routes
Browse files Browse the repository at this point in the history
  • Loading branch information
Hadrien Froger committed Dec 10, 2024
1 parent 06d0d92 commit 54096fb
Show file tree
Hide file tree
Showing 14 changed files with 1,327 additions and 1,333 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
decidim-rest_full (0.0.6)
decidim-rest_full (0.0.7)
api-pagination (~> 6.0)
cancancan
decidim-admin (>= 0.28, < 0.30)
Expand Down
63 changes: 0 additions & 63 deletions app/controllers/decidim/api/rest_full/introspect_controller.rb

This file was deleted.

3 changes: 2 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
namespace :rest_full do
scope "v#{Decidim::RestFull.major_minor_version}" do
post "/oauth/token", to: "/doorkeeper/tokens#create"
post "/oauth/introspect", to: "/decidim/api/rest_full/introspect#show"
post "/oauth/introspect", to: "/doorkeeper/tokens#introspect"

namespace :system do
resources :organizations, only: [:index]
resources :users, only: [:index]
Expand Down
2 changes: 1 addition & 1 deletion contrib/decidim-node-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@octree/decidim-sdk",
"version": "0.0.6",
"version": "0.0.7",
"description": "Typescript-fetch client for Decidim Restfull APi",
"keywords": [],
"license": "AGPL-3.0-only",
Expand Down
28 changes: 28 additions & 0 deletions lib/decidim/rest_full/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,35 @@ class Engine < ::Rails::Engine

# Enable resource owner password credentials
grant_flows %w(password client_credentials)
custom_introspection_response do |token, _context|
current_organization = token.application.organization
user = (Decidim::User.find(token.resource_owner_id) if token.resource_owner_id)
user_details = if user
{
resource: Decidim::Api::RestFull::UserSerializer.new(
user,
params: { host: current_organization.host },
fields: { user: [:email, :name, :id, :created_at, :updated_at, :personal_url, :locale] }
).serializable_hash[:data]
}
else
{}
end
token_valid = token.valid? && !token.expired?
active = if user
user_valid = !user.blocked? && user.locked_at.blank?
token_valid && user_valid
else
token_valid
end

{
sub: token.id,
# Current organization
aud: "https://#{current_organization.host}",
active: active
}.merge(user_details)
end
# Authenticate resource owner
resource_owner_from_credentials do |_routes|
# forbid system scope, exclusive to credential flow
Expand Down
2 changes: 1 addition & 1 deletion lib/decidim/rest_full/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Decidim
module RestFull
def self.version
"0.0.6" # DO NOT UPDATE MANUALLY
"0.0.7" # DO NOT UPDATE MANUALLY
end

def self.major_minor_version
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "decidim-rest_full",
"private": true,
"version": "0.0.6",
"version": "0.0.7",
"packageManager": "yarn@1.22.22",
"devDependencies": {
"@openapitools/openapi-generator-cli": "^2.15.3",
Expand Down
26 changes: 15 additions & 11 deletions spec/decidim/rest_full/oauth/introspect_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,47 @@
security [{ credentialFlowBearer: ["public"] }, { resourceOwnerFlowBearer: ["public"] }]
operationId "introspectToken"
description "Get given oauth token details"
# SEE https://datatracker.ietf.org/doc/html/rfc7662#section-2.1
parameter name: :body, in: :body, required: true, schema: { type: :object, properties: { token: { type: :string }, required: [:token] } }

response "200", "User details returned" do
schema "$ref" => "#/components/schemas/introspect_response"
context "with client_credentials grant" do
let!(:client_credential_token_b) { create(:oauth_access_token, scopes: "public", resource_owner_id: nil, application: api_client) }

let(:Authorization) { "Bearer #{client_credential_token.token}" }
let(:body) { { token: client_credential_token_b.token } }

run_test!(example_name: :bearer_client_credential) do |response|
json_response = JSON.parse(response.body)["data"]
expect(json_response["token"]["scope"]).to include("public")
json_response = JSON.parse(response.body)
expect(json_response["scope"]).to include("public")
end
end

context "with password grant" do
let(:Authorization) { "Bearer #{impersonation_token.token}" }
let(:Authorization) { "Bearer #{client_credential_token.token}" }
let(:body) { { token: impersonation_token.token } }

run_test!(example_name: :bearer_ropc) do |response|
json_response = JSON.parse(response.body)["data"]
json_response = JSON.parse(response.body)
expect(json_response["resource"]["id"]).to eq(user.id.to_s)
expect(json_response["resource"]["type"]).to eq("user")
expect(json_response["token"]["scope"]).to include("public")
expect(json_response["scope"]).to include("public")
end
end
end

response "200", "When the token is invalid" do
response "401", "When the token is invalid" do
produces "application/json"
schema "$ref" => "#/components/schemas/introspect_response"
schema "$ref" => "#/components/schemas/api_error"

context "with expired token" do
let!(:client_credential_token) { create(:oauth_access_token, scopes: "public", resource_owner_id: nil, application: api_client, created_at: 1.month.ago, expires_in: 1.minute) }

let(:Authorization) { "Bearer #{client_credential_token.token}" }
let(:body) { { token: client_credential_token.token } }

run_test!(example_name: :expired_token) do |response|
json_response = JSON.parse(response.body)["data"]
expect(json_response["active"]).to be_falsy
end
run_test!(example_name: :expired_token)
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion spec/decidim/rest_full/test/definitions/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module Definitions
title: "Api Error",
properties: {
error: { type: :string, description: "Error title, starting with HTTP Code, like 400: bad request" },
error_description: { type: :string, description: "Error detail, mostly validation error", example: "Title is required" }
error_description: { type: :string, description: "Error detail, mostly validation error", example: "Title is required" },
state: { type: :string, description: "authentification state" }
},
additionalProperties: false,
required: [:error, :error_description]
Expand Down
6 changes: 5 additions & 1 deletion spec/decidim/rest_full/test/definitions/introspect_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ module Definitions
type: :boolean,
description: "If the token can be used"
},
aud: {
type: :string,
description: "Where this token can be used (organization host)"
},
resource: {
type: :object,
properties: {
Expand Down Expand Up @@ -57,7 +61,7 @@ module Definitions
required: [:id, :type]
}
},
required: [:sub, :active]
required: [:sub, :active, :aud, :exp]
}.freeze
end
end
6 changes: 1 addition & 5 deletions spec/swagger_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,7 @@
introspect_data: Api::Definitions::INTROSPECT_DATA,
introspect_response: {
description: "Details about the token beeing used",
type: :object,
properties: {
data: { "$ref" => "#/components/schemas/introspect_data" }
},
required: [:data]
"$ref" => "#/components/schemas/introspect_data"
},
oauth_grant_param: {
oneOf: [
Expand Down
2 changes: 1 addition & 1 deletion website/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "website",
"version": "0.0.6",
"version": "0.0.7",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand Down
Loading

0 comments on commit 54096fb

Please sign in to comment.