diff --git a/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthDataModelMapping.cs b/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthDataModelMapping.cs index 856774458..a44d0188f 100644 --- a/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthDataModelMapping.cs +++ b/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthDataModelMapping.cs @@ -40,11 +40,9 @@ static AuthDataModelMapping() BsonClassMap.RegisterClassMap(cm => { cm.MapIdProperty(nameof(AuthData.AuthId)) - .SetIsRequired(true) - .SetSerializer(IdSerializer.Instance); + .SetIsRequired(true); cm.MapProperty(nameof(AuthData.UserId)) - .SetIsRequired(true) - .SetSerializer(IdSerializer.Instance); + .SetIsRequired(true); cm.MapProperty(nameof(AuthData.Cn)) .SetIsRequired(true); cm.MapProperty(nameof(AuthData.Fingerprint)) diff --git a/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthMongoUtils.cs b/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthMongoUtils.cs deleted file mode 100644 index 882855f13..000000000 --- a/Adaptors/MongoDB/src/Table/DataModel/Auth/AuthMongoUtils.cs +++ /dev/null @@ -1,156 +0,0 @@ -// This file is part of the ArmoniK project -// -// Copyright (C) ANEO, 2021-2024. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY, without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -using System; -using System.Collections.Generic; -using System.Linq; - -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; - -namespace ArmoniK.Core.Adapters.MongoDB.Table.DataModel.Auth; - -/// -/// Extension class for MongoDB string conversion -/// -public static class AuthMongoUtils -{ - /// - /// Extension method to transform a string to an objectId - /// - /// The string to convert - /// Converted string - public static string ToOidString(this string value) - => IdSerializer.ToValidIdString(value); -} - -/// -/// Serializer class to/from Object to/from string -/// -public class IdSerializer : SerializerBase -{ - /// - /// Singleton instance of the serializer - /// - public static readonly IdSerializer Instance = new(); - - /// - /// Method used by the MongoDB driver to deserialize an ObjectID to string - /// - /// Deserialization context - /// Deserialization arguments - /// ObjectID as a string - public override string Deserialize(BsonDeserializationContext context, - BsonDeserializationArgs args) - => Deserialize(context.Reader.ReadObjectId()); - - /// - /// Method to deserialize an objectId into a string - /// - /// The ObjectId - /// ObjectId as a string - public static string Deserialize(ObjectId id) - => id.ToString(); - - /// - /// Method to serialize an string into an ObjectId - /// - /// the string, must be a 24 length hexstring - /// ObjectId - public static ObjectId Serialize(string value) - => ObjectId.Parse(value); - - /// - /// Method used by the MongoDB driver to serialize a string to an ObjectID - /// - /// Serialization context - /// Serialization arguments - /// String to serialize - public override void Serialize(BsonSerializationContext context, - BsonSerializationArgs args, - string value) - => context.Writer.WriteObjectId(Serialize(value)); - - /// - /// Converts any string to a valid hex string to be used as a MongoDB ID - /// - /// the string to convert - /// String as an ObjectId string - public static string ToValidIdString(string value) - { - var hash = value.GetHashCode(); - return ObjectId.Parse(Convert.ToHexString(new List - { - hash, - hash, - hash, - }.SelectMany(BitConverter.GetBytes) - .ToArray())) - .ToString(); - } -} - -/// -/// Serializer to handle arrays of strings and arrays of ObjectIds -/// -public class IdArraySerializer : SerializerBase -{ - /// - /// Serializer singleton instance - /// - public static readonly IdArraySerializer Instance = new(); - - /// - /// Method used by the MongoDB driver to deserialize an array of ObjectIDs to an array of strings - /// - /// Deserialization context - /// Deserialization arguments - /// Array of strings deserialized from ObjectIds - public override string[] Deserialize(BsonDeserializationContext context, - BsonDeserializationArgs args) - { - var res = new List(); - context.Reader.ReadStartArray(); - while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) - { - res.Add(IdSerializer.Deserialize(context.Reader.ReadObjectId())); - } - - context.Reader.ReadEndArray(); - return res.ToArray(); - } - - /// - /// Method used by the MongoDB driver to serialize an array of strings to an array of ObjectIDs - /// - /// Serialization context - /// Serialization arguments - /// Array of strings String to serialize - public override void Serialize(BsonSerializationContext context, - BsonSerializationArgs args, - string[] value) - { - context.Writer.WriteStartArray(); - foreach (var s in value) - { - context.Writer.WriteObjectId(IdSerializer.Serialize(s)); - } - - context.Writer.WriteEndArray(); - } -} diff --git a/Adaptors/MongoDB/src/Table/DataModel/Auth/PipelineIntermediates.cs b/Adaptors/MongoDB/src/Table/DataModel/Auth/PipelineIntermediates.cs index 6df1dc1b7..1d432cbd9 100644 --- a/Adaptors/MongoDB/src/Table/DataModel/Auth/PipelineIntermediates.cs +++ b/Adaptors/MongoDB/src/Table/DataModel/Auth/PipelineIntermediates.cs @@ -19,7 +19,6 @@ using ArmoniK.Core.Common.Auth.Authentication; -using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace ArmoniK.Core.Adapters.MongoDB.Table.DataModel.Auth; @@ -34,8 +33,8 @@ namespace ArmoniK.Core.Adapters.MongoDB.Table.DataModel.Auth; /// List of users that have the id UserId [BsonIgnoreExtraElements] public record AuthDataAfterLookup([property: BsonId] - ObjectId AuthId, - ObjectId UserId, + string AuthId, + string UserId, string Cn, string Fingerprint, UserData[] UserData); @@ -48,7 +47,7 @@ public record AuthDataAfterLookup([property: BsonId] /// List of roles of the user [BsonIgnoreExtraElements] public record UserDataAfterLookup([property: BsonId] - ObjectId UserId, + string UserId, string Username, IEnumerable Roles); @@ -60,7 +59,7 @@ public record UserDataAfterLookup([property: BsonId] /// User's roles /// User's permissions public record MongoAuthResult([property: BsonId] - ObjectId Id, + string Id, string Username, IEnumerable Roles, IEnumerable Permissions) @@ -70,7 +69,7 @@ public record MongoAuthResult([property: BsonId] /// /// UserAuthenticationResult from this object public UserAuthenticationResult ToUserAuthenticationResult() - => new(IdSerializer.Deserialize(Id), + => new(Id, Username, Roles, Permissions); diff --git a/Adaptors/MongoDB/src/Table/DataModel/Auth/RoleDataModelMapping.cs b/Adaptors/MongoDB/src/Table/DataModel/Auth/RoleDataModelMapping.cs index 927715ff9..4d0fc131b 100644 --- a/Adaptors/MongoDB/src/Table/DataModel/Auth/RoleDataModelMapping.cs +++ b/Adaptors/MongoDB/src/Table/DataModel/Auth/RoleDataModelMapping.cs @@ -40,8 +40,7 @@ static RoleDataModelMapping() BsonClassMap.RegisterClassMap(cm => { cm.MapIdProperty(nameof(RoleData.RoleId)) - .SetIsRequired(true) - .SetSerializer(IdSerializer.Instance); + .SetIsRequired(true); cm.MapProperty(nameof(RoleData.RoleName)) .SetIsRequired(true); cm.MapProperty(nameof(RoleData.Permissions)) diff --git a/Adaptors/MongoDB/src/Table/DataModel/Auth/UserDataModelMapping.cs b/Adaptors/MongoDB/src/Table/DataModel/Auth/UserDataModelMapping.cs index 048647c8a..a25cd8c8e 100644 --- a/Adaptors/MongoDB/src/Table/DataModel/Auth/UserDataModelMapping.cs +++ b/Adaptors/MongoDB/src/Table/DataModel/Auth/UserDataModelMapping.cs @@ -40,13 +40,11 @@ static UserDataModelMapping() BsonClassMap.RegisterClassMap(cm => { cm.MapIdProperty(nameof(UserData.UserId)) - .SetIsRequired(true) - .SetSerializer(IdSerializer.Instance); + .SetIsRequired(true); cm.MapProperty(nameof(UserData.Username)) .SetIsRequired(true); cm.MapProperty(nameof(UserData.Roles)) .SetIgnoreIfDefault(true) - .SetSerializer(IdArraySerializer.Instance) .SetDefaultValue(Array.Empty()); cm.SetIgnoreExtraElements(true); cm.MapCreator(model => new UserData(model.UserId, diff --git a/Adaptors/MongoDB/tests/AuthenticationTableTest.cs b/Adaptors/MongoDB/tests/AuthenticationTableTest.cs index 2e6a4d5e0..cabb69c51 100644 --- a/Adaptors/MongoDB/tests/AuthenticationTableTest.cs +++ b/Adaptors/MongoDB/tests/AuthenticationTableTest.cs @@ -17,7 +17,6 @@ using System; -using ArmoniK.Core.Adapters.MongoDB.Table.DataModel.Auth; using ArmoniK.Core.Common.Auth.Authentication; using ArmoniK.Core.Common.Tests.TestBase; @@ -44,8 +43,6 @@ static AuthenticationTableTest() BsonClassMap.RegisterClassMap(cm => { cm.MapIdProperty(nameof(UserAuthenticationResult.Id)) - .SetSerializer(IdSerializer.Instance) - .SetShouldSerializeMethod(_ => true) .SetIsRequired(true); cm.MapProperty(nameof(UserAuthenticationResult.Username)) .SetIsRequired(true); diff --git a/Adaptors/MongoDB/tests/BsonSerializerTest.cs b/Adaptors/MongoDB/tests/BsonSerializerTest.cs index 0f5d39d83..6ca691d53 100644 --- a/Adaptors/MongoDB/tests/BsonSerializerTest.cs +++ b/Adaptors/MongoDB/tests/BsonSerializerTest.cs @@ -239,12 +239,12 @@ public void SerializeTaskDataModel() [Test] public void SerializeUserDataModel() { - var udm = new UserData("UserId".ToOidString(), + var udm = new UserData("UserId", "Username", new[] { - "RoleId1".ToOidString(), - "RoleId2".ToOidString(), + "RoleId1", + "RoleId2", }); var serialized = udm.ToBson(); @@ -267,7 +267,7 @@ public void SerializeUserDataModel() [Test] public void SerializeRoleDataModel() { - var rdm = new RoleData("RoleId".ToOidString(), + var rdm = new RoleData("RoleId", "RoleName", new[] { @@ -295,8 +295,8 @@ public void SerializeRoleDataModel() [Test] public void SerializeAuthDataModel() { - var adm = new AuthData("AuthId".ToOidString(), - "UserId".ToOidString(), + var adm = new AuthData("AuthId", + "UserId", "CN", "Fingerprint"); var serialized = adm.ToBson(); @@ -319,7 +319,7 @@ public void SerializeAuthDataModel() [Test] public void SerializeUserAuthenticationResult() { - var uirm = new UserAuthenticationResult("Id".ToOidString(), + var uirm = new UserAuthenticationResult("Id", "Username", new[] { diff --git a/Common/src/Injection/Options/Database/InitDatabase.cs b/Common/src/Injection/Options/Database/InitDatabase.cs index e1a2b65c8..22b35bd80 100644 --- a/Common/src/Injection/Options/Database/InitDatabase.cs +++ b/Common/src/Injection/Options/Database/InitDatabase.cs @@ -15,6 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; using System.Linq; @@ -66,10 +67,10 @@ public InitDatabase(InitServices initServices) Roles = initServices.Authentication.Roles.Select(Role.FromJson) .OrderBy(role => role.Name) - .Select((role, - i) => new RoleData(i.ToString(), - role.Name, - role.Permissions.ToArray())) + .Select(role => new RoleData(Guid.NewGuid() + .ToString(), + role.Name, + role.Permissions.ToArray())) .AsICollection(); var roleDic = Roles.ToDictionary(data => data.RoleName, @@ -77,11 +78,11 @@ public InitDatabase(InitServices initServices) Users = initServices.Authentication.Users.Select(User.FromJson) .OrderBy(user => user.Name) - .Select((user, - i) => new UserData(i.ToString(), - user.Name, - user.Roles.Select(roleName => roleDic[roleName]) - .ToArray())) + .Select(user => new UserData(Guid.NewGuid() + .ToString(), + user.Name, + user.Roles.Select(roleName => roleDic[roleName]) + .ToArray())) .AsICollection(); var userDic = Users.ToDictionary(data => data.Username, @@ -89,11 +90,11 @@ public InitDatabase(InitServices initServices) Auths = initServices.Authentication.UserCertificates.Select(Certificate.FromJson) .OrderBy(certificate => (certificate.Fingerprint, certificate.CN)) - .Select((certificate, - i) => new AuthData(i.ToString(), - userDic[certificate.User], - certificate.CN, - certificate.Fingerprint)) + .Select(certificate => new AuthData(Guid.NewGuid() + .ToString(), + userDic[certificate.User], + certificate.CN, + certificate.Fingerprint)) .AsICollection(); Partitions = initServices.Partitioning.Partitions.Select(Partition.FromJson) diff --git a/Common/tests/TestBase/AuthenticationTableTestBase.cs b/Common/tests/TestBase/AuthenticationTableTestBase.cs index bde964000..a48ad6a57 100644 --- a/Common/tests/TestBase/AuthenticationTableTestBase.cs +++ b/Common/tests/TestBase/AuthenticationTableTestBase.cs @@ -21,7 +21,6 @@ using System.Threading; using System.Threading.Tasks; -using ArmoniK.Core.Adapters.MongoDB.Table.DataModel.Auth; using ArmoniK.Core.Base.DataStructures; using ArmoniK.Core.Common.Auth.Authentication; using ArmoniK.Core.Common.Auth.Authorization.Permissions; @@ -98,7 +97,7 @@ private static bool CheckForSkipSetup() Name = "RoleEnv", Permissions = new List { - "PermEnv", + "catEnv:PermEnv", }, }; @@ -110,7 +109,7 @@ static AuthenticationTableTestBase() { Roles = new List { - new("RoleId1".ToOidString(), + new("RoleId1", "Role1", new[] { @@ -118,7 +117,7 @@ static AuthenticationTableTestBase() "category1:name2", "category2:name3", }), - new("RoleId2".ToOidString(), + new("RoleId2", "Role2", new[] { @@ -126,7 +125,7 @@ static AuthenticationTableTestBase() "category1:name2:" + PermissionScope.AllUsersScope, "category2:name4", }), - new("RoleId3".ToOidString(), + new("RoleId3", "Role3", new[] { @@ -134,20 +133,20 @@ static AuthenticationTableTestBase() "category4:name2", "category5:name3", }), - new("RoleId4".ToOidString(), + new("RoleId4", "Role4", Array.Empty()), }; Users = new List { - new("UserId1".ToOidString(), + new("UserId1", "User1", new[] { Roles[0] .RoleId, }), - new("UserId2".ToOidString(), + new("UserId2", "User2", new[] { @@ -156,7 +155,7 @@ static AuthenticationTableTestBase() Roles[1] .RoleId, }), - new("UserId3".ToOidString(), + new("UserId3", "User3", new[] { @@ -165,60 +164,60 @@ static AuthenticationTableTestBase() Roles[2] .RoleId, }), - new("UserId4".ToOidString(), + new("UserId4", "User4", new[] { Roles[0] .RoleId, - "RoleIdDontExist".ToOidString(), + "RoleIdDontExist", }), - new("UserId5".ToOidString(), + new("UserId5", "User5", Array.Empty()), }; Auths = new List { - new("AuthId1".ToOidString(), + new("AuthId1", Users[0] .UserId, "CNUser1", "Fingerprint1"), - new("AuthId2".ToOidString(), + new("AuthId2", Users[1] .UserId, "CNUser2", "Fingerprint2"), - new("AuthId3".ToOidString(), + new("AuthId3", Users[1] .UserId, "CNUser3", "Fingerprint3"), - new("AuthId4".ToOidString(), + new("AuthId4", Users[2] .UserId, "CNUser4", "Fingerprint4"), - new("AuthId5".ToOidString(), + new("AuthId5", Users[3] .UserId, "CNUser5", "Fingerprint5"), - new("AuthId6".ToOidString(), - "UserIdDontExist".ToOidString(), + new("AuthId6", + "UserIdDontExist", "CNUser6", "Fingerprint6"), - new("AuthId7".ToOidString(), + new("AuthId7", Users[1] .UserId, "CNUser2", "Fingerprint7"), - new("AuthId8".ToOidString(), + new("AuthId8", Users[2] .UserId, "CNUserCommon", null), - new("AuthId9".ToOidString(), + new("AuthId9", Users[3] .UserId, "CNUser2", @@ -371,7 +370,7 @@ public void GetIdentityFromIdShouldFail(string id) return; } - Assert.IsNull(AuthenticationTable!.GetIdentityFromUserAsync(id.ToOidString(), + Assert.IsNull(AuthenticationTable!.GetIdentityFromUserAsync(id, null) .Result); } @@ -459,6 +458,9 @@ public void UserHasRoleShouldMatch(string username, [TestCase("User2", "category1:name2:" + PermissionScope.AllUsersScope, true)] + [TestCase("UserEnv", + "catEnv:PermEnv", + true)] public void UserHasClaimShouldMatch(string username, string claim, bool hasClaim)