Skip to content

Commit

Permalink
Merge pull request #8524 from CitizenLabDotCo/TAN-1257-id-austria
Browse files Browse the repository at this point in the history
TAN-1257 - ID Austria
  • Loading branch information
jamesspeake authored Nov 13, 2024
2 parents 3cd6d3a + 3b5d19f commit 863e074
Show file tree
Hide file tree
Showing 29 changed files with 912 additions and 9 deletions.
1 change: 1 addition & 0 deletions back/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ commercial_engines = [
'id_gent_rrn',
'id_id_card_lookup',
'id_keycloak',
'id_id_austria',
'id_nemlog_in',
'id_oostende_rrn',
# Some engines actually register an authentication method rather
Expand Down
9 changes: 9 additions & 0 deletions back/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ PATH
omniauth_openid_connect
rails (~> 7.0)

PATH
remote: engines/commercial/id_id_austria
specs:
id_id_austria (1.0.0)
omniauth_openid_connect (~> 0.7.1)
rails (~> 7.0)
verification

PATH
remote: engines/commercial/id_id_card_lookup
specs:
Expand Down Expand Up @@ -1294,6 +1302,7 @@ DEPENDENCIES
id_franceconnect!
id_gent_rrn!
id_hoplr!
id_id_austria!
id_id_card_lookup!
id_keycloak!
id_nemlog_in!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

require 'citizen_lab/mixins/feature_specification'

module IdIdAustria
module FeatureSpecification
extend CitizenLab::Mixins::FeatureSpecification

def self.feature_name
'id_austria_login'
end

def self.feature_title
'ID Austria Login'
end

def self.feature_description
'Allow users to authenticate with a ID Austria account.'
end

def self.allowed_by_default
false
end

def self.enabled_by_default
false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

module IdIdAustria
class IdAustriaOmniauth < OmniauthMethods::Base
include IdAustriaVerification

def profile_to_user_attrs(auth)
{
first_name: auth.info.first_name,
last_name: auth.info.last_name,
email: auth.info.email,
locale: AppConfiguration.instance.closest_locale_to('de-DE')
}
end

# @param [AppConfiguration] configuration
def omniauth_setup(configuration, env)
return unless Verification::VerificationService.new.active?(configuration, name)

# NOTE: OmniAuth::Strategies::OpenIDConnect has been monkey patched especially for this Auth method
# Why? Gem does not support OpenID Connect without a userinfo endpoint
options = env['omniauth.strategy'].options

# Get configuration from https://eid.oesterreich.gv.at/.well-known/openid-configuration
options[:discovery] = true
options[:scope] = %i[openid profile]
options[:response_type] = :code
options[:issuer] = issuer
options[:client_auth_method] = 'jwks'
options[:client_options] = {
identifier: config[:client_id],
secret: config[:client_secret],
scheme: 'https',
host: host,
port: 443,
redirect_uri: "#{configuration.base_backend_uri}/auth/id_austria/callback"
}
end

def email_always_present?
false
end

def verification_prioritized?
true
end

def email_confirmed?(auth)
# Even if the response says the email is NOT verified, we assume that it is if email is present
auth&.info&.email.present?
end

def filter_auth_to_persist(auth)
auth_to_persist = auth.deep_dup
auth_to_persist.tap { |h| h.delete(:credentials) }
end

private

def host
'eid.oesterreich.gv.at' # Test and production are both on the same host
end

def issuer
"https://#{host}"
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

module IdIdAustria
module IdAustriaVerification
include Verification::VerificationMethod

def verification_method_type
:omniauth
end

def id
'91068f8a-c4a5-4fc8-ab3e-ca2eb74f9c3c'
end

def name
'id_austria'
end

def ui_method_name
config[:ui_method_name].presence || name
end

def config_parameters
%i[
client_id
client_secret
ui_method_name
enabled_for_verified_actions
]
end

def config_parameters_schema
{
ui_method_name: {
type: 'string',
description: 'The name this verification method will have in the UI'
},
enabled_for_verified_actions: {
private: true,
type: 'boolean',
description: 'Whether this verification method should be enabled for verified actions.'
}
}
end

def entitled?(_auth)
true
end

def exposed_config_parameters
[:ui_method_name]
end

def locked_attributes
%i[first_name last_name]
end

def locked_custom_fields
[]
end

def updateable_user_attrs
super + %i[first_name last_name]
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

ID_AUSTRIA_SETUP_PROC = lambda do |env|
IdIdAustria::IdAustriaOmniauth.new.omniauth_setup(AppConfiguration.instance, env)
end

Rails.application.config.middleware.use OmniAuth::Builder do
provider :openid_connect, setup: ID_AUSTRIA_SETUP_PROC, name: 'id_austria', issuer: IdIdAustria::IdAustriaOmniauth.new.method(:issuer)
end
23 changes: 23 additions & 0 deletions back/engines/commercial/id_id_austria/id_id_austria.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

$LOAD_PATH.push File.expand_path('lib', __dir__)

# Maintain your gem's version:
require 'id_id_austria/version'

# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = 'id_id_austria'
s.version = IdIdAustria::VERSION
s.summary = 'Verification using ID Austria'
s.authors = ['CitizenLab']
s.licenses = [Gem::Licenses::NONSTANDARD] # ['CitizenLab Commercial License V2']
s.files = Dir['{app,config,db,lib}/**/*', 'Rakefile', 'README.md']

s.add_dependency 'rails', '~> 7.0'
s.add_dependency 'verification'
s.add_dependency 'omniauth_openid_connect', '~> 0.7.1'

s.add_development_dependency 'rspec_api_documentation'
s.add_development_dependency 'rspec-rails'
end
7 changes: 7 additions & 0 deletions back/engines/commercial/id_id_austria/lib/id_id_austria.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

require 'id_id_austria/engine'

module IdIdAustria
# Your code goes here...
end
15 changes: 15 additions & 0 deletions back/engines/commercial/id_id_austria/lib/id_id_austria/engine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module IdIdAustria
class Engine < ::Rails::Engine
isolate_namespace IdIdAustria

config.to_prepare do
AppConfiguration::Settings.add_feature(IdIdAustria::FeatureSpecification)

id_austria = IdAustriaOmniauth.new
Verification.add_method(id_austria)
AuthenticationService.add_method('id_austria', id_austria)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module IdIdAustria
VERSION = '1.0.0'
end
Loading

0 comments on commit 863e074

Please sign in to comment.