From 025f6b61053d8f62c6424a17cc22b845e9c065b6 Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Mon, 20 May 2024 16:24:22 +0700 Subject: [PATCH] Use username & password (from env vars) for Mongo (#336) Mongo connections can now use a username and password, specified by environment variables. If the environment variables are not present or are empty, then no authentication parameters are sent to Mongo. --- src/LfMerge.Core/LanguageDepotProject.cs | 2 +- src/LfMerge.Core/MagicStrings.cs | 3 +++ src/LfMerge.Core/MongoConnector/MongoConnection.cs | 7 ++++++- src/LfMerge.Core/Settings/DefaultLfMergeSettings.cs | 4 ++++ src/LfMerge.Core/Settings/LfMergeSettings.cs | 9 +++++++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/LfMerge.Core/LanguageDepotProject.cs b/src/LfMerge.Core/LanguageDepotProject.cs index 8a6c66ca..d16f3da9 100644 --- a/src/LfMerge.Core/LanguageDepotProject.cs +++ b/src/LfMerge.Core/LanguageDepotProject.cs @@ -24,7 +24,7 @@ public LanguageDepotProject(LfMergeSettings settings, ILogger logger) public void Initialize(string lfProjectCode) { // TODO: This should use the MongoConnection class instead - MongoClient client = new MongoClient("mongodb://" + Settings.MongoDbHostNameAndPort); + MongoClient client = new MongoClient("mongodb://" + Settings.MongoDbHostPortAndAuth); IMongoDatabase database = client.GetDatabase("scriptureforge"); IMongoCollection projectCollection = database.GetCollection("projects"); //var userCollection = database.GetCollection("users"); diff --git a/src/LfMerge.Core/MagicStrings.cs b/src/LfMerge.Core/MagicStrings.cs index 258563e8..25f9cbc6 100644 --- a/src/LfMerge.Core/MagicStrings.cs +++ b/src/LfMerge.Core/MagicStrings.cs @@ -20,6 +20,9 @@ static MagicStrings() public const string SettingsEnvVar_TemplatesDir = "LFMERGE_TEMPLATES_DIR"; public const string SettingsEnvVar_MongoHostname = "LFMERGE_MONGO_HOSTNAME"; public const string SettingsEnvVar_MongoPort = "LFMERGE_MONGO_PORT"; + public const string SettingsEnvVar_MongoAuthSource = "LFMERGE_MONGO_AUTHSOURCE"; + public const string SettingsEnvVar_MongoUsername = "LFMERGE_MONGO_USER"; + public const string SettingsEnvVar_MongoPassword = "LFMERGE_MONGO_PASS"; public const string SettingsEnvVar_MongoMainDatabaseName = "LFMERGE_MONGO_MAIN_DB_NAME"; public const string SettingsEnvVar_MongoDatabaseNamePrefix = "LFMERGE_MONGO_DB_NAME_PREFIX"; public const string SettingsEnvVar_VerboseProgress = "LFMERGE_VERBOSE_PROGRESS"; diff --git a/src/LfMerge.Core/MongoConnector/MongoConnection.cs b/src/LfMerge.Core/MongoConnector/MongoConnection.cs index f9616bca..a5bad235 100644 --- a/src/LfMerge.Core/MongoConnector/MongoConnection.cs +++ b/src/LfMerge.Core/MongoConnector/MongoConnection.cs @@ -27,6 +27,7 @@ public enum MongoDbSelector { public class MongoConnection : IMongoConnection { + private string connectionString; private string mainDatabaseName; private Lazy client; // Since calling GetDatabase() too often creates a new connection, we memoize the databases in this dictionary. @@ -72,6 +73,10 @@ public MongoConnection(LfMergeSettings settings, ILogger logger) { _settings = settings; _logger = logger; + connectionString = string.Format( + "mongodb://{0}?authSource={1}", + Settings.MongoDbHostPortAndAuth, + Settings.MongoAuthSource); mainDatabaseName = Settings.MongoMainDatabaseName; client = new Lazy(GetNewConnection); dbs = new ConcurrentDictionary(); @@ -79,7 +84,7 @@ public MongoConnection(LfMergeSettings settings, ILogger logger) private MongoClient GetNewConnection() { - var clientSettings = new MongoClientSettings(); + var clientSettings = MongoClientSettings.FromConnectionString(connectionString); // clientSettings.WriteConcern = WriteConcern.WMajority; // If increasing the wait queue size still doesn't help, try this as well clientSettings.WaitQueueSize = 50000; clientSettings.Server = new MongoServerAddress(Settings.MongoHostname, Settings.MongoPort); diff --git a/src/LfMerge.Core/Settings/DefaultLfMergeSettings.cs b/src/LfMerge.Core/Settings/DefaultLfMergeSettings.cs index 08a98685..8f8b0dc3 100644 --- a/src/LfMerge.Core/Settings/DefaultLfMergeSettings.cs +++ b/src/LfMerge.Core/Settings/DefaultLfMergeSettings.cs @@ -12,6 +12,10 @@ public static class DefaultLfMergeSettings public const int MongoPort = 27017; public const string MongoMainDatabaseName = "scriptureforge"; public const string MongoDatabaseNamePrefix = "sf_"; + public const string MongoAuthSource = "admin"; + // Mongo username and password defaults should be *empty* + public const string MongoUsername = ""; + public const string MongoPassword = ""; public const bool VerboseProgress = false; public const string LanguageDepotRepoUri = ""; // optional, usually not set } diff --git a/src/LfMerge.Core/Settings/LfMergeSettings.cs b/src/LfMerge.Core/Settings/LfMergeSettings.cs index 2978d495..ac399145 100644 --- a/src/LfMerge.Core/Settings/LfMergeSettings.cs +++ b/src/LfMerge.Core/Settings/LfMergeSettings.cs @@ -44,6 +44,12 @@ public int MongoPort { } } + public string MongoAuthSource => Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_MongoAuthSource) ?? DefaultLfMergeSettings.MongoAuthSource; + public string MongoUsername => Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_MongoUsername) ?? DefaultLfMergeSettings.MongoUsername; + public string MongoPassword => Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_MongoPassword) ?? DefaultLfMergeSettings.MongoPassword; + private string EncodedUsername => Uri.EscapeUriString(MongoUsername); + private string EncodedPassword => Uri.EscapeUriString(MongoPassword); + public string MongoMainDatabaseName => Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_MongoMainDatabaseName) ?? DefaultLfMergeSettings.MongoMainDatabaseName; /// @@ -65,6 +71,9 @@ public bool VerboseProgress { public bool CommitWhenDone { get; internal set; } public string MongoDbHostNameAndPort { get { return String.Format("{0}:{1}", MongoHostname, MongoPort.ToString()); } } + public string MongoDbHostPortAndAuth => string.IsNullOrEmpty(MongoUsername) || string.IsNullOrEmpty(MongoPassword) + ? string.Format("{0}:{1}", MongoHostname, MongoPort.ToString()) + : string.Format("{0}:{1}@{2}:{3}", EncodedUsername, EncodedPassword, MongoHostname, MongoPort.ToString()); private string QueueDirectory { get; set; }