Commit 9e3ccd8

mo <mo@mokhan.ca>
2018-10-12 00:52:51
notify client of unsupported response types
1 parent 608b44f
Changed files (3)
app
spec
app/controllers/oauths_controller.rb
@@ -1,10 +1,17 @@
 # frozen_string_literal: true
 
 class OauthsController < ApplicationController
-  def show
-    return render_error(:not_found) unless params[:response_type] == 'code' || params[:response_type] == 'token'
+  VALID_RESPONSE_TYPES = [ 'code', 'token' ]
 
+  def show
     @client = Client.find_by!(uuid: params[:client_id])
+
+    if !VALID_RESPONSE_TYPES.include?(params[:response_type])
+      redirect_to @client.redirect_uri_path(
+        error: 'unsupported_response_type',
+        state: params[:state]
+      )
+    end
     session[:oauth] = {
       client_id: params[:client_id],
       response_type: params[:response_type],
app/models/client.rb
@@ -27,7 +27,7 @@ class Client < ApplicationRecord
     uuid
   end
 
-  def redirect_uri_path(code: nil, access_token: nil, token_type: "Bearer", expires_in: nil, scope: "", state: nil)
+  def redirect_uri_path(code: nil, access_token: nil, token_type: "Bearer", expires_in: nil, scope: "", state: nil, error: nil)
     result = redirect_uri
     if code
       result += '?code=' + code
@@ -36,6 +36,8 @@ class Client < ApplicationRecord
       result += "&token_type=#{token_type}"
       result += "&expires_in=#{expires_in.seconds.to_i}" if expires_in.present?
       result += "&scope=#{scope}" if scope.present?
+    elsif error
+      result += '#error=' + error
     end
     result += "&state=#{state}" if state.present?
     result
spec/requests/oauth_spec.rb
@@ -13,21 +13,21 @@ RSpec.describe '/oauth' do
         let(:client) { create(:client) }
 
         context "when requesting an authorization code" do
-          before { get "/oauth", params: { client_id: client.to_param, response_type: 'code', state: state } }
+          before { get "/oauth", params: { client_id: client.to_param, response_type: 'code', state: state, redirect_uri: client.redirect_uri } }
           specify { expect(response).to have_http_status(:ok) }
           specify { expect(response.body).to include(CGI.escapeHTML(client.name)) }
         end
 
         context "when requesting an access token" do
-          before { get "/oauth", params: { client_id: client.to_param, response_type: 'token', state: state } }
+          before { get "/oauth", params: { client_id: client.to_param, response_type: 'token', state: state, redirect_uri: client.redirect_uri } }
           specify { expect(response).to have_http_status(:ok) }
           specify { expect(response.body).to include(CGI.escapeHTML(client.name)) }
         end
 
         context "when an incorrect response_type is provided" do
-          before { get "/oauth", params: { client_id: client.to_param, response_type: 'invalid' } }
+          before { get "/oauth", params: { client_id: client.to_param, response_type: 'invalid', redirect_uri: client.redirect_uri } }
 
-          specify { expect(response).to have_http_status(:not_found) }
+          specify { expect(response).to redirect_to("#{client.redirect_uri}#error=unsupported_response_type") }
         end
       end
     end