[22] Client: Container session #25

Merged
PavelGrossSpb merged 1 commit from PavelGrossSpb/frostfs-sdk-csharp:misc/container_session into master 2024-08-19 11:27:24 +00:00
16 changed files with 68 additions and 27 deletions

View file

@ -1,4 +1,5 @@
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using System.Security.Cryptography;
namespace FrostFS.SDK.ClientV2.Parameters; namespace FrostFS.SDK.ClientV2.Parameters;
@ -11,8 +12,9 @@ public sealed class PrmContainerCreate(ModelsV2.Container container) : PrmBase,
/// </summary> /// </summary>
/// <value>Rules for polling the result</value> /// <value>Rules for polling the result</value>
public PrmWait? WaitParams { get; set; } public PrmWait? WaitParams { get; set; }
public string SessionKey { get; set; } /// <summary>
/// Blank session token
/// </summary>
public SessionToken? SessionToken { get; set; } public SessionToken? SessionToken { get; set; }
} }

View file

@ -1,6 +1,4 @@
using System.Collections.Specialized; namespace FrostFS.SDK.ClientV2.Parameters;
namespace FrostFS.SDK.ClientV2.Parameters;
public sealed class PrmContainerGetAll() : PrmBase() public sealed class PrmContainerGetAll() : PrmBase()
{ {

View file

@ -1,6 +1,4 @@
using System.Collections.Specialized; namespace FrostFS.SDK.ClientV2.Parameters;
namespace FrostFS.SDK.ClientV2.Parameters;
public sealed class PrmNetmapSnapshot() : PrmBase public sealed class PrmNetmapSnapshot() : PrmBase
{ {

View file

@ -1,5 +1,4 @@
using System.Collections.Specialized; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ModelsV2;
namespace FrostFS.SDK.ClientV2.Parameters; namespace FrostFS.SDK.ClientV2.Parameters;

View file

@ -7,7 +7,7 @@ public sealed class PrmObjectHeadGet(ContainerId containerId, ObjectId objectId)
public ContainerId ContainerId { get; set; } = containerId; public ContainerId ContainerId { get; set; } = containerId;
public ObjectId ObjectId { get; set; } = objectId; public ObjectId ObjectId { get; set; } = objectId;
/// <inheritdoc /> /// <inheritdoc />
public SessionToken? SessionToken { get; set; } public SessionToken? SessionToken { get; set; }
} }

View file

@ -1,4 +1,3 @@
using System.Collections.Specialized;
using System.IO; using System.IO;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;

View file

@ -15,7 +15,7 @@ public sealed class PrmObjectSearch(ContainerId containerId, params IObjectFilte
/// </summary> /// </summary>
/// <value>Collection of filters</value> /// <value>Collection of filters</value>
public IEnumerable<IObjectFilter> Filters { get; set; } = filters; public IEnumerable<IObjectFilter> Filters { get; set; } = filters;
/// <inheritdoc /> /// <inheritdoc />
public SessionToken? SessionToken { get; set; } public SessionToken? SessionToken { get; set; }
} }

View file

@ -10,11 +10,19 @@ using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ClientV2.Parameters; using FrostFS.SDK.ClientV2.Parameters;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.Session;
namespace FrostFS.SDK.ClientV2; 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<Session.SessionToken> GetOrCreateSession(ISessionToken args, Context ctx)
{
return await sessions.GetOrCreateSession(args, ctx);
}
internal async Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args) internal async Task<ModelsV2.Container> GetContainerAsync(PrmContainerGet args)
{ {
GetRequest request = GetContainerRequest(args.ContainerId.ToMessage(), args.XHeaders, args.Context!); GetRequest request = GetContainerRequest(args.ContainerId.ToMessage(), args.XHeaders, args.Context!);
@ -57,7 +65,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
var grpcContainer = args.Container.ToMessage(); var grpcContainer = args.Container.ToMessage();
grpcContainer.OwnerId = ctx.OwnerId.ToMessage(); grpcContainer.OwnerId = ctx.OwnerId.ToMessage();
grpcContainer.Version = ctx.Version.ToMessage(); grpcContainer.Version = ctx.Version.ToMessage();
var request = new PutRequest var request = new PutRequest
{ {
Body = new PutRequest.Types.Body 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); request.Sign(ctx.Key);
var response = await service.PutAsync(request, null, ctx.Deadline, ctx.CancellationToken); 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); var response = await service.DeleteAsync(request, null, ctx.Deadline, ctx.CancellationToken);
Verifier.CheckResponse(response);
await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx); await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx);
Verifier.CheckResponse(response); Verifier.CheckResponse(response);

View file

@ -2,7 +2,6 @@ using FrostFS.SDK.ModelsV2;
using Grpc.Net.Client; using Grpc.Net.Client;
using System; using System;
using System.Security.Cryptography; using System.Security.Cryptography;
using FrostFS.SDK.Cryptography;
using System.Buffers; using System.Buffers;
namespace FrostFS.SDK.ClientV2; namespace FrostFS.SDK.ClientV2;

View file

@ -4,6 +4,7 @@ using System.Security.Cryptography;
using FrostFS.Refs; using FrostFS.Refs;
using FrostFS.SDK.ClientV2.Mappers.GRPC; using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ProtosV2.Interfaces; using FrostFS.SDK.ProtosV2.Interfaces;
using FrostFS.Session; using FrostFS.Session;
@ -47,6 +48,29 @@ public static class RequestConstructor
Verb = verb 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); sessionToken.Signature = key.SignMessagePart(sessionToken.Body);
} }
} }

View file

@ -1,4 +1,3 @@
using Google.Protobuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;

View file

@ -1,6 +1,5 @@
using FrostFS.SDK.Cryptography; using FrostFS.SDK.Cryptography;
using System; using System;
using System.Security.Cryptography;
namespace FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.ModelsV2;

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Security.Cryptography;
using FrostFS.SDK.ModelsV2.Enums; using FrostFS.SDK.ModelsV2.Enums;
namespace FrostFS.SDK.ModelsV2; namespace FrostFS.SDK.ModelsV2;

View file

@ -1,9 +1,7 @@
using Moq; using Moq;
using FrostFS.Netmap; using FrostFS.Netmap;
using Grpc.Core; using Grpc.Core;
using FrostFS.SDK.ClientV2;
Review

Do we have any linter in C# that can detect unused imports during PR validation?

Do we have any linter in C# that can detect unused imports during PR validation?
Review

Not yet. I'm waiting for professinal IDE (JetBrains) to setup such tools.

Not yet. I'm waiting for professinal IDE (JetBrains) to setup such tools.
using Google.Protobuf; using Google.Protobuf;
using FrostFS.SDK.ModelsV2;
namespace FrostFS.SDK.Tests; namespace FrostFS.SDK.Tests;

View file

@ -8,7 +8,6 @@ using FrostFS.SDK.ModelsV2.Enums;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Threading;
namespace FrostFS.SDK.Tests; namespace FrostFS.SDK.Tests;

View file

@ -7,7 +7,6 @@ using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ModelsV2; using FrostFS.SDK.ModelsV2;
using FrostFS.SDK.ModelsV2.Enums; using FrostFS.SDK.ModelsV2.Enums;
using FrostFS.SDK.ModelsV2.Netmap; using FrostFS.SDK.ModelsV2.Netmap;
using FrostFS.SDK.ProtosV2.Interfaces;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Security.Cryptography; using System.Security.Cryptography;