Skip to content

Commit

Permalink
apply indexes to primitive type values only
Browse files Browse the repository at this point in the history
  • Loading branch information
npavlyk82 committed Feb 11, 2025
1 parent 2e39409 commit a199a3e
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 12 deletions.
67 changes: 56 additions & 11 deletions src/Storage.MongoDB/MongoNonceRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson.Serialization;
Expand Down Expand Up @@ -53,19 +54,16 @@ public MongoNonceRepository(IMongoDatabase database, MongoNonceOptions options)
public async ValueTask InsertOneAsync(
Token token, CancellationToken cancellationToken)
{
await _collection.InsertOneAsync(token, cancellationToken: cancellationToken);
token.ExtraProperties = token.ExtraProperties ?? new Dictionary<string, object>();

if (token.ExtraProperties != null)
{
var indexOptions = new CreateIndexOptions { Background = true };
IReadOnlySet<string> propertyNamesWithPrimitiveValueType =
GetPropertyNamesWithPrimitiveValueType(token.ExtraProperties);

foreach (KeyValuePair<string, object> extraProperty in token.ExtraProperties)
{
_collection.Indexes.CreateOne(new CreateIndexModel<Token>(
Builders<Token>.IndexKeys.Ascending(
$"{nameof(token.ExtraProperties)}.{extraProperty.Key}"), indexOptions));
}
}
SetJsonStringValue(token.ExtraProperties, propertyNamesWithPrimitiveValueType);

await _collection.InsertOneAsync(token, cancellationToken: cancellationToken);

CreateIndexes(propertyNamesWithPrimitiveValueType);
}

public async ValueTask<Token?> TakeOneAsync(
Expand Down Expand Up @@ -105,5 +103,52 @@ public static void Initialize()
{
//ensure static constructor is called
}

private void CreateIndexes(IEnumerable<string> extraPropertyNames)
{
var indexOptions = new CreateIndexOptions { Background = true };

foreach (string extraPropertyName in extraPropertyNames)
{
_collection.Indexes.CreateOne(new CreateIndexModel<Token>(
Builders<Token>.IndexKeys.Ascending(
$"{nameof(Token.ExtraProperties)}.{extraPropertyName}"), indexOptions));
}
}

private IReadOnlySet<string> GetPropertyNamesWithPrimitiveValueType(
Dictionary<string, object> extraProperties)
{
HashSet<string> names = new HashSet<string>();

foreach (KeyValuePair<string, object> keyValue in extraProperties)
{
if (keyValue.Value == null)
{
continue;
}

if (TypeChecker.IsPrimitiveType(keyValue.Value.GetType()))
{
names.Add(keyValue.Key);
}
}

return names;
}

private void SetJsonStringValue(
Dictionary<string, object> extraProperties, IReadOnlySet<string> namesToSkip)
{
foreach(string name in extraProperties.Keys)
{
if (namesToSkip.Contains(name))
{
continue;
}

extraProperties[name] = JsonSerializer.Serialize(extraProperties[name]);
}
}
}
}
55 changes: 55 additions & 0 deletions src/Storage.MongoDB/TypeChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using MongoDB.Bson;

#nullable enable

namespace Bewit.Storage.MongoDB
{
public static class TypeChecker
{
private static readonly HashSet<Type> PrimitiveTypes = new HashSet<Type>
{
typeof(string),
typeof(bool),
typeof(byte),
typeof(sbyte),
typeof(char),
typeof(decimal),
typeof(double),
typeof(float),
typeof(int),
typeof(uint),
typeof(long),
typeof(ulong),
typeof(short),
typeof(ushort),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(DateOnly),
typeof(TimeOnly),
typeof(Guid),
typeof(ObjectId),
typeof(BsonObjectId),
typeof(BsonDateTime)
};

public static bool IsPrimitiveType(object value)
{
if (value == null)
return false;

Type type = value.GetType();
return IsPrimitiveType(type);
}

public static bool IsPrimitiveType(Type type)
{
Type underlyingType = Nullable.GetUnderlyingType(type) ?? type;

return PrimitiveTypes.Contains(underlyingType) ||
underlyingType.IsEnum;
}
}
}
7 changes: 6 additions & 1 deletion test/IntegrationTests/HotChocolateServer/HCServerHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ internal static TestServer CreateHotChocolateServer(
.Resolve(ctx =>
{
ctx.AddBewitTokenExtraProperties(
new Dictionary<string, object> { ["foo"] = "bar" });
new Dictionary<string, object>
{
["foo"] = "bar",
["customType"] = new{},
["nullValue"] = null
});

return "http://foo.bar/api/dummy/WithBewitProtection?foo=bar&baz=qux";
})
Expand Down

0 comments on commit a199a3e

Please sign in to comment.