Exemplo n.º 1
0
        public HandlerMatch Match(MiddlewareData middlewareData)
        {
            var command = middlewareData.Features.RequireOne <CommandFeature>().Command;

            var commandMatched = Attribute.Command.Nullable()
                                 .Map(a => command.Command.Map(b => a.Equals(b, StringComparison.OrdinalIgnoreCase)).OrElse(false))
                                 .OrElse(false);

            var commandsMatched = Attribute.Commands.Nullable()
                                  .Map(a => command.Command.Map(b => a.Contains(b, StringComparer.OrdinalIgnoreCase)).OrElse(false))
                                  .OrElse(false);

            var commandPatternMatched = Attribute.CommandPattern.Nullable()
                                        .Map(pattern => new Regex(pattern, RegexOptions.Compiled))
                                        .Map(pattern => command.Command.Map(pattern.IsMatch).OrElse(false))
                                        .OrElse(false);

            var typeMatched = Attribute.Type.Nullable()
                              .Map(filter => filter.Equals(command.Type, StringComparison.Ordinal))
                              .OrElse(true);

            if (typeMatched && (commandMatched || commandsMatched || commandPatternMatched))
            {
                return(HandlerMatch.CreateMatched(this));
            }

            return(HandlerMatch.CreateUnmatched());
        }
Exemplo n.º 2
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var chatId    = _contextManager.GetChatId(data);
            var messageId = _contextManager.GetMessageId(data);

            var chatContext = await _storage.LoadChatContext(chatId);

            var messageContext = Enumerable.Empty <KeyValuePair <string, object> >();

            if (_contextManager.HasMessageContext(data))
            {
                messageContext = await _storage.LoadMessageContext(chatId, messageId);
            }

            var newData = data.UpdateFeatures(f => f.AddExclusive <ChatContextFeature>(new ChatContextFeature(chatContext))
                                              .AddExclusive <MessageContextFeature>(new MessageContextFeature(messageId, messageContext)));
            var resultData = await chain.NextAsync(newData);

            var newChatContext = resultData.Features.RequireOne <ChatContextFeature>();
            await _storage.SaveChatContext(chatId, newChatContext.Items);

            var newMessageContext = resultData.Features.RequireOne <MessageContextFeature>();

            foreach (var id in newMessageContext.MessageIds)
            {
                await _storage.SaveMessageContext(chatId, id, newMessageContext.Items);
            }

            return(resultData);
        }
Exemplo n.º 3
0
            public async Task <IHandlerResult> ExecuteAsync(MiddlewareData middlewareData)
            {
                var filters      = _method.GetCustomAttributes <FilterAttribute>();
                var filterResult = await FilterUtils.ExecuteFilters(filters, _serviceProvider, middlewareData);

                if (filterResult.Action == FilterAction.SkipHandler)
                {
                    return(null);
                }

                if (filterResult.Action == FilterAction.BreakExecution)
                {
                    return(filterResult.MiddlewareData
                           .Map(HandlerResultCreators.UpdateMiddlewareData)
                           .OrElseGet(HandlerResultCreators.Empty));
                }

                var parameters = _parametersMatcher.MatchParameters(filterResult.MiddlewareData.Value, _method.GetParameters());

                if (!parameters.IsPresent)
                {
                    return(null);
                }

                var instance = _serviceProvider.GetInstance(_method.DeclaringType);
                var result   = _method.Invoke(instance, parameters.Value.Select(v => v.Value).ToArray());

                if (result is Task task)
                {
                    return(await task.ContinueWith(PrepareResult));
                }
                return(PrepareResult(result));
            }
Exemplo n.º 4
0
        public async Task <Maybe <IIdentity> > HandleAuthenticationAsync(MiddlewareData data, IPrincipal principal)
        {
            var telegramIdentity = principal.GetIdentity <TelegramIdentity>()
                                   .OrElseThrow(() => new InvalidOperationException("TelegramIdentity is required"));

            var telegramUserId = telegramIdentity.Id;

            var filter = Builders <T> .Filter.Eq(u => u.UserId, telegramUserId);

            var newUser = await _identityFactory.CreateIdentityAsync(principal);

            var update = new BsonDocument {
                { "$setOnInsert", newUser.ToBsonDocument() }
            };

            IIdentity identity = await GetDatabase().GetCollection <T>(CollectionNames.UsersCollection)
                                 .FindOneAndUpdateAsync(
                filter: filter,
                update: update,
                options: new FindOneAndUpdateOptions <T>()
            {
                IsUpsert       = true,
                ReturnDocument = ReturnDocument.After
            }
                );

            return(identity.NotNull());
        }
Exemplo n.º 5
0
        private async Task ProcessUpdates(CancellationToken token)
        {
            await Task.Yield();

            while (!token.IsCancellationRequested)
            {
                UpdateInfo updateInfo;
                if (!_updatesQueue.TryDequeue(out updateInfo))
                {
                    await Task.Delay(TimeSpan.FromSeconds(1), token);

                    continue;
                }

                try {
                    var inputData = new MiddlewareData()
                                    .UpdateFeatures(f => f.AddExclusive <UpdateInfoFeature>(new UpdateInfoFeature(updateInfo)));

                    await _middlewaresChain.NextAsync(inputData);
                }
                catch (Exception e) {
                    _logger.LogError(0, e, "Unhandled exception occured");
                }
            }
        }
Exemplo n.º 6
0
 public IEnumerable <IHandler> CreateHandlers(MiddlewareData middlewareData)
 {
     return(_descriptors
            .Select(d => d.Match(middlewareData))
            .Where(m => m.Successful)
            .Select(m => new Handler(_serviceProvider, _parametersMatcher, m.Descriptor.Method)));
 }
Exemplo n.º 7
0
        private static RoutingData ParseRoutingData(MiddlewareData data)
        {
            var    updateFeature = data.Features.RequireOne <UpdateInfoFeature>();
            string messageText;

            if (updateFeature.Update.CallbackQuery != null)
            {
                var callback = updateFeature.Update.CallbackQuery;
                messageText = callback.Data;
            }
            else
            {
                var message = updateFeature.GetAnyMessage();
                messageText = message.Text;
            }
            var match = FindCommandRegex.Match(messageText);

            if (!match.Success)
            {
                return(new RoutingData("", "", new string[0], messageText));
            }
            var path    = match.Groups[1].Value;
            var parts   = path.Split(':');
            var content = match.Groups[2].Value;

            return(new RoutingData(path, path, parts, content));
        }
Exemplo n.º 8
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData input)
        {
            var fields = input.Features.RequireOne <RouterFeature>().Fields;
            var action = fields["action"];

            MethodInfo method;

            if (!_methods.TryGetValue(action, out method))
            {
                throw new Exception($"Action '{action}' not found");
            }

            var    parameters = method.GetParameters();
            var    values     = _actionParametersMapper.MapParameters(input, parameters);
            object objResult;

            if (typeof(Task <object>).GetTypeInfo().IsAssignableFrom(method.ReturnType))
            {
                var task = (Task <object>)method.Invoke(_instance, values);
                objResult = await task;
            }
            else
            {
                objResult = await Task.Run(() => method.Invoke(_instance, values));
            }

            var actionResult = objResult as IActionResult;

            if (actionResult != null)
            {
                return(actionResult.Render(input));
            }
            throw new Exception("Cannot process result");
        }
Exemplo n.º 9
0
        public async Task <MessageContext> Render(MiddlewareData middlewareData, ITelegramClient telegramClient, CancellationToken cancellationToken)
        {
            var context = middlewareData.Features.RequireOne <SessionFeature>().Context;
            var message = middlewareData.Features.RequireOne <UpdateInfoFeature>().GetAnyMessage();

            if (message == null)
            {
                throw new InvalidOperationException("Cannot send response");
            }

            if (context.SentMessageIds.Any())
            {
                await telegramClient.UpdateMessage(new UpdateMessageData(
                                                       message.Chat.Id.ToString(),
                                                       context.SentMessageIds.First(),
                                                       _messageData
                                                       ), cancellationToken);

                return(MessageContext.Empty());
            }

            var chatId     = message.Chat.Id.ToString();
            var newMessage = await telegramClient.SendMessage(new SendMessageData(
                                                                  chatId, _messageData
                                                                  ), cancellationToken);

            return(MessageContext.Builder()
                   .AddMessageId(newMessage.Id)
                   .Build());
        }
Exemplo n.º 10
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var controller = _controllerFactory.GetController(data);

            var newData = await controller.InvokeAsync(data);

            return(await chain.NextAsync(newData));
        }
Exemplo n.º 11
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var commandInfo = await _commandParser.ParseAsync(data);

            var newData = data.UpdateFeatures(f => f.Add <CommandFeature>(new CommandFeature(commandInfo)));

            return(await chain.NextAsync(newData));
        }
Exemplo n.º 12
0
 public Task <MiddlewareData> RenderAsync(MiddlewareData data)
 {
     if (_func != null)
     {
         return(Task.FromResult(_func(data)));
     }
     return(Task.FromResult(_middlewareData));
 }
Exemplo n.º 13
0
        public async Task <MessageContext> Render(MiddlewareData middlewareData, ITelegramClient telegramClient, CancellationToken cancellationToken)
        {
            var newMessage = await telegramClient.SendMessage(new SendMessageData(_chatId, _messageData), cancellationToken);

            return(MessageContext.Builder()
                   .AddMessageId(newMessage.Id)
                   .Build());
        }
Exemplo n.º 14
0
        public bool HasMessageContext(MiddlewareData middlewareData)
        {
            var updateInfo       = middlewareData.Features.RequireOne <UpdateInfoFeature>();
            var contextMessageId = updateInfo.Update.EditedMessage?.Id
                                   ?? updateInfo.Update.EditedChannelPost?.Id
                                   ?? updateInfo.Update.CallbackQuery?.Message.Id;

            return(contextMessageId != null);
        }
Exemplo n.º 15
0
 public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
 {
     try {
         return(await chain.NextAsync(data));
     }
     catch (Exception e) {
         return(GetHandler(e.GetType()).HandleException(data, e));
     }
 }
Exemplo n.º 16
0
        public CommandInfo Parse(MiddlewareData data)
        {
            var updateInfo = data.Features.RequireOne <UpdateInfoFeature>();

            if (updateInfo.Update.CallbackQuery != null)
            {
                return(MatchCommand(TelegramCommandTypes.InlineKeyboardCommand, updateInfo.Update.CallbackQuery.Data, ParseCallbackQueryRegex));
            }
            return(MatchCommand(TelegramCommandTypes.TextMessageCommand, updateInfo.GetAnyMessage().Text, ParseCommandRegex));
        }
Exemplo n.º 17
0
        public override MiddlewareData HandleException(MiddlewareData middlewareData, Exception exception)
        {
            _logger.LogError(0, exception, "Unexpected error occurred");
            var message = new BaseOutMessage()
            {
                Text = $"Error occured: [{exception.GetType().Name}] {exception.Message}"
            };

            return(middlewareData.AddRenderMessageFeature(message));
        }
        public override MiddlewareData HandleException(MiddlewareData middlewareData, NoSuchHandlerException exception)
        {
            _logger.LogInformation("Cannot find handler for message");
            var message = new BaseOutMessage()
            {
                Text = "Unknown command"
            };

            return(middlewareData.AddRenderMessageFeature(message));
        }
Exemplo n.º 19
0
            public async Task <MiddlewareData> RenderAsync(MiddlewareData data)
            {
                var lastData = data;

                foreach (var result in _results)
                {
                    lastData = await result.RenderAsync(lastData);
                }
                return(lastData);
            }
Exemplo n.º 20
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var userPreferences = data.Features.GetOne <UserPreferencesFeature>()
                                  .Map(f => f.UserPreferences)
                                  .OrElse(DefaultUserPreferences.Instance);

            var routingData     = ParseRoutingData(data);
            var prevRoutingData = await LoadSavedRoutingData(data);

            if (prevRoutingData != null)
            {
                routingData = JoinRoutingData(prevRoutingData, routingData);
            }

            var dataWithContext = data.UpdateFeatures(f => f.ReplaceExclusive <SessionFeature>(
                                                          e => e.SetRoutingData(prevRoutingData)
                                                          )
                                                      );

            _logger.LogDebug($"Try find route for {routingData.Path} ({routingData.UserCommand})");

            var match  = _router.FindRoute(routingData);
            var chatId = dataWithContext.Features.RequireOne <UpdateInfoFeature>().GetAnyMessage().Chat.Id;

            if (!match.IsMatched)
            {
                await _sessionStorage.ClearRoutingDataAsync(chatId);

                var message = _localizationManager.Localize(
                    userPreferences: userPreferences,
                    key: LocalizationKeys.UnknownCommand,
                    parameters: new { text = routingData.UserCommand }
                    );
                return(dataWithContext.AddResponseRenderer(message));
            }

            if (!match.IsCompleted)
            {
                await _sessionStorage.SaveRoutingDataAsync(chatId, routingData);

                var responseMessage = MessageData.Builder()
                                      .SetText(_localizationManager.Localize(userPreferences, LocalizationKeys.SelectOneForCompletion))
                                      .SetInlineKeyboardMarkup(bldr => BuildResponseMarkup(bldr, match.UncompletedRoutes))
                                      .Build();

                return(dataWithContext.AddResponseRenderer(responseMessage));
            }
            await _sessionStorage.ClearRoutingDataAsync(chatId);

            var route         = match.CompletedRoute;
            var feature       = new RouterFeature(route.Route, routingData, route.Fields);
            var dataWithRoute = dataWithContext.UpdateFeatures(f => f.AddExclusive <RouterFeature>(feature));

            return(await chain.NextAsync(dataWithRoute));
        }
Exemplo n.º 21
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var resultData = await chain.NextAsync(data);

            foreach (var message in resultData.Features.GetAll <RenderMessageFeature>().Select(f => f.Message))
            {
                var renderrer = GetRenderer(message.GetType());
                resultData = await renderrer.RenderAsync(resultData, message);
            }
            return(resultData);
        }
        public Task <Maybe <IIdentity> > HandleAuthenticationAsync(MiddlewareData data, IPrincipal principal)
        {
            var message = data.Features.RequireOne <UpdateInfoFeature>().GetAnyMessage();

            if (message == null)
            {
                return(Task.FromResult(Maybe <IIdentity> .Empty()));
            }
            var userId   = message.User?.Id ?? message.Chat.Id;
            var userName = message.User?.UserName ?? message.Chat.UserName;
            var identity = new TelegramIdentity(userId.ToString(), userName);

            return(Task.FromResult(Maybe <IIdentity> .Of(identity)));
        }
Exemplo n.º 23
0
        public Task <FilterResult> FilterAsync(FilterAttribute attribute, MiddlewareData data)
        {
            var principal = data.Features.RequireOne <AuthenticationFeature>().Principal;

            if (!principal.Is​Authenticated())
            {
                var message = new BaseOutMessage()
                {
                    Text = "Unauthorized access"
                };
                var result = FilterResult.BreakExecution(data.AddRenderMessageFeature(message));
                return(Task.FromResult(result));
            }
            return(Task.FromResult(FilterResult.NextFilter(data)));
        }
Exemplo n.º 24
0
        private async Task <RoutingData> LoadSavedRoutingData(MiddlewareData data)
        {
            var message   = data.Features.RequireOne <UpdateInfoFeature>().GetAnyMessage();
            var chatId    = message.Chat.Id;
            var messageId = message.Id;

            var context = await _sessionStorage.LoadMessageContextAsync(chatId, messageId);

            if (context != null)
            {
                return(context.RoutingData);
            }

            return(await _sessionStorage.GetRoutingDataAsync(chatId));
        }
Exemplo n.º 25
0
            public Task <MiddlewareData> RenderAsync(MiddlewareData data)
            {
                var messageContent = new MessageContent(Text);

                InlineKeyboardMarkup.Nullable().IfPresent(m => messageContent.ReplyMarkup = m);

                var message = new TelegramOutMessage(messageContent)
                {
                    UpdateMessage = Update,
                    MessageId     = MessageId,
                    ChatId        = ChatId
                };

                return(Task.FromResult(data.AddRenderMessageFeature(message)));
            }
Exemplo n.º 26
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            var principal = new CombinablePrincipal();

            foreach (var authenticationHandler in _authenticationHandlers)
            {
                var identity = await authenticationHandler.HandleAuthenticationAsync(data, principal);

                principal = identity.Map(principal.AddIdentity).OrElse(principal);
            }

            var newData = data.UpdateFeatures(f => f.AddExclusive <AuthenticationFeature>(new AuthenticationFeature(principal)));

            return(await chain.NextAsync(newData));
        }
Exemplo n.º 27
0
        public object[] MapParameters(MiddlewareData data, IEnumerable <ParameterInfo> parameters)
        {
            var allValues = data.Features.GetAllOfBaseType <IParameterValuesSource>()
                            .SelectMany(source => source.GetValues())
                            .Union(new [] { new ParameterValue("middlewareData", data) });

            var groupped = parameters.GroupJoin(
                inner: allValues,
                outerKeySelector: p => p.ParameterType,
                innerKeySelector: v => v.Type,
                resultSelector: (parameter, values) => new { parameter, values = values.ToArray() },
                comparer: ParametersEqualityComparer.Instance
                );

            return(groupped.Select(g => SelectValue(g.parameter, g.values)).ToArray());
        }
Exemplo n.º 28
0
        public IController GetController(MiddlewareData input)
        {
            var fields     = input.Features.RequireOne <RouterFeature>().Fields;
            var controller = fields["controller"];

            TypeInfo type;

            if (!_types.TryGetValue(controller, out type))
            {
                throw new Exception("Controller not found");
            }

            var instance = _serviceProvider.GetInstance(type.UnderlyingSystemType);

            return(instance as IController ??
                   new ActionsController(_actionParametersMapper, instance));
        }
Exemplo n.º 29
0
        public async Task <MiddlewareData> InvokeAsync(MiddlewareData data, IMiddlewaresChain chain)
        {
            foreach (var handler in _handlerFactory.CreateHandlers(data))
            {
                var result = await handler.ExecuteAsync(data);

                if (result == null)   // TODO fix this check
                {
                    continue;
                }
                var resultData = await result.RenderAsync(data);

                return(await chain.NextAsync(resultData));
            }

            throw new NoSuchHandlerException();
        }
Exemplo n.º 30
0
        public static async Task <ModuleResponseCode> RouteAsync(string Path, LanguageManager STR_LANG, WebHttpContextRaw ContextRaw)
        {
            string Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

            //Set HTTP Header to this
            ContextRaw.Response.SetHeader("X-Powered-By", $"HS Server Framework (Web)/{Version}");
            ContextRaw.Response.SetHeader("Server", $"HS Server (Web)/{Version}");

            MiddlewareData data = await Middleware.RouteAsync(new MiddlewareData(Path, STR_LANG, ContextRaw));

            ModuleResponseCode ResultCode = (ModuleResponseCode)data.StatusCode;

            if (!data.IsClose && ContextRaw.Response.IsWritable)
            {
                ResultCode = await Router.RouteAsync(data);
            }
            //MiddleWareData data_post = await MiddleWare_Post.RouteAsync(Path, Params, STR_LANG, ContextRaw);
            return(ResultCode);
        }