Commit d55ebee

mo <mo@mokhan.ca>
2018-10-29 21:07:47
start to implement RFC-7592
1 parent 818df67
Changed files (7)
app/controllers/oauth/clients_controller.rb
@@ -2,7 +2,14 @@
 
 module Oauth
   class ClientsController < ActionController::API
+    include ActionController::HttpAuthentication::Token::ControllerMethods
     before_action :apply_cache_headers
+    before_action :authenticate!, except: [:create]
+
+    def show
+      @client = @token.subject
+      render status: :ok, formats: :json
+    end
 
     def create
       @client = Client.create!(transform(secure_params))
@@ -17,6 +24,15 @@ module Oauth
 
     private
 
+    def authenticate!
+      @token = authenticate_with_http_token do |token, _options|
+        claims = Token.claims_for(token)
+        return if Token.revoked?(claims[:jti]) || claims.empty?
+        Token.find(claims[:jti])
+      end
+      request_http_token_authentication unless @token.present?
+    end
+
     def secure_params
       params.permit(
         :client_name,
app/models/client.rb
@@ -7,9 +7,9 @@ class Client < ApplicationRecord
   has_many :authorizations
   attribute :redirect_uris, :string, array: true
   enum token_endpoint_auth_method: {
-    client_secret_none: 0,
+    client_secret_basic: 0,
     client_secret_post: 1,
-    client_secret_basic: 2
+    client_secret_none: 2,
   }
 
   validates :redirect_uris, presence: true
app/views/oauth/clients/_client.json.jbuilder
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+json.client_id @client.to_param
+json.client_secret @client.password
+json.client_id_issued_at @client.created_at.to_i
+json.client_secret_expires_at 0
+json.redirect_uris @client.redirect_uris
+json.grant_types @client.grant_types
+json.client_name @client.name
+json.token_endpoint_auth_method @client.token_endpoint_auth_method
+json.logo_uri @client.logo_uri
+json.jwks_uri @client.jwks_uri
app/views/oauth/clients/create.json.jbuilder
@@ -1,12 +1,3 @@
 # frozen_string_literal: true
 
-json.client_id @client.to_param
-json.client_secret @client.password
-json.client_id_issued_at @client.created_at.to_i
-json.client_secret_expires_at 0
-json.redirect_uris @client.redirect_uris
-json.grant_types @client.grant_types
-json.client_name @client.name
-json.token_endpoint_auth_method @client.token_endpoint_auth_method
-json.logo_uri @client.logo_uri
-json.jwks_uri @client.jwks_uri
+json.partial! @client
app/views/oauth/clients/show.json.jbuilder
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+json.partial! @client
config/routes.rb
@@ -18,7 +18,7 @@ Rails.application.routes.draw do
   namespace :oauth do
     resource :authorizations, only: [:show, :create]
     resource :me, only: [:show]
-    resources :clients, only: [:create]
+    resources :clients, only: [:show, :create]
     resource :tokens, only: [:create] do
       post :introspect
       post :revoke
spec/requests/oauth/clients_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe "/oauth/clients" do
 
       specify { expect(response).to have_http_status(:created) }
       specify { expect(response.headers['Set-Cookie']).to be_nil }
-      specify { expect(response.headers['Content-Type']).to include("application/json") }
+      specify { expect(response.content_type).to eql("application/json") }
       specify { expect(response.headers['Cache-Control']).to include("no-store") }
       specify { expect(response.headers['Pragma']).to eql("no-cache") }
       specify { expect(json[:client_id]).to eql(last_client.to_param) }
@@ -71,4 +71,29 @@ RSpec.describe "/oauth/clients" do
       specify { expect(json[:error_description]).to be_present }
     end
   end
+
+  describe "GET /oauth/clients/:id" do
+    context "when the credentials are valid" do
+      let(:client) { create(:client) }
+      let(:access_token) { create(:access_token, subject: client) }
+      let(:headers) { { 'Authorization' => "Bearer #{access_token.to_jwt}" } }
+      let(:json) { JSON.parse(response.body, symbolize_names: true) }
+
+      before { get "/oauth/clients/#{client.id}", headers: headers }
+
+      specify { expect(response).to have_http_status(:ok) }
+      specify { expect(response.content_type).to eql('application/json') }
+      specify { expect(response.headers['Set-Cookie']).to be_nil }
+      specify { expect(json[:client_id]).to eql(client.to_param) }
+      specify { expect(json[:client_secret]).to eql(client.password) }
+      specify { expect(json[:client_id_issued_at]).to eql(client.created_at.to_i) }
+      specify { expect(json[:client_secret_expires_at]).to be_zero }
+      specify { expect(json[:redirect_uris]).to match_array(client.redirect_uris) }
+      specify { expect(json[:grant_types]).to match_array(client.grant_types.map(&:to_s)) }
+      specify { expect(json[:client_name]).to eql(client.name) }
+      specify { expect(json[:token_endpoint_auth_method]).to eql('client_secret_basic') }
+      specify { expect(json[:logo_uri]).to eql(client.logo_uri) }
+      specify { expect(json[:jwks_uri]).to eql(client.jwks_uri) }
+    end
+  end
 end