diff --git a/sophosfirewall_python/admin.py b/sophosfirewall_python/admin.py
index fd531af..ca15a16 100644
--- a/sophosfirewall_python/admin.py
+++ b/sophosfirewall_python/admin.py
@@ -7,6 +7,7 @@
permissions and limitations under the License.
"""
from sophosfirewall_python.utils import Utils
+from xmltodict import unparse
class AclRule:
"""Class for working with Local Service ACL Exception Rules."""
@@ -179,3 +180,200 @@ def get(self, name):
xml_tag="Notification", key="Name", value=name
)
return self.client.get_tag(xml_tag="Notification")
+
+class AdminSettings:
+ """Class for working with Admin and user settings (System > Administration)."""
+
+ def __init__(self, api_client):
+ self.client = api_client
+
+ def get(self):
+ """Get Admin and user settings
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return self.client.get_tag(xml_tag="AdminSettings")
+
+ def update_hostname_settings(self, hostname=None, description=None, debug=False):
+ """Update hostname admin settings.
+
+ Args:
+ hostname (str, optional): Hostname. Defaults to None.
+ description (str, optional): Hostname description. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ exist_settings = self.get()["Response"]["AdminSettings"]["HostnameSettings"]
+
+ template_data = """
+
+
+ {{ hostname }}
+ {{ description }}
+
+
+ """
+ template_vars = {
+ "hostname": hostname if hostname else exist_settings["HostName"],
+ "description": description if description else exist_settings["HostNameDesc"]
+ }
+
+ return self.client.submit_xml(template_data=template_data, template_vars=template_vars, set_operation="update", debug=debug)
+
+ def update_webadmin_settings(self, certificate=None,
+ https_port=None,
+ userportal_https_port=None,
+ vpnportal_https_port=None,
+ portal_redirect_mode=None,
+ portal_custom_hostname=None,
+ debug=False):
+ """Update webadmin settings. System > Administration > Admin and user settings.
+
+ Args:
+ certificate (str, optional): SSL Certificate name. Defaults to None.
+ https_port (str, optional): HTTPS port for admin interface. Defaults to None.
+ userportal_https_port (str, optional): HTTPS port for User portal. Defaults to None.
+ vpnportal_https_port (str, optional): HTTPS port for VPN portal. Defaults to None.
+ portal_redirect_mode (str, optional): Portal redirect mode. Defaults to None.
+ portal_custom_hostname (str, optional): Portal custom hostname. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ exist_settings = self.get()["Response"]["AdminSettings"]["WebAdminSettings"]
+
+ template_data = """
+
+
+ {{ certificate }}
+ {{ https_port }}
+ {{ userportal_https_port }}
+ {{ vpnportal_https_port }}
+ {{ portal_redirect_mode }}
+ {{ port_custom_hostname }}
+
+
+ """
+ template_vars = {
+ "certificate": certificate if certificate else exist_settings["Certificate"],
+ "https_port": https_port if https_port else exist_settings["HTTPSport"],
+ "userportal_https_port": userportal_https_port if userportal_https_port else exist_settings["UserPortalHTTPSPort"],
+ "vpnportal_https_port": vpnportal_https_port if vpnportal_https_port else exist_settings["VPNPortalHTTPSPort"],
+ "portal_redirect_mode": portal_redirect_mode if portal_redirect_mode else exist_settings["PortalRedirectMode"],
+ "portal_custom_hostname": portal_custom_hostname if portal_custom_hostname else exist_settings["PortalCustomHostname"]
+ }
+
+ return self.client.submit_xml(template_data=template_data, template_vars=template_vars, set_operation="update", debug=debug)
+
+ def update_loginsecurity_settings(self, logout_session=None, block_login=None, unsuccessful_attempt=None, duration=None, minutes=None, debug=False):
+ """Update login security admin settings. System > Administration > Admin and user settings.
+
+ Args:
+ logout_session (str, optional): Enable/disable logout session. Specify number of minutes to enable. Defaults to None.
+ block_login (str, optional): Enable/disable block login. Defaults to None.
+ unsuccessful_attempt (str, optional): Set number of unsuccessful attempts. Defaults to None.
+ duration (str, optional): Set block login duration. Defaults to None.
+ minutes (str, optional): Set number of minutes for block login. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ exist_settings = self.get()["Response"]["AdminSettings"]["LoginSecurity"]
+
+ template_data = """
+
+
+ {{ logout_session }}
+ {{ block_login }}
+ {% if block_login == 'Enable' %}
+
+ {{ unsuccessful_attempt }}
+ {{ duration }}
+ {{ minutes }}
+
+ {% endif %}
+
+
+ """
+ if not unsuccessful_attempt and "BlockLoginSettings" in exist_settings:
+ unsuccessful_attempt = exist_settings["BlockLoginSettings"]["UnsucccessfulAttempt"]
+ if not duration and "BlockLoginSettings" in exist_settings:
+ duration = exist_settings["BlockLoginSettings"]["Duration"]
+ if not minutes and "BlockLoginSettings" in exist_settings:
+ minutes = exist_settings["BlockLoginSettings"]["ForMinutes"]
+ template_vars = {
+ "logout_session": logout_session if logout_session else exist_settings["LogoutSession"],
+ "block_login": block_login if block_login else exist_settings["BlockLogin"],
+ "unsuccessful_attempt": unsuccessful_attempt if unsuccessful_attempt else "5",
+ "duration": duration if duration else "5",
+ "minutes": minutes if minutes else "60"
+ }
+
+ return self.client.submit_xml(template_data=template_data, template_vars=template_vars, set_operation="update", debug=debug)
+
+ def update_passwordcomplexity_settings(self, complexity_check=None, enforce_min_length=None, include_alpha=None, include_numeric=None, include_special=None, min_length=None, debug=False):
+ """Update password complexity settings. System > Administration > Admin and user settings.
+
+ Args:
+ complexity_check (str, optional): Enable/disable password complexity check. Defaults to None.
+ enforce_min_length (str, optional): Enforce minimum required password length. Defaults to None.
+ include_alpha (str, optional): Enforce inclusion of alphanumeric characters. Defaults to None.
+ include_numeric (str, optional): Enforce inclusion numeric characters. Defaults to None.
+ include_special (str, optional): Enforce inclusion of special characters. Defaults to None.
+ min_length (str, optional): Minimul required password length. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ exist_settings = self.get()["Response"]["AdminSettings"]["PasswordComplexitySettings"]
+
+ template_data = """
+
+
+ {{ complexity_check }}
+
+ {{ enforce_min_length }}
+ {{ include_alpha }}
+ {{ include_special }}
+ {{ include_special }}
+ {{ min_length }}
+
+
+
+ """
+
+ template_vars = {
+ "complexity_check": complexity_check if complexity_check else exist_settings["PasswordComplexityCheck"],
+ "enforce_min_length": enforce_min_length if enforce_min_length else exist_settings["PasswordComplexity"]["MinimumPasswordLength"],
+ "include_alpha": include_alpha if include_alpha else exist_settings["PasswordComplexity"]["IncludeAlphabeticCharacters"],
+ "include_numeric": include_numeric if include_numeric else exist_settings["PasswordComplexity"]["IncludeNumericCharacter"],
+ "include_special": include_special if include_special else exist_settings["PasswordComplexity"]["IncludeSpecialCharacter"],
+ "min_length": min_length if min_length else exist_settings["PasswordComplexity"]["MinimumPasswordLengthValue"]
+ }
+
+ return self.client.submit_xml(template_data=template_data, template_vars=template_vars, set_operation="update", debug=debug)
+
+ def update_login_disclaimer(self, enabled: bool = False, debug: bool = False):
+ """Update login disclaimer. System > Administration > Admin and user settings.
+
+ Args:
+ enabled (bool, optional): Enable or disable Login Disclaimer. Defaults to True.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ if enabled:
+ setting = "Enable"
+ else:
+ setting = "Disable"
+
+ template_data = """
+
+ {{ setting }}
+
+ """
+ template_vars = {"setting": setting}
+
+ return self.client.submit_xml(template_data=template_data, template_vars=template_vars, set_operation="update", debug=debug)
diff --git a/sophosfirewall_python/api_client.py b/sophosfirewall_python/api_client.py
index 51d082a..0542640 100644
--- a/sophosfirewall_python/api_client.py
+++ b/sophosfirewall_python/api_client.py
@@ -190,7 +190,8 @@ def submit_xml(
set_operation: str = "add",
debug: bool = False,
) -> dict:
- """Submits XML payload as a string to the API.
+ """Submits XML payload as a string to the API.
+
Args:
template_data (str): A string containing the XML payload. Variables can be optionally passed in the string using Jinja2 (ex. {{ some_var }})
template_vars (dict, optional): Dictionary of variables to inject into the XML string.
diff --git a/sophosfirewall_python/firewallapi.py b/sophosfirewall_python/firewallapi.py
index 79fb5fa..cf4b479 100644
--- a/sophosfirewall_python/firewallapi.py
+++ b/sophosfirewall_python/firewallapi.py
@@ -30,7 +30,7 @@
)
from sophosfirewall_python.service import Service, ServiceGroup
from sophosfirewall_python.network import Interface, Vlan, Zone
-from sophosfirewall_python.admin import AclRule, Notification
+from sophosfirewall_python.admin import AclRule, Notification, AdminSettings
from sophosfirewall_python.authen import User, AdminAuthen
from sophosfirewall_python.profile import AdminProfile
from sophosfirewall_python.ips import IPS
@@ -376,7 +376,7 @@ def get_admin_settings(self):
Returns:
dict: XML response converted to Python dictionary
"""
- return self.client.get_tag(xml_tag="AdminSettings")
+ return AdminSettings(self.client).get()
def get_dns_forwarders(self):
"""Get DNS forwarders.
@@ -937,6 +937,110 @@ def update_rule(self, name: str, rule_params: dict, debug: bool = False):
dict: XML response converted to Python dictionary
"""
return FirewallRule(self.client).update(name, rule_params, debug)
+
+ def update_hostname_settings(self, hostname: str = None, description: str = None, debug: bool = False):
+ """Update hostname admin settings. System > Administration > Admin and user settings.
+
+ Args:
+ hostname (str, optional): Hostname. Defaults to None.
+ description (str, optional): Hostname description. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return AdminSettings(self.client).update_hostname_settings(hostname, description, debug)
+
+ def update_webadmin_settings(self, certificate: str = None,
+ https_port: str = None,
+ userportal_https_port: str = None,
+ vpnportal_https_port: str = None,
+ portal_redirect_mode: str = None,
+ portal_custom_hostname: str = None,
+ debug: bool = False):
+ """Update webadmin settings. System > Administration > Admin and user settings.
+
+ Args:
+ certificate (str, optional): SSL Certificate name. Defaults to None.
+ https_port (str, optional): HTTPS port for admin interface. Defaults to None.
+ userportal_https_port (str, optional): HTTPS port for User portal. Defaults to None.
+ vpnportal_https_port (str, optional): HTTPS port for VPN portal. Defaults to None.
+ portal_redirect_mode (str, optional): Portal redirect mode. Defaults to None.
+ portal_custom_hostname (str, optional): Portal custom hostname. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return AdminSettings(self.client).update_webadmin_settings(certificate,
+ https_port,
+ userportal_https_port,
+ vpnportal_https_port,
+ portal_redirect_mode,
+ portal_custom_hostname,
+ debug)
+
+ def update_loginsecurity_settings(self, logout_session: str = None,
+ block_login: str = None,
+ unsuccessful_attempt: str = None,
+ duration: str = None,
+ minutes: str = None,
+ debug: bool = False):
+ """Update login security settings. System > Administration > Admin and user settings.
+
+ Args:
+ logout_session (str, optional): Enable to logout Admin Session after configured timeout. Specify number of minutes to enable (1-120). Defaults to None.
+ block_login (str, optional): Enable to block Admin login after configured number of failed attempts within configured time span. Defaults to None.
+ unsuccessful_attempt (str, optional): Allowed number of failed Admin login attempts from the same IP address (1-5). Defaults to None.
+ duration (str, optional): Time span within which if Admin Login attempts exceed configured Unsuccessful Attempts, then Admin Login gets blocked. (1-120). Defaults to None.
+ minutes (str, optional): Time interval for which Admin Login is blocked (1-60). Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return AdminSettings(self.client).update_loginsecurity_settings(logout_session,
+ block_login,
+ unsuccessful_attempt,
+ duration,
+ minutes,
+ debug)
+
+ def update_passwordcomplexity_settings(self, complexity_check: str = None,
+ enforce_min_length: str = None,
+ include_alpha: str = None,
+ include_numeric: str = None,
+ include_special: str = None,
+ min_length: str = None,
+ debug: bool = False):
+ """Update hostname admin settings. System > Administration > Admin and user settings.
+
+ Args:
+ complexity_check (str, optional): Enable/disable password complexity check. Defaults to None.
+ enforce_min_length (str, optional): Enforce minimum required password length. Defaults to None.
+ include_alpha (str, optional): Enforce inclusion of alphanumeric characters. Defaults to None.
+ include_numeric (str, optional): Enforce inclusion numeric characters. Defaults to None.
+ include_special (str, optional): Enforce inclusion of special characters. Defaults to None.
+ min_length (str, optional): Minimul required password length. Defaults to None.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return AdminSettings(self.client).update_passwordcomplexity_settings(complexity_check,
+ enforce_min_length,
+ include_alpha,
+ include_numeric,
+ include_special,
+ min_length,
+ debug)
+
+ def update_login_disclaimer(self, enabled: bool = False, debug: bool = False):
+ """Update login disclaimer. System > Administration > Admin and user settings.
+
+ Args:
+ enabled (bool, optional): Enable or disable Login Disclaimer. Defaults to True.
+
+ Returns:
+ dict: XML response converted to Python dictionary
+ """
+ return AdminSettings(self.client).update_login_disclaimer(enabled, debug)
# Export the error classes for backward compatibility
__all__ = [