Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ gem 'snmp'
gem 'yaml_db'

# OAuth
gem 'doorkeeper', '> 1.0beta'
gem 'doorkeeper'
gem 'doorkeeper-i18n'
gem 'doorkeeper-openid_connect'

gem 'matrix'
gem 'net-smtp', require: false
Expand Down
9 changes: 8 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ GEM
railties (>= 5)
doorkeeper-i18n (5.2.8)
doorkeeper (>= 5.2)
doorkeeper-openid_connect (1.9.0)
doorkeeper (>= 5.5, < 6.0)
jwt (>= 2.5)
ostruct (>= 0.5)
drb (2.2.3)
erb (6.0.4)
erubi (1.13.1)
Expand Down Expand Up @@ -187,6 +191,8 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.19.4)
jwt (3.1.2)
base64
kaminari (1.2.2)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.2)
Expand Down Expand Up @@ -455,8 +461,9 @@ DEPENDENCIES
delayed_job_active_record
devise
devise-i18n
doorkeeper (> 1.0beta)
doorkeeper
doorkeeper-i18n
doorkeeper-openid_connect
factory_bot_rails
fakefs
faker
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/doorkeeper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
# https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
#
default_scopes :public
optional_scopes :account_data_read
optional_scopes :account_data_read, :openid, :profile, :email, :roles

# Define scopes_by_grant_type to restrict only certain scopes for grant_type
# By default, all the scopes will be available for all the grant types.
Expand Down
118 changes: 118 additions & 0 deletions config/initializers/doorkeeper_openid_connect.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# frozen_string_literal: true

Doorkeeper::OpenidConnect.configure do
issuer do |resource_owner, application|
Rails.application.credentials.root_url
end

signing_key Rails.application.credentials.oidc_signing_key
# 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

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

# Enable dynamic client registration (default false)
# dynamic_client_registration true

# You can use your own model class if you need to extend (or even override) the default
# Doorkeeper::OpenidConnect::Request model (e.g. to use a different database connection).
#
# By default Doorkeeper OpenID Connect uses:
#
# open_id_request_class "Doorkeeper::OpenidConnect::Request"
#
# Don't forget to include the OpenID Connect ORM mixin into your custom model:
#
# * ::Doorkeeper::OpenidConnect::Orm::ActiveRecord::Mixins::OpenidRequest
#
# For example:
#
# open_id_request_class "MyOpenidRequest"
#
# class MyOpenidRequest < ApplicationRecord
# include ::Doorkeeper::OpenidConnect::Orm::ActiveRecord::Mixins::OpenidRequest
# end

# 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
claims do
claim :email do |resource_owner|
resource_owner.email
end

claim :name do |resource_owner|
"#{resource_owner.first_name} #{resource_owner.last_name}"
end

claim :family_name do |resource_owner|
resource_owner.last_name
end

claim :given_name do |resource_owner|
resource_owner.first_name
end

claim :picture do |resource_owner|
Gravatar.new(resource_owner.email).image_url ssl: true, s: 128, d: 'retro'
end

claim :username do |resource_owner|
resource_owner.username
end

claim :roles, scope: :roles do |resource_owner|
resource_owner.roles.map(&:name)
end
end
end
8 changes: 8 additions & 0 deletions config/locales/doorkeeper_openid_connect.bg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bg:
doorkeeper:
scopes:
openid: Вход чрез init Lab Fauna
profile: Профил в init Lab Fauna
email: Имейл адрес за init Lab Fauna
address: Адрес
phone: Телефонен номер за init Lab Fauna
23 changes: 23 additions & 0 deletions config/locales/doorkeeper_openid_connect.en.yml
Original file line number Diff line number Diff line change
@@ -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.'
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
Rails.application.routes.draw do
use_doorkeeper_openid_connect
use_doorkeeper do
controllers applications: 'oauth/applications'
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class CreateDoorkeeperOpenidConnectTables < ActiveRecord::Migration[8.1]
def change
create_table :oauth_openid_requests do |t|
t.references :access_grant, null: false, index: true
t.string :nonce, null: false
end

add_foreign_key(
:oauth_openid_requests,
:oauth_access_grants,
column: :access_grant_id,
on_delete: :cascade
)
end
end
9 changes: 8 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[8.1].define(version: 2026_01_11_102636) do
ActiveRecord::Schema[8.1].define(version: 2026_04_29_165133) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"

Expand Down Expand Up @@ -119,6 +119,12 @@
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
end

create_table "oauth_openid_requests", force: :cascade do |t|
t.bigint "access_grant_id", null: false
t.string "nonce", null: false
t.index ["access_grant_id"], name: "index_oauth_openid_requests_on_access_grant_id"
end

create_table "phone_numbers", force: :cascade do |t|
t.datetime "created_at", precision: nil, null: false
t.integer "owner_id", null: false
Expand Down Expand Up @@ -186,4 +192,5 @@
end

add_foreign_key "audit_log_entries", "users"
add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", on_delete: :cascade
end