This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new a5a6549e5b Adding certificate validation for ssl in mongo hook (#37214)
a5a6549e5b is described below

commit a5a6549e5b6609c8feeab992731854ebffddcd1c
Author: Amogh Desai <amoghrajesh1...@gmail.com>
AuthorDate: Thu Feb 8 16:00:18 2024 +0530

    Adding certificate validation for ssl in mongo hook (#37214)
---
 airflow/providers/mongo/CHANGELOG.rst  | 11 +++++++
 airflow/providers/mongo/hooks/mongo.py | 55 ++++++++++++++++++++++++++++------
 2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/airflow/providers/mongo/CHANGELOG.rst 
b/airflow/providers/mongo/CHANGELOG.rst
index eb629d0528..f7953ef77a 100644
--- a/airflow/providers/mongo/CHANGELOG.rst
+++ b/airflow/providers/mongo/CHANGELOG.rst
@@ -27,6 +27,17 @@
 Changelog
 ---------
 
+3.7.0
+......
+
+Breaking changes
+~~~~~~~~~~~~~~~~
+
+Introduced the allow_insecure flag in the extras field of for the MongoDB 
connection. This flag allows users to control
+whether insecure connections are permitted when using SSL encryption. By 
default, the allow_insecure flag is
+set to False. This means that when SSL encryption is enabled (ssl=True), 
insecure connections are not allowed unless
+explicitly specified by the user.
+
 3.6.0
 .....
 
diff --git a/airflow/providers/mongo/hooks/mongo.py 
b/airflow/providers/mongo/hooks/mongo.py
index 857bbc312f..66bc54d010 100644
--- a/airflow/providers/mongo/hooks/mongo.py
+++ b/airflow/providers/mongo/hooks/mongo.py
@@ -19,7 +19,6 @@
 from __future__ import annotations
 
 import warnings
-from ssl import CERT_NONE
 from typing import TYPE_CHECKING, Any, overload
 from urllib.parse import quote_plus, urlunsplit
 
@@ -49,6 +48,28 @@ class MongoHook(BaseHook):
     ex.
         {"srv": true, "replicaSet": "test", "ssl": true, "connectTimeoutMS": 
30000}
 
+    For enabling SSL, the `"ssl": true` option can be used within the 
connection string options, under extra.
+    In scenarios where SSL is enabled, `allow_insecure` option is not included 
by default in the connection
+    unless specified. This is so that we ensure a secure medium while handling 
connections to MongoDB.
+
+    The `allow_insecure` only makes sense in ssl context and is configurable 
and can be used in one of
+    the following scenarios:
+
+    HTTP (ssl = False)
+    Here, `ssl` is disabled and using `allow_insecure` doesn't make sense.
+    Example connection extra: {"ssl": false}
+
+    HTTPS, but insecure (ssl = True, allow_insecure = True)
+    Here, `ssl` is enabled, and the connection allows insecure connections.
+    Example connection extra: {"ssl": true, "allow_insecure": true}
+
+    HTTPS, but secure (ssl = True, allow_insecure = False - default when SSL 
enabled):
+    Here, `ssl` is enabled, and the connection does not allow insecure 
connections (default behavior when
+    SSL is enabled). Example connection extra: {"ssl": true} or {"ssl": true, 
"allow_insecure": false}
+
+    Note: `tls` is an alias to `ssl` and can be used in place of `ssl`. 
Example: {"ssl": false} or
+    {"tls": false}.
+
     :param mongo_conn_id: The :ref:`Mongo connection id 
<howto/connection:mongo>` to use
         when connecting to MongoDB.
     """
@@ -75,6 +96,27 @@ class MongoHook(BaseHook):
         self.client: MongoClient | None = None
         self.uri = self._create_uri()
 
+        self.allow_insecure = self.extras.pop("allow_insecure", 
"false").lower() == "true"
+        self.ssl_enabled = (
+            self.extras.get("ssl", "false").lower() == "true"
+            or self.extras.get("tls", "false").lower() == "true"
+        )
+
+        if self.ssl_enabled and not self.allow_insecure:
+            # Case: HTTPS
+            self.allow_insecure = False
+        elif self.ssl_enabled and self.allow_insecure:
+            # Case: HTTPS + allow_insecure
+            self.allow_insecure = True
+            self.extras.pop("ssl", None)
+        elif not self.ssl_enabled and "allow_insecure" in self.extras:
+            # Case: HTTP (ssl=False) with allow_insecure specified
+            self.log.warning("allow_insecure is only applicable when ssl is 
set")
+            self.extras.pop("allow_insecure", None)
+        elif not self.ssl_enabled:
+            # Case: HTTP (ssl=False) with allow_insecure not specified
+            self.allow_insecure = False
+
     def __enter__(self):
         return self
 
@@ -96,14 +138,9 @@ class MongoHook(BaseHook):
         # Mongo Connection Options dict that is unpacked when passed to 
MongoClient
         options = self.extras
 
-        # If we are using SSL disable requiring certs from specific hostname
-        if options.get("ssl", False):
-            if pymongo.__version__ >= "4.0.0":
-                # In pymongo 4.0.0+ `tlsAllowInvalidCertificates=True`
-                # replaces `ssl_cert_reqs=CERT_NONE`
-                options.update({"tlsAllowInvalidCertificates": True})
-            else:
-                options.update({"ssl_cert_reqs": CERT_NONE})
+        # Set tlsAllowInvalidCertificates based on allow_insecure
+        if self.allow_insecure:
+            options["tlsAllowInvalidCertificates"] = True
 
         self.client = MongoClient(self.uri, **options)
         return self.client

Reply via email to