Skip to content

Commit

Permalink
Plugin support (#49)
Browse files Browse the repository at this point in the history
* Adapt server.rb to Ruby OpenSSL changes

* Code refactoring

* Further separation between Plugins and Core functionality

* Further refactoring

* Admin & Selfservice APIs are now Plugins

* Verbose OAuth Error Messages

* First Claim Mapper Plugin

* Plugins now have their own config

* Main configuration file simplification

* Clarifications, File removals, Rubocop

* Rewrite Main README

* Fixed tests

* Better handling of the OMEJDN_ADMIN environment variable
  • Loading branch information
bellebaum authored Feb 8, 2022
1 parent 5ec7a60 commit 49f3996
Show file tree
Hide file tree
Showing 37 changed files with 1,475 additions and 1,646 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/keys/*
/keys/omejdn/*
/keys/clients/*
!/keys/.gitkeep
/config/*
/omejdn_priv.*
13 changes: 5 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ GEM
haml (5.2.2)
temple (>= 0.8.0)
tilt
i18n (1.8.11)
i18n (1.9.1)
concurrent-ruby (~> 1.0)
json (2.6.1)
json-jwt (1.13.0)
Expand All @@ -47,12 +47,12 @@ GEM
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-core (3.10.2)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
rspec-expectations (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
rspec-mocks (3.10.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.3)
Expand Down Expand Up @@ -87,9 +87,6 @@ GEM
webrick (1.7.0)

PLATFORMS
ruby
universal-darwin-20
x86_64-darwin-19
x86_64-linux

DEPENDENCIES
Expand All @@ -115,4 +112,4 @@ DEPENDENCIES
webrick

BUNDLED WITH
2.2.26
2.3.6
376 changes: 140 additions & 236 deletions README.md

Large diffs are not rendered by default.

134 changes: 73 additions & 61 deletions config/omejdn.yml
Original file line number Diff line number Diff line change
@@ -1,68 +1,80 @@
---
# The Omejdn host
host: http://localhost:4567
# A base path
path_prefix: ''
# Which address to bind to
bind_to: 0.0.0.0
# Allow Origin Header field
allow_origin: "*"
## Welcome to Omejdn.
##
## Please have a look at the documentation first, if you have any questions.
## This is the main configuration file.
## Once you start Omejdn for the first time, the comments here will disappear
## and all non-specified values will be filled in with their default values.
## Omejdn is aware of any changes to this file and will always use the new configuration.

# Set this to `production` to disable debug output
app_env: debug
## Omejdn's Issuer Identifier.
## Please ensure that, assuming the issuer id is https://example.org/some/path,
## Omejdn's /.well-known/oauth-authorization-server endpoint is reachable as
## https://example.org/.well-known/oauth-authorization-server/some/path (per RFC 8414).
## To support dynamic OpenID clients, the same endpoint should be available as
## https://example.org/.well-known/openid-configuration/some/path and
## https://example.org/some/path/.well-known/openid-configuration for backwards compatibility.
#issuer: https://localhost:4567

# Enable OpenID funtionality
openid: true
## The URL where Omejdn's endpoints are mounted, in case it differs from `issuer`
#front_url: https://localhost:4567

# Overwrite the aud claim value to accept in client's bearer tokens (defaults to host)
#accept_audience:
## IP and (optionally) port to bind to
## Changes only apply after a restart
#bind_to: 0.0.0.0:4567

# Token signing keys, certificates and default values
# jwks_additions may be used to specify additional certificates and keys to be published in the JWKS
token:
expiration: 3600
signing_key: omejdn_priv.pem
jwks_additions:
- omejdn_priv.pem.cert
algorithm: RS256
audience: TestServer
issuer: http://localhost:4567
id_token:
expiration: 3600
signing_key: omejdn_priv.pem
jwks_additions:
- omejdn_priv.pem.cert
algorithm: RS256
issuer: http://localhost:4567
## CORS allow origin response value
## Changes only apply after a restart
#allow_origin: "*"

# Enabled user backends (can be configured in user_backend.yml)
user_backend:
- yaml
# Default user backend
user_backend_default: yaml
## Application Environment. Set to production to supress debug output
#app_env: debug

# User Selfservice API
user_selfservice:
enabled: true
allow_deletion: true
allow_password_change: true
editable_attributes:
- name
- family_name
- given_name
- middle_name
- nickname
- preferred_username
- profile
- picture
- website
- gender
- birthdate
- zoneinfo
- locale
- updated_at
- email
- email_verified
- address
- phone_number
- phone_number_verified
## Enable OpenID functionality (requires at least one user_db plugin)
#openid: false

## The default user_db plugin to use
#user_backend_default: 'yaml'

## Default `aud` value in tokens
#default_audience: ''

## Accept different values as `aud`
#accept_audience: https://localhost:4567

## Set expiration time and algorithm for each token
## Does not affect already issued tokens
#access_token:
# expiration: 3600
# algorithm: RS256
#id_token:
# expiration: 3600
# algorithm: RS256

## Plugins enable additional functionality.
## See the respective plugin for configuration options.
## Loading and unloading of plugins requires a restart
#plugins:
# user_db:
# yaml:
# location: config/users.yml
# sqlite:
# location: config/users.db
# ldap:
# host: localhost
# port: 636
# base_dn: ''
# uid_key: dn
# api:
# admin_v1:
# user_selfservice_v1:
# allow_deletion: true
# allow_password_change: true
# editable_attributes:
# - email
# - address
# - phone_number
# claim_mapper:
# attribute:
# skip_access_token: false
# skip_id_token: false
25 changes: 0 additions & 25 deletions config/user_backend.yml

This file was deleted.

19 changes: 0 additions & 19 deletions config/users.yml

This file was deleted.

File renamed without changes.
Empty file added keys/omejdn/.gitkeep
Empty file.
23 changes: 0 additions & 23 deletions lib/claim_mapper.rb

This file was deleted.

23 changes: 13 additions & 10 deletions lib/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ def self.load_clients
clients
end

def self.from_json(json)
def self.from_dict(json)
client = Client.new
client.apply_values(json)
client
end

# Decodes a JWT and optionally finds the issuing client
def self.decode_jwt(jwt, client = nil)
def self.decode_jwt(jwt, verify_aud, client = nil)
jwt_dec, jwt_hdr = JWT.decode(jwt, nil, false) # Decode without verify

return nil if jwt['sub'] && jwt_dec['sub'] != jwt_dec['iss']
return nil unless %w[RS256 RS512 ES256 ES512].include? jwt_hdr['alg']
raise 'Not self-issued' if jwt['sub'] && jwt_dec['sub'] != jwt_dec['iss']
raise 'Algorithm unsupported' unless %w[RS256 RS512 ES256 ES512].include? jwt_hdr['alg']

client_id = jwt_dec['iss'] || jwt_dec['sub'] || jwt_dec['client_id']
client ||= find_by_id client_id
Expand All @@ -61,24 +61,23 @@ def self.decode_jwt(jwt, client = nil)

aud = Config.base_config['accept_audience']
jwt_dec, = JWT.decode jwt, client.certificate&.public_key, true,
{ nbf_leeway: 30, aud: aud, verify_aud: true, algorithm: jwt_hdr['alg'] }
{ nbf_leeway: 30, aud: aud, verify_aud: verify_aud, algorithm: jwt_hdr['alg'] }
[jwt_dec, client]
rescue StandardError => e
puts "Error decoding JWT #{jwt}: #{e}"
nil
raise OAuthError.new 'invalid_client', "Error decoding JWT: #{e}"
end

def to_dict
result = {
{
'client_id' => @client_id,
'name' => @name,
'redirect_uri' => @redirect_uri,
'request_uri' => @request_uri,
'allowed_scopes' => @allowed_scopes,
'allowed_resources' => @allowed_resources,
'attributes' => @attributes
}
result.compact!
}.compact
end

def filter_scopes(scopes)
Expand Down Expand Up @@ -109,7 +108,7 @@ def verify_redirect_uri(uri, require_existence)
end

def certificate_file
"keys/#{Base64.urlsafe_encode64(@client_id)}.cert"
"keys/clients/#{Base64.urlsafe_encode64(@client_id)}.cert"
end

def certificate
Expand All @@ -132,4 +131,8 @@ def certificate=(new_cert)
end
File.write(filename, new_cert)
end

def ==(other)
client_id == other.client_id
end
end
12 changes: 1 addition & 11 deletions lib/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
require 'yaml'
OMEJDN_CONFIG_DIR = 'config'
OMEJDN_BASE_CONFIG_FILE = "#{OMEJDN_CONFIG_DIR}/omejdn.yml"
OMEJDN_USER_CONFIG_FILE = "#{OMEJDN_CONFIG_DIR}/users.yml"
OMEJDN_CLIENT_CONFIG_FILE = "#{OMEJDN_CONFIG_DIR}/clients.yml"
OMEJDN_USER_BACKEND_CONFIG = "#{OMEJDN_CONFIG_DIR}/user_backend.yml"
OMEJDN_OAUTH_PROVIDER_CONFIG = "#{OMEJDN_CONFIG_DIR}/oauth_providers.yml"
SCOPE_DESCRIPTION_CONFIG = "#{OMEJDN_CONFIG_DIR}/scope_description.yml"
SCOPE_MAPPING_CONFIG = "#{OMEJDN_CONFIG_DIR}/scope_mapping.yml"
Expand All @@ -20,7 +18,7 @@ def self.write_config(file, data)
end

def self.read_config(file, fallback)
YAML.safe_load (File.read file), fallback: fallback, filename: file
(YAML.safe_load (File.read file), fallback: fallback, filename: file) || fallback
end

def self.client_config
Expand All @@ -44,14 +42,6 @@ def self.base_config=(config)
write_config OMEJDN_BASE_CONFIG_FILE, config.to_yaml
end

def self.user_backend_config
read_config OMEJDN_USER_BACKEND_CONFIG, {}
end

def self.user_backend_config=(config)
write_config OMEJDN_USER_BACKEND_CONFIG, config.to_yaml
end

def self.oauth_provider_config
read_config OMEJDN_OAUTH_PROVIDER_CONFIG, []
end
Expand Down
Loading

0 comments on commit 49f3996

Please sign in to comment.