Exemple #1
0
    async def verify_and_process(request, sso_type: str):
        """
        Fetches user details and returns a login token.
        If user does not have an account, it will be created.

        :param request: starlette request object
        :param sso_type: one of supported types - google/facebook/linkedin.
        """
        sso_client = LoginSSOFactory.get_client(sso_type)
        user_details = await sso_client.verify(request)
        try:
            AccountProcessor.get_user(user_details['email'])
            existing_user = True
        except DoesNotExist:
            existing_user = False
            user_details['password'] = SecretStr(Utility.generate_password())
            user_details['account'] = user_details['email']
        if existing_user:
            AccountProcessor.get_user_details(user_details['email'])
        else:
            await AccountProcessor.account_setup(user_details)
            tmp_token = Utility.generate_token(user_details['email'])
            await AccountProcessor.confirm_email(tmp_token)
        access_token = Authentication.create_access_token(data={"sub": user_details["email"]})
        return existing_user, user_details, access_token
Exemple #2
0
def cli():
    parser = create_argument_parser()
    arguments = parser.parse_args()
    Utility.load_environment()
    connect(**Utility.mongoengine_connection(Utility.environment['database']
                                             ["url"]))
    arguments.func(arguments)
Exemple #3
0
 def validate_channel_config_model(cls, v, values, **kwargs):
     if 'connector_type' in values:
         Utility.validate_channel_config(values['connector_type'],
                                         v,
                                         ValueError,
                                         encrypt=False)
     return v
Exemple #4
0
    async def from_training_files(cls, training_data_paths: str, domain_path: str, config_path: str, root_dir):
        """
        Create validator from training files.
        @param training_data_paths: nlu.yml file path.
        @param domain_path: domain.yml file path.
        @param config_path: config.yml file path.
        @param root_dir: training data root directory.
        @return:
        """
        if not (os.path.exists(training_data_paths) and os.path.exists(domain_path) and os.path.exists(config_path)):
            raise AppException("Some training files are absent!")
        try:
            file_importer = RasaFileImporter(
                domain_path=domain_path, training_data_paths=training_data_paths, config_file=config_path,
            )
            cls.actions = Utility.read_yaml(os.path.join(root_dir, 'actions.yml'))

            return await TrainingDataValidator.from_importer(file_importer)
        except YamlValidationException as e:
            exc = Utility.replace_file_name(str(e), root_dir)
            raise AppException(exc)
        except YamlSyntaxException as e:
            exc = Utility.replace_file_name(str(e), root_dir)
            raise AppException(exc)
        except Exception as e:
            raise AppException(e)
Exemple #5
0
    def setup(self):
        os.environ["system_file"] = "./tests/testing_data/system.yaml"
        Utility.load_environment()
        db_url = Utility.environment['database']["url"]
        pytest.db_url = db_url

        connect(**Utility.mongoengine_connection(Utility.environment['database']["url"]))
Exemple #6
0
 def validate(self, clean=True):
     if clean:
         self.clean()
     if Utility.check_empty_string(
             self.value) or Utility.check_empty_string(self.entity):
         raise ValidationError(
             "Entity name and value cannot be empty or blank spaces")
Exemple #7
0
    def __allow_access_to_bot(
        bot: Text,
        accessor_email: Text,
        user: Text,
        bot_account: int,
        role: ACCESS_ROLES = ACCESS_ROLES.TESTER.value,
        activity_status: ACTIVITY_STATUS = ACTIVITY_STATUS.INVITE_NOT_ACCEPTED.
        value):
        """
        Adds bot to a user account.

        :param bot: bot id
        :param accessor_email: email id of the new member
        :param user: user adding the new member
        :param bot_account: account where bot exists
        :param activity_status: can be one of active, inactive or deleted.
        :param role: can be one of admin, designer or tester.
        """
        bot_details = AccountProcessor.get_bot_and_validate_status(bot)
        Utility.is_exist(BotAccess,
                         'User is already a collaborator',
                         accessor_email=accessor_email,
                         bot=bot,
                         status__ne=ACTIVITY_STATUS.DELETED.value)
        BotAccess(accessor_email=accessor_email,
                  bot=bot,
                  role=role,
                  user=user,
                  bot_account=bot_account,
                  status=activity_status).save()
        return bot_details
def setup():
    os.environ["system_file"] = "./tests/testing_data/tracker.yaml"
    Utility.load_environment()
    connect(**Utility.mongoengine_connection(
        Utility.environment['tracker']['url']),
            alias="history")
    pytest.bot = '542872407658659274'
Exemple #9
0
    def validate(self, clean=True):
        if clean:
            self.clean()

        if Utility.check_empty_string(self.name) or Utility.check_empty_string(
                self.type):
            raise ValueError(
                "Slot name and type cannot be empty or blank spaces")
        error = ""
        if self.type == FloatSlot.type_name:
            if not self.min_value and not self.max_value:
                self.min_value = 0.0
                self.max_value = 1.0
            if self.min_value < self.max_value:
                error = "FloatSlot must have min_value < max_value"
            if not isinstance(self.initial_value, int):
                if error:
                    error += "\n"
                error = "FloatSlot initial_value must be numeric value"
                ValidationError(error)
        elif self.type == CategoricalSlot.type_name:
            if not self.values:
                raise ValidationError(
                    "CategoricalSlot must have list of categories in values field"
                )
Exemple #10
0
    async def send_confirmation_link(mail: str):
        """
        Sends a link to the user's mail id for account verification

        :param mail: the mail id of the user
        :return: mail id, mail subject and mail body
        """
        email_enabled = Utility.email_conf["email"]["enable"]

        if email_enabled:
            if isinstance(mail_check(mail), ValidationFailure):
                raise AppException("Please enter valid email id")
            Utility.is_exist(UserEmailConfirmation,
                             exp_message="Email already confirmed!",
                             email__iexact=mail.strip())
            if not Utility.is_exist(User,
                                    email__iexact=mail.strip(),
                                    status=True,
                                    raise_error=False):
                raise AppException(
                    "Error! There is no user with the following mail id")
            user = AccountProcessor.get_user(mail)
            token = Utility.generate_token(mail)
            link = Utility.email_conf["app"]["url"] + '/verify/' + token
            return mail, user['first_name'], link
        else:
            raise AppException("Error! Email verification is not enabled")
Exemple #11
0
    def add_account(name: str, user: str):
        """
        adds a new account

        :param name: account name
        :param user: user id
        :return: account id
        """
        if Utility.check_empty_string(name):
            raise AppException("Account Name cannot be empty or blank spaces")
        Utility.is_exist(
            Account,
            exp_message="Account name already exists!",
            name__iexact=name,
            status=True,
        )
        license = {
            "bots": 2,
            "intents": 3,
            "examples": 20,
            "training": 3,
            "augmentation": 5
        }
        return Account(name=name.strip(), user=user,
                       license=license).save().to_mongo().to_dict()
def get_connection_delete_history():
    os.environ["system_file"] = "./tests/testing_data/system.yaml"
    Utility.load_environment()
    connect(**Utility.mongoengine_connection(Utility.environment['database']
                                             ["url"]))
    os.environ["system_file"] = "./tests/testing_data/tracker.yaml"
    Utility.load_environment()
Exemple #13
0
    def add_integration(name: Text,
                        bot: Text,
                        user: Text,
                        role: ACCESS_ROLES,
                        iat: datetime = datetime.utcnow(),
                        expiry: datetime = None,
                        access_list: list = None):
        integration_limit = Utility.environment['security'].get(
            'integrations_per_user') or 2
        current_integrations_count = Integration.objects(
            bot=bot, status__ne=INTEGRATION_STATUS.DELETED.value).count()

        if current_integrations_count >= integration_limit:
            raise AppException('Integrations limit reached!')
        Utility.is_exist(
            Integration,
            'Integration token with this name has already been initiated',
            name=name,
            bot=bot,
            status__ne=INTEGRATION_STATUS.DELETED.value)
        Integration(name=name,
                    bot=bot,
                    user=user,
                    role=role,
                    iat=iat,
                    expiry=expiry,
                    access_list=access_list,
                    status=INTEGRATION_STATUS.ACTIVE.value).save()
Exemple #14
0
    def test_initiate_apm_client_with_url_present(self, monkeypatch):
        monkeypatch.setitem(Utility.environment["elasticsearch"], 'enable',
                            True)
        monkeypatch.setitem(Utility.environment["elasticsearch"],
                            'service_name', "kairon")
        monkeypatch.setitem(Utility.environment["elasticsearch"],
                            'apm_server_url', "http://localhost:8082")

        client = Utility.initiate_apm_client_config()
        assert client == {
            "SERVER_URL": "http://localhost:8082",
            "SERVICE_NAME": "kairon",
            'ENVIRONMENT': "development"
        }

        monkeypatch.setitem(Utility.environment["elasticsearch"],
                            'secret_token', "12345")

        client = Utility.initiate_apm_client_config()
        assert client == {
            "SERVER_URL": "http://localhost:8082",
            "SERVICE_NAME": "kairon",
            'ENVIRONMENT': "development",
            "SECRET_TOKEN": "12345"
        }
Exemple #15
0
 def validate(self, clean=True):
     if not self.title or not self.payload:
         raise ValidationError("title and payload must be present!")
     elif Utility.check_empty_string(
             self.title) or Utility.check_empty_string(
                 self.payload.strip()):
         raise ValidationError(
             "Response title and payload cannot be empty or blank spaces")
Exemple #16
0
 def remove_member(bot: Text, accessor_email: Text):
     Utility.is_exist(BotAccess,
                      'Bot owner cannot be removed',
                      accessor_email=accessor_email,
                      bot=bot,
                      status__ne=ACTIVITY_STATUS.DELETED.value,
                      role=ACCESS_ROLES.OWNER.value)
     AccountProcessor.remove_bot_access(bot, accessor_email=accessor_email)
Exemple #17
0
    def validate_password(cls, v, values, **kwargs):
        from kairon.shared.utils import Utility

        try:
            Utility.valid_password(v.get_secret_value())
        except AppException as e:
            raise ValueError(str(e))
        return v
Exemple #18
0
 def validate(self, clean=True):
     if clean:
         self.clean()
     if not Utility.check_empty_string(self.value) and self.type != 'slot':
         raise ValidationError("Value is allowed only for slot")
     if Utility.check_empty_string(
             self.name) and self.type != 'active_loop':
         raise ValidationError("Empty name is allowed only for active_loop")
Exemple #19
0
 def init_connection(self):
     os.environ["system_file"] = "./tests/testing_data/system.yaml"
     Utility.load_environment()
     Utility.load_email_configuration()
     connect(**Utility.mongoengine_connection(
         Utility.environment['database']["url"]))
     pytest.bot = 'test'
     yield None
     shutil.rmtree(os.path.join('training_data', pytest.bot))
Exemple #20
0
    def validate(self, clean=True):
        from kairon.shared.data.utils import DataUtility

        Utility.validate_channel_config(self.connector_type, self.config, ValidationError)
        if self.connector_type == "telegram":
            webhook_url = DataUtility.get_channel_endpoint({
                'bot': self.bot, 'user': self.user, 'connector_type': self.connector_type
            })
            Utility.register_telegram_webhook(Utility.decrypt_message(self.config['access_token']), webhook_url)
Exemple #21
0
 def validate(self, clean=True):
     if (Utility.check_empty_string(self.email)
             or Utility.check_empty_string(self.first_name)
             or Utility.check_empty_string(self.last_name)
             or Utility.check_empty_string(self.password)):
         raise ValidationError(
             "Email, FirstName, LastName and password cannot be empty or blank space"
         )
     elif isinstance(email(self.email), ValidationFailure):
         raise ValidationError("Please enter valid email address")
Exemple #22
0
 def delete_channel_config(connector_type: Text, bot: Text):
     """
     Delete a particular channel configuration for bot
     :param connector_type: channel name
     :param bot: bot id
     :return: None
     """
     Utility.hard_delete_document([Channels],
                                  bot=bot,
                                  connector_type=connector_type)
Exemple #23
0
 def test_get_action_url(self, monkeypatch):
     actual = Utility.get_action_url({})
     assert actual.url == "http://localhost:5055/webhook"
     actual = Utility.get_action_url(
         {"action_endpoint": {
             "url": "http://action-server:5055/webhook"
         }})
     assert actual.url == "http://action-server:5055/webhook"
     monkeypatch.setitem(Utility.environment['action'], "url", None)
     actual = Utility.get_action_url({})
     assert actual is None
Exemple #24
0
    def check(cls, values):
        from kairon.shared.utils import Utility

        if Utility.check_empty_string(values.get('key')):
            raise ValueError("key cannot be empty")

        if values.get('parameter_type'
                      ) == ParameterChoice.slot and Utility.check_empty_string(
                          values.get('value')):
            raise ValueError("Provide name of the slot as value")
        return values
Exemple #25
0
    def validate(self, clean=True):
        if clean:
            self.clean()

        if Utility.check_empty_string(self.name) or Utility.check_empty_string(
                self.pattern):
            raise ValidationError(
                "Regex name and pattern cannot be empty or blank spaces")
        else:
            try:
                re.compile(self.pattern)
            except Exception:
                raise AppException("invalid regular expression " +
                                   self.pattern)
Exemple #26
0
def start_training(bot: str, user: str, token: str = None):
    """
    prevents training of the bot,
    if the training session is in progress otherwise start training

    :param reload: whether to reload model in the cache
    :param bot: bot id
    :param token: JWT token for remote model reload
    :param user: user id
    :return: model path
    """
    exception = None
    model_file = None
    training_status = None
    apm_client = None
    if Utility.environment.get('model') and Utility.environment['model'][
            'train'].get('event_url'):
        Utility.train_model_event(bot, user, token)
    else:
        try:
            apm_client = Utility.initiate_fastapi_apm_client()
            if apm_client:
                elasticapm.instrument()
                apm_client.begin_transaction(transaction_type="script")
            model_file = train_model_for_bot(bot)
            training_status = MODEL_TRAINING_STATUS.DONE.value
            agent_url = Utility.environment['model']['agent'].get('url')
            if agent_url:
                if token:
                    Utility.http_request(
                        'get',
                        urljoin(agent_url, f"/api/bot/{bot}/model/reload"),
                        token, user)
        except Exception as e:
            logging.exception(e)
            training_status = MODEL_TRAINING_STATUS.FAIL.value
            exception = str(e)
        finally:
            if apm_client:
                apm_client.end_transaction(name=__name__, result="success")
            ModelProcessor.set_training_status(
                bot=bot,
                user=user,
                status=training_status,
                model_path=model_file,
                exception=exception,
            )
    return model_file
Exemple #27
0
    def test_initiate_apm_client_env_not_present(self, monkeypatch):
        monkeypatch.setitem(Utility.environment["elasticsearch"], 'enable',
                            True)
        monkeypatch.setitem(Utility.environment["elasticsearch"], 'env_type',
                            None)

        assert Utility.initiate_apm_client_config() is None
Exemple #28
0
 def test_download_csv(self):
     file_path, temp_path = Utility.download_csv(
         {"conversation_data": [{
             "test": "test_val"
         }]}, None)
     assert file_path.endswith(".csv")
     assert "tmp" in str(temp_path).lower()
Exemple #29
0
    def validate(self, clean=True):
        if clean:
            self.clean()

        if Utility.check_empty_string(self.name):
            raise ValidationError(
                "Utterance Name cannot be empty or blank spaces")
Exemple #30
0
 def test_extract_db_config_without_login(self):
     config = Utility.extract_db_config("mongodb://localhost/test")
     assert config['db'] == "test"
     assert config['username'] is None
     assert config['password'] is None
     assert config['host'] == "mongodb://localhost"
     assert len(config["options"]) == 0