Introduce privileged scopes that only an administrator can enable
This commit is contained in:
parent
6a9ab7cb2d
commit
6c6e8883f7
7 changed files with 38 additions and 20 deletions
|
@ -20,8 +20,8 @@ class Oauth2ApplicationsController < Doorkeeper::ApplicationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def application_params
|
def application_params
|
||||||
params[:doorkeeper_application][:scopes]&.delete("")
|
params[:oauth2_application][:scopes]&.delete("")
|
||||||
params.require(:doorkeeper_application)
|
params.require(:oauth2_application)
|
||||||
.permit(:name, :redirect_uri, :confidential, :scopes => [])
|
.permit(:name, :redirect_uri, :confidential, :scopes => [])
|
||||||
.merge(:owner => current_resource_owner)
|
.merge(:owner => current_resource_owner)
|
||||||
end
|
end
|
||||||
|
|
13
app/models/oauth2_application.rb
Normal file
13
app/models/oauth2_application.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class Oauth2Application < Doorkeeper::Application
|
||||||
|
belongs_to :owner, :polymorphic => true
|
||||||
|
|
||||||
|
validate :allowed_scopes
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def allowed_scopes
|
||||||
|
return if owner.administrator?
|
||||||
|
|
||||||
|
errors.add(:scopes) if scopes.any? { |scope| Oauth::PRIVILEGED_SCOPES.include?(scope) }
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,5 +3,5 @@
|
||||||
<%= f.form_group :confidential do %>
|
<%= f.form_group :confidential do %>
|
||||||
<%= f.check_box :confidential %>
|
<%= f.check_box :confidential %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= f.collection_check_boxes :scopes, Oauth.scopes, :name, :description %>
|
<%= f.collection_check_boxes :scopes, Oauth.scopes(:privileged => current_user.administrator?), :name, :description %>
|
||||||
<%= f.primary %>
|
<%= f.primary %>
|
||||||
|
|
|
@ -48,6 +48,8 @@ Doorkeeper.configure do
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
application_class "Oauth2Application"
|
||||||
|
|
||||||
# Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
|
# Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
|
||||||
# By default this option is disabled.
|
# By default this option is disabled.
|
||||||
#
|
#
|
||||||
|
@ -221,7 +223,7 @@ Doorkeeper.configure do
|
||||||
# https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
|
# https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
|
||||||
|
|
||||||
# default_scopes :public
|
# default_scopes :public
|
||||||
optional_scopes(*Oauth::SCOPES)
|
optional_scopes(*Oauth::SCOPES, *Oauth::PRIVILEGED_SCOPES)
|
||||||
|
|
||||||
# Allows to restrict only certain scopes for grant_type.
|
# Allows to restrict only certain scopes for grant_type.
|
||||||
# By default, all the scopes will be available for all the grant types.
|
# By default, all the scopes will be available for all the grant types.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module Oauth
|
module Oauth
|
||||||
SCOPES = %w[read_prefs write_prefs write_diary write_api read_gpx write_gpx write_notes].freeze
|
SCOPES = %w[read_prefs write_prefs write_diary write_api read_gpx write_gpx write_notes].freeze
|
||||||
|
PRIVILEGED_SCOPES = %w[].freeze
|
||||||
|
|
||||||
class Scope
|
class Scope
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
@ -13,7 +14,9 @@ module Oauth
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.scopes
|
def self.scopes(privileged: false)
|
||||||
SCOPES.collect { |s| Scope.new(s) }
|
scopes = SCOPES
|
||||||
|
scopes += PRIVILEGED_SCOPES if privileged
|
||||||
|
scopes.collect { |s| Scope.new(s) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -67,11 +67,11 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template "oauth2_applications/new"
|
assert_template "oauth2_applications/new"
|
||||||
assert_select "form", 1 do
|
assert_select "form", 1 do
|
||||||
assert_select "input#doorkeeper_application_name", 1
|
assert_select "input#oauth2_application_name", 1
|
||||||
assert_select "textarea#doorkeeper_application_redirect_uri", 1
|
assert_select "textarea#oauth2_application_redirect_uri", 1
|
||||||
assert_select "input#doorkeeper_application_confidential", 1
|
assert_select "input#oauth2_application_confidential", 1
|
||||||
Oauth.scopes.each do |scope|
|
Oauth.scopes.each do |scope|
|
||||||
assert_select "input#doorkeeper_application_scopes_#{scope.name}", 1
|
assert_select "input#oauth2_application_scopes_#{scope.name}", 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -87,7 +87,7 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
session_for(user)
|
session_for(user)
|
||||||
|
|
||||||
assert_difference "Doorkeeper::Application.count", 0 do
|
assert_difference "Doorkeeper::Application.count", 0 do
|
||||||
post oauth_applications_path(:doorkeeper_application => {
|
post oauth_applications_path(:oauth2_application => {
|
||||||
:name => "Test Application"
|
:name => "Test Application"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -95,7 +95,7 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_template "oauth2_applications/new"
|
assert_template "oauth2_applications/new"
|
||||||
|
|
||||||
assert_difference "Doorkeeper::Application.count", 0 do
|
assert_difference "Doorkeeper::Application.count", 0 do
|
||||||
post oauth_applications_path(:doorkeeper_application => {
|
post oauth_applications_path(:oauth2_application => {
|
||||||
:name => "Test Application",
|
:name => "Test Application",
|
||||||
:redirect_uri => "https://test.example.com/",
|
:redirect_uri => "https://test.example.com/",
|
||||||
:scopes => ["bad_scope"]
|
:scopes => ["bad_scope"]
|
||||||
|
@ -105,7 +105,7 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_template "oauth2_applications/new"
|
assert_template "oauth2_applications/new"
|
||||||
|
|
||||||
assert_difference "Doorkeeper::Application.count", 1 do
|
assert_difference "Doorkeeper::Application.count", 1 do
|
||||||
post oauth_applications_path(:doorkeeper_application => {
|
post oauth_applications_path(:oauth2_application => {
|
||||||
:name => "Test Application",
|
:name => "Test Application",
|
||||||
:redirect_uri => "https://test.example.com/",
|
:redirect_uri => "https://test.example.com/",
|
||||||
:scopes => ["read_prefs"]
|
:scopes => ["read_prefs"]
|
||||||
|
@ -154,11 +154,11 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template "oauth2_applications/edit"
|
assert_template "oauth2_applications/edit"
|
||||||
assert_select "form", 1 do
|
assert_select "form", 1 do
|
||||||
assert_select "input#doorkeeper_application_name", 1
|
assert_select "input#oauth2_application_name", 1
|
||||||
assert_select "textarea#doorkeeper_application_redirect_uri", 1
|
assert_select "textarea#oauth2_application_redirect_uri", 1
|
||||||
assert_select "input#doorkeeper_application_confidential", 1
|
assert_select "input#oauth2_application_confidential", 1
|
||||||
Oauth.scopes.each do |scope|
|
Oauth.scopes.each do |scope|
|
||||||
assert_select "input#doorkeeper_application_scopes_#{scope.name}", 1
|
assert_select "input#oauth2_application_scopes_#{scope.name}", 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -178,7 +178,7 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_template "oauth2_applications/not_found"
|
assert_template "oauth2_applications/not_found"
|
||||||
|
|
||||||
put oauth_application_path(:id => client,
|
put oauth_application_path(:id => client,
|
||||||
:doorkeeper_application => {
|
:oauth2_application => {
|
||||||
:name => "New Name",
|
:name => "New Name",
|
||||||
:redirect_uri => nil
|
:redirect_uri => nil
|
||||||
})
|
})
|
||||||
|
@ -186,7 +186,7 @@ class Oauth2ApplicationsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_template "oauth2_applications/edit"
|
assert_template "oauth2_applications/edit"
|
||||||
|
|
||||||
put oauth_application_path(:id => client,
|
put oauth_application_path(:id => client,
|
||||||
:doorkeeper_application => {
|
:oauth2_application => {
|
||||||
:name => "New Name",
|
:name => "New Name",
|
||||||
:redirect_uri => "https://new.example.com/url"
|
:redirect_uri => "https://new.example.com/url"
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :oauth_application, :class => "Doorkeeper::Application" do
|
factory :oauth_application, :class => "Oauth2Application" do
|
||||||
sequence(:name) { |n| "OAuth application #{n}" }
|
sequence(:name) { |n| "OAuth application #{n}" }
|
||||||
sequence(:redirect_uri) { |n| "https://example.com/app/#{n}" }
|
sequence(:redirect_uri) { |n| "https://example.com/app/#{n}" }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue