Commit 3b1b50a
Changed files (5)
app
controllers
models
config
spec
requests
oauth
app/controllers/oauth/mes_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Oauth
+ class MesController < ApplicationController
+ def show
+ render json: @claims
+ end
+
+ private
+
+ def authenticate!
+ @claims = authenticate_with_http_token do |token, _options|
+ claims = Token.claims_for(token)
+ Token.revoked?(claims[:jti]) ? nil : claims
+ end
+ request_http_token_authentication if @claims.nil? || @claims.empty?
+ end
+ end
+end
app/controllers/oauth/tokens_controller.rb
@@ -100,9 +100,7 @@ module Oauth
end
def revoked_tokens
- Rails.cache.fetch("revoked-tokens", expires_in: 10.minutes) do
- Hash[Token.revoked.pluck(:id).map { |x| [x, true] }]
- end
+ Token.revoked_token_identifiers
end
end
end
app/models/token.rb
@@ -57,6 +57,16 @@ class Token < ApplicationRecord
end
class << self
+ def revoked?(jti)
+ revoked_token_identifiers[jti]
+ end
+
+ def revoked_token_identifiers
+ Rails.cache.fetch("revoked-tokens", expires_in: 10.minutes) do
+ Hash[Token.revoked.pluck(:id).map { |x| [x, true] }]
+ end
+ end
+
def claims_for(token, token_type: :access)
if token_type == :any
claims = claims_for(token, token_type: :access)
config/routes.rb
@@ -17,6 +17,7 @@ Rails.application.routes.draw do
end
namespace :oauth do
resource :authorizations, only: [:show, :create]
+ resource :me, only: [:show]
resources :clients, only: [:create]
resource :tokens, only: [:create] do
post :introspect
spec/requests/oauth/users_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe '/oauth/me' do
+ describe "GET /oauth/me" do
+ context "when the access_token is valid" do
+ let(:token) { create(:access_token) }
+ let(:headers) { { 'Authorization' => "Bearer #{token.to_jwt}" } }
+ let(:json) { JSON.parse(response.body, symbolize_names: true) }
+
+ before { get '/oauth/me', headers: headers }
+
+ specify { expect(response).to have_http_status(:ok) }
+ specify { expect(response['Content-Type']).to include('application/json') }
+ specify { expect(json[:sub]).to eql(token.claims[:sub]) }
+ specify { expect(json[:aud]).to eql(token.claims[:aud]) }
+ specify { expect(json[:iss]).to eql(token.claims[:iss]) }
+ specify { expect(json[:exp]).to eql(token.claims[:exp]) }
+ specify { expect(json[:iat]).to eql(token.claims[:iat]) }
+ end
+
+ context "when the token is revoked" do
+ let(:headers) { { 'Authorization' => "Bearer #{token.to_jwt}" } }
+ let(:json) { JSON.parse(response.body, symbolize_names: true) }
+ let(:token) { create(:access_token, :revoked) }
+
+ before { get '/oauth/me', headers: headers }
+
+ specify { expect(response).to have_http_status(:unauthorized) }
+ end
+
+ context "when the token is expired" do
+ let(:headers) { { 'Authorization' => "Bearer #{token.to_jwt}" } }
+ let(:json) { JSON.parse(response.body, symbolize_names: true) }
+ let(:token) { create(:access_token, :expired) }
+
+ before { get '/oauth/me', headers: headers }
+
+ specify { expect(response).to have_http_status(:unauthorized) }
+ end
+ end
+end