[#22] Client: Container session
All checks were successful
DCO / DCO (pull_request) Successful in 26s

Signed-off-by: Pavel Gross <p.gross@yando.com>
This commit is contained in:
Pavel Gross 2024-08-19 10:48:06 +03:00
parent 22e2a53551
commit 1a02ac2ae7
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;
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;