From fcdc4476df24c7073c01f70ae3401469f4070a38 Mon Sep 17 00:00:00 2001 From: Lisoveliy Date: Wed, 16 Jul 2025 20:34:29 +0300 Subject: [PATCH] feat: added auth for telegram stage --- JOBot.Backend/Services/HeadHunterService.cs | 2 +- JOBot.Backend/Services/gRPC/UserService.cs | 13 ++++++++++++- .../Buttons/EulaAgreementButtonCommand.cs | 3 ++- JOBot.TClient/Services/MenuService.cs | 6 ++---- JOBot.TClient/Services/PrepareUserService.cs | 15 +++++++++++++++ JOBot.TClient/Statements/PrepareUserState.cs | 17 ++++++++++++----- JOBot.TClient/TextResource.Designer.cs | 9 +++++++++ JOBot.TClient/TextResource.resx | 3 +++ Proto/user.proto | 14 ++++++++++++-- 9 files changed, 68 insertions(+), 14 deletions(-) diff --git a/JOBot.Backend/Services/HeadHunterService.cs b/JOBot.Backend/Services/HeadHunterService.cs index 80b3283..2204a6c 100644 --- a/JOBot.Backend/Services/HeadHunterService.cs +++ b/JOBot.Backend/Services/HeadHunterService.cs @@ -16,7 +16,7 @@ public class HeadHunterService(ILogger logger, IOptions /// Telegram UserId /// Link for auth - public string GenerateAuthLink(int userId) + public string GenerateAuthLink(long userId) { var redirectUri = new UriBuilder(_config.Links.HookDomain) { diff --git a/JOBot.Backend/Services/gRPC/UserService.cs b/JOBot.Backend/Services/gRPC/UserService.cs index f694431..4a1cfe6 100644 --- a/JOBot.Backend/Services/gRPC/UserService.cs +++ b/JOBot.Backend/Services/gRPC/UserService.cs @@ -1,3 +1,4 @@ +using Google.Protobuf.WellKnownTypes; using Grpc.Core; using JOBot.Backend.DAL.Context; using JOBot.Backend.DAL.Models; @@ -7,7 +8,7 @@ using User = JOBot.Backend.DAL.Models.User; namespace JOBot.Backend.Services.gRPC; -public class UserService(AppDbContext dbContext) : Proto.User.UserBase +public class UserService(AppDbContext dbContext, HeadHunterService hhService) : Proto.User.UserBase { /// /// Create user @@ -62,6 +63,16 @@ public class UserService(AppDbContext dbContext) : Proto.User.UserBase return new AcceptEulaResponse { Success = true }; } + public override Task GetHeadHunterAuthHook( + GetHeadHunterAuthHookRequest request, + ServerCallContext context) + { + return Task.Run(() => new GetHeadHunterAuthHookResponse + { + RegistrationUrl = hhService.GenerateAuthLink(request.UserId) + }); + } + /// /// Throw RPCException if user not found /// diff --git a/JOBot.TClient/Commands/Buttons/EulaAgreementButtonCommand.cs b/JOBot.TClient/Commands/Buttons/EulaAgreementButtonCommand.cs index 87d6368..f28e9ab 100644 --- a/JOBot.TClient/Commands/Buttons/EulaAgreementButtonCommand.cs +++ b/JOBot.TClient/Commands/Buttons/EulaAgreementButtonCommand.cs @@ -12,6 +12,7 @@ public class EulaAgreementButtonCommand(PrepareUserState prepareUserState) : IAu { public async Task ExecuteAsync(Update update, GetUserResponse user, CancellationToken ct) { - await prepareUserState.AcceptEula(update, ct); + if (!user.Eula) + await prepareUserState.AcceptEula(user, update, ct); } } \ No newline at end of file diff --git a/JOBot.TClient/Services/MenuService.cs b/JOBot.TClient/Services/MenuService.cs index 9849490..e8ba02e 100644 --- a/JOBot.TClient/Services/MenuService.cs +++ b/JOBot.TClient/Services/MenuService.cs @@ -6,12 +6,10 @@ namespace JOBot.TClient.Services; public class MenuService(ITelegramBotClient bot) { - public Task RenderMenu(Update update, CancellationToken ct = default) + public async Task RenderMenu(Update update, CancellationToken ct = default) { ArgumentNullException.ThrowIfNull(update.Message?.From); - bot.SendMessage(update.Message.From.Id,"PrepareUser stage is done.", cancellationToken: ct); - - return Task.CompletedTask; + await bot.SendMessage(update.Message.From.Id,"PrepareUser stage is done.", cancellationToken: ct); } } \ No newline at end of file diff --git a/JOBot.TClient/Services/PrepareUserService.cs b/JOBot.TClient/Services/PrepareUserService.cs index 4f2921e..941286d 100644 --- a/JOBot.TClient/Services/PrepareUserService.cs +++ b/JOBot.TClient/Services/PrepareUserService.cs @@ -83,4 +83,19 @@ public class PrepareUserService(ITelegramBotClient bot, User.UserClient userClie if (!result.Success) throw new FallbackException(TextResource.FallbackMessage, update.Message, _bot); } + + public async Task Auth(Update update, CancellationToken ct = default) + { + ArgumentNullException.ThrowIfNull(update.Message?.From); + + var url = await _userClient.GetHeadHunterAuthHookAsync(new GetHeadHunterAuthHookRequest() + { + UserId = update.Message.From.Id + }); + + await _bot.SendMessage( + update.Message.From.Id, + string.Format(TextResource.AskForAuth, [url]), + cancellationToken: ct); + } } \ No newline at end of file diff --git a/JOBot.TClient/Statements/PrepareUserState.cs b/JOBot.TClient/Statements/PrepareUserState.cs index 855ebe4..eb87901 100644 --- a/JOBot.TClient/Statements/PrepareUserState.cs +++ b/JOBot.TClient/Statements/PrepareUserState.cs @@ -1,3 +1,4 @@ +using JOBot.Proto; using JOBot.TClient.Services; using Telegram.Bot.Types; using User = JOBot.Proto.User; @@ -21,27 +22,33 @@ public class PrepareUserState(PrepareUserService prepareUserService, MenuService return; //interrupt while eula isn't accepted } - await OnUserEulaValidStage(update, ct); + await OnUserEulaValidStage(user, update, ct); } /// /// Signal for accepted eula /// + /// /// /// - public async Task AcceptEula(Update update, CancellationToken ct = default) + public async Task AcceptEula(GetUserResponse user, Update update, CancellationToken ct = default) { await prepareUserService.AcceptEula(update, ct: ct); - await OnUserEulaValidStage(update, ct); + await OnUserEulaValidStage(user, update, ct); } - + /// /// Continue prepare stage /// + /// /// /// - private async Task OnUserEulaValidStage(Update update, CancellationToken ct = default) + private async Task OnUserEulaValidStage(GetUserResponse user, Update update, CancellationToken ct = default) { + if (!user.IsLogged) + { + prepareUserService.Auth(update, ct); + } await menuService.RenderMenu(update, ct); //boilerplate } } \ No newline at end of file diff --git a/JOBot.TClient/TextResource.Designer.cs b/JOBot.TClient/TextResource.Designer.cs index 3104beb..088802e 100644 --- a/JOBot.TClient/TextResource.Designer.cs +++ b/JOBot.TClient/TextResource.Designer.cs @@ -59,6 +59,15 @@ namespace JOBot.TClient { } } + /// + /// Looks up a localized string similar to Авторизируйтесь на сайте HeadHunter для получения доступа к резюме и вакансиям {0}. + /// + public static string AskForAuth { + get { + return ResourceManager.GetString("AskForAuth", resourceCulture); + } + } + /// /// Looks up a localized string similar to Команда не найдена, попробуйте что-то другое. /// diff --git a/JOBot.TClient/TextResource.resx b/JOBot.TClient/TextResource.resx index 3d541c9..7bed097 100644 --- a/JOBot.TClient/TextResource.resx +++ b/JOBot.TClient/TextResource.resx @@ -34,4 +34,7 @@ https://hh.ru/account/agreement?backurl=%2Faccount%2Fsignup%3Fbackurl%3D%252F%26 Это бот для упрощения поиска работы на HH.ru + + Авторизируйтесь на сайте HeadHunter для получения доступа к резюме и вакансиям {0} + \ No newline at end of file diff --git a/Proto/user.proto b/Proto/user.proto index 98072c3..687316c 100644 --- a/Proto/user.proto +++ b/Proto/user.proto @@ -1,14 +1,16 @@ syntax = "proto3"; option csharp_namespace = "JOBot.Proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/empty.proto"; + service User { rpc Register (RegisterRequest) returns (RegisterResponse); rpc GetUser (GetUserRequest) returns (GetUserResponse); rpc AcceptEula (AcceptEulaRequest) returns (AcceptEulaResponse); + rpc GetHeadHunterAuthHook(GetHeadHunterAuthHookRequest) returns (GetHeadHunterAuthHookResponse); } -import "google/protobuf/wrappers.proto"; - message RegisterRequest{ int64 user_id = 1; google.protobuf.StringValue username = 2; @@ -37,4 +39,12 @@ message AcceptEulaRequest { message AcceptEulaResponse{ bool success = 1; +} + +message GetHeadHunterAuthHookRequest{ + int64 user_id = 1; +} + +message GetHeadHunterAuthHookResponse{ + string registration_url = 1; } \ No newline at end of file