Ejemplo n.º 1
0
    def _set_subscription_key(self, service_name, use_robocloud_vault):
        common_key = "AZURE_SUBSCRIPTION_KEY"
        service_key = f"AZURE_{service_name.upper()}_KEY"
        sub_key = None
        if use_robocloud_vault:
            vault = Secrets()
            vault_items = vault.get_secret(self.robocloud_vault_name)
            vault_items = {k.upper(): v for (k, v) in vault_items.items()}
            if service_key in vault_items and vault_items[service_key].strip(
            ) != "":
                sub_key = vault_items[service_key]
            elif common_key in vault_items and vault_items[common_key].strip(
            ) != "":
                sub_key = vault_items[common_key]
            if sub_key is None:
                raise KeyError(
                    "The 'robocloud_vault_name' is required to access "
                    "Robocloud Vault. Set them in library "
                    "init or with `set_robocloud_vault` keyword.")
        else:
            sub_key = os.getenv(service_key)
            if sub_key is None or sub_key.strip() == "":
                sub_key = os.getenv(common_key)
            if sub_key is None or sub_key.strip() == "":
                raise KeyError(
                    "Azure service key is required to use Azure Cloud "
                    "service: %s" % service_name)

        self.services[service_name] = sub_key
Ejemplo n.º 2
0
 def __init__(self):
     self._secrets = Secrets()
     self._key = None
     listener = RobotLogListener()
     listener.register_protected_keywords(
         ["RPA.Crypto.generate_key", "RPA.Crypto.use_encryption_key"]
     )
Ejemplo n.º 3
0
def get_wicksly_info(tracking_number):
    secrets = Secrets()
    USER_NAME = secrets.get_secret("credentials")["PLATFORM_USERNAME"]
    PASSWORD = secrets.get_secret("credentials")["PLATFORM_PASS"]
    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False)
        wicksly_context = browser.newContext()
        w_page = wicksly_context.newPage()
        w_page.goto(os.environ.get('PLATFORM_URL'))
        w_page.fill('#id_username', USER_NAME)
        w_page.fill('#id_password', PASSWORD)
        with w_page.expect_navigation():
            w_page.click('input[type=submit]')
        w_page.goto(os.environ.get('PLATFORM_URL'))
        w_page.fill('#searchbar', tracking_number)

        with w_page.expect_navigation():
            w_page.click('text=Search')

        w_page.querySelectorAll('table#result_list tbody tr a')[0].click()
        street = w_page.getAttribute('#id_street1', 'value')
        city = w_page.getAttribute('#id_city', 'value')
        state = w_page.getAttribute('#id_state', 'value')
        postal_code = w_page.getAttribute('#id_postal_code', 'value')

        return {
            'street': street,
            'city': city,
            'state': state,
            'postal_code': postal_code
        }
Ejemplo n.º 4
0
 def _init_client(
     self,
     service_name: str,
     aws_key_id: str = None,
     aws_key: str = None,
     region: str = None,
     use_robocloud_vault: bool = False,
 ):
     if region is None:
         region = self.region
     if use_robocloud_vault:
         vault = Secrets()
         vault_items = vault.get_secret(self.robocloud_vault_name)
         vault_items = {k.upper(): v for (k, v) in vault_items.items()}
         aws_key_id = vault_items["AWS_KEY_ID"]
         aws_key = vault_items["AWS_KEY"]
     else:
         if aws_key_id is None or aws_key_id.strip() == "":
             aws_key_id = required_env("AWS_KEY_ID")
         if aws_key is None or aws_key.strip() == "":
             aws_key = required_env("AWS_KEY")
     if (aws_key_id is None or aws_key_id.strip() == "" or aws_key is None
             or aws_key.strip() == ""):
         raise KeyError("AWS key ID and secret access key are required "
                        " to use AWS cloud service: %s" % service_name)
     client = boto3.client(
         service_name,
         region_name=region,
         aws_access_key_id=aws_key_id,
         aws_secret_access_key=aws_key,
     )
     self._set_service(service_name, client)
Ejemplo n.º 5
0
def login(page):
    page.goto(sales_navigator_login_url)
    page.waitForLoadState('load')
    secrets = Secrets()
    USER_NAME = secrets.get_secret("credentials")["LINKEDIN_EMAIL"]
    PASSWORD = secrets.get_secret("credentials")["LINKEDIN_PASSWORD"]
    page.fill('input#username', USER_NAME)
    page.fill('input#password', PASSWORD)
    page.click('button[type=submit]')
Ejemplo n.º 6
0
def test_file_secret_manager(monkeypatch):
    monkeypatch.setenv("RPA_SECRET_MANAGER",
                       "RPA.Robocloud.Secrets.FileSecrets")
    monkeypatch.setenv("RPA_SECRET_FILE", "tests/resources/secrets.json")
    from RPA.Robocloud.Secrets import Secrets

    sm = Secrets()
    assert sm.secretmanager == "RPA.Robocloud.Secrets.FileSecrets"
    secrets = sm.get_secret("credentials")
    assert secrets["sap"]["login"] == "robot"
    assert secrets["sap"]["password"] == "secret"
    assert secrets["google"]["apikey"] == "1234567890"
Ejemplo n.º 7
0
    def _get_service_account_from_robocloud(self):
        temp_filedesc = None
        if self.robocloud_vault_name is None or self.robocloud_vault_secret_key is None:
            raise KeyError(
                "Both 'robocloud_vault_name' and 'robocloud_vault_secret_key' "
                "are required to access Robocloud Vault. Set them in library "
                "init or with `set_robocloud_vault` keyword."
            )
        vault = Secrets()

        vault_items = vault.get_secret(self.robocloud_vault_name)
        secret = json.loads(vault_items[self.robocloud_vault_secret_key].strip())
        with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp_filedesc:
            json.dump(secret, temp_filedesc, ensure_ascii=False)

        return temp_filedesc.name
Ejemplo n.º 8
0
 def _init_with_robocloud(self, client_object, service_name):
     temp_filedesc = None
     if self.robocloud_vault_name is None or self.robocloud_vault_secret_key is None:
         raise KeyError(
             "Both 'robocloud_vault_name' and 'robocloud_vault_secret_key' "
             "are required to access Robocloud Vault. Set them in library "
             "init or with `set_robocloud_vault` keyword."
         )
     vault = Secrets()
     try:
         vault_items = vault.get_secret(self.robocloud_vault_name)
         secret = json.loads(vault_items[self.robocloud_vault_secret_key].strip())
         with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp_filedesc:
             json.dump(secret, temp_filedesc, ensure_ascii=False)
         client = client_object.from_service_account_json(temp_filedesc.name)
         self._set_service(service_name, client)
     finally:
         if temp_filedesc:
             os.remove(temp_filedesc.name)
Ejemplo n.º 9
0
def test_secrets_custom_adapter_arguments(mock_env_default):
    library = Secrets("pos-value",
                      key="key-value",
                      default_adapter=MockAdapter)
    library.get_secret("not-relevant")  # Adapter created on first request
    assert MockAdapter.args == (("pos-value", ), {"key": "key-value"})
Ejemplo n.º 10
0
def test_secrets_vault_missing_token(mock_env_default, mock_env_vault,
                                     monkeypatch):
    monkeypatch.delenv("RC_API_SECRET_TOKEN", raising=False)
    library = Secrets()
    with pytest.raises(KeyError):
        _ = library.adapter
Ejemplo n.º 11
0
def test_secrets_vault_as_default(mock_env_default, mock_env_vault):
    library = Secrets()
    assert isinstance(library.adapter, RobocloudVault)
Ejemplo n.º 12
0
'''
Variables for Robot Framework goes here.
'''
import calendar
from datetime import date

from RPA.Robocloud.Secrets import Secrets

WEEK_DAY_NAME = calendar.day_name[date.today().weekday()]

secrets = Secrets()
GA_UCC_USERNAME = secrets.get_secret("ga_ucc_creds")["username"]
GA_UCC_PASSWORD = secrets.get_secret("ga_ucc_creds")["password"]
Ejemplo n.º 13
0
 def __init__(self):
     super().__init__()
     self.dbx = dropbox.Dropbox(
         Secrets().get_secret("Dropbox")["ACCESS_TOKEN"])
Ejemplo n.º 14
0
def test_not_existing_class_as_secret_manager(monkeypatch):
    monkeypatch.setenv("RPA_SECRET_MANAGER", "RPA.NotExistingSecretManager")
    from RPA.Robocloud.Secrets import Secrets

    with pytest.raises(Exception):
        Secrets()
from RPA.Email.ImapSmtp import ImapSmtp
from RPA.Robocloud.Secrets import Secrets

secrets = Secrets()
secret = secrets.get_secret("emailCredentials")
gmail_account = secret["username"]
gmail_password = secret["password"]


def send_email(recipient, subject, body):
    mail = ImapSmtp(smtp_server="smtp.gmail.com", smtp_port=587)
    mail.authorize(account=gmail_account, password=gmail_password)
    mail.send_message(
        sender=gmail_account,
        recipients=recipient,
        subject=subject,
        body=body,
    )
Ejemplo n.º 16
0
def test_invalid_base_class_as_secret_manager(monkeypatch):
    monkeypatch.setenv("RPA_SECRET_MANAGER", "RPA.Trollo")
    from RPA.Robocloud.Secrets import Secrets

    with pytest.raises(Exception):
        Secrets()
Ejemplo n.º 17
0
def test_use_secret_manager_when_environment_is_not_set(monkeypatch):
    monkeypatch.delenv("RPA_SECRET_MANAGER", raising=False)
    from RPA.Robocloud.Secrets import Secrets

    sm = Secrets()
    assert sm.secretmanager == "RPA.Robocloud.Secrets.RobocloudVault"
Ejemplo n.º 18
0
import os
from pathlib import Path
import shutil
import sys

from RPA.Archive import Archive
from RPA.Browser import Browser
from RPA.FileSystem import FileSystem
from RPA.PDF import PDF
from RPA.Robocloud.Secrets import Secrets
from RPA.Robocloud.Items import Items

archive = Archive()
browser = Browser()
pdf = PDF()
secretmanager = Secrets()
workitems = Items()
files = FileSystem()

output_dir = Path(".") / "output"
image_dir = output_dir / "images"
pdf_dir = output_dir / "pdfs"


def main():
    """Robot workflow actions."""
    all_steps_done = False
    try:
        clear_previous_run()  # this can be skipped
        open_page()
        log_in()
Ejemplo n.º 19
0
def test_secrets_adapter_invalid_baseclass(mock_env_default):
    with pytest.raises(ValueError):
        Secrets(default_adapter=InvalidBaseClass)
Ejemplo n.º 20
0
def get_and_display_secrets(credential: str):
    secrets = Secrets()
    user_details = secrets.get_secret(credential)["username"]
    print(user_details)
Ejemplo n.º 21
0
'''
Variables for Robot Framework goes here.
'''
import calendar
from datetime import date

# +
from RPA.Robocloud.Secrets import Secrets

secrets = Secrets()
USER_NAME = secrets.get_secret("credentials")["username"]
PASSWORD = secrets.get_secret("credentials")["password"]
# -

WEEK_DAY_NAME = calendar.day_name[date.today().weekday()]
Ejemplo n.º 22
0
from RPA.Robocloud.Secrets import Secrets

EXCEL_FILE_PATH = __file__ + "/../../devdata/Data.xlsx"
SWAG_LABS_URL = "https://www.saucedemo.com"

secrets = Secrets()
SWAG_LABS_USER_NAME = secrets.get_secret("swaglabs")["username"]
SWAG_LABS_PASSWORD = secrets.get_secret("swaglabs")["password"]
Ejemplo n.º 23
0
def test_secrets_custom_adapter_get_secret(mock_env_default):
    MockAdapter.value = "mock-secret"
    library = Secrets(default_adapter=MockAdapter)
    assert library.get_secret("mock-name") == "mock-secret"
    assert MockAdapter.name == "mock-name"
Ejemplo n.º 24
0
def test_secrets_adapter_missing_import(monkeypatch):
    monkeypatch.setenv("RPA_SECRET_MANAGER", "RPA.AdapterNotExist")
    with pytest.raises(ValueError):
        Secrets()
Ejemplo n.º 25
0
class Crypto:
    """Library for common encryption and hashing operations.

    It uses the `Fernet <https://github.com/fernet/spec/blob/master/Spec.md>`_
    format for encryption. More specifically, it uses AES in
    CBC mode with a 128-bit key for encryption and HMAC with SHA256 for
    authentication.

    To use the encryption features, generate a key with the command line
    utility ``rpa-crypto`` or with the keyword ``Generate Key``. Store
    the key in a secure place, such as Robocorp Vault, and load it within
    the execution before calling encryption/decryption keywords.

    **Example usage with Robocorp Vault**

    Create an encryption key with the CLI utility:

    .. code-block:: console

        > rpa-crypto key
        rGx1edA07yz7uD08ChiPSunn8vaauRxw0pAbsal9zjM=

    Store the key in Robocorp Vault, in this case with the name ``EncryptionKey``.

    Load the key from the vault before encryption operations:

    .. code-block:: robotframework

        Use encryption key from vault    EncryptionKey
        ${encrypted}=   Encrypt file    orders.xlsx
        Add work item file    ${encrypted}    name=Orders

    In another task, this same key can be used to decrypt the file:

    .. code-block:: robotframework

        Use encryption key from vault    EncryptionKey
        ${encrypted}=    Get work item file    Orders
        ${orders}=   Decrypt file    ${encrypted}
    """

    ROBOT_LIBRARY_SCOPE = "GLOBAL"
    ROBOT_LIBRARY_DOC_FORMAT = "REST"

    def __init__(self):
        self._secrets = Secrets()
        self._key = None
        listener = RobotLogListener()
        listener.register_protected_keywords(
            ["RPA.Crypto.generate_key", "RPA.Crypto.use_encryption_key"]
        )

    def generate_key(self) -> str:
        """Generate a Fernet encryption key as base64 string.

        This key can be used for encryption/decryption operations
        with this library.

        *NOTE:* Store the generated key in a secure place!
        If the key is lost, the encrypted data can not be recovered.
        If anyone else gains access to it, they can decrypt your data.
        """
        return Fernet.generate_key().decode("utf-8")

    def use_encryption_key(self, key: str):
        """Set key for all following encryption/decryption operations.

        :param key: Encryption key as base64 string

        Assumes the given key has been generated previously using
        either the keyword ``Generate Key`` or with the matching command
        line utility.

        Example:

        .. code-block:: robotframework

            ${key}=    Read file    encryption.key
            Use encryption key      ${key}
        """
        self._key = Fernet(key)

    def use_encryption_key_from_vault(self, name: str, key: Optional[str] = None):
        """Load an encryption key from Robocorp Vault.

        :param name: Name of secret in Vault
        :param key: Name of encryption key in secret

        If the secret only has one value, the key argument is optional.

        Example:

        .. code-block:: robotframework

            # Secret with one value
            Use encryption key from vault    Encryption
            # Secret with multiple values
            Use encryption key from vault    name=Encryption    key=CryptoKey
        """
        secret = self._secrets.get_secret(name)

        if key:
            value = secret[key]
        elif len(secret) == 1:
            value = list(secret.values())[0]
        elif len(secret) == 0:
            raise ValueError(f"Secret '{name}' has no values")
        else:
            options = ", ".join(str(k) for k in secret.keys())
            raise ValueError(f"Secret '{name}' has multiple values: {options}")

        self.use_encryption_key(value)

    def hash_string(self, text: str, method: Hash = Hash.SHA1, encoding="utf-8") -> str:
        """Calculate a hash from a string, in base64 format.

        :param text: String to hash
        :param method: Used hashing method
        :param encoding: Used text encoding

        Example:

        .. code-block:: robotframework

            ${digest}=    Hash string    A value that will be hashed
            Should be equal    ${digest}    uSlyRHlbu8NzY29YMZhDUpdErP4=
        """
        if isinstance(text, str):
            text = text.encode(encoding)

        context = to_hash_context(method)
        context.update(text)

        digest = context.finalize()
        return base64.b64encode(digest).decode("utf-8")

    def hash_file(self, path: str, method: Hash = Hash.SHA1) -> str:
        """Calculate a hash from a file, in base64 format.

        :param path: Path to file
        :param method: The used hashing method

        Example:

        .. code-block:: robotframework

            ${digest}=    Hash file    orders.xlsx    method=MD5
            Should not be equal    ${digest}    uSlyRHlbu8NzY29YMZhDUpdErP4=
        """
        context = to_hash_context(method)
        with open(path, "rb") as infile:
            while True:
                chunk = infile.read(65536)
                if not chunk:
                    break
                context.update(chunk)

        digest = context.finalize()
        return base64.b64encode(digest).decode("utf-8")

    def encrypt_string(self, text: Union[bytes, str], encoding="utf-8") -> bytes:
        """Encrypt a string.

        :param text: Source text to encrypt
        :param encoding: Used text encoding

        Example:

        .. code-block:: robotframework

            Use encryption key    ${key}
            ${token}=    Encrypt string    This is a secret, don't share it
        """
        if not self._key:
            raise ValueError("No encryption key set")

        if isinstance(text, str):
            text = text.encode(encoding)

        token = self._key.encrypt(text)
        return token

    def decrypt_string(
        self, data: Union[bytes, str], encoding="utf-8"
    ) -> Union[str, bytes]:
        """Decrypt a string.

        :param data: Encrypted data as base64 string
        :param encoding: Original encoding of string

        Returns the decrypted string that is parsed with the given encoding,
        or if the encoding is ``None`` the raw bytes are returned.

        Example:

        .. code-block:: robotframework

            Use encryption key    ${key}
            ${text}=    Decrypt string    ${token}
            Log    Secret string is: ${text}
        """
        if not self._key:
            raise ValueError("No encryption key set")

        if isinstance(data, str):
            data = data.encode("utf-8")

        try:
            text = self._key.decrypt(data)
        except InvalidToken as err:
            raise ValueError(
                "Failed to decrypt string (malformed content or invalid signature)"
            ) from err

        if encoding is not None:
            text = text.decode(encoding)

        return text

    def encrypt_file(self, path: str, output: Optional[str] = None) -> str:
        """Encrypt a file.

        :param path: Path to source input file
        :param output: Path to encrypted output file

        If not output path is given, it will generate one from the input path.
        The resulting output path is returned.

        Example:

        .. code-block:: robotframework

            Use encryption key    ${key}
            ${path}=    Encrypt file    orders.xlsx
            Log    Path to encrypted file is: ${path}
        """
        path = Path(path)
        if not self._key:
            raise ValueError("No encryption key set")

        if output:
            output = Path(output)
        else:
            output = path.parent / (path.name + ".enc")

        with open(path, "rb") as infile:
            data = infile.read()
            token = self._key.encrypt(data)

        with open(output, "wb") as outfile:
            outfile.write(token)
            return str(output)

    def decrypt_file(self, path: str, output: Optional[str] = None) -> str:
        """Decrypt a file.

        :param path: Path to encrypted input file
        :param output: Path to decrypted output file

        If not output path is given, it will generate one from the input path.
        The resulting output path is returned.

        Example:

        .. code-block:: robotframework

            Use encryption key    ${key}
            ${path}=    Decrypt file    orders.xlsx.enc
            Log    Path to decrypted file is: ${path}
        """
        path = Path(path)
        if not self._key:
            raise ValueError("No encryption key set")

        if output:
            output = Path(output)
        elif path.name.endswith(".enc"):
            output = path.parent / path.name[: -len(".enc")]
        else:
            parts = (path.stem, "dec", path.suffix[1:])
            output = path.parent / ".".join(part for part in parts if part.strip())

        try:
            with open(path, "rb") as infile:
                token = infile.read()
                data = self._key.decrypt(token)
        except InvalidToken as err:
            raise ValueError(
                "Failed to decrypt file (malformed content or invalid signature)"
            ) from err

        with open(output, "wb") as outfile:
            outfile.write(data)
            return str(output)
Ejemplo n.º 26
0
from RPA.Robocloud.Secrets import Secrets

secrets = Secrets()
USER_NAME = secrets.get_secret("CaptureFastCredentials")["username"]
PASSWORD = secrets.get_secret("CaptureFastCredentials")["password"]
TEAMID = secrets.get_secret("CaptureFastCredentials")["teamid"]
from RPA.Robocloud.Secrets import Secrets

# Set global variable for local file path for Order backlog (CSV file)
CSV_LOCAL_FILE_PATH = "./output/orders.csv"

# Use vault to store secret URLs for RobotSpareBin website and Order backlog (CSV file)
secrets = Secrets()
WEBSITE_URL = secrets.get_secret("ROBOTSPAREBIN")["WEBSITE_URL"]
CSV_URL = secrets.get_secret("ROBOTSPAREBIN")["CSV_URL"]