Skip to content

Commit 72903cd

Browse files
authored
feat: flex linux setup casa fix
feat: flex linux setup casa fix
2 parents 9541dcc + 83d280e commit 72903cd

File tree

4 files changed

+178
-51
lines changed

4 files changed

+178
-51
lines changed

flex-linux-setup/flex_linux_setup/flex_setup.py

+159-48
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,46 @@
55
import zipfile
66
import argparse
77
import time
8+
import glob
9+
import code
10+
import configparser
11+
12+
from pathlib import Path
13+
from urllib import request
814
from urllib.parse import urljoin
915

10-
if not os.path.join('/etc/jans/conf/jans.properties'):
11-
print("Please install Jans server then execute this script.")
12-
sys.exit()
1316

14-
if not os.path.exists('/opt/jans/jetty/jans-config-api/start.ini'):
15-
print("Please install Jans Config Api then execute this script.")
16-
sys.exit()
17+
def get_flex_setup_parser():
18+
parser = argparse.ArgumentParser(description="This script downloads Gluu Admin UI components and installs")
19+
parser.add_argument('--jans-setup-branch', help="Jannsen setup github branch", default='main')
20+
parser.add_argument('--flex-branch', help="Jannsen flex setup github branch", default='main')
21+
parser.add_argument('--jans-branch', help="Jannsen github branch", default='main')
1722

18-
__STATIC_SETUP_DIR__ = '/opt/jans/jans-setup/'
23+
return parser
1924

25+
__STATIC_SETUP_DIR__ = '/opt/jans/jans-setup/'
2026

2127
try:
2228
import jans_setup
23-
sys.path.append(jans_setup.__path__[0])
29+
path_ = list(jans_setup.__path__)
30+
sys.path.append(path_[0])
2431
except ModuleNotFoundError:
25-
if os.path.exists(__STATIC_SETUP_DIR__):
32+
if os.path.exists(os.path.join(__STATIC_SETUP_DIR__, 'setup_app')):
2633
sys.path.append(__STATIC_SETUP_DIR__)
2734
else:
28-
print("Unable to locate jans-setup, exiting ...")
29-
sys.exit()
35+
argsp = get_flex_setup_parser().parse_known_args()[0]
36+
37+
print("Unable to locate jans-setup, installing ...")
38+
39+
setup_branch = argsp.jans_setup_branch or 'main'
40+
install_url = 'https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-linux-setup/jans_setup/install.py'.format(setup_branch)
41+
request.urlretrieve(install_url, 'install.py')
42+
install_cmd = 'python3 install.py --setup-branch={} --no-setup'.format(setup_branch)
43+
if '-yes' in sys.argv:
44+
install_cmd += ' -yes'
45+
print("Executing", install_cmd)
46+
os.system(install_cmd)
47+
sys.path.append(__STATIC_SETUP_DIR__)
3048

3149
logs_dir = os.path.join(__STATIC_SETUP_DIR__, 'logs')
3250

@@ -43,6 +61,22 @@
4361
print(paths.LOG_ERROR_FILE)
4462
print('\033[0m')
4563

64+
65+
parser = get_flex_setup_parser()
66+
from setup_app.utils import arg_parser
67+
arg_parser.add_to_me(parser)
68+
installed = False
69+
70+
if not os.path.exists('/etc/jans/conf/jans.properties'):
71+
installed = True
72+
try:
73+
from jans_setup import jans_setup
74+
except ImportError:
75+
import jans_setup
76+
jans_setup.main()
77+
78+
argsp = arg_parser.get_parser()
79+
4680
from setup_app import static
4781
from setup_app.utils import base
4882

@@ -53,41 +87,40 @@
5387
from setup_app.installers.httpd import HttpdInstaller
5488
from setup_app.installers.config_api import ConfigApiInstaller
5589
from setup_app.installers.jetty import JettyInstaller
90+
from setup_app.installers.jans_auth import JansAuthInstaller
91+
from setup_app.installers.jans_cli import JansCliInstaller
92+
5693

5794
Config.outputFolder = os.path.join(__STATIC_SETUP_DIR__, 'output')
5895
if not os.path.join(Config.outputFolder):
5996
os.makedirs(Config.outputFolder)
6097

61-
parser = argparse.ArgumentParser(description="This script downloads Gluu Admin UI components and installs")
62-
parser.add_argument('--setup-branch', help="Jannsen setup github branch", default='main')
63-
parser.add_argument('--flex-branch', help="Jannsen flex setup github branch", default='main')
64-
parser.add_argument('--jans-branch', help="Jannsen github branch", default='main')
65-
parser.add_argument('-casa-integration', help="Install Casa Integration", action='store_true')
66-
67-
argsp = parser.parse_args()
98+
if not installed:
6899

69-
# initialize config object
70-
Config.init(paths.INSTALL_DIR)
71-
Config.determine_version()
100+
# initialize config object
101+
Config.init(paths.INSTALL_DIR)
102+
Config.determine_version()
72103

73-
collectProperties = CollectProperties()
74-
collectProperties.collect()
104+
collectProperties = CollectProperties()
105+
collectProperties.collect()
75106

76107
maven_base_url = 'https://jenkins.jans.io/maven/io/jans/'
77108
app_versions = {
78-
"SETUP_BRANCH": argsp.setup_branch,
109+
"SETUP_BRANCH": argsp.jans_setup_branch,
79110
"FLEX_BRANCH": argsp.flex_branch,
80111
"JANS_BRANCH": argsp.jans_branch,
81112
"JANS_APP_VERSION": "1.0.0",
82113
"JANS_BUILD": "-SNAPSHOT",
83114
"NODE_VERSION": "v14.18.2",
84115
"CASA_VERSION": "5.0.0-SNAPSHOT",
116+
"TWILIO_VERSION": "7.17.0",
85117
}
86118

87119
node_installer = NodeInstaller()
88120
httpd_installer = HttpdInstaller()
89121
config_api_installer = ConfigApiInstaller()
90-
122+
jansAuthInstaller = JansAuthInstaller()
123+
jans_cli_installer = JansCliInstaller()
91124

92125
class flex_installer(JettyInstaller):
93126

@@ -97,23 +130,38 @@ def __init__(self):
97130
self.gluu_admin_ui_source_path = os.path.join(Config.distJansFolder, 'gluu-admin-ui.zip')
98131
self.log4j2_adminui_path = os.path.join(Config.distJansFolder, 'log4j2-adminui.xml')
99132
self.log4j2_path = os.path.join(Config.distJansFolder, 'log4j2.xml')
100-
self.admin_ui_plugin_source_path = os.path.join(Config.distJansFolder, 'admin-ui-plugin-distribution.jar')
133+
self.admin_ui_plugin_source_path = os.path.join(Config.distJansFolder, 'admin-ui-plugin.jar')
101134
self.flex_path = os.path.join(Config.distJansFolder, 'flex.zip')
102135
self.source_dir = os.path.join(Config.outputFolder, 'admin-ui')
103136
self.flex_setup_dir = os.path.join(self.source_dir, 'flex-linux-setup')
104137
self.templates_dir = os.path.join(self.flex_setup_dir, 'templates')
105138
self.admin_ui_config_properties_path = os.path.join(self.templates_dir, 'auiConfiguration.properties')
106-
self.casa_web_resources_fn = os.path.join(Config.distJansFolder, 'casa_web_resources.xml')
107-
self.casa_war_fn = os.path.join(Config.distJansFolder, 'casa.war')
139+
self.casa_dist_dir = os.path.join(Config.distJansFolder, 'gluu-casa')
140+
self.casa_web_resources_fn = os.path.join(self.casa_dist_dir, 'casa_web_resources.xml')
141+
self.casa_war_fn = os.path.join(self.casa_dist_dir, 'casa.war')
142+
self.casa_config_fn = os.path.join(self.casa_dist_dir,'casa-config.jar')
143+
self.casa_script_fn = os.path.join(self.casa_dist_dir,'Casa.py')
144+
self.twillo_fn = os.path.join(self.casa_dist_dir,'twilio.jar')
145+
self.py_lib_dir = os.path.join(Config.jansOptPythonFolder, 'libs')
146+
147+
self.dbUtils.bind(force=True)
108148

109149
def download_files(self):
110150
print("Downloading components")
111-
base.download(urljoin(maven_base_url, 'jans-config-api/plugins/admin-ui-plugin/{0}{1}/admin-ui-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), self.admin_ui_plugin_source_path)
112-
base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/server/src/main/resources/log4j2.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_path)
113-
base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/plugins/admin-ui-plugin/config/log4j2-adminui.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_adminui_path)
114-
base.download('https://github.com/GluuFederation/flex/archive/refs/heads/{}.zip'.format(app_versions['FLEX_BRANCH']), self.flex_path)
115-
base.download('https://github.com/GluuFederation/casa/raw/gluu_cloud/extras/casa_web_resources.xml', self.casa_web_resources_fn)
116-
base.download('https://maven.gluu.org/maven/org/gluu/casa/{0}/casa-{0}.war'.format(app_versions['CASA_VERSION']), self.casa_war_fn)
151+
base.download(urljoin(maven_base_url, 'jans-config-api/plugins/admin-ui-plugin/{0}{1}/admin-ui-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), self.admin_ui_plugin_source_path, verbose=True)
152+
base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/server/src/main/resources/log4j2.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_path, verbose=True)
153+
base.download('https://raw.githubusercontent.com/JanssenProject/jans/{}/jans-config-api/plugins/admin-ui-plugin/config/log4j2-adminui.xml'.format(app_versions['JANS_BRANCH']), self.log4j2_adminui_path, verbose=True)
154+
base.download('https://github.com/GluuFederation/flex/archive/refs/heads/{}.zip'.format(app_versions['FLEX_BRANCH']), self.flex_path, verbose=True)
155+
base.download('https://github.com/GluuFederation/casa/raw/gluu_cloud/extras/casa_web_resources.xml', self.casa_web_resources_fn, verbose=True)
156+
base.download('https://maven.gluu.org/maven/org/gluu/casa/{0}/casa-{0}.war'.format(app_versions['CASA_VERSION']), self.casa_war_fn, verbose=True)
157+
base.download('https://maven.gluu.org/maven/org/gluu/casa-config/{0}/casa-config-{0}.jar'.format(app_versions['CASA_VERSION']), self.casa_config_fn, verbose=True)
158+
base.download('https://repo1.maven.org/maven2/com/twilio/sdk/twilio/{0}/twilio-{0}.jar'.format(app_versions['TWILIO_VERSION']), self.twillo_fn, verbose=True)
159+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/Casa.py', self.casa_script_fn, verbose=True)
160+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/casa-external_fido2.py', os.path.join(self.casa_dist_dir, 'pylib/casa-external_fido2.py'), verbose=True)
161+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/casa-external_otp.py', os.path.join(self.casa_dist_dir, 'pylib/casa-external_otp.py'), verbose=True)
162+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/casa-external_super_gluu.py', os.path.join(self.casa_dist_dir, 'pylib/casa-external_super_gluu.py'), verbose=True)
163+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/casa-external_twilio_sms.py', os.path.join(self.casa_dist_dir, 'pylib/casa-external_twilio_sms.py'), verbose=True)
164+
base.download('https://raw.githubusercontent.com/GluuFederation/flex/main/casa/extras/casa-external_u2f.py', os.path.join(self.casa_dist_dir, 'pylib/casa-external_u2f.py'), verbose=True)
117165

118166

119167
def install_gluu_admin_ui(self):
@@ -147,15 +195,65 @@ def install_gluu_admin_ui(self):
147195
config_api_installer.check_clients([('role_based_client_id', '2000.')])
148196
config_api_installer.renderTemplateInOut(self.admin_ui_config_properties_path, os.path.join(self.flex_setup_dir, 'templates'), config_api_installer.custom_config_dir)
149197
admin_ui_plugin_path = os.path.join(config_api_installer.libDir, os.path.basename(self.admin_ui_plugin_source_path))
150-
config_api_installer.web_app_xml_fn = os.path.join(config_api_installer.jetty_base, config_api_installer.service_name, 'webapps/jans-config-api.xml')
151198
config_api_installer.copyFile(self.admin_ui_plugin_source_path, config_api_installer.libDir)
152199
config_api_installer.add_extra_class(admin_ui_plugin_path)
153200

154201
for logfn in (self.log4j2_adminui_path, self.log4j2_path):
155202
config_api_installer.copyFile(logfn, config_api_installer.custom_config_dir)
156203

204+
cli_config = Path(jans_cli_installer.config_ini_fn)
205+
206+
current_plugins = []
207+
208+
if cli_config.exists():
209+
210+
config = configparser.ConfigParser()
211+
config.read_file(cli_config.open())
212+
current_plugins = config['DEFAULT'].get('jca_plugins', '').split(',')
213+
214+
plugins = config_api_installer.get_plugins()
215+
216+
for plugin in plugins:
217+
if not plugin in current_plugins:
218+
current_plugins.append(plugin)
219+
220+
config['DEFAULT']['jca_plugins'] = ','.join(current_plugins)
221+
config.write(cli_config.open('w'))
222+
cli_config.chmod(0o600)
157223

158224
def install_casa(self):
225+
226+
jans_auth_dir = os.path.join(Config.jetty_base, jansAuthInstaller.service_name)
227+
jans_auth_custom_lib_dir = os.path.join(jans_auth_dir, 'custom/libs')
228+
229+
print("Adding twillo and casa config to jans-auth")
230+
self.copyFile(self.casa_config_fn, jans_auth_custom_lib_dir)
231+
self.copyFile(self.twillo_fn, jans_auth_custom_lib_dir)
232+
class_path = '{},{}'.format(
233+
os.path.join(jans_auth_custom_lib_dir, os.path.basename(self.casa_config_fn)),
234+
os.path.join(jans_auth_custom_lib_dir, os.path.basename(self.twillo_fn)),
235+
)
236+
jansAuthInstaller.add_extra_class(class_path)
237+
238+
simple_auth_scr_inum = 'A51E-76DA'
239+
print("Enabling script", simple_auth_scr_inum)
240+
self.dbUtils.enable_script(simple_auth_scr_inum)
241+
242+
# copy casa scripts
243+
if not os.path.exists(self.py_lib_dir):
244+
os.makedirs(self.py_lib_dir)
245+
for fn in glob.glob(os.path.join(self.casa_dist_dir, 'pylib/*.py')):
246+
print("Copying", fn, "to", self.py_lib_dir)
247+
self.copyFile(fn, self.py_lib_dir)
248+
249+
self.run([paths.cmd_chown, '-R', '{0}:{0}'.format(Config.jetty_user), self.py_lib_dir])
250+
251+
# prepare casa scipt ldif
252+
casa_auth_script_fn = os.path.join(self.templates_dir, 'casa_person_authentication_script.ldif')
253+
base64_script_file = self.generate_base64_file(self.casa_script_fn, 1)
254+
Config.templateRenderingDict['casa_person_authentication_script'] = base64_script_file
255+
self.renderTemplateInOut(casa_auth_script_fn, self.templates_dir, self.source_dir)
256+
159257
Config.templateRenderingDict['casa_redirect_uri'] = 'https://{}/casa'.format(Config.hostname)
160258
Config.templateRenderingDict['casa_redirect_logout_uri'] = 'https://{}/casa/bye.zul'.format(Config.hostname)
161259
Config.templateRenderingDict['casa_frontchannel_logout_uri'] = 'https://{}/casa/autologout'.format(Config.hostname)
@@ -167,15 +265,18 @@ def install_casa(self):
167265

168266
self.check_clients([('casa_client_id', '3000.')])
169267

170-
print(Config.casa_client_id)
171-
print(Config.casa_client_encoded_pw)
172-
print(Config.casa_client_pw)
268+
print("Casa client id", Config.casa_client_id)
269+
print("Casa client password", Config.casa_client_pw)
270+
print("Casa client encoded password", Config.casa_client_encoded_pw)
271+
272+
print("Importing LDIF Files")
173273

174274
self.renderTemplateInOut(self.casa_client_fn, self.templates_dir, self.source_dir)
175275
self.renderTemplateInOut(self.casa_config_fn, self.templates_dir, self.source_dir)
176276
self.dbUtils.import_ldif([
177277
os.path.join(self.source_dir, os.path.basename(self.casa_client_fn)),
178278
os.path.join(self.source_dir, os.path.basename(self.casa_config_fn)),
279+
os.path.join(self.source_dir, os.path.basename(casa_auth_script_fn)),
179280
])
180281

181282

@@ -216,6 +317,7 @@ def install_casa(self):
216317

217318
self.calculate_aplications_memory(Config.application_max_ram, self.jetty_app_configuration, installedComponents)
218319

320+
print("Deploying casa as Jetty application")
219321
self.installJettyService(self.jetty_app_configuration[self.service_name], True)
220322
self.copyFile(os.path.join(self.templates_dir, 'casa.service'), '/etc/systemd/system')
221323
jetty_service_dir = os.path.join(Config.jetty_base, self.service_name)
@@ -227,10 +329,8 @@ def install_casa(self):
227329
self.copyFile(self.casa_war_fn, jetty_service_webapps_dir)
228330
self.copyFile(self.casa_web_resources_fn, jetty_service_webapps_dir)
229331
self.run([paths.cmd_chown, '-R', '{0}:{0}'.format(Config.jetty_user), jetty_service_dir])
230-
gluu_python_dir = '/opt/gluu/python/'
231-
self.run([paths.cmd_mkdir, '-p', os.path.join(gluu_python_dir, 'libs')])
232-
self.run([paths.cmd_chown, '-R', '{0}:{0}'.format(Config.jetty_user), gluu_python_dir])
233332

333+
print("Updating apache configuration")
234334
apache_directive_template_text = self.readFile(os.path.join(self.templates_dir, 'casa_apache_directive'))
235335

236336
apache_directive_text = self.fomatWithDict(apache_directive_template_text, Config.templateRenderingDict)
@@ -248,6 +348,7 @@ def install_casa(self):
248348

249349
https_jans_list.insert(n+1, '\n' + apache_directive_text + '\n')
250350
self.writeFile(httpd_installer.https_jans_fn, '\n'.join(https_jans_list))
351+
print("Restarting Apache")
251352
httpd_installer.restart()
252353

253354
self.enable()
@@ -259,24 +360,34 @@ def main():
259360
node_fn = 'node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION'])
260361
node_path = os.path.join(Config.distAppFolder, node_fn)
261362
if not os.path.exists(node_path):
262-
print("Downloading", node_fn)
263-
base.download('https://nodejs.org/dist/{0}/node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']), node_path)
363+
base.download('https://nodejs.org/dist/{0}/node-{0}-linux-x64.tar.xz'.format(app_versions['NODE_VERSION']), node_path, verbose=True)
264364
print("Installing node")
265365
node_installer.install()
266366

267367
installer_obj = flex_installer()
268368
installer_obj.download_files()
369+
269370
installer_obj.install_gluu_admin_ui()
270371

271-
if argsp.casa_integration:
272-
installer_obj.install_casa()
372+
installer_obj.install_casa()
373+
374+
print("Starting Casa")
375+
config_api_installer.start('casa')
376+
377+
print("Restarting Jans Auth")
378+
config_api_installer.restart('jans-auth')
273379

274-
sys.exit()
275380
print("Restarting Janssen Config Api")
276381
config_api_installer.restart()
277382

278-
print("Installation was completed. Browse https://{}/admin".format(Config.hostname))
383+
print("Installation was completed.")
384+
print("Browse https://{}/admin".format(Config.hostname))
385+
print("Browse https://{}/casa".format(Config.hostname))
279386

280387
if __name__ == "__main__":
281-
main()
388+
if argsp.shell:
389+
code.interact(local=locals())
390+
sys.exit()
391+
else:
392+
main()
282393

flex-linux-setup/flex_linux_setup/templates/casa_client.ldif

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jansInclClaimsInIdTkn: false
1818
jansLogoutSessRequired: false
1919
jansPersistClntAuthzs: true
2020
jansRedirectURI: %(casa_redirect_uri)s
21-
jansRedirectURI: %(casa_redirect_logout_uri)s
21+
jansPostLogoutRedirectURI: %(casa_redirect_logout_uri)s
2222
jansLogoutURI: %(casa_frontchannel_logout_uri)s
2323
jansRequireAuthTime: false
2424
jansRespTyp: code
@@ -30,4 +30,5 @@ jansScope: inum=341A,ou=scopes,o=jans
3030
jansSignedRespAlg: RS256
3131
jansSubjectTyp: pairwise
3232
jansTknEndpointAuthMethod: client_secret_basic
33-
jansTrustedClnt: false
33+
jansTrustedClnt: true
34+

flex-linux-setup/flex_linux_setup/templates/casa_config.ldif

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ dn: ou=casa,ou=configuration,o=jans
22
objectClass: jansAppConf
33
objectClass: top
44
ou: casa
5-
jansConfApp: {"enable_pass_reset": true, "oidc_config": {"authz_redirect_uri": "%(casa_redirect_uri)s", "post_logout_uri": "%(casa_redirect_logout_uri)s", "frontchannel_logout_uri": "%(casa_frontchannel_logout_uri)s", "scopes": ["openid", "profile", "user_name", "clientinfo"], "op_host": "%(hostname)s", "client": {"clientId": "%(casa_client_id)s", "clientSecret": "casa_client_pw", "clientName": "Client for Casa"}}}
5+
jansConfApp: {"enable_pass_reset": true, "oidc_config": {"authz_redirect_uri": "%(casa_redirect_uri)s", "post_logout_uri": "%(casa_redirect_logout_uri)s", "frontchannel_logout_uri": "%(casa_frontchannel_logout_uri)s", "scopes": ["openid", "profile", "user_name", "clientinfo"], "op_host": "%(hostname)s", "client": {"clientId": "%(casa_client_id)s", "clientSecret": "%(casa_client_pw)s", "clientName": "Client for Casa"}}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
dn: inum=3000-F75A,ou=scripts,o=jans
2+
description: Gluu Casa Person Authentication
3+
displayName: casa
4+
inum: 3000-F75A
5+
jansLevel: 1
6+
jansModuleProperty: {"value1":"location_type","value2":"ldap","description":""}
7+
jansRevision: 1
8+
jansScr::%(casa_person_authentication_script)s
9+
jansConfProperty: {"value1":"supergluu_app_id","value2":"https://%(hostname)s/casa","description":""}
10+
jansConfProperty: {"value1":"u2f_app_id","value2":"https://%(hostname)s","description":""}
11+
jansScrTyp: person_authentication
12+
objectClass: top
13+
objectClass: jansCustomScr
14+
jansEnabled: true
15+
jansProgLng: python

0 commit comments

Comments
 (0)