From fbb61c247df048f1afac86d56dff2a672af7b158 Mon Sep 17 00:00:00 2001
From: Romain J <romain.ordi@gmail.com>
Date: Tue, 26 Jan 2021 11:59:36 +0100
Subject: [PATCH] feat(secure): add ip to the list of things to not to display

---
 tuxbot/cogs/Network/functions/converters.py |  8 ++++--
 tuxbot/core/config.py                       |  1 +
 tuxbot/core/utils/functions/extra.py        | 26 +++++++++++------
 tuxbot/setup.py                             | 32 +++++++++++++++++++++
 4 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/tuxbot/cogs/Network/functions/converters.py b/tuxbot/cogs/Network/functions/converters.py
index de387e3..79bcba2 100644
--- a/tuxbot/cogs/Network/functions/converters.py
+++ b/tuxbot/cogs/Network/functions/converters.py
@@ -10,7 +10,8 @@ def _(x):
 
 
 DOMAIN_PATTERN = r"^([A-Za-z0-9]\.|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9]\.){1,3}[A-Za-z]{2,6}$"
-IP_PATTERN = r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
+IPV4_PATTERN = r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
+IPV6_PATTERN = r"^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
 
 
 class IPConverter(commands.Converter):
@@ -18,9 +19,10 @@ class IPConverter(commands.Converter):
         argument = argument.replace("http://", "").replace("https://", "")
 
         check_domain = re.match(DOMAIN_PATTERN, argument)
-        check_ip = re.match(IP_PATTERN, argument)
+        check_ipv4 = re.match(IPV4_PATTERN, argument)
+        check_ipv6 = re.match(IPV6_PATTERN, argument)
 
-        if check_domain or check_ip:
+        if check_domain or check_ipv4 or check_ipv6:
             return argument
 
         raise InvalidIp(_("Invalid ip or domain"))
diff --git a/tuxbot/core/config.py b/tuxbot/core/config.py
index d4e04a8..465cc99 100644
--- a/tuxbot/core/config.py
+++ b/tuxbot/core/config.py
@@ -56,6 +56,7 @@ class Config(Structure):
         owners_id: List[int] = []
         prefixes: List[str] = []
         token: str = StrField("")
+        ip: str = StrField("")
         mentionable: bool = BoolField("")
         locale: str = StrField("")
         disabled_command: List[str] = []
diff --git a/tuxbot/core/utils/functions/extra.py b/tuxbot/core/utils/functions/extra.py
index 05b8fe4..380ee8a 100644
--- a/tuxbot/core/utils/functions/extra.py
+++ b/tuxbot/core/utils/functions/extra.py
@@ -11,6 +11,7 @@ console = Console()
 
 TOKEN_REPLACEMENT = "\\*" * random.randint(3, 15)
 PASSWORD_REPLACEMENT = "\\*" * random.randint(3, 15)
+IP_REPLACEMENT = "\\*" * random.randint(3, 15)
 
 
 class ContextPlus(commands.Context):
@@ -29,20 +30,27 @@ class ContextPlus(commands.Context):
     ):  # i know *args and **kwargs but, i prefer work with same values
 
         if content:
-            content = content.replace(
-                self.bot.config.Core.token, TOKEN_REPLACEMENT
-            ).replace(
-                self.bot.config.Core.Database.password, PASSWORD_REPLACEMENT
+            content = (
+                content.replace(self.bot.config.Core.token, TOKEN_REPLACEMENT)
+                .replace(
+                    self.bot.config.Core.Database.password,
+                    PASSWORD_REPLACEMENT,
+                )
+                .replace(self.bot.config.Core.ip, IP_REPLACEMENT)
             )
         if embed:
             e = embed.to_dict()
             for key, value in e.items():
                 if isinstance(value, (str, bytes)):
-                    e[key] = value.replace(
-                        self.bot.config.Core.token, TOKEN_REPLACEMENT
-                    ).replace(
-                        self.bot.config.Core.Database.password,
-                        PASSWORD_REPLACEMENT,
+                    e[key] = (
+                        value.replace(
+                            self.bot.config.Core.token, TOKEN_REPLACEMENT
+                        )
+                        .replace(
+                            self.bot.config.Core.Database.password,
+                            PASSWORD_REPLACEMENT,
+                        )
+                        .replace(self.bot.config.Core.ip, IP_REPLACEMENT)
                     )
             embed = Embed.from_dict(e)
 
diff --git a/tuxbot/setup.py b/tuxbot/setup.py
index 007a75b..ebc1bf6 100644
--- a/tuxbot/setup.py
+++ b/tuxbot/setup.py
@@ -168,6 +168,35 @@ def get_token() -> str:
     return token
 
 
+def get_ip() -> str:
+    """Get ip via input.
+
+    Returns
+    -------
+    str
+        The ip choose by user.
+    """
+    ip = ""
+
+    # pylint: disable=line-too-long
+    ipv4_pattern = r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
+    ipv6_pattern = r"^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
+
+    while not ip:
+        ip = Prompt.ask(
+            "Please the ip of this machine "
+            "(you can find it with `curl ifconfig.me`)",
+            console=console,
+        )
+        ipv4 = re.match(ipv4_pattern, ip)
+        ipv6 = re.match(ipv6_pattern, ip)
+
+        if not ipv4 and not ipv6:
+            console.print("[prompt.invalid]ERROR: Invalid ip provided")
+            ip = ""
+    return ip
+
+
 def get_multiple(
     question: str, confirmation: str, value_type: type
 ) -> List[Union[str, int]]:
@@ -281,6 +310,8 @@ def finish_setup(data_dir: Path) -> None:
 
     token = get_token()
 
+    ip = get_ip()
+
     console.print()
     prefixes = get_multiple(
         "Choice a (or multiple) prefix for the bot",
@@ -338,6 +369,7 @@ def finish_setup(data_dir: Path) -> None:
     instance_config.config.Core.owners_id = owners_id
     instance_config.config.Core.prefixes = prefixes
     instance_config.config.Core.token = token
+    instance_config.config.Core.ip = ip
     instance_config.config.Core.mentionable = mentionable
     instance_config.config.Core.locale = "en-US"