Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jans-linux-setup): gluu/flex casa installer #5590

Merged
merged 3 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions docs/admin/install/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,25 @@ To check usage of this script run help command
python3 /opt/jans/jans-setup/setup.py --help

usage: jans_setup.py [-h] [--version] [-c] [-d D] [-f F] [-n] [-N] [-u] [-csx]
[-remote-rdbm {mysql,pgsql,spanner} | -local-rdbm {mysql,pgsql}] [-ip-address IP_ADDRESS]
[-host-name HOST_NAME] [-org-name ORG_NAME] [-email EMAIL] [-city CITY] [-state STATE] [-country COUNTRY]
[-rdbm-user RDBM_USER] [-rdbm-password RDBM_PASSWORD] [-rdbm-port RDBM_PORT] [-rdbm-db RDBM_DB]
[-rdbm-host RDBM_HOST] [--reset-rdbm-db] [--shell] [--dump-config-on-error] [--no-progress]
[-admin-password ADMIN_PASSWORD] [-jans-max-mem JANS_MAX_MEM] [-properties-password PROPERTIES_PASSWORD]
[-approved-issuer APPROVED_ISSUER] [--force-download] [--download-exit] [-jans-app-version JANS_APP_VERSION]
[-jans-build JANS_BUILD] [-setup-branch SETUP_BRANCH] [--disable-config-api-security] [--cli-test-client]
[--import-ldif IMPORT_LDIF] [-enable-script ENABLE_SCRIPT] [-disable-script DISABLE_SCRIPT] [-disable-selinux]
[-stm] [-w] [-t] [-x] [--allow-pre-released-features] [--listen_all_interfaces]
[-remote-rdbm {mysql,pgsql,spanner} | -local-rdbm {mysql,pgsql}] [-ip-address IP_ADDRESS] [-host-name HOST_NAME]
[-org-name ORG_NAME] [-email EMAIL] [-city CITY] [-state STATE] [-country COUNTRY] [-rdbm-user RDBM_USER]
[-rdbm-password RDBM_PASSWORD] [-rdbm-port RDBM_PORT] [-rdbm-db RDBM_DB] [-rdbm-host RDBM_HOST] [--reset-rdbm-db]
[--shell] [--dump-config-on-error] [--no-progress] [-admin-password ADMIN_PASSWORD] [-jans-max-mem JANS_MAX_MEM]
[-properties-password PROPERTIES_PASSWORD] [-approved-issuer APPROVED_ISSUER] [--force-download] [--download-exit]
[-jans-app-version JANS_APP_VERSION] [-jans-build JANS_BUILD] [-setup-branch SETUP_BRANCH]
[--disable-config-api-security] [--cli-test-client] [--import-ldif IMPORT_LDIF] [-enable-script ENABLE_SCRIPT]
[-disable-script DISABLE_SCRIPT] [-stm] [-w] [-t] [-x] [--allow-pre-released-features] [--listen_all_interfaces]
[--remote-ldap | --disable-local-ldap] [--remote-couchbase] [--local-couchbase]
[-couchbase-admin-user COUCHBASE_ADMIN_USER] [-couchbase-admin-password COUCHBASE_ADMIN_PASSWORD]
[-couchbase-bucket-prefix COUCHBASE_BUCKET_PREFIX] [-couchbase-hostname COUCHBASE_HOSTNAME] [--no-data]
[--no-jsauth] [-ldap-admin-password LDAP_ADMIN_PASSWORD] [--no-config-api] [--no-scim] [--no-fido2]
[--install-eleven] [--install-cache-refresh] [--load-config-api-test] [-config-patch-creds CONFIG_PATCH_CREDS]
[-spanner-project SPANNER_PROJECT] [-spanner-instance SPANNER_INSTANCE] [-spanner-database SPANNER_DATABASE]
[--install-eleven] [--install-jans-link] [--install-casa] [--load-config-api-test]
[-config-patch-creds CONFIG_PATCH_CREDS] [-spanner-project SPANNER_PROJECT] [-spanner-instance SPANNER_INSTANCE]
[-spanner-database SPANNER_DATABASE]
[-spanner-emulator-host SPANNER_EMULATOR_HOST | -google-application-credentials GOOGLE_APPLICATION_CREDENTIALS]
[-test-client-id TEST_CLIENT_ID] [-test-client-pw TEST_CLIENT_PW]
[-test-client-redirect-uri TEST_CLIENT_REDIRECT_URI] [--test-client-trusted]```
[-test-client-redirect-uri TEST_CLIENT_REDIRECT_URI] [--test-client-trusted]
```

Use this script to configure your Jans Server and to add initial data required for oxAuth and oxTrust to start. If setup.properties is found in this folder, these properties will automatically be used instead of the interactive setup.

Expand Down Expand Up @@ -160,6 +161,8 @@ Below are the optional arguments:
| --no-scim | Do not install Scim Server |
| --no-fido2 | Do not install Fido2 Server |
| --install-eleven | Install Eleven Server |
| --install-jans-link | Install Link Server |
| --install-casa | Install Gluu/Flex Casa Server |
| --load-config-api-test | Load Config Api Test Data |
| --install-cache-refresh | Install Cache Refresh Server |
| -config-patch-creds CONFIG_PATCH_CREDS | password:username for downloading auto test ciba password |
Expand Down
4 changes: 3 additions & 1 deletion jans-linux-setup/jans_setup/app_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@
"PYGMENTS": "https://github.com/pygments/pygments/archive/refs/tags/2.13.0.zip",
"CRYPTOGRAPHY": "https://files.pythonhosted.org/packages/20/8b/66600f5851ec7893ace9b74445d7eaf3499571b347e339d18c76c876b0f9/cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"TWILIO_MAVEN": "https://repo1.maven.org/maven2/com/twilio/sdk/twilio/",
"TWILIO_VERSION": "7.17.0"
"TWILIO_VERSION": "7.17.0",
"GLUU_MAVEN": "https://maven.gluu.org",
"CASA_VERSION": "5.0.0-SNAPSHOT"
}
8 changes: 8 additions & 0 deletions jans-linux-setup/jans_setup/jans_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ def ami_packaged():
from setup_app.installers.fido import FidoInstaller
from setup_app.installers.eleven import ElevenInstaller
from setup_app.installers.jans_link import JansLinkInstaller
from setup_app.installers.casa import CasaInstaller


from setup_app.installers.config_api import ConfigApiInstaller
from setup_app.installers.jans_cli import JansCliInstaller
Expand Down Expand Up @@ -251,6 +253,7 @@ def ami_packaged():
fidoInstaller = FidoInstaller()
scimInstaller = ScimInstaller()
elevenInstaller = ElevenInstaller()
casa_installer = CasaInstaller()
jans_link_installer = JansLinkInstaller()

jansCliInstaller = JansCliInstaller()
Expand Down Expand Up @@ -429,6 +432,11 @@ def do_installation():
not Config.installed_instance and Config.get(elevenInstaller.install_var)):
elevenInstaller.start_installation()

if (Config.installed_instance and casa_installer.install_var in Config.addPostSetupService) or (
not Config.installed_instance and Config.get(casa_installer.install_var)):
casa_installer.start_installation()


if (Config.installed_instance and jans_link_installer.install_var in Config.addPostSetupService) or (
not Config.installed_instance and Config.get(jans_link_installer.install_var)):
jans_link_installer.start_installation()
Expand Down
2 changes: 1 addition & 1 deletion jans-linux-setup/jans_setup/setup_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def progress(self, service_name, msg, incr=False):
self.install_scim_server = True
self.installFido2 = True
self.install_config_api = True
self.installCasa = False
self.install_casa = False
self.installOxd = False
self.installEleven = False
self.install_jans_cli = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"memory": {
"max_allowed_mb": 1024,
"jvm_heap_ration": 0.7,
"ratio": 0.15
"ratio": 0.10
},
"jetty": {
"modules": "server,deploy,resources,http,http-forwarded,console-capture,jsp,websocket"
Expand All @@ -51,7 +51,7 @@
"memory": {
"max_allowed_mb": 1024,
"jvm_heap_ration": 0.7,
"ratio": 0.15
"ratio": 0.10
},
"jetty": {
"modules": "server,deploy,resources,http,http-forwarded,console-capture,jsp,websocket"
Expand All @@ -70,5 +70,18 @@
},
"installed": false,
"name": "jans-link"
}
},
"casa": {
"memory": {
"max_allowed_mb": 1024,
"metaspace_mb": 128,
"jvm_heap_ration": 0.7,
"ratio": 0.1
},
"jetty": {
"modules": "server,deploy,resources,http,http-forwarded,console-capture,jsp,cdi-decorate"
},
"installed": false,
"name": "casa"
}
}
170 changes: 170 additions & 0 deletions jans-linux-setup/jans_setup/setup_app/installers/casa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import os
import re
import glob
import ssl
import time
import json

from xml.etree import ElementTree

from setup_app import paths
from setup_app.config import Config
from setup_app.pylib.ldif4.ldif import LDIFWriter
from setup_app.static import AppType, InstallOption, SetupProfiles
from setup_app.utils import base
from setup_app.utils.properties_utils import propertiesUtils
from setup_app.utils.ldif_utils import myLdifParser
from setup_app.installers.jetty import JettyInstaller

Config.casa_web_port = '8080'
CASA_GIT = 'https://raw.githubusercontent.com/GluuFederation/flex/main/casa'


class CasaInstaller(JettyInstaller):

client_id_prefix = '3000.'
casa_dist_dir = os.path.join(Config.dist_jans_dir, 'casa')
source_files = [
(os.path.join(casa_dist_dir, 'casa.war'), os.path.join(base.current_app.app_info['GLUU_MAVEN'], 'maven/org/gluu/casa/{0}/casa-{0}.war').format(base.current_app.app_info['CASA_VERSION'])),
(os.path.join(casa_dist_dir, 'casa-config.jar'), os.path.join(base.current_app.app_info['GLUU_MAVEN'], 'maven/org/gluu/casa-config/{0}/casa-config-{0}.jar').format(base.current_app.app_info['CASA_VERSION'])),
(os.path.join(casa_dist_dir, 'twillo.jar'), os.path.join(base.current_app.app_info['TWILIO_MAVEN'], '{0}/twilio-{0}.jar'.format(base.current_app.app_info['TWILIO_VERSION']))),
(os.path.join(casa_dist_dir, 'jans-fido2-client.jar'), (os.path.join(base.current_app.app_info['JANS_MAVEN'], 'maven/io/jans/jans-fido2-client/{0}{1}/jans-fido2-client-{0}{1}.jar'.format(base.current_app.app_info['JANS_APP_VERSION'], base.current_app.app_info['JANS_BUILD'])))),
(os.path.join(casa_dist_dir, 'casa_web_resources.xml'), os.path.join(CASA_GIT, 'extras/casa_web_resources.xml')),
]

casa_python_libs = ['Casa.py', 'casa-external_fido2.py', 'casa-external_otp.py', 'casa-external_super_gluu.py', 'casa-external_twilio_sms.py']

casa_script_files = []

for plib in casa_python_libs:
casa_script_files.append((
os.path.join(casa_dist_dir, 'pylib', plib),
os.path.join(CASA_GIT, 'extras', plib)
))

def __init__(self):
setattr(base.current_app, self.__class__.__name__, self)
self.service_name = 'casa'
self.app_type = AppType.SERVICE
self.install_type = InstallOption.OPTONAL
self.install_var = 'install_casa'
self.register_progess()

self.source_files += self.casa_script_files
self.jetty_service_dir = os.path.join(self.jetty_base, self.service_name)
self.jetty_service_webapps = os.path.join(self.jetty_service_dir, 'webapps')
self.output_folder = os.path.join(Config.output_dir, self.service_name)
self.templates_dir = os.path.join(Config.templateFolder, self.service_name)
self.ldif_config_fn = os.path.join(self.output_folder, 'configuration.ldif')
self.ldif_client_fn = os.path.join(self.output_folder, 'client.ldif')
self.ldif_auth_script_fn = os.path.join(self.output_folder, 'person_authentication_script.ldif')
self.config_json_fn = os.path.join(self.output_folder, 'casa-config.json')
self.ldif_person_authentication_script_fn = os.path.join(self.output_folder, 'person_authentication_script.ldif')
self.scopes_fn = os.path.join(self.templates_dir, 'scopes.json')
self.pylib_dir = os.path.join(Config.jansOptPythonFolder, 'libs')


def install(self):

self.installJettyService(self.jetty_app_configuration[self.service_name], True)
self.copyFile(self.source_files[0][0], self.jetty_service_webapps)
self.copyFile(self.source_files[4][0], self.jetty_service_webapps)

self.casa_scopes = self.create_scopes()
self.add_plugins()
self.enable()

def add_plugins(self):
jans_auth_web_app_xml = self.readFile(base.current_app.JansAuthInstaller.web_app_xml_fn)

for plugin,_ in self.source_files[1:4]:
plugin_name = os.path.basename(plugin)
if plugin_name not in jans_auth_web_app_xml:
self.logIt("Adding plugin {} to jans-auth".format(plugin_name))
self.copyFile(plugin, base.current_app.JansAuthInstaller.custom_lib_dir)
plugin_class_path = os.path.join(base.current_app.JansAuthInstaller.custom_lib_dir, plugin_name)
base.current_app.JansAuthInstaller.add_extra_class(plugin_class_path)
self.chown(plugin_class_path, Config.jetty_user, Config.jetty_group)

def copy_static(self):
for fn in glob.glob(os.path.join(self.casa_dist_dir, 'pylib/*.py')):
self.copyFile(fn, self.pylib_dir)


def generate_configuration(self):
self.casa_scopes = self.create_scopes()

self.check_clients([('casa_client_id', self.client_id_prefix)])

if not Config.get('casa_client_pw'):
Config.casa_client_pw = self.getPW()
Config.casa_client_encoded_pw = self.obscure(Config.jca_client_pw)

def render_import_templates(self):

Config.templateRenderingDict['casa_redirect_uri'] = 'https://{}/casa'.format(Config.hostname)
Config.templateRenderingDict['casa_redirect_logout_uri'] = 'https://{}/casa/bye.zul'.format(Config.hostname)
Config.templateRenderingDict['casa_frontchannel_logout_uri'] = 'https://{}/casa/autologout'.format(Config.hostname)

# prepare casa scipt ldif
base64_script_file = self.generate_base64_file(self.casa_script_files[0][0], 1)
Config.templateRenderingDict['casa_person_authentication_script'] = base64_script_file
self.renderTemplateInOut(self.ldif_auth_script_fn, self.templates_dir, self.output_folder)

self.renderTemplateInOut(self.config_json_fn, self.templates_dir, self.output_folder)
Config.templateRenderingDict['casa_config_base64'] = self.generate_base64_file(self.config_json_fn, 1)


self.renderTemplateInOut(self.ldif_client_fn, self.templates_dir, self.output_folder)
self.renderTemplateInOut(self.ldif_config_fn, self.templates_dir, self.output_folder)

casa_client_ldif_parser = myLdifParser(self.ldif_client_fn)
casa_client_ldif_parser.parse()

casa_client_ldif_parser.entries[0][1]['jansScope'] += self.casa_scopes
with open(self.ldif_client_fn, 'wb') as w:
casa_client_ldif_writer = LDIFWriter(w)
casa_client_ldif_writer.unparse(casa_client_ldif_parser.entries[0][0], casa_client_ldif_parser.entries[0][1])

self.dbUtils.import_ldif([self.ldif_client_fn, self.ldif_config_fn, self.ldif_auth_script_fn])


def create_folders(self):
self.createDirs(self.pylib_dir)
for cdir in ('plugins', 'static'):
self.createDirs(os.path.join(self.jetty_service_dir, cdir))

def create_scopes(self):
self.logIt("Creating Casa client scopes")
scopes = base.readJsonFile(self.scopes_fn)
casa_scopes_ldif_fn = os.path.join(self.output_folder, 'scopes.ldif')
self.createDirs(self.output_folder)
scope_ldif_fd = open(casa_scopes_ldif_fn, 'wb')
scopes_list = []

ldif_scopes_writer = LDIFWriter(scope_ldif_fd, cols=1000)

for scope in scopes:
scope_dn = 'inum={},ou=scopes,o=jans'.format(scope['inum'])
scopes_list.append(scope_dn)
ldif_dict = {
'objectClass': ['top', 'jansScope'],
'description': [scope['description']],
'displayName': [scope['displayName']],
'inum': [scope['inum']],
'jansDefScope': [str(scope['jansDefScope'])],
'jansId': [scope['jansId']],
'jansScopeTyp': [scope['jansScopeTyp']],
'jansAttrs': [json.dumps({"spontaneousClientId":None, "spontaneousClientScopes":[], "showInConfigurationEndpoint": False})],
}
ldif_scopes_writer.unparse(scope_dn, ldif_dict)

scope_ldif_fd.close()

self.dbUtils.import_ldif([casa_scopes_ldif_fn])

return scopes_list

def service_post_setup(self):
self.chown(self.pylib_dir, Config.jetty_user, Config.jetty_group, recursive=True)
self.chown(self.jetty_service_dir, Config.jetty_user, Config.jetty_group, recursive=True)
2 changes: 2 additions & 0 deletions jans-linux-setup/jans_setup/setup_app/installers/jans.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __repr__(self):
txt += 'Install Fido2 Server'.ljust(30) + repr(Config.installFido2).rjust(35) + (' *' if 'installFido2' in Config.addPostSetupService else '') + "\n"
txt += 'Install Scim Server'.ljust(30) + repr(Config.install_scim_server).rjust(35) + (' *' if 'install_scim_server' in Config.addPostSetupService else '') + "\n"
txt += 'Install Jans Link Server'.ljust(30) + repr(Config.install_jans_link).rjust(35) + (' *' if 'install_jans_link' in Config.addPostSetupService else '') + "\n"
txt += 'Install Gluu/Flex Casa Server'.ljust(30) + repr(Config.install_casa).rjust(35) + (' *' if 'install_casa' in Config.addPostSetupService else '') + "\n"
#txt += 'Install Oxd '.ljust(30) + repr(Config.installOxd).rjust(35) + (' *' if 'installOxd' in Config.addPostSetupService else '') + "\n"

if Config.profile == 'jans' and Config.installEleven:
Expand Down Expand Up @@ -620,6 +621,7 @@ def order_services(self):
('jans-eleven', 'installEleven'),
('jans-auth', 'installOxAuth'),
('jans-config-api', 'install_config_api'),
('casa', 'install_casa'),
('jans-fido2', 'installFido2'),
('jans-link', 'install_jans_link'),
('jans-scim', 'install_scim_server'),
Expand Down
3 changes: 3 additions & 0 deletions jans-linux-setup/jans_setup/setup_app/setup_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def get_setup_options():
'installFido2': True,
'installEleven': False,
'install_jans_link': True,
'install_casa': False,
'loadTestData': False,
'allowPreReleasedFeatures': False,
'listenAllInterfaces': False,
Expand Down Expand Up @@ -105,6 +106,8 @@ def get_setup_options():
if base.argsp.install_jans_link:
setupOptions['install_jans_link'] = True

if base.argsp.install_casa:
setupOptions['install_casa'] = True

if base.argsp.jans_max_mem:
setupOptions['jans_max_mem'] = base.argsp.jans_max_mem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
parser.add_argument('--no-fido2', help="Do not install Fido2 Server", action='store_true')
parser.add_argument('--install-eleven', help="Install Eleven Server", action='store_true')
parser.add_argument('--install-jans-link', help="Install Link Server", action='store_true')
parser.add_argument('--install-casa', help="Install Gluu/Flex Casa Server", action='store_true')

#parser.add_argument('--oxd-use-jans-storage', help="Use Jans Storage for Oxd Server", action='store_true')
parser.add_argument('--load-config-api-test', help="Load Config Api Test Data", action='store_true')
Expand Down
Loading