Skip to content

Commit

Permalink
Merge pull request #1237 from doorkeeper-gem/optional_redirect_uri
Browse files Browse the repository at this point in the history
Fix #947: Allow blank redirect URI for URI-less grant flows
  • Loading branch information
nbulaj authored Apr 1, 2019
2 parents 28dee4e + 4ac115d commit 119386a
Show file tree
Hide file tree
Showing 18 changed files with 97 additions and 8 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ User-visible changes worth mentioning.

## master

- [#1237] Allow to set blank redirect URI if Doorkeeper configured to use redirect URI-less grant flows.
- [#1234] Fix `StaleRecordsCleaner` to properly work with big amount of records.
- [#1228] Allow to explicitly set non-expiring tokens in `custom_access_token_expires_in` configuration
option using `Float::INIFINITY` return value.
Expand Down
2 changes: 2 additions & 0 deletions app/validators/redirect_uri_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def self.native_redirect_uri
end

def validate_each(record, attribute, value)
return if Doorkeeper.configuration.allow_blank_redirect_uri?

if value.blank?
record.errors.add(attribute, :blank)
else
Expand Down
6 changes: 6 additions & 0 deletions app/views/doorkeeper/applications/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
<%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, class: 'bg-light') { Doorkeeper.configuration.native_redirect_uri }) %>
</span>
<% end %>
<% if Doorkeeper.configuration.allow_blank_redirect_uri? %>
<span class="form-text text-secondary">
<%= t('doorkeeper.applications.help.blank_redirect_uri') %>
</span>
<% end %>
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ en:
help:
confidential: 'Application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.'
redirect_uri: 'Use one line per URI'
blank_redirect_uri: "Leave it blank if you configured your provider to use Client Credentials, Resource Owner Password Credentials or any other grant type that doesn't require redirect URI."
native_redirect_uri: 'Use %{native_redirect_uri} if you want to add localhost URIs for development purposes'
scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.'
edit:
Expand Down
5 changes: 5 additions & 0 deletions lib/doorkeeper/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ def token_grant_types
@token_grant_types ||= calculate_token_grant_types.freeze
end

def allow_blank_redirect_uri?
grant_flows.exclude?("authorization_code") &&
grant_flows.exclude?("implicit")
end

def option_defined?(name)
!instance_variable_get("@#{name}").nil?
end
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/doorkeeper/application_owner_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
require "rails/generators/active_record"

module Doorkeeper
# Generates migration to add reference to owner of the
# Doorkeeper application.
#
class ApplicationOwnerGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
require "rails/generators/active_record"

module Doorkeeper
# Generates migration to add confidential column to Doorkeeper
# applications table.
#
class ConfidentialApplicationsGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
2 changes: 2 additions & 0 deletions lib/generators/doorkeeper/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require "rails/generators/active_record"

module Doorkeeper
# Setup doorkeeper into Rails application: locales, routes, etc.
#
class InstallGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
2 changes: 2 additions & 0 deletions lib/generators/doorkeeper/migration_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require "rails/generators/active_record"

module Doorkeeper
# Copies main Doorkeeper migration into parent Rails application.
#
class MigrationGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/doorkeeper/pkce_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
require "rails/generators/active_record"

module Doorkeeper
# Generates migration with PKCE required database columns for
# Doorkeeper tables.
#
class PkceGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/doorkeeper/previous_refresh_token_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
require "rails/generators/active_record"

module Doorkeeper
# Generates migration to add previous refresh token column to the
# database for Doorkeeper tables.
#
class PreviousRefreshTokenGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration
source_root File.expand_path("templates", __dir__)
Expand Down
4 changes: 4 additions & 0 deletions lib/generators/doorkeeper/templates/migration.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
t.string :name, null: false
t.string :uid, null: false
t.string :secret, null: false

# Remove `null: false` if you are planning to use grant flows
# that doesn't require redirect URI to be used during authorization
# like Client Credentials flow or Resource Owner Password.
t.text :redirect_uri, null: false
t.string :scopes, null: false, default: ''
t.boolean :confidential, null: false, default: true
Expand Down
2 changes: 2 additions & 0 deletions lib/generators/doorkeeper/views_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Doorkeeper
module Generators
# Generates doorkeeper views for Rails application
#
class ViewsGenerator < ::Rails::Generators::Base
source_root File.expand_path("../../../app/views", __dir__)

Expand Down
2 changes: 1 addition & 1 deletion spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
t.string "name", null: false
t.string "uid", null: false
t.string "secret", null: false
t.text "redirect_uri", null: false
t.text "redirect_uri"
t.string "scopes", default: "", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
Expand Down
2 changes: 0 additions & 2 deletions spec/lib/oauth/password_access_token_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@ module Doorkeeper::OAuth
222
elsif context.scopes.exists?("magic")
Float::INFINITY
else
nil
end
}
)
Expand Down
32 changes: 28 additions & 4 deletions spec/models/doorkeeper/application_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,34 @@ module Doorkeeper
expect(new_application).not_to be_valid
end

it "is invalid without redirect_uri" do
new_application.save
new_application.redirect_uri = nil
expect(new_application).not_to be_valid
context "redirect URI" do
context "when grant flows allow blank redirect URI" do
before do
Doorkeeper.configure do
grant_flows %w[password client_credentials]
end
end

it "is valid without redirect_uri" do
new_application.save
new_application.redirect_uri = nil
expect(new_application).to be_valid
end
end

context "when grant flows require redirect URI" do
before do
Doorkeeper.configure do
grant_flows %w[password client_credentials authorization_code]
end
end

it "is invalid without redirect_uri" do
new_application.save
new_application.redirect_uri = nil
expect(new_application).not_to be_valid
end
end
end

it "checks uniqueness of uid" do
Expand Down
30 changes: 30 additions & 0 deletions spec/requests/applications/applications_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,36 @@
true
)
end

context "redirect URI" do
scenario "adding app with blank redirect URI when configured flows requires redirect uri" do
config_is_set("grant_flows", %w[authorization_code implicit client_credentials])

fill_in "doorkeeper_application[name]", with: "My Application"
fill_in "doorkeeper_application[redirect_uri]",
with: ""

click_button "Submit"
i_should_see "Whoops! Check your form for possible errors"
end

scenario "adding app with blank redirect URI when configured flows without redirect uri" do
config_is_set("grant_flows", %w[client_credentials password])

# Visit it once again to consider grant flows
visit "/oauth/applications/new"

i_should_see I18n.t("doorkeeper.applications.help.blank_redirect_uri")

fill_in "doorkeeper_application[name]", with: "My Application"
fill_in "doorkeeper_application[redirect_uri]",
with: ""

click_button "Submit"
i_should_see "Application created"
i_should_see "My Application"
end
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/requests/flows/password_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
end

describe "Resource Owner Password Credentials Flow" do
let(:client_attributes) { {} }
let(:client_attributes) { { redirect_uri: nil } }

before do
config_is_set(:grant_flows, ["password"])
Expand Down

0 comments on commit 119386a

Please sign in to comment.