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

fix(jans-cli-tui): working branch 9 #3871

Merged
merged 20 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0a31b49
fix: jans-cli-tui check if ssa successfully saved
devrimyatar Feb 15, 2023
642d28f
fix(jans-cli-tui): new scope missing from client configuration menu (…
AbdelwahabAdam Feb 15, 2023
a866301
fix:jans-cli-tui fix typo
AbdelwahabAdam Feb 15, 2023
eb5e53f
Revert "fix(jans-cli-tui): new scope missing from client configuratio…
devrimyatar Feb 16, 2023
7ee1c16
fix(jans-cli-tui): new scope missing from client configuration menu (…
devrimyatar Feb 16, 2023
47af97b
fix(jans-cli-tui): rerfresh scopes all the time (ref: #3860)
devrimyatar Feb 16, 2023
dcc4461
fix(jans-cli-tui): add custom claims to SSA (unfinished)
devrimyatar Feb 16, 2023
3cddd57
fix(jans-cli-tui): ask project name if not exists in project.json for…
devrimyatar Feb 16, 2023
c71eb72
fix(jans-cli-tui): rerfresh scopes after deleting (ref: #3860)
devrimyatar Feb 16, 2023
eaaa85b
fix(jans-cli-tui): remove debug line
devrimyatar Feb 16, 2023
87ff6d5
fix(jans-cli-tui): delete SSA custom claim
devrimyatar Feb 16, 2023
55673a7
fix(jans-cli-tui): code smell
devrimyatar Feb 16, 2023
4a162ba
fix(jans-cli-tui): typo
devrimyatar Feb 16, 2023
03dc34d
fix: jans-cli-tui start if jans-cli.ini is not exist (ref: #3873)
devrimyatar Feb 17, 2023
83e1e25
fix(jans-cli-tui): unable to use SSA endpint in first start(ref:#3874)
devrimyatar Feb 17, 2023
ecc11b7
fix:jans-cli-tui update help (ref: #3879)
AbdelwahabAdam Feb 18, 2023
8ad1200
feat(jans-cli-tui) import script from file (ref: #3884)
devrimyatar Feb 20, 2023
4895d51
feat(jans-cli-tui) code smells
devrimyatar Feb 20, 2023
7b77711
fix(jans-cli-tui) code smell
devrimyatar Feb 20, 2023
944f064
fix(jans-li-tui): hide SSA custom claims until server is ready
devrimyatar Feb 20, 2023
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
3 changes: 2 additions & 1 deletion jans-cli-tui/cli_tui/cli_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

"outh-titledtext":"green",
"outh-label":"blue",

# PLUGINS
"plugin-navbar":"#2600ff",
"plugin-navbar-headcolor":"green",
Expand All @@ -78,6 +78,7 @@
"plugin-container":"",
"plugin-container.text":"green",
"plugin-black-bg": "bg: black",
"plugin-titledtext":"green",

## edit_client_dialog
"outh-client-navbar":"#2600ff",
Expand Down
24 changes: 17 additions & 7 deletions jans-cli-tui/cli_tui/jans_cli_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,7 @@ async def coroutine():

else:
self.cli_object_ok = True

self.check_available_plugins()
self.check_available_plugins()


def check_available_plugins(self) -> None:
Expand Down Expand Up @@ -548,10 +547,21 @@ def focus_previous(self, ev: KeyPressEvent) -> None:
focus_previous(ev)

def help(self,ev: KeyPressEvent) -> None:
self.logger.debug("ev:"+str(ev))
self.logger.debug("ev:"+str(type(ev)))
self.show_message(_("Help"),'''<Enter> {} \n<j> {}\n<d> {}'''.format(_("Edit current selection"),_("Display current item in JSON format"),_("Delete current selection")))

self.show_message(_("Help"),
("<Enter> {} \n"
"<Esc> {}\n"
"<Alt + letter> {}\n"
"<d> {}\n"
"<Delete> {}\n"
"For More Visite {}")
.format(
_("Confirm or Edit current selection"),
_("Close the current dialog"),
_("Navigate to an other tab"),
_("Display current item in JSON format if possible"),
_("Delete current selection if possible"),
"https://docs.jans.io/v1.0.6/admin/config-guide/tui/"))

def escape(self,ev: KeyPressEvent) -> None:
try:
if self.layout.container.floats:
Expand Down Expand Up @@ -901,7 +911,7 @@ def get_confirm_dialog(
) -> Dialog:
body = VSplit([Label(message)], align=HorizontalAlign.CENTER)
buttons = [Button(_("No")), Button(_("Yes"), handler=confirm_handler)]
dialog = JansGDialog(self, title=_("Confirmation"), body=body, buttons=buttons)
dialog = JansGDialog(self, title=_("Confirmation"), body=body, buttons=buttons, width=self.dialog_width-20)
return dialog


Expand Down
64 changes: 47 additions & 17 deletions jans-cli-tui/cli_tui/plugins/010_auth_server/agama.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
from prompt_toolkit.layout.containers import HSplit, VSplit, DynamicContainer
from prompt_toolkit.buffer import Buffer
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.widgets import Button

from utils.multi_lang import _
from utils.utils import DialogUtils
from utils.static import cli_style, common_strings
from wui_components.jans_vetrical_nav import JansVerticalNav
from wui_components.jans_path_browser import jans_file_browser_dialog, BrowseType
from wui_components.jans_cli_dialog import JansGDialog

class Agama(DialogUtils):
def __init__(
Expand Down Expand Up @@ -110,7 +112,48 @@ async def coroutine():

def upload_project(self):

def project_uploader(path, project_name):
async def coroutine():
cli_args = {'operation_id': 'post-agama-dev-studio-prj', 'data_fn': path, 'url_suffix':'name:{}'.format(project_name)}
self.app.start_progressing(_("Uploading agama project..."))
await get_event_loop().run_in_executor(self.app.executor, self.app.cli_requests, cli_args)
self.app.stop_progressing()
self.get_agama_projects()

asyncio.ensure_future(coroutine())


def aks_project_name(path):
body = self.app.getTitledText(_("Project Name"), name='oauth:agama:projectname', style=cli_style.edit_text)
ok = _("OK")
buttons = [Button(_("Cancel")), Button(ok)]
dialog = JansGDialog(self.app, body=body, title=_("Enter Project Name"), buttons=buttons, width=self.app.dialog_width-20)

async def coroutine():
focused_before = self.app.layout.current_window
result = await self.app.show_dialog_as_float(dialog)

try:
self.app.layout.focus(focused_before)
except Exception:
self.app.layout.focus(self.app.center_frame)

if result != ok:
return

project_name = body.me.text.strip()

if not project_name:
aks_project_name(path)

project_uploader(path, project_name)

return asyncio.ensure_future(coroutine())


def do_upload_project(path):
project_name = None

try:
project_zip = zipfile.ZipFile(path)
except Exception:
Expand All @@ -119,23 +162,10 @@ def do_upload_project(path):

try:
project_json = json.loads(project_zip.read('project.json'))
except Exception as e:
self.app.show_message(_(common_strings.error), HTML(_("Can't read <b>project.json</b> from zip file:\n {}").format(str(e))), tobefocused=self.app.center_container)
return

if 'projectName' not in project_json:
self.app.show_message(_(common_strings.error), HTML(_("Property <b>projectName</b> does not exist in <b>project.json</b>.")), tobefocused=self.app.center_container)
return

async def coroutine():
cli_args = {'operation_id': 'post-agama-dev-studio-prj', 'data_fn': path, 'url_suffix':'name:{}'.format(project_json['projectName'])}
self.app.start_progressing(_("Uploading agama project..."))
await get_event_loop().run_in_executor(self.app.executor, self.app.cli_requests, cli_args)
self.app.stop_progressing()
self.get_agama_projects()

asyncio.ensure_future(coroutine())

project_name = project_json['projectName']
project_uploader(path, project_name)
except Exception:
aks_project_name(path)

file_browser_dialog = jans_file_browser_dialog(self.app, path=self.app.browse_path, browse_type=BrowseType.file, ok_handler=do_upload_project)
self.app.show_jans_dialog(file_browser_dialog)
Expand Down
4 changes: 4 additions & 0 deletions jans-cli-tui/cli_tui/plugins/010_auth_server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def init_plugin(self) -> None:
if not hasattr(common_data, 'scopes'):
self.app.create_background_task(self.retrieve_sopes())

self.ssa.init_cli_object()

async def get_appconfiguration(self) -> None:
'Coroutine for getting application configuration.'

Expand Down Expand Up @@ -781,6 +783,7 @@ async def coroutine():
if response.status_code == 500:
self.app.show_message(_('Error'), response.text + '\n' + response.reason)
else:
self.app.create_background_task(self.retrieve_sopes())
self.oauth_get_scopes()

asyncio.ensure_future(coroutine())
Expand Down Expand Up @@ -859,6 +862,7 @@ async def coroutine():
data={}
)
self.oauth_get_scopes()
self.app.create_background_task(self.retrieve_sopes())
return result

asyncio.ensure_future(coroutine())
Expand Down
109 changes: 94 additions & 15 deletions jans-cli-tui/cli_tui/plugins/010_auth_server/ssa.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@
from prompt_toolkit.layout.dimension import D
from prompt_toolkit.layout.containers import HSplit, VSplit
from prompt_toolkit.layout.containers import DynamicContainer, Window
from prompt_toolkit.widgets import Button, Label, Checkbox
from prompt_toolkit.widgets import Button, Label, Checkbox, Dialog
from prompt_toolkit.buffer import Buffer

from cli import config_cli
from utils.multi_lang import _
from utils.utils import DialogUtils
from utils.static import cli_style, common_strings
from wui_components.jans_vetrical_nav import JansVerticalNav
from wui_components.jans_cli_dialog import JansGDialog
from wui_components.jans_label_container import JansLabelContainer
from wui_components.jans_date_picker import DateSelectWidget

from cli import config_cli


from utils.multi_lang import _

class SSA(DialogUtils):
def __init__(
Expand All @@ -40,7 +38,8 @@ def __init__(
selectes=0,
headerColor=cli_style.navbar_headcolor,
entriesColor=cli_style.navbar_entriescolor,
hide_headers = True
hide_headers = True,
max_height=20
)

self.main_container = HSplit([
Expand All @@ -56,15 +55,15 @@ def __init__(
],style='class:outh_containers_scopes')


def init_cli_object(self):
self.cli_object = config_cli.JCA_CLI(
host=config_cli.host,
client_id=config_cli.client_id,
client_secret=config_cli.client_secret,
access_token=config_cli.access_token,
host=self.app.cli_object.idp_host,
client_id=self.app.cli_object.client_id,
client_secret=self.app.cli_object.client_secret,
access_token=self.app.cli_object.access_token,
op_mode = 'auth'
)


def update_ssa_container(self, start_index=0, search_str=''):

self.working_container.clear()
Expand Down Expand Up @@ -136,13 +135,65 @@ async def coroutine():
result = await get_event_loop().run_in_executor(self.app.executor, self.app.cli_requests, cli_args)
self.app.stop_progressing()
ssa = result.json()
self.app.data_display_dialog(data=ssa, title=_("SSA Token"), message=_("Save and store it securely. This is the only time you see this token."))

self.get_ssa()
dialog.future.set_result(True)
if 'ssa' in ssa:
self.app.data_display_dialog(data=ssa, title=_("SSA Token"), message=_("Save and store it securely. This is the only time you see this token."))
self.get_ssa()
else:
self.app.show_message(_(common_strings.error), _("Something not went good while creating SSA:" + "\n" + str(ssa)), tobefocused = self.main_container)

asyncio.ensure_future(coroutine())


def edit_custom_claim(self, **kwargs: Any) -> None:

"""Method for editing the custom claim
"""

key, val = kwargs.get('data', ('',''))

key_widget = self.app.getTitledText(_("Key"), name='claim_key', value=key, style=cli_style.edit_text, jans_help=_("Custom claim Key"))
val_widget = self.app.getTitledText(_("Value"), name='claim_val', value=val, style=cli_style.edit_text, jans_help=_("Custom claim value"))

def add_claim(dialog: Dialog) -> None:
key_ = key_widget.me.text
val_ = val_widget.me.text
cur_data = [key_, val_]

if not kwargs.get('data'):
self.custom_claims_container.add_item(cur_data)
self.custom_claims_container.all_data.append(cur_data)
else:
self.custom_claims_container.replace_item(kwargs['selected'], cur_data)
self.custom_claims_container.all_data[kwargs['selected']] = cur_data

body_widgets = [key_widget, val_widget]
body = HSplit(body_widgets)
buttons = [Button(_("Cancel")), Button(_("OK"), handler=add_claim)]
dialog = JansGDialog(self.app, title=_("Edit Custom Claim"), body=body, buttons=buttons, width=self.app.dialog_width-20)
self.app.show_jans_dialog(dialog)


def delete_custom_claim(self, **kwargs: Any) -> None:
"""This method for deleting custom claim
"""

dialog = self.app.get_confirm_dialog(_("Are you sure want to delete custom claim with Key:")+"\n {} ?".format(kwargs['selected'][0]))

async def coroutine():
focused_before = self.app.layout.current_window
result = await self.myparent.show_dialog_as_float(dialog)
try:
self.myparent.layout.focus(focused_before)
except Exception:
self.myparent.app.focus(self.myparent.center_frame)

if result.lower() == 'yes':
self.custom_claims_container.remove_item(kwargs['selected'])

asyncio.ensure_future(coroutine())


def edit_ssa_dialog(self, data=None):
if data:
title = _("Edit SSA")
Expand All @@ -156,6 +207,25 @@ def edit_ssa_dialog(self, data=None):
expiration_iso = datetime.fromtimestamp(data['exp']).isoformat() if 'exp' in data else ''
self.expire_widget = DateSelectWidget(value=expiration_iso, parent=self)

custom_claims_title = _("Custom Claims: ")
add_custom_claim_title = _("Add Claim")
self.custom_claims_container = JansVerticalNav(
myparent=self.app,
headers=['Key', 'Value'],
preferred_size=[15, 20],
on_enter=self.edit_custom_claim,
on_delete=self.delete_custom_claim,
on_display=self.myparent.data_display_dialog,
selectes=0,
all_data=[],
headerColor=cli_style.navbar_headcolor,
entriesColor=cli_style.navbar_entriescolor,
underline_headings=False,
max_width=52,
jans_name='customClaims',
max_height=3
)

body = HSplit([

self.app.getTitledText(
Expand Down Expand Up @@ -195,6 +265,15 @@ def edit_ssa_dialog(self, data=None):
style=cli_style.edit_text_required
),

#VSplit([
# HSplit([Label(text=custom_claims_title, style=cli_style.titled_text, width=len(custom_claims_title)+1)], height=1),
# self.custom_claims_container,
# Window(width=2),
# HSplit([Button(text=add_custom_claim_title, width=len(add_custom_claim_title)+ 2, handler=self.edit_custom_claim)], height=1),
# ],
# height=5, width=D(),
# ),

self.app.getTitledCheckBox(
_("One Time Use"),
name='one_time_use',
Expand All @@ -210,7 +289,7 @@ def edit_ssa_dialog(self, data=None):
),

VSplit([
Label(expiration_label + ': ', width=len(expiration_label)+2, style=cli_style.edit_text),
Label(expiration_label + ': ', width=len(expiration_label)+2, style=cli_style.titled_text),
HSplit([self.never_expire_cb], width=len(never_expire_label)+7),
self.expire_widget,
], height=1),
Expand Down
Loading