#!/usr/bin/env python # coding=utf-8 import time, os from datetime import datetime, timedelta import pprint import logging as log import traceback import yaml, json import psycopg2 from admin.lib.mysql import Mysql from admin.lib.keycloak_client import KeycloakClient import string, random app={} app['config']={} class WordpressSaml(): def __init__(self): self.url="http://isard-sso-keycloak:8080/auth/" self.username=os.environ['KEYCLOAK_USER'] self.password=os.environ['KEYCLOAK_PASSWORD'] self.realm='master' self.verify=True ready=False while not ready: try: self.db=Mysql('isard-apps-mariadb','wordpress','root',os.environ['MARIADB_PASSWORD']) ready=True except: log.warning('Could not connect to wordpress database. Retrying...') time.sleep(2) log.info('Connected to wordpress database.') ready=False while not ready: try: with open(os.path.join("./saml_certs/public.cert"),"r") as crt: app['config']['PUBLIC_CERT_RAW']=crt.read() app['config']['PUBLIC_CERT']=self.cert_prepare(app['config']['PUBLIC_CERT_RAW']) ready=True except IOError: log.warning('Could not get public certificate to be used in wordpress. Retrying...') log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') time.sleep(2) except: log.error(traceback.format_exc()) log.info('Got moodle srt certificate to be used in wordpress.') ready=False while not ready: try: with open(os.path.join("./saml_certs/private.key"),"r") as pem: app['config']['PRIVATE_KEY']=self.cert_prepare(pem.read()) ready=True except IOError: log.warning('Could not get private key to be used in wordpress. Retrying...') log.warning(' You should generate them: /admin/saml_certs # openssl req -nodes -new -x509 -keyout private.key -out public.cert') time.sleep(2) log.info('Got moodle pem certificate to be used in wordpress.') # ## This seems related to the fact that the certificate generated the first time does'nt work. # ## And when regenerating the certificate de privatekeypass seems not to be used and instead it # ## will use always this code as filename: 0f635d0e0f3874fff8b581c132e6c7a7 # ## As this bug I'm not able to solve, the process is: # ## 1.- Bring up moodle and regenerate certificates on saml2 plugin in plugins-authentication # ## 2.- Execute this script # ## 3.- Cleanup all caches in moodle (Development tab) # # with open(os.path.join("./moodledata/saml2/"+os.environ['NEXTCLOUD_SAML_PRIVATEKEYPASS'].replace("moodle."+os.environ['DOMAIN'],'')+'.idp.xml'),"w") as xml: # # xml.write(self.parse_idp_metadata()) # with open(os.path.join("./moodledata/saml2/0f635d0e0f3874fff8b581c132e6c7a7.idp.xml"),"w") as xml: # xml.write(self.parse_idp_metadata()) try: self.reset_saml_certs() except: print(traceback.format_exc()) print('Error resetting saml certs on wordpress') try: self.set_wordpress_saml_plugin_certs() except: print(traceback.format_exc()) print('Error adding saml on wordpress') # SAML clients don't work well with composite roles so disabling and adding on realm # self.add_client_roles() # def activate_saml_plugin(self): # ## After you need to purge moodle caches: /var/www/html # php admin/cli/purge_caches.php # return self.db.update("""UPDATE "mdl_config" SET value = 'email,saml2' WHERE "name" = 'auth'""") # def get_privatekey_pass(self): # return self.db.select("""SELECT * FROM "mdl_config" WHERE "name" = 'siteidentifier'""")[0][2] def connect(self): self.keycloak= KeycloakClient(url=self.url, username=self.username, password=self.password, realm=self.realm, verify=self.verify) def cert_prepare(self,cert): return ''.join(cert.split('-----')[2].splitlines()) def parse_idp_cert(self): self.connect() rsa=self.keycloak.get_server_rsa_key() self.keycloak=None return rsa['certificate'] def set_wordpress_saml_plugin_certs(self): # ('active_plugins', 'a:2:{i:0;s:33:\"edwiser-bridge/edwiser-bridge.php\";i:1;s:17:\"onelogin_saml.php\";}', 'yes'), self.db.update("""INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('onelogin_saml_idp_x509cert', '%s', 'yes'), ('onelogin_saml_advanced_settings_sp_x509cert', '%s', 'yes'), ('onelogin_saml_advanced_settings_sp_privatekey', '%s', 'yes');""" % (self.parse_idp_cert(),app['config']['PUBLIC_CERT'],app['config']['PRIVATE_KEY'])) def reset_saml_certs(self): self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_idp_x509cert'""") self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_x509cert'""") self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_privatekey'""") nw=WordpressSaml()