From 1dcefdb9986882f8082282f46370a99a082ced07 Mon Sep 17 00:00:00 2001 From: theworldbright Date: Fri, 25 Sep 2015 13:13:36 -0700 Subject: [PATCH] Validate sector identifier uri and redirect uri --- .../api/openid_connect/clients_controller.rb | 23 +++++++++-------- .../api/openid_connect/o_auth_application.rb | 25 ++++++++++++++++++- .../exception/invalid_redirect_uri.rb | 11 ++++++++ .../invalid_sector_identifier_uri.rb | 11 ++++++++ .../openid_connect/clients_controller_spec.rb | 4 +++ 5 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 lib/api/openid_connect/exception/invalid_redirect_uri.rb create mode 100644 lib/api/openid_connect/exception/invalid_sector_identifier_uri.rb diff --git a/app/controllers/api/openid_connect/clients_controller.rb b/app/controllers/api/openid_connect/clients_controller.rb index 28d34bae8..ae906c58a 100644 --- a/app/controllers/api/openid_connect/clients_controller.rb +++ b/app/controllers/api/openid_connect/clients_controller.rb @@ -5,10 +5,15 @@ module Api http_error_page_as_json(e) end - rescue_from OpenIDConnect::ValidationFailed, ActiveRecord::RecordInvalid do |e| + rescue_from OpenIDConnect::ValidationFailed, + ActiveRecord::RecordInvalid, Api::OpenidConnect::Exception::InvalidSectorIdentifierUri do |e| validation_fail_as_json(e) end + rescue_from Api::OpenidConnect::Exception::InvalidRedirectUri do |e| + validation_fail_redirect_uri(e) + end + def create registrar = OpenIDConnect::Client::Registrar.new(request.url, params) client = Api::OpenidConnect::OAuthApplication.register! registrar @@ -27,19 +32,15 @@ module Api private def http_error_page_as_json(e) - render json: - { - error: :invalid_request, - error_description: e.message - }, status: 400 + render json: { error: :invalid_request, error_description: e.message}, status: 400 end def validation_fail_as_json(e) - render json: - { - error: :invalid_client_metadata, - error_description: e.message - }, status: 400 + render json: {error: :invalid_client_metadata, error_description: e.message}, status: 400 + end + + def validation_fail_redirect_uri(e) + render json: {error: :invalid_redirect_uri, error_description: e.message}, status: 400 end end end diff --git a/app/models/api/openid_connect/o_auth_application.rb b/app/models/api/openid_connect/o_auth_application.rb index fc8482b53..668592dab 100644 --- a/app/models/api/openid_connect/o_auth_application.rb +++ b/app/models/api/openid_connect/o_auth_application.rb @@ -39,7 +39,30 @@ module Api private def build_client_application(registrar) - create! registrar_attributes(registrar) + attributes = registrar_attributes(registrar) + check_sector_identifier_uri(attributes) + check_redirect_uris(attributes) + create! attributes + end + + def check_sector_identifier_uri(attributes) + sector_identifier_uri = attributes[:sector_identifier_uri] + return unless sector_identifier_uri + uri = URI.parse(sector_identifier_uri) + response = Net::HTTP.get_response(uri) + sector_identifier_uri_json = JSON.parse(response.body) + redirect_uris = attributes[:redirect_uris] + sector_identifier_uri_includes_redirect_uris = (redirect_uris - sector_identifier_uri_json).empty? + return if sector_identifier_uri_includes_redirect_uris + raise Api::OpenidConnect::Exception::InvalidSectorIdentifierUri.new + end + + def check_redirect_uris(attributes) + redirect_uris = attributes[:redirect_uris] + uri_array = redirect_uris.map {|uri| URI(uri) } + any_uri_contains_fragment = uri_array.any? {|uri| !uri.fragment.nil? } + return unless any_uri_contains_fragment + raise Api::OpenidConnect::Exception::InvalidRedirectUri.new end def supported_metadata diff --git a/lib/api/openid_connect/exception/invalid_redirect_uri.rb b/lib/api/openid_connect/exception/invalid_redirect_uri.rb new file mode 100644 index 000000000..a407505b4 --- /dev/null +++ b/lib/api/openid_connect/exception/invalid_redirect_uri.rb @@ -0,0 +1,11 @@ +module Api + module OpenidConnect + module Exception + class InvalidRedirectUri < ::ArgumentError + def initialize + super "Redirect uri contains fragment" + end + end + end + end +end diff --git a/lib/api/openid_connect/exception/invalid_sector_identifier_uri.rb b/lib/api/openid_connect/exception/invalid_sector_identifier_uri.rb new file mode 100644 index 000000000..6383aee22 --- /dev/null +++ b/lib/api/openid_connect/exception/invalid_sector_identifier_uri.rb @@ -0,0 +1,11 @@ +module Api + module OpenidConnect + module Exception + class InvalidSectorIdentifierUri < ::ArgumentError + def initialize + super "Invalid sector identifier uri" + end + end + end + end +end diff --git a/spec/controllers/api/openid_connect/clients_controller_spec.rb b/spec/controllers/api/openid_connect/clients_controller_spec.rb index 618909d69..1b138386a 100644 --- a/spec/controllers/api/openid_connect/clients_controller_spec.rb +++ b/spec/controllers/api/openid_connect/clients_controller_spec.rb @@ -4,6 +4,10 @@ describe Api::OpenidConnect::ClientsController, type: :controller do describe "#create" do context "when valid parameters are passed" do it "should return a client id" do + stub_request(:get, "http://example.com/uris") + .with(headers: {"Accept" => "*/*", "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Host" => "example.com", "User-Agent" => "Ruby"}) + .to_return(status: 200, body: "[\"http://localhost\"]", headers: {}) post :create, redirect_uris: ["http://localhost"], client_name: "diaspora client", response_types: [], grant_types: [], application_type: "web", contacts: [], logo_uri: "http://example.com/logo.png", client_uri: "http://example.com/client",