Commit 03b2b0a

mo <mo@mokhan.ca>
2018-10-19 00:12:12
implement token revokation endpoint RFC-7009
1 parent 26b479c
Changed files (3)
app
config
spec
app/controllers/tokens_controller.rb
@@ -23,6 +23,15 @@ class TokensController < ApplicationController
     end
   end
 
+  def revoke
+    claims = Token.claims_for(params[:token], token_type: :any)
+    Token.find_by(uuid: claims[:jti]).revoke! unless claims.empty?
+    render plain: "", status: :ok
+  rescue StandardError => error
+    logger.error(error)
+    render plain: "", status: :ok
+  end
+
   private
 
   attr_reader :current_client
config/routes.rb
@@ -13,6 +13,7 @@ Rails.application.routes.draw do
   resource :response, only: [:show]
   resource :tokens, only: [:create] do
     post :introspect
+    post :revoke
   end
 
   namespace :my do
spec/requests/tokens_spec.rb
@@ -357,4 +357,36 @@ RSpec.describe '/tokens' do
       specify { expect(json[:active]).to eql(false) }
     end
   end
+
+  describe "POST /tokens/revoke" do
+    context "when the client credentials are valid" do
+      context "when the access token is active and known" do
+        let(:token) { create(:access_token) }
+
+        before { post '/tokens/revoke', params: { token: token.to_jwt, token_type_hint: :access_token }, headers: headers }
+
+        specify { expect(response).to have_http_status(:ok) }
+        specify { expect(response.body).to be_empty }
+        specify { expect(token.reload).to be_revoked }
+      end
+
+      context "when the refresh token is active and known" do
+        let(:token) { create(:refresh_token) }
+
+        before { post '/tokens/revoke', params: { token: token.to_jwt, token_type_hint: :refresh_token }, headers: headers }
+
+        specify { expect(response).to have_http_status(:ok) }
+        specify { expect(response.body).to be_empty }
+        specify { expect(token.reload).to be_revoked }
+      end
+
+      context "when the access token is expired" do
+        let(:token) { create(:access_token, :expired) }
+
+        before { post '/tokens/revoke', params: { token: token.to_jwt, token_type_hint: :refresh_token }, headers: headers }
+
+        specify { expect(response).to have_http_status(:ok) }
+      end
+    end
+  end
 end