diff --git a/Gemfile b/Gemfile index cd8730df7..094d18846 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem 'aws-sdk', '~> 2.10' gem "cellect-client", '~> 3.0.2' gem 'dalli-elasticache' gem 'devise', '~> 4.3' -gem 'doorkeeper', '~> 4.2' +gem 'doorkeeper', '~> 4.4' gem 'doorkeeper-jwt', '~> 0.2.1' gem 'httparty' gem 'faraday', '~> 0.9' diff --git a/Gemfile.lock b/Gemfile.lock index 41caed031..178884710 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -120,7 +120,7 @@ GEM diff-lcs (1.3) domain_name (0.5.20170404) unf (>= 0.0.5, < 1.0.0) - doorkeeper (4.2.6) + doorkeeper (4.4.0) railties (>= 4.2) doorkeeper-jwt (0.2.1) jwt (~> 1.5.2, >= 1.5.2) @@ -454,7 +454,7 @@ DEPENDENCIES dalli-elasticache database_cleaner (~> 1.7.0) devise (~> 4.3) - doorkeeper (~> 4.2) + doorkeeper (~> 4.4) doorkeeper-jwt (~> 0.2.1) factory_bot_rails faraday (~> 0.9) diff --git a/db/migrate/20180726133210_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180726133210_add_confidential_to_doorkeeper_application.rb new file mode 100644 index 000000000..42522275d --- /dev/null +++ b/db/migrate/20180726133210_add_confidential_to_doorkeeper_application.rb @@ -0,0 +1,39 @@ +class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration + def change + add_column( + :oauth_applications, + :confidential, + :boolean, + null: false, + default: true # maintaining backwards compatibility: require secrets + ) + + # setting all the existing apps to confidential will break login for grant flows(password) + # that do not supply a client_secret, e.g. our main zooniverse.org UI and api clients + # these apps will require a confidential = false setting + # all implicit apps will require confidential = false as well + # apps that can keep secrets and use them to authenticate will require the default value + reversible do |dir| + dir.up do + non_confidential_opts = { confidential: false } + + Doorkeeper::Application + .where("redirect_uri ~* ?", '://') # all implicit apps & native apps (protocol scheme in the redirect_uri) + .where("redirect_uri !~* ?", 'auth/.+/callback') # not the omniauth server apps + .update_all(non_confidential_opts) + + # only change the apps we know use the password grant without a client_secret + known_non_confidential_first_party_app_names = [ + "ZooniverseFirstParty - PFE", + "Panoptes python client - official", + "PFE Application" + ] + Doorkeeper::Application + .first_party # all first_party apps (e.g. PFE, python client) + .where(name: known_non_confidential_first_party_app_names) + .where.not(confidential: false) + .update_all(non_confidential_opts) + end + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 1ab391223..59790de21 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -665,7 +665,8 @@ CREATE TABLE public.oauth_applications ( owner_type character varying, trust_level integer DEFAULT 1 NOT NULL, default_scope character varying[] DEFAULT '{}'::character varying[], - scopes character varying DEFAULT ''::character varying NOT NULL + scopes character varying DEFAULT ''::character varying NOT NULL, + confidential boolean DEFAULT true NOT NULL ); @@ -4156,3 +4157,5 @@ INSERT INTO schema_migrations (version) VALUES ('20180710151618'); INSERT INTO schema_migrations (version) VALUES ('20180724112620'); +INSERT INTO schema_migrations (version) VALUES ('20180726133210'); + diff --git a/spec/controllers/tokens_controller_spec.rb b/spec/controllers/tokens_controller_spec.rb index 8c58d01ca..4ecca349b 100644 --- a/spec/controllers/tokens_controller_spec.rb +++ b/spec/controllers/tokens_controller_spec.rb @@ -84,6 +84,7 @@ end context "when supplied a valid users's devise session" do + let(:app) { create(:non_confidential_first_party_app, owner: owner) } let(:req) do @request.env['devise.mapping'] = Devise.mappings[:user] sign_in owner diff --git a/spec/factories/applications.rb b/spec/factories/applications.rb index ac8b974da..0128cae1c 100644 --- a/spec/factories/applications.rb +++ b/spec/factories/applications.rb @@ -8,6 +8,10 @@ factory :first_party_app do trust_level 2 + + factory :non_confidential_first_party_app do + confidential false + end end factory :secure_app do