diff --git a/code/zato-cli/src/zato/cli/enmasse.py b/code/zato-cli/src/zato/cli/enmasse.py index f14ab0f7bc..a006f2c5e1 100644 --- a/code/zato-cli/src/zato/cli/enmasse.py +++ b/code/zato-cli/src/zato/cli/enmasse.py @@ -120,11 +120,13 @@ class Include_Type: All = 'all' Cache = 'cache' LDAP = 'ldap' + Microsoft_365 = 'cloud-microsoft-365' SQL = 'sql' PubSub = 'pubsub' REST = 'rest' Scheduler = 'scheduler' Security = 'security' + WebSockets = 'websockets' # An indicator that this is an include directive Item_Type_Include = 'include' @@ -197,6 +199,14 @@ class Include_Type: # ################################################################################################################################ +zato_generic_connection_microsoft_365 = 'zato_generic_connection_' + ModuleCtx.Include_Type.Microsoft_365 + +_enmasse_type_generic = ( + ModuleCtx.Include_Type.LDAP, + ModuleCtx.Include_Type.Microsoft_365, + ModuleCtx.Include_Type.WebSockets, +) + ModuleCtx.Enmasse_Type = { # REST connections @@ -204,7 +214,7 @@ class Include_Type: 'outconn_plain_http': ModuleCtx.Include_Type.REST, 'zato_cache_builtin': ModuleCtx.Include_Type.Cache, 'zato_generic_rest_wrapper': ModuleCtx.Include_Type.REST, - 'zato_generic_connection': ModuleCtx.Include_Type.LDAP, + 'zato_generic_connection': _enmasse_type_generic, # Security definitions 'def_sec': ModuleCtx.Include_Type.Security, @@ -321,6 +331,14 @@ class Include_Type: 'hook_service_name', ], + # Generic connections - Cloud Microsoft 365 + zato_generic_connection_microsoft_365: [ + 'client_id', + 'name', + 'scopes', + 'tenant_id', + 'type_', + ] } # ################################################################################################################################ @@ -351,6 +369,9 @@ class Include_Type: # ################################################################################################################################ +# +# This is used during export +# ModuleCtx.Enmasse_Attr_List_Rename = { # Security definitions @@ -361,7 +382,7 @@ class Include_Type: # Pub/sub endpoints 'pubsub_endpoint': { 'sec_name':'security_name' - } + }, } @@ -550,6 +571,15 @@ class Include_Type: 'outgoing_rest': { 'security_name': Zato_No_Security, 'merge_url_params_req': True, + }, + + # Generic connections - Cloud Microsoft 365 + zato_generic_connection_microsoft_365: { + 'is_channel': False, + 'is_internal': False, + 'is_outconn': True, + 'pool_size': 20, + 'sec_use_rbac': False, } } @@ -675,6 +705,14 @@ class Include_Type: 'topic_list', ], + # Generic connections - Cloud Microsoft 365 + zato_generic_connection_microsoft_365: [ + 'type_', + 'name', + 'client_id', + 'tenant_id', + 'scopes', + ] } # ################################################################################################################################ @@ -2957,6 +2995,9 @@ def _pre_process_input_before_import(self, data:'strdict') -> 'strdict': # .. add values for attributes that are optional .. for def_type, items in data.items(): + # .. reusable .. + is_generic_connection = def_type == 'zato_generic_connection' + # .. replace new names with old ones but only for specific types .. if item_type_name_map_reverse_by_type := ModuleCtx.Enmasse_Item_Type_Name_Map_Reverse_By_Type.get(def_type): @@ -2977,9 +3018,6 @@ def _pre_process_input_before_import(self, data:'strdict') -> 'strdict': # .. if we are here, we know we can swap the names .. item[old_name] = item.pop(new_name) - # .. for attributes that should be populated if they do not exist .. - attr_list_default_by_type = ModuleCtx.Enmasse_Attr_List_Default_By_Type.get(def_type) or {} - # .. go through each definition .. for item in items: @@ -2990,6 +3028,17 @@ def _pre_process_input_before_import(self, data:'strdict') -> 'strdict': # .. add type hints .. item = cast_('strdict', item) + # .. what configuration to look up depends on whether it's a generic connection or not .. + if is_generic_connection: + wrapper_type = item['type_'] + by_type_key = f'{def_type}_{wrapper_type}' + + else: + by_type_key = def_type + + # .. for attributes that should be populated if they do not exist .. + attr_list_default_by_type = ModuleCtx.Enmasse_Attr_List_Default_By_Type.get(by_type_key) or {} + # .. everything is active unless it is configured not to be .. if not 'is_active' in item: item['is_active'] = True @@ -3340,17 +3389,20 @@ def _should_write_type_to_output( # Get an include type that matches are item type .. enmasse_include_type = ModuleCtx.Enmasse_Type.get(item_type) + if not isinstance(enmasse_include_type, (list, tuple)): + enmasse_include_type = [enmasse_include_type] + # .. if there is no match, it means that we do not write it on output .. if not enmasse_include_type: return False # .. check further if this type is what we had on input .. - if not enmasse_include_type in include_type: + for elem in enmasse_include_type: + if elem in include_type: + return True + else: return False - # .. if we are here, we know we should write this type to output. - return True - # ################################################################################################################################ def _should_write_name_to_output( @@ -3743,6 +3795,9 @@ def write_output( # .. go through everything that we collected in earlier steps in the process .. for item_type, items in iteritems(output): # type: ignore + # .. reusable .. + is_generic_connection = item_type == 'zato_generic_connection' + # .. add type hints .. items = cast_('dictlist', items) @@ -3765,10 +3820,20 @@ def write_output( continue # .. this is required because generic connections are differentiated .. - # .. by their embedded 'type_' attribute, rather but item_type itself .. - if item_type == 'zato_generic_connection': + # .. by their embedded 'type_' attribute, rather than by item_type itself .. + if is_generic_connection: wrapper_type = item['type_'] attr_key = f'{item_type}_{wrapper_type}' + + # .. make sure to filter out include types embedded in generic connections, .. + # .. but first, confirm if we are not to return all the types .. + if not ModuleCtx.Include_Type.All in include_type: + + # .. if we are here, it means that we need to check the actual include type .. + # .. which will be equal to the generic connection's wrapper type .. + if not wrapper_type in include_type: + continue + else: attr_key = item_type diff --git a/code/zato-server/src/zato/server/connection/cloud/microsoft_365.py b/code/zato-server/src/zato/server/connection/cloud/microsoft_365.py index 13693b5987..9790d36b75 100644 --- a/code/zato-server/src/zato/server/connection/cloud/microsoft_365.py +++ b/code/zato-server/src/zato/server/connection/cloud/microsoft_365.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2022, Zato Source s.r.o. https://zato.io +Copyright (C) 2024, Zato Source s.r.o. https://zato.io Licensed under AGPLv3, see LICENSE.txt for terms and conditions. """ @@ -50,7 +50,7 @@ def impl_from_config(self, config:'stranydict') -> 'Office365Account': tenant_id = config['tenant_id'] client_id = config['client_id'] - secret_value = config.get('secret_value') or config['password'] + secret_value = config.get('secret_value') or config.get('secret') or config['password'] credentials = (client_id, secret_value) diff --git a/code/zato-server/src/zato/server/service/internal/generic/connection.py b/code/zato-server/src/zato/server/service/internal/generic/connection.py index e34da30cfd..b1b6f8fcd1 100644 --- a/code/zato-server/src/zato/server/service/internal/generic/connection.py +++ b/code/zato-server/src/zato/server/service/internal/generic/connection.py @@ -433,7 +433,7 @@ def _run_pre_handle_tasks_CLOUD_MICROSOFT_365(self, session:'any_', instance:'an opaque1 = loads(opaque1) client_id = opaque1['client_id'] - secret_value = opaque1['secret_value'] + secret_value = opaque1.get('secret_value') or opaque1.get('secret') or opaque1['password'] credentials = (client_id, secret_value)