Commit 4896fc7
Changed files (4)
app
controllers
models
spec
factories
models
app/controllers/clients_controller.rb
@@ -7,7 +7,7 @@ class ClientsController < ApplicationController
render status: :created, formats: :json
rescue ActiveRecord::RecordInvalid => error
json = {
- error: :invalid_redirect_uri,
+ error: error.record.errors[:redirect_uris].present? ? :invalid_redirect_uri : :invalid_client_metadata,
error_description: error.record.errors.full_messages.join(' ')
}
render json: json, status: :bad_request
app/models/client.rb
@@ -8,11 +8,15 @@ class Client < ApplicationRecord
attribute :redirect_uris, :string, array: true
enum token_endpoint_auth_method: { client_secret_none: 0, client_secret_post: 1, client_secret_basic: 2 }
- validates :redirect_uris, presence: true, format: { with: URI_REGEX }
- validates :jwks_uri, format: { with: URI_REGEX }
- validates :logo_uri, format: { with: URI_REGEX }
+ validates :redirect_uris, presence: true#, format: { with: URI_REGEX }
+ validates :jwks_uri, format: { with: URI_REGEX }, allow_blank: true
+ validates :logo_uri, format: { with: URI_REGEX }, allow_blank: true
validates :name, presence: true
validates :uuid, presence: true, format: { with: UUID }
+ validates_each :redirect_uris do |record, attr, value|
+ invalid_uri = Array(value).find { |x| !x.match?(URI_REGEX) }
+ record.errors[:redirect_uris] << 'is invalid.' if invalid_uri
+ end
after_initialize do
self.uuid = SecureRandom.uuid unless uuid
@@ -37,7 +41,7 @@ class Client < ApplicationRecord
end
def valid_redirect_uri?(redirect_uri)
- self.redirect_uri == redirect_uri
+ self.redirect_uris.include? redirect_uri
end
def valid_response_type?(response_type)
@@ -72,7 +76,7 @@ class Client < ApplicationRecord
def redirect_url(fragments = {})
URI.parse(
- "#{redirect_uri}#" + fragments.map do |(key, value)|
+ "#{redirect_uris[0]}#" + fragments.map do |(key, value)|
"#{key}=#{value}" if value.present?
end.compact.join("&")
).to_s
spec/factories/client.rb
@@ -4,6 +4,6 @@ FactoryBot.define do
factory :client do
uuid { SecureRandom.uuid }
name { FFaker::Name.name }
- redirect_uri { FFaker::Internet.uri('https') }
+ redirect_uris { [FFaker::Internet.uri('https')] }
end
end
spec/models/client_spec.rb
@@ -5,9 +5,11 @@ require 'rails_helper'
RSpec.describe Client do
describe "#validation" do
specify { expect(build(:client)).to be_valid }
- specify { expect(build(:client, redirect_uri: nil)).to be_invalid }
- specify { expect(build(:client, redirect_uri: '<script>alert("hi")</script>')).to be_invalid }
- specify { expect(build(:client, redirect_uri: 'invalid')).to be_invalid }
+ specify { expect(build(:client, redirect_uris: nil)).to be_invalid }
+ specify { expect(build(:client, redirect_uris: [])).to be_invalid }
+ specify { expect(build(:client, redirect_uris: ['<script>alert("hi")</script>'])).to be_invalid }
+ specify { expect(build(:client, redirect_uris: ['invalid'])).to be_invalid }
+ specify { expect(build(:client, redirect_uris: 'invalid')).to be_invalid }
specify { expect(build(:client, uuid: nil)).to be_invalid }
specify { expect(build(:client, uuid: 'invalid')).to be_invalid }
specify { expect(build(:client, name: nil)).to be_invalid }
@@ -17,7 +19,7 @@ RSpec.describe Client do
subject { build(:client) }
let(:code) { SecureRandom.uuid }
- let(:redirect_uri) { subject.redirect_uri }
+ let(:redirect_uri) { subject.redirect_uris[0] }
specify { expect(subject.redirect_url(code: code)).to eql("#{redirect_uri}#code=#{code}") }
specify { expect { subject.redirect_url(state: '<script>alert("hi");</script>') }.to raise_error(URI::InvalidURIError) }