From 8a22bfb222b3b063a03efd5e85da834f3d63b5fc Mon Sep 17 00:00:00 2001 From: Milan Cvetkovic Date: Wed, 30 Aug 2023 12:19:00 +0000 Subject: [PATCH] Add unconfigured doorkeeper-openid_connect After executing: rails generate doorkeeper:openid_connect:install rails generate doorkeeper:openid_connect:install Split migration script to 2 to avoid deadlock. --- Gemfile | 1 + Gemfile.lock | 4 ++ .../initializers/doorkeeper_openid_connect.rb | 72 +++++++++++++++++++ .../locales/doorkeeper_openid_connect.en.yml | 23 ++++++ config/routes.rb | 1 + ...create_doorkeeper_openid_connect_tables.rb | 18 +++++ ...create_doorkeeper_openid_connect_tables.rb | 6 ++ db/structure.sql | 62 ++++++++++++++++ 8 files changed, 187 insertions(+) create mode 100644 config/initializers/doorkeeper_openid_connect.rb create mode 100644 config/locales/doorkeeper_openid_connect.en.yml create mode 100644 db/migrate/20230830115219_create_doorkeeper_openid_connect_tables.rb create mode 100644 db/migrate/20230830115220_validate_create_doorkeeper_openid_connect_tables.rb diff --git a/Gemfile b/Gemfile index f60a219e7..bf65965d4 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,7 @@ gem "omniauth-rails_csrf_protection", "~> 1.0" # Doorkeeper for OAuth2 gem "doorkeeper" gem "doorkeeper-i18n" +gem "doorkeeper-openid_connect" # Markdown formatting support gem "kramdown" diff --git a/Gemfile.lock b/Gemfile.lock index 5f36ab055..2a51a3d36 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,6 +166,9 @@ GEM railties (>= 5) doorkeeper-i18n (5.2.6) doorkeeper (>= 5.2) + doorkeeper-openid_connect (1.8.7) + doorkeeper (>= 5.5, < 5.7) + jwt (>= 2.5) dry-configurable (1.1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) @@ -567,6 +570,7 @@ DEPENDENCIES delayed_job_active_record doorkeeper doorkeeper-i18n + doorkeeper-openid_connect erb_lint factory_bot_rails faraday diff --git a/config/initializers/doorkeeper_openid_connect.rb b/config/initializers/doorkeeper_openid_connect.rb new file mode 100644 index 000000000..e91a907c2 --- /dev/null +++ b/config/initializers/doorkeeper_openid_connect.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +Doorkeeper::OpenidConnect.configure do + issuer do |_resource_owner, _application| + "issuer string" + end + + signing_key <<~KEY + -----BEGIN RSA PRIVATE KEY----- + .... + -----END RSA PRIVATE KEY----- + KEY + + subject_types_supported [:public] + + resource_owner_from_access_token do |access_token| + # Example implementation: + # User.find_by(id: access_token.resource_owner_id) + end + + auth_time_from_resource_owner do |resource_owner| + # Example implementation: + # resource_owner.current_sign_in_at + end + + reauthenticate_resource_owner do |resource_owner, return_to| + # Example implementation: + # store_location_for resource_owner, return_to + # sign_out resource_owner + # redirect_to new_user_session_url + end + + # Depending on your configuration, a DoubleRenderError could be raised + # if render/redirect_to is called at some point before this callback is executed. + # To avoid the DoubleRenderError, you could add these two lines at the beginning + # of this callback: (Reference: https://github.com/rails/rails/issues/25106) + # self.response_body = nil + # @_response_body = nil + select_account_for_resource_owner do |resource_owner, return_to| + # Example implementation: + # store_location_for resource_owner, return_to + # redirect_to account_select_url + end + + subject do |resource_owner, application| + # Example implementation: + # resource_owner.id + + # or if you need pairwise subject identifier, implement like below: + # Digest::SHA256.hexdigest("#{resource_owner.id}#{URI.parse(application.redirect_uri).host}#{'your_secret_salt'}") + end + + # Protocol to use when generating URIs for the discovery endpoint, + # for example if you also use HTTPS in development + # protocol do + # :https + # end + + # Expiration time on or after which the ID Token MUST NOT be accepted for processing. (default 120 seconds). + # expiration 600 + + # Example claims: + # claims do + # normal_claim :_foo_ do |resource_owner| + # resource_owner.foo + # end + + # normal_claim :_bar_ do |resource_owner| + # resource_owner.bar + # end + # end +end diff --git a/config/locales/doorkeeper_openid_connect.en.yml b/config/locales/doorkeeper_openid_connect.en.yml new file mode 100644 index 000000000..1bed506b2 --- /dev/null +++ b/config/locales/doorkeeper_openid_connect.en.yml @@ -0,0 +1,23 @@ +en: + doorkeeper: + scopes: + openid: 'Authenticate your account' + profile: 'View your profile information' + email: 'View your email address' + address: 'View your physical address' + phone: 'View your phone number' + errors: + messages: + login_required: 'The authorization server requires end-user authentication' + consent_required: 'The authorization server requires end-user consent' + interaction_required: 'The authorization server requires end-user interaction' + account_selection_required: 'The authorization server requires end-user account selection' + openid_connect: + errors: + messages: + # Configuration error messages + resource_owner_from_access_token_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.resource_owner_from_access_token missing configuration.' + auth_time_from_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.auth_time_from_resource_owner missing configuration.' + reauthenticate_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.reauthenticate_resource_owner missing configuration.' + select_account_for_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.select_account_for_resource_owner missing configuration.' + subject_not_configured: 'ID Token generation failed due to Doorkeeper::OpenidConnect.configure.subject missing configuration.' diff --git a/config/routes.rb b/config/routes.rb index 404e7b0a3..5b537ea3e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ OpenStreetMap::Application.routes.draw do + use_doorkeeper_openid_connect use_doorkeeper :scope => "oauth2" do controllers :authorizations => "oauth2_authorizations", :applications => "oauth2_applications", diff --git a/db/migrate/20230830115219_create_doorkeeper_openid_connect_tables.rb b/db/migrate/20230830115219_create_doorkeeper_openid_connect_tables.rb new file mode 100644 index 000000000..4924e158d --- /dev/null +++ b/db/migrate/20230830115219_create_doorkeeper_openid_connect_tables.rb @@ -0,0 +1,18 @@ +class CreateDoorkeeperOpenidConnectTables < ActiveRecord::Migration[7.0] + def change + create_table :oauth_openid_requests do |t| + t.references :access_grant, :null => false, :index => true + t.string :nonce, :null => false + end + + # Avoid validating foreign keys doe to possible deadlock + # create a separate migration instead, as suggested by db:migrate + + add_foreign_key( + :oauth_openid_requests, + :oauth_access_grants, + :column => :access_grant_id, + :on_delete => :cascade, :validate => false + ) + end +end diff --git a/db/migrate/20230830115220_validate_create_doorkeeper_openid_connect_tables.rb b/db/migrate/20230830115220_validate_create_doorkeeper_openid_connect_tables.rb new file mode 100644 index 000000000..0596cbeb1 --- /dev/null +++ b/db/migrate/20230830115220_validate_create_doorkeeper_openid_connect_tables.rb @@ -0,0 +1,6 @@ +class ValidateCreateDoorkeeperOpenidConnectTables < ActiveRecord::Migration[7.0] + # Validate foreign key created by CreateDoorkeeperOpenidConnectTables + def change + validate_foreign_key :oauth_openid_requests, :oauth_access_grants + end +end diff --git a/db/structure.sql b/db/structure.sql index 1874e6461..bd65755f2 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1152,6 +1152,36 @@ CREATE SEQUENCE public.oauth_nonces_id_seq ALTER SEQUENCE public.oauth_nonces_id_seq OWNED BY public.oauth_nonces.id; +-- +-- Name: oauth_openid_requests; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.oauth_openid_requests ( + id bigint NOT NULL, + access_grant_id bigint NOT NULL, + nonce character varying NOT NULL +); + + +-- +-- Name: oauth_openid_requests_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.oauth_openid_requests_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: oauth_openid_requests_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.oauth_openid_requests_id_seq OWNED BY public.oauth_openid_requests.id; + + -- -- Name: oauth_tokens; Type: TABLE; Schema: public; Owner: - -- @@ -1704,6 +1734,13 @@ ALTER TABLE ONLY public.oauth_applications ALTER COLUMN id SET DEFAULT nextval(' ALTER TABLE ONLY public.oauth_nonces ALTER COLUMN id SET DEFAULT nextval('public.oauth_nonces_id_seq'::regclass); +-- +-- Name: oauth_openid_requests id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.oauth_openid_requests ALTER COLUMN id SET DEFAULT nextval('public.oauth_openid_requests_id_seq'::regclass); + + -- -- Name: oauth_tokens id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2033,6 +2070,14 @@ ALTER TABLE ONLY public.oauth_nonces ADD CONSTRAINT oauth_nonces_pkey PRIMARY KEY (id); +-- +-- Name: oauth_openid_requests oauth_openid_requests_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.oauth_openid_requests + ADD CONSTRAINT oauth_openid_requests_pkey PRIMARY KEY (id); + + -- -- Name: oauth_tokens oauth_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2573,6 +2618,13 @@ CREATE UNIQUE INDEX index_oauth_applications_on_uid ON public.oauth_applications CREATE UNIQUE INDEX index_oauth_nonces_on_nonce_and_timestamp ON public.oauth_nonces USING btree (nonce, "timestamp"); +-- +-- Name: index_oauth_openid_requests_on_access_grant_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_oauth_openid_requests_on_access_grant_id ON public.oauth_openid_requests USING btree (access_grant_id); + + -- -- Name: index_oauth_tokens_on_token; Type: INDEX; Schema: public; Owner: - -- @@ -2989,6 +3041,14 @@ ALTER TABLE ONLY public.oauth_access_tokens ADD CONSTRAINT fk_rails_732cb83ab7 FOREIGN KEY (application_id) REFERENCES public.oauth_applications(id) NOT VALID; +-- +-- Name: oauth_openid_requests fk_rails_77114b3b09; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.oauth_openid_requests + ADD CONSTRAINT fk_rails_77114b3b09 FOREIGN KEY (access_grant_id) REFERENCES public.oauth_access_grants(id) ON DELETE CASCADE; + + -- -- Name: active_storage_variant_records fk_rails_993965df05; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -3404,6 +3464,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220223140543'), ('20230816135800'), ('20230825162137'), +('20230830115219'), +('20230830115220'), ('21'), ('22'), ('23'), -- 2.39.5