From 8ed157c256f13ccc31a543e6f834b8442716a0b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johan=20Bj=C3=B6rklund?= <bjorklund@sunet.se>
Date: Wed, 20 Nov 2024 12:40:41 +0100
Subject: [PATCH] Trying to get SSO class work with both docker and apache2

---
 .../etc/puppet/modules/soc/manifests/sso.pp   | 188 ++++++++++--------
 1 file changed, 105 insertions(+), 83 deletions(-)

diff --git a/global/overlay/etc/puppet/modules/soc/manifests/sso.pp b/global/overlay/etc/puppet/modules/soc/manifests/sso.pp
index ead316d..1b01367 100644
--- a/global/overlay/etc/puppet/modules/soc/manifests/sso.pp
+++ b/global/overlay/etc/puppet/modules/soc/manifests/sso.pp
@@ -1,5 +1,4 @@
-#
-# General SSO documentation: https://wiki.sunet.se/x/sZGLBg
+# General SSO class for SOC. Based on cnaas::sso
 #
 # @param hostname FQDN of the host this is running on.
 #
@@ -21,50 +20,67 @@
 #   cases where the service we reverse proxy for can't create new accounts automatically.
 #   We use this only for Graylog at the time of writing.
 #
-# @param swamid_testing Set this to true if your SP is registered in swamid-testing.
+# @param satos
+#   If we have a satosa proxy or not, default true.
+#
+# @param proxy
+#   Hostname of the satosa proxy.
+#
+# @param entityID
+#   EntityID of the satosa proxy, must not be the same as the proxy hostname.
+#   Default set to value of proxy.
 
 class soc::sso(
-  $hostname,
-  $email,
-  $service_endpoint,
-  $groups = ['PLACEHOLDER'],
-  $passthrough = [],
-  $x_remote_user = false,
-  $swamid_testing = false,
-  $single_user = false,
-  $satosa = true,
-  $satosa_certbot = false,
-  $translog = 'INFO',
-  $proxy = 'https://shared-sso-proxy1.cert.sunet.se/idp',
-  $entityID = $proxy,
-  $norpan = false,
+  String  $ssotype          = "docker",
+  String  $hostname         = undef,
+  String  $email            = "cert@cert.sunet.se",
+  String  $service_endpoint = undef,
+  Array   $groups           = ['PLACEHOLDER'],
+  Array   $passthrough      = [],
+  Boolean $x_remote_user    = false,
+  Boolean $single_user      = false,
+  Boolean $satosa           = true,
+  Boolean $satosa_certbot   = false,
+  String  $translog         = 'INFO',
+  String  $proxy            = 'https://shared-sso-proxy1.cert.sunet.se/idp',
+  Strnng  $entityID         = $proxy,
 ) {
 
-  file { '/opt/sso':
-    ensure => directory,
+  if $ssotype == "docker" { 
+    file { '/opt/sso':
+      ensure => directory,
+    }
+
+    #
+    # Apache files
+    #
+
+    file { '/opt/sso/apache':
+      ensure => directory,
+    }
+
+    file { '/opt/sso/apache/site.conf':
+      ensure  => file,
+      content => template('soc/sso/apache-site.conf.erb'),
+    }
+
+    # SSL defaults copied from certbot:
+    # https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf
+    file { '/opt/sso/apache/ssl.conf':
+      ensure  => file,
+      content => file('soc/sso/apache-ssl.conf'),
+    }
   }
 
-  #
-  # Apache files
-  #
-
-  file { '/opt/sso/apache':
-    ensure => directory,
+  if $ssotype == 'docker' {
+    $apache_groups = '/opt/sso/apache/groups.txt'
+  } elsif $ssotype == 'apache' {
+    $apache_groups = '/etc/apache2/groups.txt'
+  } else {
+    $apache_groups = '/tmp/groups.txt'
   }
 
-  file { '/opt/sso/apache/site.conf':
-    ensure  => file,
-    content => template('soc/sso/apache-site.conf.erb'),
-  }
-
-  # SSL defaults copied from certbot:
-  # https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf
-  file { '/opt/sso/apache/ssl.conf':
-    ensure  => file,
-    content => file('soc/sso/apache-ssl.conf'),
-  }
-
-  file { '/opt/sso/apache/groups.txt':
+  file { $apache_groups:
     ensure  => file,
     content => template('soc/sso/apache-groups.txt.erb')
   }
@@ -73,60 +89,63 @@ class soc::sso(
   # Shibboleth files
   #
 
-  file { '/opt/sso/shibboleth':
-    ensure => directory,
+  if $ssotype == 'apache' {
+    pakage { ['apache2', 'libapache2-mod-shib', 'shibboleth-sp-utils']:
+      ensure => present
+    }
+
+    $shibbase = '/etc/shibboleth'
+  } elsif $ssotype == 'docker' {
+    $shibbase = '/opt/sso/shibboleth'
+
+    file { $shibbase:
+      ensure => directory,
+    }
   }
 
-  file { '/opt/sso/shibboleth/shibboleth2.xml':
+  file { "${shibbase}/shibboleth2.xml":
     ensure  => file,
     content => template('soc/sso/shibboleth2.xml.erb'),
   }
 
-  file { '/opt/sso/shibboleth/shibd.logger':
+  file { "${shibbase}/shibd.logger":
     ensure  => file,
     content => template('soc/sso/shibd.logger.erb'),
   }
 
-  file { '/opt/sso/shibboleth/attribute-map.xml':
+  file { "${shibbase}/attribute-map.xml":
     ensure  => file,
     content => file('soc/sso/attribute-map.xml'),
   }
 
-  file { '/opt/sso/shibboleth/md-signer2.crt':
+  file { "${shibbase}/md-signer2.crt":
     ensure  => file,
     content => file('soc/sso/md-signer2.crt'),
   }
+
   if $satosa {
-    if $norpan {
-        file { '/opt/sso/shibboleth/frontend.xml':
-          ensure  => file,
-          content => file('soc/sso/frontend_norpan.xml'),
-        }
-    } else {
-        file { '/opt/sso/shibboleth/frontend.xml':
-          ensure  => file,
-          content => file('soc/sso/frontend.xml'),
-        }
+    file { "${shibbase}/frontend.xml":
+      ensure  => file,
+      content => file('soc/sso/frontend.xml'),
     }
 
-    file { '/opt/sso/shibboleth/attribute-policy.xml':
+    file { "${shibbase}/attribute-policy.xml":
       ensure  => file,
       content => file('soc/sso/attribute-policy.xml'),
     }
 
     if lookup('sso_sp_key', undef, undef, undef) != undef {
-      sunet::snippets::secret_file { '/opt/sso/shibboleth/sp-key.pem':
+      sunet::snippets::secret_file { "${shibbase}/sp-key.pem":
         hiera_key => 'sso_sp_key'
       }
     } else {
       sunet::snippets::keygen {'shib_cert':
-        key_file  => '/opt/sso/shibboleth/sp-key.pem',
-        cert_file => '/opt/sso/shibboleth/sp-cert.pem'
+        key_file  => "${shibbase}/sp-key.pem",
+        cert_file => "${shibbase}/sp-cert.pem"
       }
     }
-
   } else {
-    sunet::snippets::secret_file { '/opt/sso/shibboleth/sp-key.pem':
+    sunet::snippets::secret_file { "${shibbase}/sp-key.pem":
       hiera_key => 'sso_sp_key'
     }
   }
@@ -162,33 +181,36 @@ class soc::sso(
   # Docker
   #
 
-  exec {"Create Docker network \"sso\" to talk to service":
-    # We OR with true to ignore errors, since the network often already exists.
-    # We specify a subnet so that services which have the option/requirement can
-    # specify this subnet as source of trusted proxies. This is used in Graylog,
-    # for example; see setting "trusted_proxies".
-    command => 'docker network create sso --subnet 172.29.0.0/24 || true'
-  }
+  if $ssotype == 'docker' {
 
-  file { '/opt/sso/docker-compose.yml':
-    ensure  => file,
-    mode    => '0600',
-    content => template('soc/sso/docker-compose.yml.erb'),
-  }
+    exec {"Create Docker network \"sso\" to talk to service":
+      # We OR with true to ignore errors, since the network often already exists.
+      # We specify a subnet so that services which have the option/requirement can
+      # specify this subnet as source of trusted proxies. This is used in Graylog,
+      # for example; see setting "trusted_proxies".
+      command => 'docker network create sso --subnet 172.29.0.0/24 || true'
+    }
 
-  sunet::docker_compose_service { 'sso':
-    description  =>  '',
-    compose_file => '/opt/sso/docker-compose.yml',
-  }
+    file { '/opt/sso/docker-compose.yml':
+      ensure  => file,
+      mode    => '0600',
+      content => template('soc/sso/docker-compose.yml.erb'),
+    }
 
-  #
-  # NFT Rules
-  #
+    sunet::docker_compose_service { 'sso':
+      description  =>  '',
+      compose_file => '/opt/sso/docker-compose.yml',
+    }
 
-  sunet::nftables::docker_expose { 'apache_sso_https' :
-    allow_clients => ['0.0.0.0/0'],
-    port          => 443,
-    iif           => 'ens3',
+    #
+    # NFT Rules
+    #
+
+    sunet::nftables::docker_expose { 'apache_sso_https' :
+      allow_clients => ['0.0.0.0/0'],
+      port          => 443,
+      iif           => 'ens3',
+    }
   }
 
 }