예제 #1
0
def list_systems(ctx, system: str, mandant: int, user: str, customer: str,
                 description: str, url: bool, verbose: bool,
                 enum: bool) -> list:
    """
    \b
    Print information about SAP systems \b
    \b
    Optional arguments:
    1. System: Request a SAP system by system id
    2. Mandant: Request a SAP system by mandant/client\n
    \b
    If no arguments - print information about all SAP systems from database
    """

    result = ""

    with _sap_db(ctx.obj.config):
        sap_system_sql = Sap_system(
            str(system).upper() if system else None,
            str(mandant) if mandant else None, user if user else None, None,
            customer if customer else None,
            description if description else None, None)
        result = sap.query_system(sap_system_sql)

        if not result:
            no_system_found = Sap_system(
                str(system).upper() if system else "",
                str(mandant).zfill(3) if mandant else "",
                user.upper() if user else "", "",
                str(customer).upper() if customer else "",
                description.upper() if description else "", "")
            utilities.print_system_list(
                no_system_found,
                title="NOTHING FOUND according to search criteria",
                color=utilities.color_warning,
            )
            return list()
        else:
            sap_system = [
                Sap_system(item[0], item[1], item[2],
                           ctx.obj.crypto.decrypto(item[3]), item[4], item[5],
                           item[6]) for item in result
            ]

            utilities.print_system_list(*sap_system,
                                        title="Available systems",
                                        verbose=verbose,
                                        url=url,
                                        enum=enum)
            if verbose:
                click.echo(
                    f"Information about passwords will be deleted from screen in {TIMER_TO_CLEAR_SCREEN}: \n"
                )
                try:
                    utilities.countdown(TIMER_TO_CLEAR_SCREEN)
                except KeyboardInterrupt:
                    click.echo("Aborted!")
                click.clear()

            return sap_system
예제 #2
0
def test_update_record(db, added_record, crypto):
    system_updated = Sap_system(system='XXX',
                                mandant='111',
                                user='******',
                                password=crypto.encrypto(str.encode('123')),
                                customer='TEST_test',
                                description='Development',
                                url='')
    db.update(system_updated)
    result_lst = db.query_system(
        Sap_system(system='XXX', mandant='111', user='******'))
    assert Sap_system(*result_lst[0]) == system_updated
예제 #3
0
def add(ctx, system: str, mandant: str, user: str, password: str,
        description: str, customer: str, url: str, verbose: bool):
    """
    Add sap system with it's parameters to db. Just run 'sap add' and follow instructions.
    """

    with _sap_db(ctx.obj.config):
        encrypted_password = ctx.obj.crypto.encrypto(str.encode(password))
        sap_system = Sap_system(
            str(system).upper(),
            str(mandant).zfill(3),
            str(user).upper(),
            encrypted_password,
            str(customer).upper(),
            str(description),
            str(url),
        )
        result = sap.add(sap_system)

        if result is not None:
            click.echo(
                click.style(
                    "Failed to add system to database ... \n",
                    **utilities.color_sensitive,
                ))
            click.echo(result)
        else:
            sap_system = Sap_system(
                str(system).upper() if system else None,
                str(mandant) if mandant else None,
                user.upper() if user else None)
            result = sap.query_system(sap_system)

            added_system = [
                Sap_system(item[0], item[1], item[2],
                           ctx.obj.crypto.decrypto(item[3]), item[4], item[5],
                           item[6]) for item in result
            ]
            utilities.print_system_list(
                *added_system,
                title="The following system is ADDED to the database: ",
                verbose=verbose)
            if verbose:
                click.echo(
                    f"Information about passwords will be deleted from screen in {TIMER_TO_CLEAR_SCREEN}: \n"
                )
                try:
                    utilities.countdown(TIMER_TO_CLEAR_SCREEN)
                except KeyboardInterrupt:
                    click.echo("Aborted!")
                click.clear()
예제 #4
0
def added_record(db, crypto):
    """ Add temporary record for testing purpose """
    system = Sap_system(system='XXX',
                        mandant='111',
                        user='******',
                        password=crypto.encrypto(str.encode('123')),
                        customer='Test',
                        description='Dev',
                        url='')
    db.add(system)
    return system
예제 #5
0
def stat(ctx, system: str, mandant: str, user: str, customer: str,
         description: str, language: str):
    """
    \b
    Displays 'System: status' window \n
    \b
    Optional arguments:
    1. SYSTEM: Request a SAP system by system id
    2. MANDANT: Request a SAP system by mandant/client
    """

    query_result = ctx.invoke(list_systems,
                              system=system,
                              mandant=mandant,
                              user=user,
                              customer=customer,
                              description=description,
                              url=False,
                              verbose=False,
                              enum=True)
    # --------------------------
    if query_result != []:
        selected_sap_systems = [
            Sap_system(item[0], item[1], item[2], item[3], item[4], item[5],
                       item[6]) for item in query_result
        ]

        if language is None:
            language = ctx.obj.config.language

        selected_system = utilities.choose_system(selected_sap_systems)
        try:
            argument = utilities.prepare_parameters_to_launch_system(
                selected_system, None, language, None, None, None, user, "",
                ctx.obj.config.command_line_path)
        except WrongPath as err:
            click.echo(f"{err}")
            raise click.Abort

        argument = argument + " -command=?STAT" + " -type=SystemCommand"

        utilities.print_system_list(
            selected_system, title="Opening STATUS of the following system")

        logger.info(f"{argument}")

        pop = Popen(argument)
        pop.wait()

        if pop.returncode:
            click.echo(pop.returncode, pop.communicate()[0])
예제 #6
0
def choose_system(sap_systems: list, verbose=False) -> Sap_system:
    ans = 0
    if len(sap_systems) >= 2:
        # print_system_list(sap_systems, 'Available systems', verbose=verbose, enum=True)

        while int(ans) > len(sap_systems) or int(ans) < 1:
            if 1 <= int(ans) <= len(sap_systems):
                break

            click.echo()
            ans = click.prompt(click.style(
                f"\nChoose system you want to logon. Available values from 1 to {str(len(sap_systems))}: \n>>>",
                **color_message),
                               type=int)
        ans = ans - 1

    selected_system: Sap_system = Sap_system(
        sap_systems[ans].system, sap_systems[ans].mandant,
        sap_systems[ans].user, sap_systems[ans].password,
        sap_systems[ans].customer, sap_systems[ans].description,
        sap_systems[ans].url)

    return selected_system
예제 #7
0
def delete(ctx, system: str, mandant: str, user: str, customer: str,
           description: str, confirm: bool):
    """
    \b
    Delete requested record about SAP system from database\n
    \b
    Optional arguments:
    1. SYSTEM: Request a SAP system by system id
    2. MANDANT: Request a SAP system by mandant/client
    """

    query_result = ctx.invoke(list_systems,
                              system=system,
                              mandant=mandant,
                              user=user,
                              customer=customer,
                              description=description,
                              url=False,
                              verbose=False,
                              enum=True)
    # --------------------------
    if query_result != []:
        selected_sap_systems = [
            Sap_system(item[0], item[1], item[2], item[3], item[4], item[5],
                       item[6]) for item in query_result
        ]

        selected_system = utilities.choose_system(selected_sap_systems)

        message = "Trying to DELETE the following systtem"
        utilities.print_system_list(selected_system, title=message)

        click.confirm(click.style('\nDo you really want to delete the system?',
                                  **utilities.color_sensitive),
                      abort=True,
                      default=confirm)

        system_to_delete = Sap_system(
            selected_system.system, selected_system.mandant,
            selected_system.user, selected_system.password,
            selected_system.customer, selected_system.description,
            selected_system.url)

        result = sap.delete(system_to_delete)

        result = sap.query_system(system_to_delete)

        if result == []:

            utilities.print_system_list(
                system_to_delete,
                title="The following system is DELETED from database")
        else:
            no_system_found = Sap_system(
                system.upper() if system else None,
                str(mandant).zfill(3) if mandant else None,
                user.upper() if user else None, None,
                customer.upper() if customer else None,
                description.upper() if description else None, None)

            utilities.print_system_list(
                no_system_found,
                title="FAILED TO UPDATE the following system",
                color=utilities.color_warning)
예제 #8
0
def update(ctx, system: str, mandant: str, user: str, customer: str,
           description: str, verbose: bool):
    """
    \b
    Update password, customer, system description or url of the requested record from database\n
    \b
    Optional arguments:
    1. SYSTEM: Request a SAP system by system id
    2. MANDANT: Request a SAP system by mandant/client
    """

    query_result = ctx.invoke(list_systems,
                              system=system,
                              mandant=mandant,
                              user=user,
                              customer=customer,
                              description=description,
                              url=False,
                              verbose=False,
                              enum=True)
    # --------------------------
    if query_result != []:
        selected_sap_systems = [
            Sap_system(item[0], item[1], item[2], item[3], item[4], item[5],
                       item[6]) for item in query_result
        ]

        selected_system = utilities.choose_system(selected_sap_systems)

        password_new = click.prompt("\nEnter new password",
                                    default=selected_system.password)
        customer_new = click.prompt("Enter Customer",
                                    default=selected_system.customer)
        description_new = click.prompt("Enter system description",
                                       default=selected_system.description)
        url_new = click.prompt("Enter URL", default=selected_system.url)

        sap_encrypted_system = Sap_system(
            str(selected_system.system).upper(),
            str(selected_system.mandant).zfill(3),
            str(selected_system.user).upper(),
            ctx.obj.crypto.encrypto(str.encode(password_new)),
            str(customer_new),
            str(description_new),
            str(url_new),
        )

        result = sap.update(sap_encrypted_system)

        if result is None:
            result = sap.query_system(sap_encrypted_system)

            updated_system = [
                Sap_system(item[0], item[1], item[2],
                           ctx.obj.crypto.decrypto(item[3]), item[4], item[5],
                           item[6]) for item in result
            ]

            utilities.print_system_list(
                *updated_system,
                title="The following system is UPDATED",
                verbose=verbose)

            click.echo(
                f"Information about passwords will be deleted from screen in {TIMER_TO_CLEAR_SCREEN}: \n"
            )
            try:
                utilities.countdown(TIMER_TO_CLEAR_SCREEN)
            except KeyboardInterrupt:
                click.echo("Aborted!")
            click.clear()
        else:
            no_system_found = Sap_system(
                system.upper() if system else None,
                str(mandant).zfill(3) if mandant else None,
                user.upper() if user else None, None,
                customer.upper() if customer else None,
                description.upper() if description else None, None)

            utilities.print_system_list(
                no_system_found,
                title="FAILED TO UPDATE the following system",
                color=utilities.color_warning)
예제 #9
0
def pw(ctx, system: str, mandant: int, user: str, customer: str,
       description: str, clear_clipboard: bool, time_to_clear: int):
    """
    \b
    Copy password for the requested system into clipboard.
    Script waits 15 seconds and clears clipboard.\n
    \b
    Optional argument:
    1. SYSTEM: Request a SAP system by system id
    2. MANDANT: Request a SAP system by mandant/client
    """

    query_result = ctx.invoke(list_systems,
                              system=system,
                              mandant=mandant,
                              user=user,
                              customer=customer,
                              description=description,
                              url=False,
                              verbose=False,
                              enum=True)
    # --------------------------
    if query_result != []:
        selected_sap_systems = [
            Sap_system(item[0], item[1], item[2], item[3], item[4], item[5],
                       item[6]) for item in query_result
        ]

        selected_system = utilities.choose_system(selected_sap_systems)

        pyperclip.copy(selected_system.password)

        click.echo(
            click.style(
                f"\nPassword is copied into clipboard.\n",
                **utilities.color_message,
            ))

        if clear_clipboard:
            click.echo(
                click.style(
                    "If you use Clipboard manager, you should add PY.EXE, CMD.EXE applications to the exclusion list,\n"
                    "in order to keep sensitive information safe.",
                    **utilities.color_sensitive,
                ))

            click.echo(
                click.style(
                    f"\nClipboard will be cleared in {time_to_clear} seconds.\n",
                    **utilities.color_message,
                ))

            try:
                utilities.countdown(time_to_clear)
            except KeyboardInterrupt:
                click.echo("\nAborted!")
            if ctypes.windll.user32.OpenClipboard(None):
                ctypes.windll.user32.EmptyClipboard()
            ctypes.windll.user32.CloseClipboard()

            click.echo(
                click.style("\nClipboard is cleared. \n",
                            **utilities.color_success))
예제 #10
0
def debug(ctx, system: str, mandant: str, user: str, customer: str,
          description: str, language: str, guiparm: str, snc_name: str,
          snc_qop: str, file: bool, open_file: bool):
    """
    \b
    System debug
    You can:
    1. Creat debug file - to debug modal dialog box: run 'sap debug -f'
    2. Start debuggin of the opened system (the last used windows will be used): run 'sap debug <system> <mandant>'
    \b
    Optional arguments:
    1. SYSTEM: Request a SAP system by system
    2. MANDANT: Request a SAP system by mandant/clien
    """

    if file:
        debug_folder = ctx.obj.config.config_path if ctx.obj.config.config_path else utilities.path(
        )
        debug_file_path = os.path.join(debug_folder, DEBUG_FILE_NAME)

        click.echo(f"\n{debug_file_path} file will be created.")
        click.echo(
            f"After creation, a folder with {DEBUG_FILE_NAME} file will be opened \n"
        )
        click.echo("Drag the file to the SAP system to start debug mode \n")
        click.pause("Press Enter to continue")

        with open(debug_file_path, "w", encoding='utf-8') as writer:
            writer.write("[FUNCTION]\n")
            writer.write("Command =/H\n")
            writer.write("Title=Debugger\n")
            writer.write("Type=SystemCommand")

        if open_file:
            click.launch(url=debug_file_path, locate=True)

    else:
        query_result = ctx.invoke(list_systems,
                                  system=system,
                                  mandant=mandant,
                                  user=user,
                                  customer=customer,
                                  description=description,
                                  url=False,
                                  verbose=False,
                                  enum=True)
        # --------------------------
        if query_result != []:
            selected_sap_systems = [
                Sap_system(item[0], item[1], item[2], item[3], item[4],
                           item[5], item[6]) for item in query_result
            ]

            if language is None:
                language = ctx.obj.config.language

            # As soon as dubugger stops working - revert all the changes to "prepare_parameters_to_launch_system"
            #  as it influence whether to open new windows, or to debug the latest opened. All arguments
            #  values must be entered
            selected_system = utilities.choose_system(selected_sap_systems)
            try:
                argument = utilities.prepare_parameters_to_launch_system(
                    selected_system, None, language, guiparm, snc_name,
                    snc_qop, None, user, "", ctx.obj.config.command_line_path)
            except WrongPath as err:
                click.echo(f"{err}")
                raise click.Abort

            argument = argument + " -command=/H" + " -type=SystemCommand"

            utilities.print_system_list(
                selected_system, title="Trying to DEBUG the following system")

            logger.info(f"{argument}")

            pop = Popen(argument)
            pop.wait()

            if pop.returncode:
                click.echo(pop.returncode, pop.communicate()[0])
예제 #11
0
def run(ctx, system: str, mandant: int, user: str, customer: str,
        description: str, external_user: bool, language: str, guiparm: str,
        snc_name: str, snc_qop: str, transaction: str, system_command: str,
        report: str, parameter: str, web: bool, reuse: bool):
    """
    \b
    Launch SAP system \n
    \b
    Optional arguments:
    1. SYSTEM: Request a SAP system by systedm id
    2. MANDANT: Request a SAP system by mandant/client
    """
    password = ""

    if snc_name is not None and snc_qop is None or snc_name is None and snc_qop is not None:
        click.echo(
            click.style(
                f"\nBoth parameters must be used: -sname/--snc_name and -sqop/--snc_qop",
                **utilities.color_warning))
        raise click.Abort

    if external_user:

        if not mandant:
            mandant = input("Enter mandant: ")
        user = input("Enter external user id: ")
        password = getpass.getpass("Enter password for external user: "******"", "",
                       "")
        ]
    else:

        query_result = ctx.invoke(list_systems,
                                  system=system,
                                  mandant=mandant,
                                  user=user,
                                  customer=customer,
                                  description=description,
                                  url=False,
                                  verbose=False,
                                  enum=True)
    # --------------------------
    if query_result != []:
        selected_sap_systems = [
            Sap_system(item[0], item[1], item[2], item[3], item[4], item[5],
                       item[6]) for item in query_result
        ]

        if language is None:
            language = ctx.obj.config.language

        selected_system = utilities.choose_system(selected_sap_systems)
        try:
            argument = utilities.prepare_parameters_to_launch_system(
                selected_system, password, language, guiparm, snc_name,
                snc_qop, user, "", ctx.obj.config.command_line_path)
        except WrongPath as err:
            click.echo(f"{err}")
            raise click.Abort

        if web:
            if selected_system.url != " ":
                # TODO: доделать передачу пароля для авторизации по аналогии с KeePass
                #   https://keepass.info/help/base/autotype.html
                #   https://github.com/allo-/passautotype - РЕАЛИЗАЦИЯ
                #   Сделать настройку для каждого сайта - т.е. отдельная таблица по параметрам сайтов

                # Not enough good solution but it works
                click.echo(
                    click.style(
                        f"\nLaunching web: {selected_system.description} of {selected_system.customer} ",
                        **utilities.color_success))

                click.launch(url=f"{selected_system.url}")
                time.sleep(2)
                pyautogui.write(selected_system.user)
                pyautogui.keyDown('tab')
                pyautogui.write(selected_system.password)
                pyautogui.keyDown('tab')
                pyautogui.keyDown('tab')
                pyautogui.keyDown('enter')
            else:
                no_system_found = Sap_system(
                    system.upper() if system else None,
                    str(mandant).zfill(3) if mandant else None,
                    user.upper() if user else None, None,
                    customer.upper() if customer else None,
                    description.upper() if description else None, None)

                utilities.print_system_list(
                    no_system_found,
                    title="NO URL FOUND according to search criteria",
                    color=utilities.color_warning)
                raise click.Abort
        else:
            if transaction:
                command = transaction
                command_type = 'transaction'

                argument = argument + " -type=transaction"

                if parameter:
                    param_data = sap.query_param(str(transaction).upper())

                    if param_data:
                        argument = argument + f' -command="{transaction.upper()} {param_data[0][1]}={parameter};"'
                    else:
                        click.echo(
                            click.style(
                                f"\nThere is no parameter info for {transaction.upper()} transaction",
                                **utilities.color_sensitive))
                        argument = argument + f' -command="{transaction.upper()}"'
                else:
                    argument = argument + " -command=" + transaction
            elif system_command:
                command = system_command
                command_type = 'system command'

                argument = argument + " -type=SystemCommand"
                argument = argument + " -command=" + system_command

            elif report:
                command = report
                command_type = 'report'

                argument = argument + " -type=report"
                argument = argument + " -command=" + report
            else:
                command = None
                command_type = None

            if external_user:
                message = "Trying to LAUNCH the following system with EXTERNAL USERS"
            else:
                message = "Trying to LAUNCH the following system "

            if reuse:
                argument = argument + f' -reuse=1'
            else:
                argument = argument + f' -reuse=0'

            utilities.print_system_list(selected_system,
                                        title=message,
                                        command=command,
                                        command_type=command_type)

            logger.info(f"{argument}")

            # Запускаем SAP
            pop = Popen(argument)
            pop.wait()

            if pop.returncode:
                click.echo(pop.returncode, pop.communicate()[0])
예제 #12
0
def test_delete_record_from_db(db, added_record):
    """ Test deleting records from database """
    system = Sap_system(*added_record)
    db.delete(system)
    result_lst = db.query_system(Sap_system(system='XXX'))
    assert result_lst == []
예제 #13
0
def test_add_record_to_db(db, added_record):
    """ Test adding records to database """
    result_lst = db.query_system(Sap_system(system='XXX'))
    assert Sap_system(*result_lst[0]) == added_record
예제 #14
0
def added_record(temp_db, crypto):
    """ Add temporary record for testing purpose """
    system = Sap_system('XXX', '100', 'USER',
                        crypto.encrypto(str.encode('123')), 'CUSTOMER',
                        'DEV_SYSTEM', '')
    temp_db.add(system)