Skip to content

Commit 47fc4a7

Browse files
authored
Merge pull request #4 from g4-api/development
Development
2 parents eeb6db0 + 14677df commit 47fc4a7

9 files changed

Lines changed: 263 additions & 47 deletions

File tree

src/G4.Api/Abstractions/IAutomationAsyncClient.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using G4.Api.Models;
2-
using G4.Models;
3-
using G4.Models.Events;
4-
using G4.Plugins;
1+
using G4.Models;
52

63
using Microsoft.Extensions.Logging;
74

src/G4.Api/Abstractions/IEnvironmentsClient.cs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,33 @@ public interface IEnvironmentsClient
4242
Dictionary<string, IDictionary<string, object>> GetEnvironments();
4343

4444
/// <summary>
45-
/// Retrieves the value of a specified environment parameter.
45+
/// Retrieves the value of a specified environment parameter without any additional processing.
4646
/// </summary>
4747
/// <param name="environment">The name of the environment from which to retrieve the parameter.</param>
4848
/// <param name="parameter">The name of the parameter to retrieve.</param>
49-
/// <param name="decode">A boolean value indicating whether to decode the parameter value from base64.</param>
49+
/// <returns>The raw value of the specified parameter if it exists; otherwise, the default value.</returns>
50+
string GetParameter(string environment, string parameter);
51+
52+
/// <summary>
53+
/// Retrieves the value of a specified environment parameter with an option to decode it from Base64.
54+
/// </summary>
55+
/// <param name="environment">The name of the environment from which to retrieve the parameter.</param>
56+
/// <param name="parameter">The name of the parameter to retrieve.</param>
57+
/// <param name="decode">A boolean value indicating whether to decode the parameter value from Base64.</param>
5058
/// <returns>The value of the specified parameter if it exists; otherwise, the default value.</returns>
5159
string GetParameter(string environment, string parameter, bool decode);
5260

61+
/// <summary>
62+
/// Retrieves the value of a specified environment parameter with options to decode it from Base64
63+
/// and decrypt it using the provided encryption key.
64+
/// </summary>
65+
/// <param name="environment">The name of the environment from which to retrieve the parameter.</param>
66+
/// <param name="parameter">The name of the parameter to retrieve.</param>
67+
/// <param name="decode">A boolean value indicating whether to decode the parameter value from Base64.</param>
68+
/// <param name="encryptionKey">An optional encryption key used to decrypt the parameter value. If <c>null</c> or empty, no decryption is performed.</param>
69+
/// <returns>The processed parameter value as a string if it exists; otherwise, the default value.</returns>
70+
string GetParameter(string environment, string parameter, bool decode, string encryptionKey);
71+
5372
/// <summary>
5473
/// Removes the specified environment from the database.
5574
/// </summary>
@@ -107,6 +126,21 @@ public interface IEnvironmentsClient
107126
/// </returns>
108127
int SetEnvironment(string name, IDictionary<string, string> parameters, bool encode);
109128

129+
/// <summary>
130+
/// Updates an existing environment with the specified name and parameters,
131+
/// optionally encoding and encrypting the parameter values.
132+
/// </summary>
133+
/// <param name="name">The name of the environment to update.</param>
134+
/// <param name="parameters">A dictionary of parameters to update in the environment. If <c>null</c>, an empty dictionary is used.</param>
135+
/// <param name="encode">Indicates whether the parameter values should be converted to Base64.</param>
136+
/// <param name="encryptionKey">An optional encryption key used to encrypt the parameter values. If <c>null</c> or empty, no encryption is applied.</param>
137+
/// <returns>An integer representing the HTTP status code:
138+
/// <c>201</c> if the environment was created successfully,
139+
/// <c>204</c> if the environment was updated successfully.
140+
/// </returns>
141+
int SetEnvironment(string name, IDictionary<string, string> parameters, bool encode, string encryptionKey);
142+
143+
110144
/// <summary>
111145
/// Sets an environment parameter in the specified environment collection.
112146
/// </summary>

src/G4.Api/Clients/EnvironmentsClient.cs

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
using LiteDB;
66

7+
using Microsoft.Extensions.Primitives;
8+
79
using System;
810
using System.Collections.Generic;
911
using System.Linq;
12+
using System.Reflection.Metadata;
1013

1114
namespace G4.Api.Clients
1215
{
@@ -38,8 +41,20 @@ public void ClearEnvironments()
3841
collection.DeleteMany(predicate: "_id IN @0", args: new BsonArray(documentsToRemove));
3942
}
4043

44+
/// <inheritdoc />
45+
public string GetParameter(string environment, string parameter)
46+
{
47+
return GetParameter(environment, parameter, decode: true, encryptionKey: default);
48+
}
49+
4150
/// <inheritdoc />
4251
public string GetParameter(string environment, string parameter, bool decode)
52+
{
53+
return GetParameter(environment, parameter, decode, encryptionKey: default);
54+
}
55+
56+
/// <inheritdoc />
57+
public string GetParameter(string environment, string parameter, bool decode, string encryptionKey)
4358
{
4459
// Retrieve the environment parameters for the specified environment name
4560
var applicationEnviornment = G4Environment
@@ -56,9 +71,14 @@ public string GetParameter(string environment, string parameter, bool decode)
5671
}
5772

5873
// Return the decoded value if requested, otherwise return the raw value as a string
59-
return decode
74+
var decodedValue = decode
6075
? $"{value}".ConvertFromBase64()
6176
: $"{value}";
77+
78+
// Return the decrypted value if an encryption key is provided, otherwise return the decoded value
79+
return !string.IsNullOrEmpty(encryptionKey)
80+
? decodedValue.Decrypt(encryptionKey)
81+
: decodedValue;
6282
}
6383

6484
/// <inheritdoc />
@@ -204,8 +224,15 @@ public int RemoveParameter(string environment, string parameter)
204224
Name = name
205225
};
206226

227+
// Encrypt the parameter value if an encryption key is provided
228+
parameterValue = !string.IsNullOrEmpty(parameter.EncryptionKey)
229+
? parameter.Value.Encrypt(parameter.EncryptionKey)
230+
: parameter.Value;
231+
207232
// Encode the parameter value if required
208-
parameterValue = parameter.Encode ? parameter.Value.ConvertToBase64() : parameter.Value;
233+
parameterValue = parameter.Encode
234+
? parameter.Value.ConvertToBase64()
235+
: parameter.Value;
209236

210237
// Check if the Parameters dictionary is null (i.e., no parameters exist)
211238
if (document.Parameters == null)
@@ -254,18 +281,60 @@ public int SetEnvironment(string name, IDictionary<string, string> parameters)
254281
/// <inheritdoc />
255282
public int SetEnvironment(string name, IDictionary<string, string> parameters, bool encode)
256283
{
284+
return SetEnvironment(name, parameters, encode, encryptionKey: default);
285+
}
286+
287+
/// <inheritdoc />
288+
public int SetEnvironment(string name, IDictionary<string, string> parameters, bool encode, string encryptionKey)
289+
{
290+
// Initializes a new environment with the specified name and parameters.
291+
static void InitializeEnvironment(
292+
ILiteCollection<ApplicationParametersModel> collection,
293+
string name, IDictionary<string, string> parameters,
294+
bool encode,
295+
string encryptionKey)
296+
{
297+
// Create a new ApplicationParametersModel with a unique ID, the specified name, and the provided parameters.
298+
var document = new ApplicationParametersModel
299+
{
300+
Id = Guid.NewGuid(),
301+
Name = name,
302+
Parameters = InitializeParameters(parameters, encode, encryptionKey)
303+
};
304+
305+
// Insert the newly created parameters model into the collection.
306+
collection.Insert(document);
307+
}
308+
309+
// Initializes a collection of parameters by optionally encrypting and encoding their values.
310+
static Dictionary<string, object> InitializeParameters(
311+
IDictionary<string, string> parameters, bool encode, string encryptionKey)
312+
{
313+
// Create a dictionary to hold the processed parameters.
314+
var parametersCollection = new Dictionary<string, object>();
315+
316+
// Iterate through each key-value pair in the provided parameters dictionary.
317+
foreach (var parameter in parameters)
318+
{
319+
// Store the processed value in the collection using the original parameter key.
320+
parametersCollection[parameter.Key] = InitializeParameterValue(value: parameter.Value, encode, encryptionKey);
321+
}
322+
323+
// Return the collection of processed parameters.
324+
return parametersCollection;
325+
}
326+
257327
// Initialize parameters to an empty dictionary if it is null
258328
parameters ??= new Dictionary<string, string>();
259329

260-
// TODO: Find a way to remove double call to GetDocument when calling InitializeEnvironment
261330
// Attempt to find the existing parameters model in the collection
262331
var (collection, documents) = GetDocuments(LiteDatabase, name);
263332

264333
// Check if the parameters model does not exist
265334
if (documents.Length == 0)
266335
{
267336
// Initialize the environment if the parameters model does not exist
268-
InitializeEnvironment(LiteDatabase, name, parameters, encode);
337+
InitializeEnvironment(collection, name, parameters, encode, encryptionKey);
269338

270339
// Return 201 Created to indicate successful initialization
271340
return 201;
@@ -280,7 +349,7 @@ public int SetEnvironment(string name, IDictionary<string, string> parameters, b
280349
// Iterate through each parameter and update or add it to the Parameters dictionary
281350
foreach (var parameter in parameters)
282351
{
283-
document.Parameters[parameter.Key] = parameter.Value;
352+
document.Parameters[parameter.Key] = InitializeParameterValue(value: parameter.Value, encode, encryptionKey);
284353
}
285354

286355
// Update the parameters model in the collection to persist the changes
@@ -291,31 +360,16 @@ public int SetEnvironment(string name, IDictionary<string, string> parameters, b
291360
return 204;
292361
}
293362

294-
// Initializes a new environment with the specified name and parameters.
295-
private static void InitializeEnvironment(ILiteDatabase liteDatabase, string name, IDictionary<string, string> parameters, bool encode)
363+
// Initializes the parameter value by optionally encrypting and encoding it.
364+
private static string InitializeParameterValue(string value, bool encode, string encryptionKey)
296365
{
297-
// Retrieve the collection and existing documents for the specified environment name.
298-
var (collection, documents) = GetDocuments(liteDatabase, name);
299-
300-
// Check if the parameters model already exists.
301-
if (documents.Length > 0)
302-
{
303-
// If the parameters model exists, return HTTP 204 No Content with the existing model.
304-
return;
305-
}
366+
// Encrypt the value if an encryption key is provided.
367+
value = !string.IsNullOrEmpty(encryptionKey)
368+
? value.Encrypt(encryptionKey)
369+
: value;
306370

307-
// Create a new ApplicationParametersModel with a unique ID, the specified name, and the provided parameters.
308-
var document = new ApplicationParametersModel
309-
{
310-
Id = Guid.NewGuid(),
311-
Name = name,
312-
Parameters = parameters?.ToDictionary(
313-
k => k.Key,
314-
v => encode ? (object)v.Value.ConvertToBase64() : v.Value)
315-
};
316-
317-
// Insert the newly created parameters model into the collection.
318-
collection.Insert(document);
371+
// Encode the value in Base64 if encoding is enabled, otherwise return the original value.
372+
return encode ? value.ConvertToBase64() : value;
319373
}
320374

321375
// Retrieves a single ApplicationParametersModel document from the specified LiteDatabase collection based on the provided environment name.

src/G4.Api/Extensions/LocalExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using System.Text.Json;
1010
using System.Threading.Tasks;
1111
using System.Threading;
12-
using G4.Cache;
1312

1413
namespace G4.Extensions
1514
{

src/G4.Api/G4.Api.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
</ItemGroup>
3131

3232
<ItemGroup>
33-
<PackageReference Include="G4.Plugins" Version="2025.3.7.34" />
34-
<PackageReference Include="G4.Plugins.Common" Version="2025.3.11.106" />
35-
<PackageReference Include="G4.Plugins.Ui" Version="2025.3.11.106" />
33+
<PackageReference Include="G4.Plugins" Version="2025.3.28.36" />
34+
<PackageReference Include="G4.Plugins.Common" Version="2025.3.28.107" />
35+
<PackageReference Include="G4.Plugins.Ui" Version="2025.3.28.107" />
3636
</ItemGroup>
3737

3838
</Project>

src/G4.Api/Models/EnvironmentParameterModel.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ public class EnvironmentParameterModel
1313
/// <remarks>Optional field; defaults to true.</remarks>
1414
public bool Encode { get; set; } = true;
1515

16+
/// <summary>
17+
/// The encryption key used to encrypt the parameter value.
18+
/// </summary>
19+
public string EncryptionKey { get; set; }
20+
1621
/// <summary>
1722
/// The name of the environment.
1823
/// </summary>

src/G4.IntegrationTests/G4.IntegrationTests.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
<ItemGroup>
3535
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="8.0.10" PrivateAssets="all" />
3636
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
37-
<PackageReference Include="MSTest.TestAdapter" Version="3.8.2" />
38-
<PackageReference Include="MSTest.TestFramework" Version="3.8.2" />
37+
<PackageReference Include="MSTest.TestAdapter" Version="3.8.3" />
38+
<PackageReference Include="MSTest.TestFramework" Version="3.8.3" />
3939
<PackageReference Include="coverlet.collector" Version="6.0.4">
4040
<PrivateAssets>all</PrivateAssets>
4141
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4242
</PackageReference>
43-
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.3.1" />
43+
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.0.0" />
4444
</ItemGroup>
4545

4646
<ItemGroup>

0 commit comments

Comments
 (0)