From 1a02ac2ae7d278f20879ebdc2985f04e04d760f7 Mon Sep 17 00:00:00 2001 From: Pavel Gross Date: Mon, 19 Aug 2024 10:48:06 +0300 Subject: [PATCH] [#22] Client: Container session Signed-off-by: Pavel Gross --- .../Parameters/PrmContainerCreate.cs | 8 ++-- .../Parameters/PrmContainerGetAll.cs | 4 +- .../Parameters/PrmNetmapSnapshot.cs | 4 +- .../Parameters/PrmObjectDelete.cs | 3 +- .../Parameters/PrmObjectHeadGet.cs | 2 +- .../Parameters/PrmObjectPut.cs | 1 - .../Parameters/PrmObjectSearch.cs | 2 +- .../Services/ContainerServiceProvider.cs | 39 ++++++++++++++++--- .../Tools/ClientEnvironment.cs | 1 - .../Tools/RequestConstructor.cs | 24 ++++++++++++ .../Client/ClientSettings.cs | 1 - src/FrostFS.SDK.ModelsV2/Misc/CheckSum.cs | 1 - .../Object/FrostFsObject.cs | 1 - src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs | 2 - src/FrostFS.SDK.Tests/NetworkTest.cs | 1 - src/FrostFS.SDK.Tests/ObjectTest.cs | 1 - 16 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs index 21e4931..a2a3315 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs @@ -1,4 +1,5 @@ using FrostFS.SDK.ModelsV2; +using System.Security.Cryptography; namespace FrostFS.SDK.ClientV2.Parameters; @@ -11,8 +12,9 @@ public sealed class PrmContainerCreate(ModelsV2.Container container) : PrmBase, /// /// Rules for polling the result public PrmWait? WaitParams { get; set; } - - public string SessionKey { get; set; } - + + /// + /// Blank session token + /// public SessionToken? SessionToken { get; set; } } diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerGetAll.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerGetAll.cs index e155606..b365188 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerGetAll.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerGetAll.cs @@ -1,6 +1,4 @@ -using System.Collections.Specialized; - -namespace FrostFS.SDK.ClientV2.Parameters; +namespace FrostFS.SDK.ClientV2.Parameters; public sealed class PrmContainerGetAll() : PrmBase() { diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs index e5316ee..e8387dc 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs @@ -1,6 +1,4 @@ -using System.Collections.Specialized; - -namespace FrostFS.SDK.ClientV2.Parameters; +namespace FrostFS.SDK.ClientV2.Parameters; public sealed class PrmNetmapSnapshot() : PrmBase { diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectDelete.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectDelete.cs index 96df2c1..3195bb8 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectDelete.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectDelete.cs @@ -1,5 +1,4 @@ -using System.Collections.Specialized; -using FrostFS.SDK.ModelsV2; +using FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.ClientV2.Parameters; diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs index cdc75cb..f5a9b77 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs @@ -7,7 +7,7 @@ public sealed class PrmObjectHeadGet(ContainerId containerId, ObjectId objectId) public ContainerId ContainerId { get; set; } = containerId; public ObjectId ObjectId { get; set; } = objectId; - + /// public SessionToken? SessionToken { get; set; } } diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs index 0fcf91d..e2c7a51 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs @@ -1,4 +1,3 @@ -using System.Collections.Specialized; using System.IO; using FrostFS.SDK.ModelsV2; diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectSearch.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectSearch.cs index e7c56be..778b4a0 100644 --- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectSearch.cs +++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectSearch.cs @@ -15,7 +15,7 @@ public sealed class PrmObjectSearch(ContainerId containerId, params IObjectFilte /// /// Collection of filters public IEnumerable Filters { get; set; } = filters; - + /// public SessionToken? SessionToken { get; set; } } diff --git a/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs index b91fcd1..5811a3b 100644 --- a/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs +++ b/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs @@ -10,11 +10,19 @@ using FrostFS.SDK.Cryptography; using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ClientV2.Parameters; using FrostFS.Refs; +using FrostFS.Session; namespace FrostFS.SDK.ClientV2; -internal class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientEnvironment context) : ContextAccessor(context) +internal class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientEnvironment context) : ContextAccessor(context), ISessionProvider { + readonly SessionProvider sessions = new(context); + + public async ValueTask GetOrCreateSession(ISessionToken args, Context ctx) + { + return await sessions.GetOrCreateSession(args, ctx); + } + internal async Task GetContainerAsync(PrmContainerGet args) { GetRequest request = GetContainerRequest(args.ContainerId.ToMessage(), args.XHeaders, args.Context!); @@ -57,7 +65,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient var grpcContainer = args.Container.ToMessage(); grpcContainer.OwnerId = ctx.OwnerId.ToMessage(); grpcContainer.Version = ctx.Version.ToMessage(); - + var request = new PutRequest { Body = new PutRequest.Types.Body @@ -67,7 +75,18 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient } }; - request.AddMetaHeader(args.XHeaders); + var sessionToken = await GetOrCreateSession(args, ctx); + + sessionToken.CreateContainerTokenContext( + null, + ContainerSessionContext.Types.Verb.Put, + ctx.Key, + ctx.PublicKeyCache); + + var v = sessionToken.Body.OwnerId == grpcContainer.OwnerId; + + request.AddMetaHeader(args.XHeaders, sessionToken); + request.Sign(ctx.Key); var response = await service.PutAsync(request, null, ctx.Deadline, ctx.CancellationToken); @@ -91,12 +110,22 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient } }; - request.AddMetaHeader(args.XHeaders); + var sessionToken = await GetOrCreateSession(args, ctx); - request.Sign(ctx.Key); + sessionToken.CreateContainerTokenContext( + request.Body.ContainerId, + ContainerSessionContext.Types.Verb.Delete, + ctx.Key, + ctx.PublicKeyCache); + + request.AddMetaHeader(args.XHeaders, sessionToken); + + request.Sign(ctx.Key); var response = await service.DeleteAsync(request, null, ctx.Deadline, ctx.CancellationToken); + Verifier.CheckResponse(response); + await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx); Verifier.CheckResponse(response); diff --git a/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs b/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs index 6fe2f15..14ccd40 100644 --- a/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs +++ b/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs @@ -2,7 +2,6 @@ using FrostFS.SDK.ModelsV2; using Grpc.Net.Client; using System; using System.Security.Cryptography; -using FrostFS.SDK.Cryptography; using System.Buffers; namespace FrostFS.SDK.ClientV2; diff --git a/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs b/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs index acced67..2bbba92 100644 --- a/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs +++ b/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs @@ -4,6 +4,7 @@ using System.Security.Cryptography; using FrostFS.Refs; using FrostFS.SDK.ClientV2.Mappers.GRPC; +using FrostFS.SDK.Cryptography; using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ProtosV2.Interfaces; using FrostFS.Session; @@ -47,6 +48,29 @@ public static class RequestConstructor Verb = verb }; + sessionToken.Body.SessionKey = Google.Protobuf.ByteString.CopyFrom(key.PublicKey()); + + sessionToken.Signature = key.SignMessagePart(sessionToken.Body); + } + + public static void CreateContainerTokenContext(this Session.SessionToken sessionToken, + ContainerID? containerId, + ContainerSessionContext.Types.Verb verb, + ECDsa key, + Google.Protobuf.ByteString publicKey) + { + if (sessionToken.Body.Container?.ContainerId != null) + return; + + sessionToken.Body.Container = new (){ Verb = verb }; + + if (containerId != null) + sessionToken.Body.Container.ContainerId = containerId; + else + sessionToken.Body.Container.Wildcard = true; + + sessionToken.Body.SessionKey = publicKey; + sessionToken.Signature = key.SignMessagePart(sessionToken.Body); } } diff --git a/src/FrostFS.SDK.ModelsV2/Client/ClientSettings.cs b/src/FrostFS.SDK.ModelsV2/Client/ClientSettings.cs index 049d3f7..c2abf26 100644 --- a/src/FrostFS.SDK.ModelsV2/Client/ClientSettings.cs +++ b/src/FrostFS.SDK.ModelsV2/Client/ClientSettings.cs @@ -1,4 +1,3 @@ -using Google.Protobuf; using System; using System.Collections.Generic; using System.Text; diff --git a/src/FrostFS.SDK.ModelsV2/Misc/CheckSum.cs b/src/FrostFS.SDK.ModelsV2/Misc/CheckSum.cs index 0b7f3bd..872038b 100644 --- a/src/FrostFS.SDK.ModelsV2/Misc/CheckSum.cs +++ b/src/FrostFS.SDK.ModelsV2/Misc/CheckSum.cs @@ -1,6 +1,5 @@ using FrostFS.SDK.Cryptography; using System; -using System.Security.Cryptography; namespace FrostFS.SDK.ModelsV2; diff --git a/src/FrostFS.SDK.ModelsV2/Object/FrostFsObject.cs b/src/FrostFS.SDK.ModelsV2/Object/FrostFsObject.cs index 971d41d..1443abf 100644 --- a/src/FrostFS.SDK.ModelsV2/Object/FrostFsObject.cs +++ b/src/FrostFS.SDK.ModelsV2/Object/FrostFsObject.cs @@ -1,5 +1,4 @@ using System; -using System.Security.Cryptography; using FrostFS.SDK.ModelsV2.Enums; namespace FrostFS.SDK.ModelsV2; diff --git a/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs b/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs index ace5c9f..8a63410 100644 --- a/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs +++ b/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs @@ -1,9 +1,7 @@ using Moq; using FrostFS.Netmap; using Grpc.Core; -using FrostFS.SDK.ClientV2; using Google.Protobuf; -using FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.Tests; diff --git a/src/FrostFS.SDK.Tests/NetworkTest.cs b/src/FrostFS.SDK.Tests/NetworkTest.cs index 35959d3..0fce906 100644 --- a/src/FrostFS.SDK.Tests/NetworkTest.cs +++ b/src/FrostFS.SDK.Tests/NetworkTest.cs @@ -8,7 +8,6 @@ using FrostFS.SDK.ModelsV2.Enums; using Google.Protobuf; using Microsoft.Extensions.Options; using System.Security.Cryptography; -using System.Threading; namespace FrostFS.SDK.Tests; diff --git a/src/FrostFS.SDK.Tests/ObjectTest.cs b/src/FrostFS.SDK.Tests/ObjectTest.cs index 30ec8f0..db20741 100644 --- a/src/FrostFS.SDK.Tests/ObjectTest.cs +++ b/src/FrostFS.SDK.Tests/ObjectTest.cs @@ -7,7 +7,6 @@ using FrostFS.SDK.Cryptography; using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2.Enums; using FrostFS.SDK.ModelsV2.Netmap; -using FrostFS.SDK.ProtosV2.Interfaces; using Google.Protobuf; using Microsoft.Extensions.Options; using System.Security.Cryptography;