Skip to content

Commit

Permalink
Support Dex local users (OSC#1335)
Browse files Browse the repository at this point in the history
* Support Dex local users

* Mount project root into dev container

* Ensure removal of bcrypt from Gemfile is reflected in Gemfile.lock

* Revert "Mount project root into dev container"

This reverts commit 4d319bf.

* Remove mock connector and only allow Dex local user if no connectors

* Only allow local users with Dex via --insecure flag

* Add insecure flag to package testing, needed to get local dex user

* Use --insecure flag for package tests too

* Fix how rubocop is required
  • Loading branch information
treydock authored Sep 15, 2021
1 parent 43d930c commit eee14f5
Show file tree
Hide file tree
Showing 15 changed files with 113 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Defaults:apache env_keep += "NGINX_STAGE_* OOD_*" \n\
apache ALL=(ALL) NOPASSWD: /opt/ood/nginx_stage/sbin/nginx_stage' >/etc/sudoers.d/ood

# run the OOD executables to setup the env
RUN /opt/ood/ood-portal-generator/sbin/update_ood_portal
RUN /opt/ood/ood-portal-generator/sbin/update_ood_portal --insecure
RUN /opt/ood/nginx_stage/sbin/update_nginx_stage
RUN echo $VERSION > /opt/ood/VERSION
# this one bc centos:8 doesn't generate localhost cert
Expand Down
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "rake"
gem "bcrypt"

group :test do
gem "rspec"
Expand Down
2 changes: 0 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ GEM
specs:
ansi (1.5.0)
ast (2.4.2)
bcrypt (3.1.16)
beaker (4.30.0)
beaker-hostgenerator
hocon (~> 1.0)
Expand Down Expand Up @@ -185,7 +184,6 @@ PLATFORMS
ruby

DEPENDENCIES
bcrypt
beaker
beaker-docker!
beaker-rspec
Expand Down
6 changes: 1 addition & 5 deletions docker/dev-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ sudo su root <<SETUP
cd $OOD_DEV_DIR
ln -s $APP_DEV_DIR gateway
/opt/ood/ood-portal-generator/sbin/update_ood_portal --force
if [ -n "$OOD_STATIC_USER" ] && [ -f "$OOD_STATIC_USER" ]; then
cat "$OOD_STATIC_USER" >> /etc/ood/dex/config.yaml
fi
/opt/ood/ood-portal-generator/sbin/update_ood_portal --force --insecure
SETUP

sudo runuser -u ondemand-dex /usr/sbin/ondemand-dex serve /etc/ood/dex/config.yaml &
Expand Down
2 changes: 1 addition & 1 deletion docker/launch-ood
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

set -e

/opt/ood/ood-portal-generator/sbin/update_ood_portal
/opt/ood/ood-portal-generator/sbin/update_ood_portal --force --insecure
runuser -u ondemand-dex /usr/sbin/ondemand-dex serve /etc/ood/dex/config.yaml &
/usr/sbin/httpd -DFOREGROUND
35 changes: 10 additions & 25 deletions lib/tasks/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace :dev do
require_relative 'build_utils'
require 'yaml'
require 'bcrypt'
include BuildUtils

def dev_container_name
Expand All @@ -14,6 +13,10 @@ def init_ood_portal
file = "#{config_directory}/ood_portal.yml"
return if File.exist?(file)

require 'io/console'
puts 'Enter password:'
plain_password = $stdin.noecho(&:gets).chomp

File.open(file, File::WRONLY|File::CREAT|File::EXCL) do |f|
f.write({
'servername': 'localhost',
Expand All @@ -25,35 +28,18 @@ def init_ood_portal
'type': 'mockCallback',
'id': 'mock',
'name': 'Mock'
}],
'static_passwords': [{
'email': "#{user.name}@localhost",
'password': plain_password,
'username': "#{user.name}",
'userID': "71e63e31-7af3-41d7-add2-575568f4525f"
}]
}
}.to_yaml)
end
end

def init_ctr_user
file = "#{config_directory}/static_user.yml"
return if File.exist?(file)

require 'io/console'
puts 'Enter password:'
plain_password = $stdin.noecho(&:gets).chomp
bcrypted = BCrypt::Password.create(plain_password)

content = <<~CONTENT
enablePasswordDB: true
staticPasswords:
- email: "#{user.name}@localhost"
hash: "#{bcrypted}"
username: "#{user.name}"
userID: "71e63e31-7af3-41d7-add2-575568f4525f"
CONTENT

File.open(file, File::WRONLY | File::CREAT | File::EXCL) do |f|
f.write(content)
end
end

def container_rt_args
podman_runtime? ? podman_rt_args : docker_rt_args
end
Expand Down Expand Up @@ -134,7 +120,6 @@ def dev_mounts
task :ensure_dev_files do
[
:init_ood_portal,
:init_ctr_user
].each do |initer|
send(initer)
end
Expand Down
1 change: 1 addition & 0 deletions ood-portal-generator/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'activesupport', '5.2.4.3'
gem 'dotenv', '~> 2.1'
gem "bcrypt"

group :development, :test do
gem "rake"
Expand Down
2 changes: 2 additions & 0 deletions ood-portal-generator/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ GEM
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
bcrypt (3.1.16)
climate_control (0.2.0)
concurrent-ruby (1.1.6)
diff-lcs (1.3)
Expand Down Expand Up @@ -36,6 +37,7 @@ PLATFORMS

DEPENDENCIES
activesupport (= 5.2.4.3)
bcrypt
climate_control
dotenv (~> 2.1)
rake
Expand Down
10 changes: 9 additions & 1 deletion ood-portal-generator/lib/ood_portal_generator/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def skip_exit
detailed_exitcodes ? 4 : 0
end

def insecure
@insecure.nil? ? false : @insecure
end

def apache
ENV['APACHE'] || (OodPortalGenerator.scl_apache? ? '/opt/rh/httpd24/root/etc/httpd/conf.d/ood-portal.conf' : '/etc/httpd/conf.d/ood-portal.conf')
end
Expand Down Expand Up @@ -140,7 +144,7 @@ def exit!(code)

def generate()
view = View.new(context)
dex = Dex.new(context, view)
dex = Dex.new(context, view, insecure)
rendered_template = view.render(template.read)
output.write(rendered_template)
if Dex.installed? && dex.enabled?
Expand Down Expand Up @@ -307,6 +311,10 @@ def add_shared_opt_parser_attrs(parser)
@template = v
end

parser.on("-i", "--insecure", TrueClass, "Generate insecure configs if configured") do |v|
@insecure = v
end

parser.on("-v", "--version", "Print current version") do
puts "version #{OodPortalGenerator::VERSION}"
exit
Expand Down
40 changes: 31 additions & 9 deletions ood-portal-generator/lib/ood_portal_generator/dex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
require 'active_support/core_ext'
require 'securerandom'
require 'fileutils'
require 'bcrypt'

module OodPortalGenerator
# A view class that renders a Dex configuration
class Dex
# @param opts [#to_h] the options describing the context used to render the Dex config
def initialize(opts = {}, view)
def initialize(opts = {}, view = nil, insecure = false)
opts = opts.to_h.deep_symbolize_keys
config = opts.fetch(:dex, {})
if config.nil? || config == false
Expand All @@ -34,14 +35,11 @@ def initialize(opts = {}, view)
@dex_config[:staticClients] = static_clients
@dex_config[:connectors] = connectors unless connectors.nil?
@dex_config[:oauth2] = { skipApprovalScreen: true }
@dex_config[:enablePasswordDB] = connectors.nil?
if connectors.nil?
@dex_config[:staticPasswords] = [{
email: 'ood@localhost',
hash: '$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W',
username: 'ood',
userID: '08a8684b-db88-4b73-90a9-3cd1661f5466',
}]
if insecure
@dex_config[:enablePasswordDB] = true
@dex_config[:staticPasswords] = static_passwords
else
@dex_config[:enablePasswordDB] = false
end
@dex_config[:frontend] = frontend
# Pass values back to main ood-portal.conf view
Expand Down Expand Up @@ -195,6 +193,30 @@ def connectors
@config.fetch(:connectors, nil)
end

def hash_password(password)
BCrypt::Password.create(password).to_s
end

def static_passwords
passwords = []
configured = @config.fetch(:static_passwords, nil)
if configured.nil?
default = {
email: 'ood@localhost',
hash: '$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W',
username: 'ood',
userID: '08a8684b-db88-4b73-90a9-3cd1661f5466',
}
passwords << default
else
configured.each do |conf|
conf[:hash] = hash_password(conf[:password]) if conf.key?(:password)
passwords << conf.except(:password)
end
end
passwords
end

def frontend
{
dir: '/usr/share/ondemand-dex/web',
Expand Down
25 changes: 25 additions & 0 deletions ood-portal-generator/spec/application_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,28 @@
described_class.generate()
end

it 'generates default dex configs with custom static password' do
allow(described_class).to receive(:insecure).and_return(true)
allow_any_instance_of(OodPortalGenerator::Dex).to receive(:hash_password).with('secret').and_return('$2a$12$iKLecAIN9MrxOZ0UltRb.OQOms/bgQbs5F.qCehq15oc3CvGFYzLy')
allow(described_class).to receive(:context).and_return({
dex: {
static_passwords: [{
'email' => 'username@localhost',
'password' => 'secret',
'username' => 'username',
'userID' => 'D642A38C-402F-47AA-879B-FEC95745F5BA',
}]
},
})
expected_rendered = read_fixture('ood-portal.conf.dex')
expect(described_class.output).to receive(:write).with(expected_rendered)
expected_dex_yaml = read_fixture('dex.yaml.static_passwords').gsub('/etc/ood/dex', config_dir)
expect(described_class.dex_output).to receive(:write).with(expected_dex_yaml)
described_class.generate()
end

it 'generates full dex configs with SSL using proxy' do
allow(described_class).to receive(:insecure).and_return(true)
allow(described_class).to receive(:context).and_return({
servername: 'example.com',
proxy_server: 'example-proxy.com',
Expand All @@ -175,6 +196,7 @@
end

it 'generates full dex configs with SSL' do
allow(described_class).to receive(:insecure).and_return(true)
allow(described_class).to receive(:context).and_return({
servername: 'example.com',
port: '443',
Expand All @@ -192,6 +214,7 @@
end

it 'generates full dex configs with SSL and multiple redirect URIs' do
allow(described_class).to receive(:insecure).and_return(true)
allow(described_class).to receive(:context).and_return({
servername: 'example.com',
port: '443',
Expand All @@ -214,6 +237,7 @@

it 'generates custom dex configs' do
with_modified_env CONFIG: 'spec/fixtures/ood_portal.dex.yaml' do
allow(described_class).to receive(:insecure).and_return(true)
expected_dex_yaml = read_fixture('dex.custom.yaml').gsub('/etc/ood/dex', config_dir)
expect(described_class.dex_output).to receive(:write).with(expected_dex_yaml)
described_class.generate()
Expand Down Expand Up @@ -287,6 +311,7 @@
end

it 'generates Dex config using secure secret' do
allow(described_class).to receive(:insecure).and_return(true)
secret = Tempfile.new('secret')
File.write(secret.path, "supersecret\n")
allow(described_class).to receive(:context).and_return({
Expand Down
7 changes: 1 addition & 6 deletions ood-portal-generator/spec/fixtures/dex.yaml.default
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ staticClients:
secret: 83bc78b7-6f5e-4010-9d80-22f328aa6550
oauth2:
skipApprovalScreen: true
enablePasswordDB: true
staticPasswords:
- email: ood@localhost
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: ood
userID: '08a8684b-db88-4b73-90a9-3cd1661f5466'
enablePasswordDB: false
frontend:
dir: "/usr/share/ondemand-dex/web"
theme: ondemand
27 changes: 27 additions & 0 deletions ood-portal-generator/spec/fixtures/dex.yaml.static_passwords
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
issuer: http://example.com:5556
storage:
type: sqlite3
config:
file: "/etc/ood/dex/dex.db"
web:
http: 0.0.0.0:5556
telemetry:
http: 0.0.0.0:5558
staticClients:
- id: example.com
redirectURIs:
- http://example.com/oidc
name: OnDemand
secret: 83bc78b7-6f5e-4010-9d80-22f328aa6550
oauth2:
skipApprovalScreen: true
enablePasswordDB: true
staticPasswords:
- email: username@localhost
username: username
userID: D642A38C-402F-47AA-879B-FEC95745F5BA
hash: "$2a$12$iKLecAIN9MrxOZ0UltRb.OQOms/bgQbs5F.qCehq15oc3CvGFYzLy"
frontend:
dir: "/usr/share/ondemand-dex/web"
theme: ondemand
1 change: 0 additions & 1 deletion packaging/ondemand.spec
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ set -x
set -e
export GEM_HOME=$(pwd)/gems-build
export GEM_PATH=$(pwd)/gems-build:$GEM_PATH
bundle install
rake --trace -mj%{ncpus} build
EOS

Expand Down
5 changes: 4 additions & 1 deletion spec/e2e/e2e_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ def install_ondemand
end
on hosts, "#{config_manager} --save --setopt ondemand-web.exclude='ondemand ondemand-gems* ondemand-selinux'"
install_packages(['ondemand', 'ondemand-dex', 'ondemand-selinux'])
# Avoid 'update_ood_portal --rpm' so that --insecure can be used
on hosts, "sed -i 's|--rpm|--rpm --insecure|g' /etc/systemd/system/#{apache_service}.service.d/ood-portal.conf"
on hosts, "systemctl daemon-reload"
end
end

Expand All @@ -131,7 +134,7 @@ def upload_portal_config(file)
end

def update_ood_portal
on hosts, '/opt/ood/ood-portal-generator/sbin/update_ood_portal'
on hosts, '/opt/ood/ood-portal-generator/sbin/update_ood_portal --insecure'
end

def restart_apache
Expand Down

0 comments on commit eee14f5

Please sign in to comment.