From 29a6c2c22427d327ae75adc852600c5c19eadfad Mon Sep 17 00:00:00 2001 From: Vijay Jangir <6284383+vijay-jangir@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:39:23 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20updated=20mongo=20provider=20to=20accept?= =?UTF-8?q?=20special=20character=20in=20passwords,=20pass=E2=80=A6=20(#62?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../documentation/mongodb-provider.mdx | 14 +++-- .../mongodb_provider/mongodb_provider.py | 57 +++++++++++++------ 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/docs/providers/documentation/mongodb-provider.mdx b/docs/providers/documentation/mongodb-provider.mdx index ac9c16378..6294c93ae 100644 --- a/docs/providers/documentation/mongodb-provider.mdx +++ b/docs/providers/documentation/mongodb-provider.mdx @@ -19,22 +19,24 @@ The `query` function returns either a `list` or a `tuple` of results, depending The following authentication parameters are used to connect to the MongoDB database: -- `uri` (str, optional): The MongoDB connection URI. If provided, other authentication parameters will be ignored. -- `username` (str): The MongoDB username. -- `password` (str): The MongoDB password. -- `host` (str): The MongoDB hostname. -- `database` (str): The name of the MongoDB database. +- `host` (str): The MongoDB connection URI. It can be a full uri with database, authSource, user, pass; or just hostip. +- `username` (str, optional): The MongoDB username. +- `password` (str, optional): The MongoDB password. +- `database` (str, optional): The name of the MongoDB database. +- `authSource` (str, optional): The name of the database against which authentication needs to be done. +- `additional_options` (str, optional): Additinal options to be passed to MongoClient as kwargs. ## Connecting with the Provider In order to connect to the MongoDB database, you can use either a connection URI or individual parameters. Here's how you can provide authentication information: -1. If using a connection URI, provide the `uri` parameter with the MongoDB connection string. +1. If using a connection URI, provide the `host` parameter with the MongoDB connection string. 2. If using individual parameters, provide the following: - `username`: MongoDB username. - `password`: MongoDB password. - `host`: MongoDB hostname. - `database`: MongoDB database name. + - `authSource`: MongoDB database name. ## Notes diff --git a/keep/providers/mongodb_provider/mongodb_provider.py b/keep/providers/mongodb_provider/mongodb_provider.py index 223c6244d..94061b726 100644 --- a/keep/providers/mongodb_provider/mongodb_provider.py +++ b/keep/providers/mongodb_provider/mongodb_provider.py @@ -1,3 +1,7 @@ +""" +MongodbProvider is a class that provides a way to read data from MySQL. +""" + import dataclasses import os @@ -11,24 +15,38 @@ @pydantic.dataclasses.dataclass class MongodbProviderAuthConfig: - uri: str | None = dataclasses.field( - metadata={"required": False, "description": "MongoDB connection URI"} + host: str = dataclasses.field( + metadata={ + "required": True, + "description": "Mongo host_uri", + "hint": "any valid mongo host_uri like host:port, user:paassword@host:port?authSource", + } ) username: str = dataclasses.field( - metadata={"required": False, "description": "MongoDB username"} + metadata={"required": False, "description": "MongoDB username"}, default=None ) password: str = dataclasses.field( metadata={ "required": False, "description": "MongoDB password", "sensitive": True, - } - ) - host: str = dataclasses.field( - metadata={"required": False, "description": "MongoDB hostname"} + }, + default=None, ) database: str = dataclasses.field( - metadata={"required": False, "description": "MongoDB database name"} + metadata={"required": False, "description": "MongoDB database name"}, + default=None, + ) + auth_source: str | None = dataclasses.field( + metadata={"required": False, "description": "Mongo authSource database name"}, + default=None, + ) + additional_options: dict | None = dataclasses.field( + metadata={ + "required": False, + "description": "Mongo kwargs, these will be passed to MongoClient", + }, + default_factory=dict, ) @@ -74,12 +92,18 @@ def __generate_client(self): Returns: pymongo.MongoClient: MongoDB Client """ - if self.authentication_config.uri: - client = MongoClient(self.authentication_config.uri) - else: - client = MongoClient( - f"mongodb://{self.authentication_config.username}:{self.authentication_config.password}@{self.authentication_config.host}/{self.authentication_config.database}" - ) + # removing all None fields, as mongo will not accept None fields} + client_conf = { + k: v + for k, v in self.authentication_config.__dict__.items() + if v + and not k.startswith("__pydantic") # removing pydantic default key + and k != "additional_options" # additional_options will go seperately + and k != "database" + } # database is not a valid mongo option + client = MongoClient( + **client_conf, **self.authentication_config.additional_options + ) return client def dispose(self): @@ -107,7 +131,7 @@ def _query( """ client = self.__generate_client() database = client[self.authentication_config.database] - results = list(database.command(**query)) + results = list(database.cursor_command(query)) if single_row: return results[0] if results else None @@ -118,10 +142,9 @@ def _query( if __name__ == "__main__": config = ProviderConfig( authentication={ - "uri": os.environ.get("MONGODB_URI"), + "host": os.environ.get("MONGODB_HOST"), "username": os.environ.get("MONGODB_USER"), "password": os.environ.get("MONGODB_PASSWORD"), - "host": os.environ.get("MONGODB_HOST"), "database": os.environ.get("MONGODB_DATABASE"), } )