Repository: rucio/rucio

Issue:
MongoDB metadata implementation does not allow using authentication
### Description

There is now way to configure username / password for the mongo db connection

### Motivation

Any real deployment will need authenticated access to a database

### Change

Add configuration options `mongo_service_user` and `mongo_service_password` in the `[metdata]` section, use to create and authenticated client.

I can open a PR


Discussion:
Hi @maxnoe - that'd be great, thanks! It would be good to build up this plugin beyond a proof of concept.
@robbarnsley I opened a draft PR here: #6606 

I'll rebase that with following the procedures in the contributors guide, which I didn't read before

Resolving patch:
diff --git a/lib/rucio/core/did_meta_plugins/mongo_meta.py b/lib/rucio/core/did_meta_plugins/mongo_meta.py
--- a/lib/rucio/core/did_meta_plugins/mongo_meta.py
+++ b/lib/rucio/core/did_meta_plugins/mongo_meta.py
@@ -36,7 +36,15 @@
 
 
 class MongoDidMeta(DidMetaPlugin):
-    def __init__(self, host=None, port=None, db=None, collection=None):
+    def __init__(
+        self,
+        host: "Optional[str]" = None,
+        port: "Optional[int]" = None,
+        db: "Optional[str]" = None,
+        collection: "Optional[str]" = None,
+        user: "Optional[str]" = None,
+        password: "Optional[str]" = None,
+    ):
         super(MongoDidMeta, self).__init__()
         if host is None:
             host = config.config_get('metadata', 'mongo_service_host')
@@ -47,7 +55,17 @@ def __init__(self, host=None, port=None, db=None, collection=None):
         if collection is None:
             collection = config.config_get('metadata', 'mongo_collection')
 
-        self.client = pymongo.MongoClient("mongodb://{}:{}/".format(host, port))
+        if user is None and config.config_has_section("metadata"):
+            user = config.config_get("metadata", "mongo_user", default=None)
+
+        if user is not None:
+            if password is None:
+                password = config.config_get("metadata", "mongo_password")
+            auth = "{user}:{password}@".format(user=user, password=password)
+        else:
+            auth = ""
+
+        self.client = pymongo.MongoClient("mongodb://{auth}{host}:{port}/".format(auth=auth, host=host, port=port))
         self.db = self.client[db]
         self.col = self.db[collection]
 


Test patch:
diff --git a/tests/test_did_meta_plugins.py b/tests/test_did_meta_plugins.py
--- a/tests/test_did_meta_plugins.py
+++ b/tests/test_did_meta_plugins.py
@@ -192,14 +192,24 @@ def test_list_did_meta(self, mock_scope, root_account):
         assert [tmp_dsn4] == results
 
 
-@pytest.fixture
-def mongo_meta():
-    return MongoDidMeta(
-        host='mongo',
-        port=27017,
-        db='test_db',
-        collection='test_collection'
-    )
+@pytest.fixture(params=["with-auth", "no-auth"])
+def mongo_meta(request):
+    if request.param == "with-auth":
+        return MongoDidMeta(
+            host='mongo',
+            port=27017,
+            db='test_db',
+            collection='test_collection',
+            user="rucio",
+            password="mongo-meta",
+        )
+    else:
+        return MongoDidMeta(
+            host='mongo-noauth',
+            port=27017,
+            db='test_db',
+            collection='test_collection',
+        )
 
 
 @skip_rse_tests_with_accounts