public async Task SendToGroupFromOutsideOfHub()
        {
            using (var host = new MemoryHost())
            {
                IHubContext<IBasicClient> hubContext = null;
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapSignalR(configuration);
                    hubContext = configuration.Resolver.Resolve<IConnectionManager>().GetHubContext<SendToSome, IBasicClient>();
                });

                var connection1 = new HubConnection("http://foo/");

                using (connection1)
                {
                    var wh1 = new AsyncManualResetEvent(initialState: false);

                    var hub1 = connection1.CreateHubProxy("SendToSome");

                    await connection1.Start(host);

                    hub1.On("send", wh1.Set);

                    hubContext.Groups.Add(connection1.ConnectionId, "Foo").Wait();
                    hubContext.Clients.Group("Foo").send();

                    Assert.True(await wh1.WaitAsync(TimeSpan.FromSeconds(10)));
                }
            }
        }
Ejemplo n.º 2
0
        public void AuthenticatedAndAuthorizedUserCanInvokeMethodsInHubsAuthorizedSpecifyingUserAndRole()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity("User"), new string[] { "Admin" }));
                    app.MapHubs("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                var hub = connection.CreateHubProxy("UserAndRoleAuthHub");
                var wh = new ManualResetEvent(false);
                hub.On<string, string>("invoked", (id, time) =>
                {
                    Assert.NotNull(id);
                    wh.Set();
                });

                connection.Start(host).Wait();

                hub.InvokeWithTimeout("InvokedFromClient");

                Assert.True(wh.WaitOne(TimeSpan.FromSeconds(3)));
                connection.Stop();
            }
        }
Ejemplo n.º 3
0
        public async Task AuthenticatedUserCanReceiveHubMessagesByDefault()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity("test"), new string[] { }));
                    app.MapSignalR("/signalr", configuration);

                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("NoAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string, object>("joined", (id, time, authInfo) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    await connection.Start(host);

                    Assert.True(wh.WaitOne(TimeSpan.FromSeconds(3)));
                }
            }
        }
Ejemplo n.º 4
0
        public static IDisposable StressGroups(int max = 100)
        {
            var host = new MemoryHost();
            host.Configure(app =>
            {
                var config = new HubConfiguration()
                {
                    Resolver = new DefaultDependencyResolver()
                };

                app.MapSignalR(config);

                var configuration = config.Resolver.Resolve<IConfigurationManager>();
                // The below effectively sets the heartbeat interval to five seconds.
                configuration.KeepAlive = TimeSpan.FromSeconds(10);
            });

            var countDown = new CountDownRange<int>(Enumerable.Range(0, max));
            var connection = new HubConnection("http://foo");
            var proxy = connection.CreateHubProxy("HubWithGroups");

            proxy.On<int>("Do", i =>
            {
                if (!countDown.Mark(i))
                {
                    Debugger.Break();
                }
            });

            try
            {
                connection.Start(new Client.Transports.LongPollingTransport(host)).Wait();

                proxy.Invoke("Join", "foo").Wait();

                for (int i = 0; i < max; i++)
                {
                    proxy.Invoke("Send", "foo", i).Wait();
                }

                proxy.Invoke("Leave", "foo").Wait();

                for (int i = max + 1; i < max + 50; i++)
                {
                    proxy.Invoke("Send", "foo", i).Wait();
                }

                if (!countDown.Wait(TimeSpan.FromSeconds(10)))
                {
                    Console.WriteLine("Didn't receive " + max + " messages. Got " + (max - countDown.Count) + " missed " + String.Join(",", countDown.Left.Select(i => i.ToString())));
                    Debugger.Break();
                }
            }
            finally
            {
                connection.Stop();
            }

            return host;
        }
Ejemplo n.º 5
0
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR<SendingConnection>("/sending-connection");
            app.MapSignalR<TestConnection>("/test-connection");
            app.MapSignalR<RawConnection>("/raw-connection");
            app.MapSignalR<StreamingConnection>("/streaming-connection");

            app.Use(typeof(ClaimsMiddleware));

            ConfigureSignalR(GlobalHost.DependencyResolver, GlobalHost.HubPipeline);

            var config = new HubConfiguration()
            {
                EnableDetailedErrors = true
            };

            app.MapSignalR(config);

            app.Map("/cors", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.MapSignalR<RawConnection>("/raw-connection");
                map.MapSignalR();
            });

            app.Map("/basicauth", map =>
            {
                map.UseBasicAuthentication(new BasicAuthenticationProvider());
                map.MapSignalR<AuthenticatedEchoConnection>("/echo");
                map.MapSignalR();
            });

            BackgroundThread.Start();
        }
Ejemplo n.º 6
0
        public static IDisposable BrodcastFromServer()
        {
            var host = new MemoryHost();
            IHubContext context = null;

            host.Configure(app =>
            {
                var config = new HubConfiguration()
                {
                    Resolver = new DefaultDependencyResolver()
                };

                app.MapHubs(config);

                var configuration = config.Resolver.Resolve<IConfigurationManager>();
                // The below effectively sets the heartbeat interval to five seconds.
                configuration.KeepAlive = TimeSpan.FromSeconds(10);

                var connectionManager = config.Resolver.Resolve<IConnectionManager>();
                context = connectionManager.GetHubContext("EchoHub");
            });

            var cancellationTokenSource = new CancellationTokenSource();

            var thread = new Thread(() =>
            {
                while (!cancellationTokenSource.IsCancellationRequested)
                {
                    context.Clients.All.echo();
                }
            });

            thread.Start();

            var connection = new Client.Hubs.HubConnection("http://foo");
            var proxy = connection.CreateHubProxy("EchoHub");

            try
            {
                connection.Start(host).Wait();

                Thread.Sleep(1000);
            }
            finally
            {
                connection.Stop();
            }

            return new DisposableAction(() =>
            {
                cancellationTokenSource.Cancel();

                thread.Join();

                host.Dispose();
            });
        }
        protected override void ConfigureApp(IAppBuilder app)
        {
            var config = new HubConfiguration
            {
                Resolver = Resolver
            };

            app.MapHubs(config);

            config.Resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData());
        }
Ejemplo n.º 8
0
        public async Task GroupsWorkAfterServerRestart()
        {
            var host = new ServerRestarter(app =>
            {
                var config = new HubConfiguration
                {
                    Resolver = new DefaultDependencyResolver()
                };

                app.MapSignalR(config);
            });

            using (host)
            {
                using (var connection = CreateHubConnection("http://foo/"))
                {
                    var reconnectedEvent = new AsyncManualResetEvent();
                    connection.Reconnected += reconnectedEvent.Set;

                    var hubProxy = connection.CreateHubProxy("groupChat");
                    var sendEvent = new AsyncManualResetEvent();
                    string sendMessage = null;
                    hubProxy.On<string>("send", message =>
                    {
                        sendMessage = message;
                        sendEvent.Set();
                    });

                    var groupName = "group$&+,/:;=?@[]1";
                    var groupMessage = "hello";

                    // MemoryHost doesn't support WebSockets, and it is difficult to ensure that
                    // the reconnected event is reliably fired with the LongPollingTransport.
                    await connection.Start(new ServerSentEventsTransport(host));

                    await hubProxy.Invoke("Join", groupName);

                    host.Restart();

                    Assert.True(await reconnectedEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for client side reconnect.");

                    await hubProxy.Invoke("Send", groupName, groupMessage);

                    Assert.True(await sendEvent.WaitAsync(TimeSpan.FromSeconds(15)), "Timed out waiting for message.");
                    Assert.Equal(groupMessage, sendMessage);
                }
            }
        }
Ejemplo n.º 9
0
        public void DisconnectFiresForHubsWhenConnectionGoesAway()
        {
            using (var host = new MemoryHost())
            {
                var dr = new DefaultDependencyResolver();
                var configuration = dr.Resolve<IConfigurationManager>();

                var connectWh = new ManualResetEventSlim();
                var disconnectWh = new ManualResetEventSlim();
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = dr
                    };

                    app.MapHubs("/signalr", config);

                    configuration.DisconnectTimeout = TimeSpan.Zero;
                    configuration.HeartbeatInterval = TimeSpan.FromSeconds(5);
                    dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh));
                });

                var connection = new Client.Hubs.HubConnection("http://foo/");

                connection.CreateHubProxy("MyHub");

                // Maximum wait time for disconnect to fire (3 heart beat intervals)
                var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval.Ticks * 3);

                connection.Start(host).Wait();

                Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired");

                connection.Stop();

                Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired");
            }
        }
Ejemplo n.º 10
0
        public void CreatedHubsGetDisposed()
        {
            var mockHubs = new List<Mock<IHub>>();

            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapHubs("/signalr", config);

                    config.Resolver.Register(typeof(IHub), () =>
                    {
                        var mockHub = new Mock<IHub>() { CallBase = true };

                        mockHubs.Add(mockHub);
                        return mockHub.Object;
                    });
                });

                var connection = new Client.Hubs.HubConnection("http://foo/");

                var hub = connection.CreateHubProxy("demo");

                connection.Start(host).Wait();

                var result = hub.InvokeWithTimeout<string>("ReadStateValue");

                foreach (var mockDemoHub in mockHubs)
                {
                    mockDemoHub.Verify(d => d.Dispose(), Times.Once());
                }

                connection.Stop();
            }
        }
Ejemplo n.º 11
0
        public void SendToSpecificClientFromOutsideOfHub()
        {
            using (var host = new MemoryHost())
            {
                IHubContext hubContext = null;
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapHubs(configuration);
                    hubContext = configuration.Resolver.Resolve<IConnectionManager>().GetHubContext("SendToSome");
                });

                var connection1 = new Client.Hubs.HubConnection("http://foo/");

                var wh1 = new ManualResetEventSlim(initialState: false);

                var hub1 = connection1.CreateHubProxy("SendToSome");

                connection1.Start(host).Wait();

                hub1.On("send", wh1.Set);

                hubContext.Clients.Client(connection1.ConnectionId).send();

                Assert.True(wh1.Wait(TimeSpan.FromSeconds(10)));

                connection1.Stop();
            }
        }
Ejemplo n.º 12
0
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR <SendingConnection>("/sending-connection");
            app.MapSignalR <TestConnection>("/test-connection");
            app.MapSignalR <RawConnection>("/raw-connection");
            app.MapSignalR <StreamingConnection>("/streaming-connection");

            app.Use(typeof(ClaimsMiddleware));

            ConfigureSignalR(GlobalHost.DependencyResolver, GlobalHost.HubPipeline);

            var config = new HubConfiguration()
            {
                EnableDetailedErrors = true
            };

            app.MapSignalR(config);

            app.Map("/cors", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.MapSignalR <RawConnection>("/raw-connection");
                map.MapSignalR();
            });

            app.Map("/cookieauth", map =>
            {
                var options = new CookieAuthenticationOptions()
                {
                    AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
                    LoginPath          = CookieAuthenticationDefaults.LoginPath,
                    LogoutPath         = CookieAuthenticationDefaults.LogoutPath,
                };

                map.UseCookieAuthentication(options);

                map.Use(async(context, next) =>
                {
                    if (context.Request.Path.Value.Contains(options.LoginPath.Value))
                    {
                        if (context.Request.Method == "POST")
                        {
                            var form     = await context.Request.ReadFormAsync();
                            var userName = form["UserName"];
                            var password = form["Password"];

                            var identity = new ClaimsIdentity(options.AuthenticationType);
                            identity.AddClaim(new Claim(ClaimTypes.Name, userName));
                            context.Authentication.SignIn(identity);
                        }
                    }
                    else
                    {
                        await next();
                    }
                });

                map.MapSignalR <AuthenticatedEchoConnection>("/echo");
                map.MapSignalR();
            });

            BackgroundThread.Start();
        }
Ejemplo n.º 13
0
 public HubDispatcherHandler(AppFunc next, string path, HubConfiguration configuration)
 {
     _next = next;
     _path = path;
     _configuration = configuration;
 }
Ejemplo n.º 14
0
        public void GroupsTokenIsPerConnectionId()
        {
            using (var host = new MemoryHost())
            {
                IProtectedData protectedData = null;

                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapSignalR <MyGroupConnection>("/echo", config);

                    protectedData = config.Resolver.Resolve <IProtectedData>();
                });

                var connection = new Client.Connection("http://memoryhost/echo");

                using (connection)
                {
                    var inGroup = new ManualResetEventSlim();

                    connection.Received += data =>
                    {
                        if (data == "group")
                        {
                            inGroup.Set();
                        }
                    };

                    connection.Start(host).Wait();

                    inGroup.Wait();

                    Assert.NotNull(connection.GroupsToken);

                    var spyWh            = new ManualResetEventSlim();
                    var hackerConnection = new Client.Connection(connection.Url)
                    {
                        ConnectionId = "hacker"
                    };

                    var url      = GetUrl(protectedData, connection, connection.GroupsToken);
                    var response = host.Get(url).Result;
                    var reader   = new EventSourceStreamReader(hackerConnection, response.GetStream());

                    reader.Message = sseEvent =>
                    {
                        if (sseEvent.EventType == EventType.Data &&
                            sseEvent.Data != "initialized" &&
                            sseEvent.Data != "{}")
                        {
                            spyWh.Set();
                        }
                    };

                    reader.Start();
                    connection.Send("random").Wait();

                    Assert.False(spyWh.Wait(TimeSpan.FromSeconds(5)));
                }
            }
        }
Ejemplo n.º 15
0
        private static void InitializePlatform(
            IAppBuilder app,
            IUnityContainer container,
            IPathMapper pathMapper,
            string connectionString,
            HangfireLauncher hangfireLauncher,
            string modulesPath,
            ModuleInitializerOptions moduleInitializerOptions)
        {
            container.RegisterType <ICurrentUser, CurrentUser>(new HttpContextLifetimeManager());
            container.RegisterType <IUserNameResolver, UserNameResolver>();

            #region Setup database

            using (var db = new SecurityDbContext(connectionString))
            {
                new IdentityDatabaseInitializer().InitializeDatabase(db);
            }

            using (var context = new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor()))
            {
                new PlatformDatabaseInitializer().InitializeDatabase(context);
            }

            hangfireLauncher.ConfigureDatabase();

            #endregion

            Func <IPlatformRepository> platformRepositoryFactory = () => new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor());
            container.RegisterType <IPlatformRepository>(new InjectionFactory(c => platformRepositoryFactory()));
            container.RegisterInstance(platformRepositoryFactory);
            var moduleCatalog = container.Resolve <IModuleCatalog>();

            #region Caching

            //Cure for System.Runtime.Caching.MemoryCache freezing
            //https://www.zpqrtbnk.net/posts/appdomains-threads-cultureinfos-and-paracetamol
            app.SanitizeThreadCulture();
            ICacheManager <object> cacheManager = null;

            var redisConnectionString = ConfigurationHelper.GetConnectionStringValue("RedisConnectionString");

            //Try to load cache configuration from web.config first
            //Should be aware to using Web cache cache handle because it not worked in native threads. (Hangfire jobs)
            if (ConfigurationManager.GetSection(CacheManagerSection.DefaultSectionName) is CacheManagerSection cacheManagerSection)
            {
                CacheManagerConfiguration configuration = null;

                var defaultCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("platformCache"));
                if (defaultCacheManager != null)
                {
                    configuration = ConfigurationBuilder.LoadConfiguration(defaultCacheManager.Name);
                }

                var redisCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("redisPlatformCache"));
                if (redisConnectionString != null && redisCacheManager != null)
                {
                    configuration = ConfigurationBuilder.LoadConfiguration(redisCacheManager.Name);
                    configuration.BackplaneChannelName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Cache:Redis:ChannelName");
                }

                if (configuration != null)
                {
                    configuration.LoggerFactoryType          = typeof(CacheManagerLoggerFactory);
                    configuration.LoggerFactoryTypeArguments = new object[] { container.Resolve <ILog>() };
                    cacheManager = CacheFactory.FromConfiguration <object>(configuration);
                }
            }

            // Create a default cache manager if there is no any others
            if (cacheManager == null)
            {
                cacheManager = CacheFactory.Build("platformCache", settings =>
                {
                    settings.WithUpdateMode(CacheUpdateMode.Up)
                    .WithSystemRuntimeCacheHandle("memCacheHandle")
                    .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(5));
                });
            }

            container.RegisterInstance(cacheManager);

            #endregion

            #region Settings

            var platformModuleManifest = new ModuleManifest
            {
                Id              = "VirtoCommerce.Platform",
                Version         = PlatformVersion.CurrentVersion.ToString(),
                PlatformVersion = PlatformVersion.CurrentVersion.ToString(),
                Settings        = new[]
                {
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendGrid",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendGrid.ApiKey",
                                ValueType   = ModuleSetting.TypeSecureString,
                                Title       = "SendGrid API key",
                                Description = "Your SendGrid API key"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendingJob",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendingJob.TakeCount",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Job Take Count",
                                Description = "Take count for sending job"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SmtpClient",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Host",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server host",
                                Description = "Smtp server host"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Port",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Smtp server port",
                                Description = "Smtp server port"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Login",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server login",
                                Description = "Smtp server login"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Password",
                                ValueType   = ModuleSetting.TypeSecureString,
                                Title       = "Smtp server password",
                                Description = "Smtp server password"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.UseSsl",
                                ValueType   = ModuleSetting.TypeBoolean,
                                Title       = "Use SSL",
                                Description = "Use secure connection"
                            },
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Security",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.Security.AccountTypes",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Account types",
                                Description  = "Dictionary for possible account types",
                                IsArray      = true,
                                ArrayValues  = Enum.GetNames(typeof(AccountType)),
                                DefaultValue = AccountType.Manager.ToString()
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Profile",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name      = "VirtoCommerce.Platform.UI.MainMenu.State",
                                ValueType = ModuleSetting.TypeJson,
                                Title     = "Persisted state of main menu"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Language",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Language",
                                Description  = "Default language (two letter code from ISO 639-1, case-insensitive). Example: en, de",
                                DefaultValue = "en"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.RegionalFormat",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Regional format",
                                Description  = "Default regional format (CLDR locale code, with dash or underscore as delemiter, case-insensitive). Example: en, en_US, sr_Cyrl, sr_Cyrl_RS",
                                DefaultValue = "en"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.UI.TimeZone",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Time zone",
                                Description = "Default time zone (IANA time zone name [tz database], exactly as in database, case-sensitive). Examples: America/New_York, Europe/Moscow"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.ShowMeridian",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Meridian labels based on user preferences",
                                Description  = "When set to true (by default), system will display time in format like '12 hour format' when possible",
                                DefaultValue = true.ToString()
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.UseTimeAgo",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Use time ago format when is possible",
                                Description  = "When set to true (by default), system will display date in format like 'a few seconds ago' when possible",
                                DefaultValue = true.ToString()
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.UI.FullDateThreshold",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Full date threshold",
                                Description = "Number of units after time ago format will be switched to full date format"
                            },
                            new ModuleSetting
                            {
                                Name          = "VirtoCommerce.Platform.UI.FullDateThresholdUnit",
                                ValueType     = ModuleSetting.TypeString,
                                Title         = "Full date threshold unit",
                                Description   = "Unit of full date threshold",
                                DefaultValue  = "Never",
                                AllowedValues = new[]
                                {
                                    "Never",
                                    "Seconds",
                                    "Minutes",
                                    "Hours",
                                    "Days",
                                    "Weeks",
                                    "Months",
                                    "Quarters",
                                    "Years"
                                }
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.FourDecimalsInMoney",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Show 4 decimal digits for money",
                                Description  = "Set to true to show 4 decimal digits for money. By default - false, 2 decimal digits are shown.",
                                DefaultValue = "false",
                            },
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Interface",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Customization",
                                ValueType    = ModuleSetting.TypeJson,
                                Title        = "Customization",
                                Description  = "JSON contains personalization settings of manager UI",
                                DefaultValue = "{\n" +
                                               "  \"title\": \"Virto Commerce\",\n" +
                                               "  \"logo\": \"Content/themes/main/images/logo.png\",\n" +
                                               "  \"contrast_logo\": \"Content/themes/main/images/contrast-logo.png\",\n" +
                                               "  \"favicon\": \"favicon.ico\"\n" +
                                               "}"
                            }
                        }
                    }
                }
            };

            var settingsManager = new SettingsManager(moduleCatalog, platformRepositoryFactory, cacheManager, new[] { new ManifestModuleInfo(platformModuleManifest) });
            container.RegisterInstance <ISettingsManager>(settingsManager);

            #endregion

            #region Dynamic Properties

            container.RegisterType <IDynamicPropertyService, DynamicPropertyService>(new ContainerControlledLifetimeManager());

            #endregion

            #region Notifications

            // Redis
            if (!string.IsNullOrEmpty(redisConnectionString))
            {
                // Cache
                RedisConfigurations.AddConfiguration(new RedisConfiguration("redisConnectionString", redisConnectionString));

                // SignalR
                // https://stackoverflow.com/questions/29885470/signalr-scaleout-on-azure-rediscache-connection-issues
                GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(redisConnectionString, "VirtoCommerce.Platform.SignalR"));
            }

            // SignalR
            var tempCounterManager = new TempPerformanceCounterManager();
            GlobalHost.DependencyResolver.Register(typeof(IPerformanceCounterManager), () => tempCounterManager);
            var hubConfiguration = new HubConfiguration {
                EnableJavaScriptProxies = false
            };
            app.MapSignalR("/" + moduleInitializerOptions.RoutePrefix + "signalr", hubConfiguration);

            var hubSignalR = GlobalHost.ConnectionManager.GetHubContext <ClientPushHub>();
            var notifier   = new InMemoryPushNotificationManager(hubSignalR);
            container.RegisterInstance <IPushNotificationManager>(notifier);

            var resolver = new LiquidNotificationTemplateResolver();
            container.RegisterInstance <INotificationTemplateResolver>(resolver);

            var notificationTemplateService = new NotificationTemplateServiceImpl(platformRepositoryFactory);
            container.RegisterInstance <INotificationTemplateService>(notificationTemplateService);

            var notificationManager = new NotificationManager(resolver, platformRepositoryFactory, notificationTemplateService);
            container.RegisterInstance <INotificationManager>(notificationManager);

            IEmailNotificationSendingGateway emailNotificationSendingGateway = null;

            var emailNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:Gateway", "Default");

            if (string.Equals(emailNotificationSendingGatewayName, "Default", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new DefaultSmtpEmailNotificationSendingGateway(settingsManager);
            }
            else if (string.Equals(emailNotificationSendingGatewayName, "SendGrid", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new SendGridEmailNotificationSendingGateway(settingsManager);
            }

            if (emailNotificationSendingGateway != null)
            {
                container.RegisterInstance(emailNotificationSendingGateway);
            }

            ISmsNotificationSendingGateway smsNotificationSendingGateway = null;
            var smsNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway", "Default");

            if (smsNotificationSendingGatewayName.EqualsInvariant("Twilio"))
            {
                smsNotificationSendingGateway = new TwilioSmsNotificationSendingGateway(new TwilioSmsGatewayOptions
                {
                    AccountId       = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"),
                    AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"),
                    Sender          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"),
                });
            }
            else if (smsNotificationSendingGatewayName.EqualsInvariant("ASPSMS"))
            {
                smsNotificationSendingGateway = new AspsmsSmsNotificationSendingGateway(new AspsmsSmsGatewayOptions
                {
                    AccountId       = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"),
                    AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"),
                    Sender          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"),
                    JsonApiUri      = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:ASPSMS:JsonApiUri"),
                });
            }
            else
            {
                smsNotificationSendingGateway = new DefaultSmsNotificationSendingGateway();
            }

            container.RegisterInstance(smsNotificationSendingGateway);

            #endregion

            #region Assets

            var blobConnectionString = BlobConnectionString.Parse(ConfigurationHelper.GetConnectionStringValue("AssetsConnectionString"));

            if (string.Equals(blobConnectionString.Provider, FileSystemBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var fileSystemBlobProvider = new FileSystemBlobProvider(NormalizePath(pathMapper, blobConnectionString.RootPath), blobConnectionString.PublicUrl);

                container.RegisterInstance <IBlobStorageProvider>(fileSystemBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(fileSystemBlobProvider);
            }
            else if (string.Equals(blobConnectionString.Provider, AzureBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var azureBlobProvider = new AzureBlobProvider(blobConnectionString.ConnectionString, blobConnectionString.CdnUrl);
                container.RegisterInstance <IBlobStorageProvider>(azureBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(azureBlobProvider);
            }

            container.RegisterType <IAssetEntryService, AssetEntryService>(new ContainerControlledLifetimeManager());
            container.RegisterType <IAssetEntrySearchService, AssetEntryService>(new ContainerControlledLifetimeManager());

            #endregion

            #region Modularity

            var modulesDataSources    = ConfigurationHelper.SplitAppSettingsStringValue("VirtoCommerce:ModulesDataSources");
            var externalModuleCatalog = new ExternalManifestModuleCatalog(moduleCatalog.Modules, modulesDataSources, container.Resolve <ILog>());
            container.RegisterType <ModulesController>(new InjectionConstructor(externalModuleCatalog, new ModuleInstaller(modulesPath, externalModuleCatalog), notifier, container.Resolve <IUserNameResolver>(), settingsManager));

            #endregion

            #region ChangeLogging

            var changeLogService = new ChangeLogService(platformRepositoryFactory);
            container.RegisterInstance <IChangeLogService>(changeLogService);

            #endregion

            #region Security
            container.RegisterInstance <IPermissionScopeService>(new PermissionScopeService());
            container.RegisterType <IRoleManagementService, RoleManagementService>(new ContainerControlledLifetimeManager());

            var apiAccountProvider = new ApiAccountProvider(platformRepositoryFactory, cacheManager);
            container.RegisterInstance <IApiAccountProvider>(apiAccountProvider);

            container.RegisterType <IClaimsIdentityProvider, ApplicationClaimsIdentityProvider>(new ContainerControlledLifetimeManager());

            container.RegisterInstance(app.GetDataProtectionProvider());
            container.RegisterType <SecurityDbContext>(new InjectionConstructor(connectionString));
            container.RegisterType <IUserStore <ApplicationUser>, ApplicationUserStore>();
            container.RegisterType <IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
            container.RegisterType <ApplicationUserManager>();
            container.RegisterType <ApplicationSignInManager>();

            var nonEditableUsers = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:NonEditableUsers", string.Empty);
            container.RegisterInstance <ISecurityOptions>(new SecurityOptions(nonEditableUsers));

            container.RegisterType <ISecurityService, SecurityService>();

            container.RegisterType <IPasswordCheckService, PasswordCheckService>();

            #endregion

            #region ExportImport
            container.RegisterType <IPlatformExportImportManager, PlatformExportImportManager>();
            #endregion

            #region Serialization

            container.RegisterType <IExpressionSerializer, XmlExpressionSerializer>();

            #endregion

            #region Events
            var inProcessBus = new InProcessBus();
            container.RegisterInstance <IHandlerRegistrar>(inProcessBus);
            container.RegisterInstance <IEventPublisher>(inProcessBus);

            inProcessBus.RegisterHandler <UserChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            inProcessBus.RegisterHandler <UserPasswordChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            inProcessBus.RegisterHandler <UserResetPasswordEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            #endregion
        }
Ejemplo n.º 16
0
        public async Task DisconnectFiresForHubsWhenClientCallsStop()
        {
            using (var host = new MemoryHost())
            {
                var dr = new DefaultDependencyResolver();
                var configuration = dr.Resolve<IConfigurationManager>();

                var connectWh = new AsyncManualResetEvent();
                var disconnectWh = new AsyncManualResetEvent();
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = dr
                    };

                    app.MapSignalR("/signalr", config);

                    configuration.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh));
                });

                var connection = new HubConnection("http://foo/");

                connection.CreateHubProxy("MyHub");

                // Maximum wait time for disconnect to fire (3 heart beat intervals)
                var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3);

                await connection.Start(host);

                Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired");

                connection.Stop();

                Assert.True(await disconnectWh.WaitAsync(disconnectWait), "Disconnect never fired");
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Maps Azure SignalR hubs to the app builder pipeline at "/signalr".
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="applicationName">The name of your app, it is case-incensitive.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 /// <param name="optionsConfigure">A callback to configure the <see cref="ServiceOptions"/>.</param>
 /// <returns>The app builder</returns>
 public static IAppBuilder MapAzureSignalR(this IAppBuilder builder, string applicationName, HubConfiguration configuration, Action <ServiceOptions> optionsConfigure)
 {
     return(builder.MapAzureSignalR("/signalr", applicationName, configuration, optionsConfigure));
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Maps Azure SignalR hubs to the app builder pipeline at the specified path.
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="path">The path to map signalr hubs.</param>
 /// <param name="applicationName">The name of your app, it is case-incensitive.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 /// <param name="optionsConfigure">A callback to configure the <see cref="ServiceOptions"/>.</param>
 /// <returns>The app builder</returns>
 public static IAppBuilder MapAzureSignalR(this IAppBuilder builder, string path, string applicationName, HubConfiguration configuration, Action <ServiceOptions> optionsConfigure)
 {
     return(builder.Map(path, subApp => subApp.RunAzureSignalR(applicationName, configuration, optionsConfigure)));
 }
 public ClientConnectionManager(HubConfiguration configuration, ILoggerFactory loggerFactory)
 {
     _configuration = configuration;
     _logger        = loggerFactory?.CreateLogger <ClientConnectionManager>() ?? NullLogger <ClientConnectionManager> .Instance;
 }
 public ClientConnectionHubDispatcher(HubConfiguration config, string connectionId) : base(config)
 {
     _connectionId = connectionId;
 }
Ejemplo n.º 21
0
        // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext <ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext <ApplicationSignInManager>(ApplicationSignInManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath          = new PathString("/Account/Login"),
                Provider           = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity <ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                },
                CookieName = "ArktinMonitorCookie"
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Configure the application for OAuth based flow
            PublicClientId = "self";
            OAuthOptions   = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath         = new PathString("/Token"),
                Provider                  = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath     = new PathString("/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(30),//TODO: Change value later
                AllowInsecureHttp         = false
            };

            // Enable the application to use bearer tokens to authenticate users
            app.UseOAuthBearerTokens(OAuthOptions);

            // https://stackoverflow.com/questions/26657296/signalr-authentication-with-webapi-bearer-token
            app.Map("/signalr", map =>
            {
                map.UseCors(CorsOptions.AllowAll);

                map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
                {
                    Provider = new QueryStringOAuthBearerProvider()
                });

                var hubConfiguration = new HubConfiguration
                {
                    Resolver = GlobalHost.DependencyResolver,
                };
                map.RunSignalR(hubConfiguration);
            });

            //app.Use(async (context, next) =>
            //{
            //    if (context.Request.QueryString.HasValue)
            //    {
            //        foreach (var header in context.Request.Headers)
            //        {
            //            Debug.WriteLine($"Header: {header.Key}");
            //            foreach (var value in header.Value)
            //            {
            //                Debug.WriteLine($"Value: {value}");
            //            }
            //        }
            //        if (string.IsNullOrWhiteSpace(context.Request.Headers.Get("Authorization")))
            //        {
            //            var queryString = HttpUtility.ParseQueryString(context.Request.QueryString.Value);
            //            string token = queryString.Get("access_token");
            //            if (!string.IsNullOrWhiteSpace(token))
            //            {
            //                context.Request.Headers.Add("Authorization", new[] { $"Bearer {token}" });
            //            }
            //        }
            //    }
            //    await next.Invoke();
            //});

            // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

            // Enables the application to remember the second login verification factor such as phone or email.
            // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
            // This is similar to the RememberMe option when you log in.
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            //{
            //    ClientId = "",
            //    ClientSecret = ""
            //});
        }
Ejemplo n.º 22
0
        public void Configuration(IAppBuilder app)
        {
            // Modify the JSON serializer to serialize dates as UTC - otherwise, timezone will not be appended
            // to date strings and browsers will select whatever timezone suits them
            JsonSerializerSettings settings = JsonUtility.CreateDefaultSerializerSettings();

            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            JsonSerializer serializer = JsonSerializer.Create(settings);

            GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);

            // Load security hub in application domain before establishing SignalR hub configuration
            try
            {
                using (new SecurityHub()) { }
            }
            catch (Exception ex)
            {
                throw new SecurityException($"Failed to load Security Hub, validate database connection string in configuration file: {ex.Message}", ex);
            }

            HubConfiguration  hubConfig  = new HubConfiguration();
            HttpConfiguration httpConfig = new HttpConfiguration();

            // Setup resolver for web page controller instances
            httpConfig.DependencyResolver = WebPageController.GetDependencyResolver(WebServer.Default, Program.Host.DefaultWebPage, new AppModel(), typeof(AppModel));

            // Make sure any hosted exceptions get propagated to service error handling
            httpConfig.Services.Replace(typeof(IExceptionHandler), new HostedExceptionHandler());

            // Enabled detailed client errors
            hubConfig.EnableDetailedErrors = true;

            // Enable GSF session management
            httpConfig.EnableSessions(AuthenticationOptions);

            // Enable GSF role-based security authentication
            app.UseAuthentication(AuthenticationOptions);


            // Enable cross-domain scripting default policy - controllers can manually
            // apply "EnableCors" attribute to class or an action to override default
            // policy configured here
            try
            {
                if (!string.IsNullOrWhiteSpace(Program.Host.Model.Global.DefaultCorsOrigins))
                {
                    httpConfig.EnableCors(new EnableCorsAttribute(Program.Host.Model.Global.DefaultCorsOrigins, Program.Host.Model.Global.DefaultCorsHeaders, Program.Host.Model.Global.DefaultCorsMethods)
                    {
                        SupportsCredentials = Program.Host.Model.Global.DefaultCorsSupportsCredentials
                    });
                }
            }
            catch (Exception ex)
            {
                Program.Host.LogException(new InvalidOperationException($"Failed to establish default CORS policy: {ex.Message}", ex));
            }

            // Load ServiceHub SignalR class
            app.MapSignalR(hubConfig);

            // Set configuration to use reflection to setup routes
            httpConfig.MapHttpAttributeRoutes();

            // Load the WebPageController class and assign its routes
            app.UseWebApi(httpConfig);

            // Check for configuration issues before first request
            httpConfig.EnsureInitialized();
        }
Ejemplo n.º 23
0
        public void RejoiningGroupsOnlyReceivesGroupsBelongingToHub()
        {
            var logRejoiningGroups = new LogRejoiningGroupsModule();
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapHubs("/signalr", config);

                    config.Resolver.Resolve<IHubPipeline>().AddModule(logRejoiningGroups);
                    var configuration = config.Resolver.Resolve<IConfigurationManager>();
                    // The following sets the heartbeat to 1 s
                    configuration.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    configuration.KeepAlive = null;
                    configuration.ConnectionTimeout = TimeSpan.FromSeconds(2);
                });

                var connection = new Client.Hubs.HubConnection("http://foo");
                var proxy = connection.CreateHubProxy("MultGroupHub");
                var proxy2 = connection.CreateHubProxy("MultGroupHub2");

                connection.Start(host).Wait();

                var user = new User { Name = "tester" };
                proxy.InvokeWithTimeout("login", user);
                proxy2.InvokeWithTimeout("login", user);

                // Force Reconnect
                Thread.Sleep(TimeSpan.FromSeconds(3));

                proxy.InvokeWithTimeout("joinRoom", user);
                proxy2.InvokeWithTimeout("joinRoom", user);

                Thread.Sleep(TimeSpan.FromSeconds(3));

                Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("foo"));
                Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("tester"));
                Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("foo2"));
                Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("tester2"));
                Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("foo2"));
                Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("tester2"));
                Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("foo"));
                Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("tester"));

                connection.Stop();
            }
        }
Ejemplo n.º 24
0
 public HubDispatcherMiddleware(OwinMiddleware next, HubConfiguration configuration)
     : base(next)
 {
     _configuration = configuration;
 }
 public static void ConfigureSignalR(IAppBuilder app, HubConfiguration config)
 {
     //Changed this method to accept a HubConfiguration parameter
     //and pass it off to the MapSignalR method
     app.MapSignalR(config);
 }
Ejemplo n.º 26
0
        public void Configuration(IAppBuilder app)
        {
            if (true)
            {
                app.Map("/signalr", map =>
                {
                    // Setup the CORS middleware to run before SignalR.
                    // By default this will allow all origins. You can
                    // configure the set of origins and/or http verbs by
                    // providing a cors options with a different policy.
                    map.UseCors(CorsOptions.AllowAll);
                    var hubConfiguration = new HubConfiguration
                    {
                        EnableDetailedErrors = true
                                               //EnableJSONP = true
                                               // You can enable JSONP by uncommenting line below.
                                               // JSONP requests are insecure but some older browsers (and some
                                               // versions of IE) require JSONP to work cross domain
                                               // EnableJSONP = true
                    };
                    // Run the SignalR pipeline. We're not using MapSignalR
                    // since this branch already runs under the "/signalr"
                    // path.
                    map.RunSignalR(hubConfiguration);
                });
            }
            else
            {
                //app.UseCors(CorsOptions.AllowAll);
                app.MapSignalR(); // replaced by the above
            }
            app.Map("/echo", a => a.Run(c =>
            {
                var accept = c.Get <WebSocketAccept>("websocket.Accept");
                if (accept == null)
                {
                    c.Response.StatusCode = 500;
                    return(Task.Delay(0));
                }
                accept(
                    null,
                    async wsEnv =>
                {
                    var sendAsync    = wsEnv.Get <WebSocketSendAsync>("websocket.SendAsync");
                    var receiveAsync = wsEnv.Get <WebSocketReceiveAsync>("websocket.ReceiveAsync");
                    var closeAsync   = wsEnv.Get <WebSocketCloseAsync>("websocket.CloseAsync");

                    var buffer        = new ArraySegment <byte>(new byte[1000]);
                    var serverReceive = await receiveAsync(buffer, CancellationToken.None);
                    await sendAsync(new ArraySegment <byte>(buffer.Array, 0, serverReceive.Item3),
                                    serverReceive.Item1, serverReceive.Item2, CancellationToken.None);
                    await closeAsync((int)WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
                });

                return(Task.Delay(0));
            }));
            app.Run(async c =>
            {
                var path = c.Request.Path.Value;
                if (path == "/")
                {
                    c.Response.StatusCode  = 200;
                    c.Response.ContentType = "text/plain";
                    c.Response.Write("Hello World!");
                    return;
                }
                if (path == "/sse")
                {
                    c.Response.StatusCode  = 200;
                    c.Response.ContentType = "text/event-stream";
                    c.Response.Headers.Add("Cache-Control", new[] { "no-cache" });
                    for (int i = 0; i < 10; i++)
                    {
                        await c.Response.WriteAsync("data: " + i.ToString() + "\n\n");
                        await c.Response.Body.FlushAsync();
                        await Task.Delay(500);
                    }
                    await c.Response.WriteAsync("data: Finish!\n\n");
                    return;
                }
                if (path.Contains(".."))
                {
                    // hackers ..
                    c.Response.StatusCode = 500;
                    return;
                }
                var p = Path.Combine(@"..\..\..\SampleOwinApp\", path.Substring(1));
                if (File.Exists(p))
                {
                    c.Response.StatusCode  = 200;
                    c.Response.ContentType = p.EndsWith(".js") ? "application/javascript" : "text/html";
                    await c.Response.WriteAsync(File.ReadAllBytes(p));
                    return;
                }
                c.Response.StatusCode = 404;
                return;
            });
        }
Ejemplo n.º 27
0
        public static IDisposable ManyUniqueGroups(int concurrency)
        {
            var host = new MemoryHost();
            var threads = new List<Thread>();
            var cancellationTokenSource = new CancellationTokenSource();

            host.Configure(app =>
            {
                var config = new HubConfiguration()
                {
                    Resolver = new DefaultDependencyResolver()
                };
                app.MapHubs(config);
            });

            for (int i = 0; i < concurrency; i++)
            {
                var thread = new Thread(_ =>
                {
                    while (!cancellationTokenSource.IsCancellationRequested)
                    {
                        RunOne(host);
                    }
                });

                threads.Add(thread);
                thread.Start();
            }

            return new DisposableAction(() =>
            {
                cancellationTokenSource.Cancel();

                threads.ForEach(t => t.Join());

                host.Dispose();
            });
        }
Ejemplo n.º 28
0
 private void ConfigureSignalR(IAppBuilder app, HubConfiguration config)
 {
     app.UseCors(CorsOptions.AllowAll);
     app.MapSignalR("/s", config);
 }
Ejemplo n.º 29
0
        public void UnauthenticatedUserCannotInvokeMethodsWhenAuthenticationRequiredGlobally()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    configuration.Resolver.Resolve<IHubPipeline>().RequireAuthentication();

                    WithUser(app, new GenericPrincipal(new GenericIdentity(""), new string[] { }));
                    app.MapSignalR("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("NoAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string>("invoked", (id, time) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    Assert.Throws<AggregateException>(() => connection.Start(host).Wait());
                }
            }
        }
Ejemplo n.º 30
0
 public static Func <AppFunc, AppFunc> Hub(HubConfiguration configuration,
                                           IDictionary <string, object> startupEnv)
 {
     return(next => BuildHubFunc(configuration, startupEnv, next));
 }
Ejemplo n.º 31
0
        public void UnauthorizedUserCannotInvokeMethodsInHubsAuthorizedSpecifyingUserAndRole()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity("test"), new string[] { "User", "Admin" }));
                    app.MapSignalR("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("UserAndRoleAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string>("invoked", (id, time) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    Assert.Throws<AggregateException>(() => connection.Start(host).Wait());
                }
            }
        }
Ejemplo n.º 32
0
 /// <summary>
 /// Maps SignalR hubs to the app builder pipeline at "/signalr".
 /// </summary>
 /// <param name="builder">The app builder</param>
 /// <param name="configuration">The <see cref="HubConfiguration"/> to use</param>
 public static IAppBuilder MapSignalR(this IAppBuilder builder, HubConfiguration configuration)
 {
     return(builder.MapSignalR("/signalr", configuration));
 }
Ejemplo n.º 33
0
 //protected abstract void  RegisterSettingsFileInstance (ContainerBuilder builder);
 protected abstract void  RegisterCustomComponents(ContainerBuilder builder, HubConfiguration hubCfg);
Ejemplo n.º 34
0
 /// <summary>
 /// Adds SignalR hubs to the app builder pipeline.
 /// </summary>
 /// <param name="builder">The app builder</param>
 /// <param name="configuration">The <see cref="HubConfiguration"/> to use</param>
 public static void RunSignalR(this IAppBuilder builder, HubConfiguration configuration)
 {
     builder.UseSignalRMiddleware <HubDispatcherMiddleware>(configuration);
 }
Ejemplo n.º 35
0
        public void UnauthenticatedUserCanReceiveHubMessagesFromIncomingAuthorizedHubs()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity(""), new string[] { "User", "NotAdmin" }));
                    app.MapHubs("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                var hub = connection.CreateHubProxy("IncomingAuthHub");
                var wh = new ManualResetEvent(false);
                hub.On<string, string, object>("joined", (id, time, authInfo) =>
                {
                    Assert.NotNull(id);
                    wh.Set();
                });

                connection.Start(host).Wait();

                Assert.True(wh.WaitOne(TimeSpan.FromSeconds(3)));
                connection.Stop();
            }
        }
Ejemplo n.º 36
0
        private static void RunAzureSignalRCore(IAppBuilder builder, string applicationName, HubConfiguration configuration, ServiceOptions options)
        {
            // applicationName is case insensitive, it will be lower cased in the service side
            if (string.IsNullOrEmpty(applicationName))
            {
                throw new ArgumentException(nameof(applicationName), "Empty application name is not allowed.");
            }

            var hubs = GetAvailableHubNames(configuration);

            // TODO: Update to use Middleware when SignalR SDK is ready
            // Replace default HubDispatcher with a custom one, which has its own negotiation logic
            // https://github.com/SignalR/SignalR/blob/dev/src/Microsoft.AspNet.SignalR.Core/Hosting/PersistentConnectionFactory.cs#L42
            configuration.Resolver.Register(typeof(PersistentConnection), () => new ServiceHubDispatcher(configuration, applicationName));
            builder.RunSignalR(typeof(PersistentConnection), configuration);

            RegisterServiceObjects(configuration, options, applicationName, hubs);

            ILoggerFactory logger;
            var            traceManager = configuration.Resolver.Resolve <ITraceManager>();

            if (traceManager != null)
            {
                logger = new LoggerFactory(new ILoggerProvider[] { new TraceManagerLoggerProvider(traceManager) });
            }
            else
            {
                logger = NullLoggerFactory.Instance;
            }

            if (hubs?.Count > 0)
            {
                // Start the server->service connection asynchronously
                _ = new ConnectionFactory(hubs, configuration).StartAsync();
            }
            else
            {
                logger.CreateLogger <IAppBuilder>().Log(LogLevel.Warning, "No hubs found.");
            }
        }
Ejemplo n.º 37
0
        public void ChangeHubUrl()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var config = new HubConfiguration()
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapHubs("/foo", config);
                });

                var connection = new Client.Hubs.HubConnection("http://site/foo", useDefaultUrl: false, queryString: new Dictionary<string, string> { { "test", "ChangeHubUrl" } });

                var hub = connection.CreateHubProxy("demo");

                var wh = new ManualResetEventSlim(false);

                hub.On("signal", id =>
                {
                    Assert.NotNull(id);
                    wh.Set();
                });

                connection.Start(host).Wait();

                hub.InvokeWithTimeout("DynamicTask");

                Assert.True(wh.Wait(TimeSpan.FromSeconds(10)));
                connection.Stop();
            }
        }
Ejemplo n.º 38
0
        private static IReadOnlyList <string> GetAvailableHubNames(HubConfiguration configuration)
        {
            var hubManager = configuration.Resolver.Resolve <IHubManager>();

            return(hubManager?.GetHubs().Select(s => s.Name).ToList());
        }
Ejemplo n.º 39
0
        public void JoiningGroupMultipleTimesGetsMessageOnce(MessageBusType messagebusType)
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    UseMessageBus(messagebusType, config.Resolver);

                    app.MapHubs(config);
                });

                var connection = new HubConnection("http://foo");

                var hub = connection.CreateHubProxy("SendToSome");
                int invocations = 0;

                connection.Start(host).Wait();

                hub.On("send", () =>
                {
                    invocations++;
                });

                // Join the group multiple times
                hub.InvokeWithTimeout("JoinGroup", "a");
                hub.InvokeWithTimeout("JoinGroup", "a");
                hub.InvokeWithTimeout("JoinGroup", "a");
                hub.InvokeWithTimeout("SendToGroup", "a");

                Thread.Sleep(TimeSpan.FromSeconds(3));

                Assert.Equal(1, invocations);

                connection.Stop();
            }
        }
Ejemplo n.º 40
0
 /// <summary>
 /// Maps Azure SignalR hubs to the app builder pipeline at the specified path.
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="path">The path to map signalr hubs.</param>
 /// <param name="applicationName">The name of your app, it is case-incensitive.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 /// <returns>The app builder</returns>
 public static IAppBuilder MapAzureSignalR(this IAppBuilder builder, string path, string applicationName, HubConfiguration configuration)
 {
     return(builder.Map(path, subApp => subApp.RunAzureSignalR(applicationName, configuration)));
 }
Ejemplo n.º 41
0
        public void ReturningNullFromReconnectAccepted()
        {
            var mockHub = new Mock<SomeHub>() { CallBase = true };
            mockHub.Setup(h => h.OnReconnected()).Returns<Task>(null).Verifiable();

            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapHubs("/signalr", config);

                    var configuration = config.Resolver.Resolve<IConfigurationManager>();
                    // The following sets the heartbeat to 1 s
                    configuration.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    configuration.KeepAlive = null;
                    configuration.ConnectionTimeout = TimeSpan.FromSeconds(2);
                    config.Resolver.Register(typeof(SomeHub), () => mockHub.Object);
                });

                var connection = new Client.Hubs.HubConnection("http://foo");

                var hub = connection.CreateHubProxy("SomeHub");
                connection.Start(host).Wait();

                // Force Reconnect
                Thread.Sleep(TimeSpan.FromSeconds(3));

                hub.InvokeWithTimeout("AllFoo");

                Thread.Sleep(TimeSpan.FromSeconds(3));

                connection.Stop();

                mockHub.Verify();
            }
        }
Ejemplo n.º 42
0
        public static void SetupContainer(IAppBuilder app, IUnityContainer container, IPathMapper pathMapper,
                                          string virtualRoot, string routePrefix, string modulesPhysicalPath)
        {
            container.RegisterInstance(app);

            var moduleInitializerOptions = (ModuleInitializerOptions)container.Resolve <IModuleInitializerOptions>();

            moduleInitializerOptions.VirtualRoot = virtualRoot;
            moduleInitializerOptions.RoutePrefix = routePrefix;

            //Initialize Platform dependencies
            var connectionString = ConfigurationHelper.GetConnectionStringValue("VirtoCommerce");

            var hangfireOptions = new HangfireOptions
            {
                StartServer              = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Jobs.Enabled", true),
                JobStorageType           = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Jobs.StorageType", "Memory"),
                DatabaseConnectionString = connectionString,
                WorkerCount              = ConfigurationHelper.GetNullableAppSettingsValue("VirtoCommerce:Jobs.WorkerCount", (int?)null)
            };
            var hangfireLauncher = new HangfireLauncher(hangfireOptions);

            var authenticationOptions = new AuthenticationOptions
            {
                AllowOnlyAlphanumericUserNames = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:AllowOnlyAlphanumericUserNames", false),
                RequireUniqueEmail             = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:RequireUniqueEmail", false),

                PasswordRequiredLength          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Password.RequiredLength", 5),
                PasswordRequireNonLetterOrDigit = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Password.RequireNonLetterOrDigit", false),
                PasswordRequireDigit            = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Password.RequireDigit", false),
                PasswordRequireLowercase        = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Password.RequireLowercase", false),
                PasswordRequireUppercase        = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Password.RequireUppercase", false),

                UserLockoutEnabledByDefault          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:UserLockoutEnabledByDefault", true),
                DefaultAccountLockoutTimeSpan        = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:DefaultAccountLockoutTimeSpan", TimeSpan.FromMinutes(5)),
                MaxFailedAccessAttemptsBeforeLockout = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:MaxFailedAccessAttemptsBeforeLockout", 5),

                DefaultTokenLifespan = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:DefaultTokenLifespan", TimeSpan.FromDays(1)),

                CookiesEnabled          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Cookies.Enabled", true),
                CookiesValidateInterval = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Cookies.ValidateInterval", TimeSpan.FromDays(1)),

                BearerTokensEnabled        = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:BearerTokens.Enabled", true),
                BearerTokensExpireTimeSpan = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:BearerTokens.AccessTokenExpireTimeSpan", TimeSpan.FromHours(1)),

                HmacEnabled = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Hmac.Enabled", true),
                HmacSignatureValidityPeriod = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:Hmac.SignatureValidityPeriod", TimeSpan.FromMinutes(20)),

                ApiKeysEnabled                  = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.Enabled", true),
                ApiKeysHttpHeaderName           = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.HttpHeaderName", "api_key"),
                ApiKeysQueryStringParameterName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Authentication:ApiKeys.QueryStringParameterName", "api_key"),
            };

            container.RegisterInstance(authenticationOptions);

            InitializePlatform(app, container, pathMapper, connectionString, hangfireLauncher, modulesPhysicalPath);

            var moduleManager = container.Resolve <IModuleManager>();
            var moduleCatalog = container.Resolve <IModuleCatalog>();

            var applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase.EnsureEndSeparator();

            // Register URL rewriter for platform scripts
            var scriptsPhysicalPath        = pathMapper.MapPath(VirtualRoot + "/Scripts").EnsureEndSeparator();
            var scriptsRelativePath        = MakeRelativePath(applicationBase, scriptsPhysicalPath);
            var platformUrlRewriterOptions = new UrlRewriterOptions();

            platformUrlRewriterOptions.Items.Add(PathString.FromUriComponent("/$(Platform)/Scripts"), "");
            app.Use <UrlRewriterOwinMiddleware>(platformUrlRewriterOptions);
            app.UseStaticFiles(new StaticFileOptions
            {
                FileSystem = new Microsoft.Owin.FileSystems.PhysicalFileSystem(scriptsRelativePath)
            });

            // Register URL rewriter before modules initialization
            if (Directory.Exists(modulesPhysicalPath))
            {
                var modulesRelativePath = MakeRelativePath(applicationBase, modulesPhysicalPath);

                var urlRewriterOptions = new UrlRewriterOptions();

                foreach (var module in moduleCatalog.Modules.OfType <ManifestModuleInfo>())
                {
                    var urlRewriteKey   = string.Format(CultureInfo.InvariantCulture, "/Modules/$({0})", module.ModuleName);
                    var urlRewriteValue = MakeRelativePath(modulesPhysicalPath, module.FullPhysicalPath);
                    urlRewriterOptions.Items.Add(PathString.FromUriComponent(urlRewriteKey), "/" + urlRewriteValue);

                    moduleInitializerOptions.ModuleDirectories.Add(module.ModuleName, module.FullPhysicalPath);
                }

                app.Use <UrlRewriterOwinMiddleware>(urlRewriterOptions);
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileSystem = new Microsoft.Owin.FileSystems.PhysicalFileSystem(modulesRelativePath)
                });
            }

            container.RegisterInstance(GlobalConfiguration.Configuration);

            // Ensure all modules are loaded
            foreach (var module in moduleCatalog.Modules.OfType <ManifestModuleInfo>().Where(x => x.State == ModuleState.NotStarted))
            {
                moduleManager.LoadModule(module.ModuleName);
            }

            SwaggerConfig.RegisterRoutes(container);

            // Post-initialize

            // Register MVC areas unless running in the Web Platform Installer mode
            if (IsApplication)
            {
                AreaRegistration.RegisterAllAreas();
            }

            // Register other MVC resources
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            if (IsApplication)
            {
                RouteConfig.RegisterRoutes(RouteTable.Routes);
            }

            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            // Security OWIN configuration
            OwinConfig.Configure(app, container);

            hangfireLauncher.ConfigureOwin(app, container);

            RecurringJob.AddOrUpdate <SendNotificationsJobs>("SendNotificationsJob", x => x.Process(), "*/1 * * * *");

            var notificationManager = container.Resolve <INotificationManager>();

            notificationManager.RegisterNotificationType(() => new RegistrationEmailNotification(container.Resolve <IEmailNotificationSendingGateway>())
            {
                DisplayName          = "Registration notification",
                Description          = "This notification is sent by email to a client when he finishes registration",
                NotificationTemplate = new NotificationTemplate
                {
                    Subject  = PlatformNotificationResource.RegistrationNotificationSubject,
                    Body     = PlatformNotificationResource.RegistrationNotificationBody,
                    Language = "en-US",
                }
            });

            notificationManager.RegisterNotificationType(() => new ResetPasswordEmailNotification(container.Resolve <IEmailNotificationSendingGateway>())
            {
                DisplayName          = "Reset password notification",
                Description          = "This notification is sent by email to a client upon reset password request",
                NotificationTemplate = new NotificationTemplate
                {
                    Subject  = PlatformNotificationResource.ResetPasswordNotificationSubject,
                    Body     = PlatformNotificationResource.ResetPasswordNotificationBody,
                    Language = "en-US",
                }
            });

            notificationManager.RegisterNotificationType(() => new TwoFactorEmailNotification(container.Resolve <IEmailNotificationSendingGateway>())
            {
                DisplayName          = "Two factor authentication",
                Description          = "This notification contains a security token for two factor authentication",
                NotificationTemplate = new NotificationTemplate
                {
                    Subject  = PlatformNotificationResource.TwoFactorNotificationSubject,
                    Body     = PlatformNotificationResource.TwoFactorNotificationBody,
                    Language = "en-US",
                }
            });

            notificationManager.RegisterNotificationType(() => new TwoFactorSmsNotification(container.Resolve <ISmsNotificationSendingGateway>())
            {
                DisplayName          = "Two factor authentication",
                Description          = "This notification contains a security token for two factor authentication",
                NotificationTemplate = new NotificationTemplate
                {
                    Subject  = PlatformNotificationResource.TwoFactorNotificationSubject,
                    Body     = PlatformNotificationResource.TwoFactorNotificationBody,
                    Language = "en-US",
                }
            });

            //Get initialized modules list sorted by dependency order
            var postInitializeModules = moduleCatalog.CompleteListWithDependencies(moduleCatalog.Modules.OfType <ManifestModuleInfo>())
                                        .Where(m => m.ModuleInstance != null && m.State == ModuleState.Initialized)
                                        .ToArray();

            foreach (var module in postInitializeModules)
            {
                moduleManager.PostInitializeModule(module);
            }

            var redisConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"];

            // Redis
            if (redisConnectionString != null && !string.IsNullOrEmpty(redisConnectionString.ConnectionString))
            {
                // Cache
                RedisConfigurations.AddConfiguration(new RedisConfiguration("redisConnectionString", redisConnectionString.ConnectionString));

                // SignalR
                // https://stackoverflow.com/questions/29885470/signalr-scaleout-on-azure-rediscache-connection-issues
                GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(redisConnectionString.ConnectionString, "VirtoCommerce.Platform.SignalR"));
            }

            // SignalR
            var tempCounterManager = new TempPerformanceCounterManager();

            GlobalHost.DependencyResolver.Register(typeof(IPerformanceCounterManager), () => tempCounterManager);
            var hubConfiguration = new HubConfiguration {
                EnableJavaScriptProxies = false
            };

            app.MapSignalR("/" + moduleInitializerOptions.RoutePrefix + "signalr", hubConfiguration);

            // Initialize InstrumentationKey from EnvironmentVariable
            var appInsightKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");

            if (!string.IsNullOrEmpty(appInsightKey))
            {
                TelemetryConfiguration.Active.InstrumentationKey = appInsightKey;
            }
        }
Ejemplo n.º 43
0
        public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver)
        {
            var hubConfig = new HubConfiguration
            {
                Resolver = resolver,
                EnableDetailedErrors = true
            };

            app.MapSignalR(hubConfig);

            app.MapSignalR("/signalr2/test", new HubConfiguration()
            {
                Resolver = resolver
            });

            var config = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.Map("/multisend", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<MySendingConnection>(config);
            });

            app.Map("/autoencodedjson", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<EchoConnection>(config);
            });

            app.Map("/redirectionConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<RedirectionConnection>(config);
            });

            app.Map("/statusCodeConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<StatusCodeConnection>(config);
            });

            app.Map("/jsonp", map =>
            {
                var jsonpConfig = new ConnectionConfiguration
                {
                    Resolver = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR<EchoConnection>("/echo", jsonpConfig);

                var jsonpHubsConfig = new HubConfiguration
                {
                    Resolver = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR(jsonpHubsConfig);
            });

            app.MapSignalR<MyBadConnection>("/ErrorsAreFun", config);
            app.MapSignalR<MyGroupEchoConnection>("/group-echo", config);
            app.MapSignalR<MyReconnect>("/my-reconnect", config);
            app.MapSignalR<ExamineHeadersConnection>("/examine-request", config);
            app.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config);
            app.MapSignalR<MyGroupConnection>("/groups", config);
            app.MapSignalR<MyRejoinGroupsConnection>("/rejoin-groups", config);
            app.MapSignalR<BroadcastConnection>("/filter", config);
            app.MapSignalR<ConnectionThatUsesItems>("/items", config);
            app.MapSignalR<SyncErrorConnection>("/sync-error", config);
            app.MapSignalR<AddGroupOnConnectedConnection>("/add-group", config);
            app.MapSignalR<UnusableProtectedConnection>("/protected", config);
            app.MapSignalR<FallbackToLongPollingConnection>("/fall-back", config);
            app.MapSignalR<FallbackToLongPollingConnectionThrows>("/fall-back-throws", config);
            app.MapSignalR<PreserializedJsonConnection>("/preserialize", config);

            // This subpipeline is protected by basic auth
            app.Map("/basicauth", map =>
            {
                map.UseBasicAuthentication(new BasicAuthenticationProvider());

                var subConfig = new ConnectionConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR<AuthenticatedEchoConnection>("/echo", subConfig);

                var subHubsConfig = new HubConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR(subHubsConfig);
            });

            app.Map("/force-lp-reconnect", map =>
            {
                map.Use((context, next) =>
                {
                    if (context.Request.Path.Value.Contains("poll"))
                    {
                        context.Response.StatusCode = 500;
                        return TaskAsyncHelper.Empty;
                    }

                    return next();
                });
                map.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config);
                map.MapSignalR(hubConfig);
            });

            // Perf/stress test related
            var performanceConfig = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.MapSignalR<StressConnection>("/echo", performanceConfig);

            performanceConfig.Resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData());

            // IMPORTANT: This needs to run last so that it runs in the "default" part of the pipeline

            // Session is enabled for ASP.NET on the session path
            app.Map("/session", map =>
            {
                map.MapSignalR();
            });
        }
Ejemplo n.º 44
0
        public void Configuration(IAppBuilder appBuilder)
        {
            // Setup the cors middleware to run before other pipeline entries.
            // By default this will allow all origins. You can
            // configure the set of origins and/or http verbs by
            // providing a cors options with a different policy.
            appBuilder.UseCors(CorsOptions.AllowAll);

            appBuilder.Use <GlobalExceptionMiddleware>();

            appBuilder.Map("/api", api =>
            {
                // Create our config object we'll use to configure the API
                //
                var config = new HttpConfiguration();

                config.UseStructureMap <DefaultRegistry>();

                // Use attribute routing
                //
                config.MapHttpAttributeRoutes();

                config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());

                // clear the supported mediatypes of the xml formatter
                config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

                //Remove the XM Formatter from the web api
                config.Formatters.Remove(config.Formatters.XmlFormatter);

                var jsonFormatter = config.Formatters.JsonFormatter;
                jsonFormatter.UseDataContractJsonSerializer = false;

                var settings = jsonFormatter.SerializerSettings;
                settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

#if DEBUG
                settings.Formatting = Formatting.Indented; // Pretty json for developers.
#else
                settings.Formatting = Formatting.None;
#endif

                // Now add in the WebAPI middleware
                //
                api.UseWebApi(config);
            });

            appBuilder.Map("/signalr", map =>
            {
                var hubConfiguration = new HubConfiguration
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                    EnableDetailedErrors    = true,
                    EnableJavaScriptProxies = true,
                    EnableJSONP             = true
                };

                hubConfiguration.UseStructureMap <DefaultRegistry>();

                // camelcase contract resolver
                var serializer = JsonSerializer.Create(new JsonSerializerSettings
                {
                    ContractResolver = new SignalRContractResolver()
                });

                hubConfiguration.Resolver.Register(typeof(JsonSerializer), () => serializer);

                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch is already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });

            var webRoot = @"./wwwroot";
            var cfg     = ConfigurationManager.AppSettings["web:wwwroot"];
            if (!string.IsNullOrEmpty(cfg))
            {
                if (Directory.Exists(cfg))
                {
                    if (File.Exists(Path.Combine(cfg, "index.html")))
                    {
                        webRoot = cfg;
                    }
                }
            }

            var physicalFileSystem = new PhysicalFileSystem(webRoot);
            var options            = new FileServerOptions
            {
                EnableDefaultFiles      = true,
                FileSystem              = physicalFileSystem,
                EnableDirectoryBrowsing = false
            };
            options.StaticFileOptions.FileSystem            = physicalFileSystem;
            options.StaticFileOptions.ServeUnknownFileTypes = true;
            options.DefaultFilesOptions.DefaultFileNames    = new[]
            {
                "index.html"
            };

            appBuilder.UseFileServer(options);
        }
Ejemplo n.º 45
0
        public async Task DisconnectFiresForHubsWhenClientDisconnects()
        {
            using (var host = new MemoryHost())
            {
                var dr = new DefaultDependencyResolver();
                var configuration = dr.Resolve<IConfigurationManager>();

                var connectWh = new AsyncManualResetEvent();
                var disconnectWh = new AsyncManualResetEvent();
                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = dr
                    };

                    app.MapSignalR("/signalr", config);

                    configuration.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh));
                });

                var connection = new HubConnection("http://foo/");

                connection.CreateHubProxy("MyHub");

                await connection.Start(host);

                Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired");

                ((Client.IConnection)connection).Disconnect();

                Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(20)), "Disconnect never fired");
            }
        }
Ejemplo n.º 46
0
 /// <summary>
 /// Adds Azure SignalR hubs to the app builder pipeline at "/signalr" using the connection string specified in web.config
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="applicationName">The name of your app, it is case-insensitive.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 public static void RunAzureSignalR(this IAppBuilder builder, string applicationName, HubConfiguration configuration)
 {
     RunAzureSignalR(builder, applicationName, configuration, null);
 }
Ejemplo n.º 47
0
        public static IDisposable RunConnectDisconnect(int connections)
        {
            var host = new MemoryHost();

            host.Configure(app =>
            {
                var config = new HubConfiguration()
                {
                    Resolver = new DefaultDependencyResolver()
                };
                app.MapHubs(config);
            });

            for (int i = 0; i < connections; i++)
            {
                var connection = new Client.Hubs.HubConnection("http://foo");
                var proxy = connection.CreateHubProxy("EchoHub");
                var wh = new ManualResetEventSlim(false);

                proxy.On("echo", _ => wh.Set());

                try
                {
                    connection.Start(host).Wait();

                    proxy.Invoke("Echo", "foo").Wait();

                    if (!wh.Wait(TimeSpan.FromSeconds(10)))
                    {
                        Debugger.Break();
                    }
                }
                finally
                {
                    connection.Stop();
                }
            }

            return host;
        }
Ejemplo n.º 48
0
 /// <summary>
 /// Adds Azure SignalR hubs to the app builder pipeline at "/signalr".
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="applicationName">The name of your app, it is case-insensitive.</param>
 /// <param name="connectionString">The connection string of an Azure SignalR Service instance.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 public static void RunAzureSignalR(this IAppBuilder builder, string applicationName, string connectionString, HubConfiguration configuration)
 {
     RunAzureSignalR(builder, applicationName, configuration, s => s.ConnectionString = connectionString);
 }
Ejemplo n.º 49
0
        public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver)
        {
            var hubConfig = new HubConfiguration
            {
                Resolver = resolver,
                EnableDetailedErrors = true
            };

            app.MapSignalR(hubConfig);

            app.MapSignalR("/signalr2/test", new HubConfiguration()
            {
                Resolver = resolver
            });

            var config = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.Map("/multisend", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<MySendingConnection>(config);
            });

            app.Map("/echo", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<EchoConnection>(config);
            });

            app.Map("/redirectionConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<RedirectionConnection>(config);
            });

            app.Map("/statusCodeConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR<StatusCodeConnection>(config);
            });

            app.Map("/jsonp", map =>
            {
                var jsonpConfig = new ConnectionConfiguration
                {
                    Resolver = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR<EchoConnection>("/echo", jsonpConfig);

                var jsonpHubsConfig = new HubConfiguration
                {
                    Resolver = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR(jsonpHubsConfig);
            });

            app.MapSignalR<MyBadConnection>("/ErrorsAreFun", config);
            app.MapSignalR<MyGroupEchoConnection>("/group-echo", config);
            app.MapSignalR<MyReconnect>("/my-reconnect", config);
            app.MapSignalR<ExamineHeadersConnection>("/examine-request", config);
            app.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config);
            app.MapSignalR<MyGroupConnection>("/groups", config);
            app.MapSignalR<MyRejoinGroupsConnection>("/rejoin-groups", config);
            app.MapSignalR<BroadcastConnection>("/filter", config);
            app.MapSignalR<ConnectionThatUsesItems>("/items", config);
            app.MapSignalR<SyncErrorConnection>("/sync-error", config);
            app.MapSignalR<AddGroupOnConnectedConnection>("/add-group", config);
            app.MapSignalR<UnusableProtectedConnection>("/protected", config);
            app.MapSignalR<FallbackToLongPollingConnectionThrows>("/fall-back-throws", config);
            app.MapSignalR<PreserializedJsonConnection>("/preserialize", config);
            app.MapSignalR<AsyncOnConnectedConnection>("/async-on-connected", config);

            // This subpipeline is protected by basic auth
            app.Map("/basicauth", map =>
            {
                map.Use(async (context, next) =>
                {
                    var authorization = context.Request.Headers.Get("Authorization");
                    if (string.IsNullOrEmpty(authorization))
                    {
                        context.Response.StatusCode = 401;
                        context.Response.Headers.Add("WWW-Authenticate", new string[] { "Basic" });
                    }
                    else
                    {
                        var base64Encoded = authorization.Replace("Basic ", "");
                        byte[] base64EncodedBytes = Convert.FromBase64String(base64Encoded);
                        var base64Decoded = System.Text.ASCIIEncoding.ASCII.GetString(base64EncodedBytes);
                        var credentials = base64Decoded.Split(':');
                        var identity = new ClaimsIdentity("Basic");
                        identity.AddClaim(new Claim(ClaimTypes.Name, credentials[0]));
                        context.Request.User = new ClaimsPrincipal(identity);
                        await next();
                    }
                });

                var subConfig = new ConnectionConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR<AuthenticatedEchoConnection>("/echo", subConfig);

                var subHubsConfig = new HubConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR(subHubsConfig);
            });

            // This subpipeline is protected by cookie auth
            app.Map("/cookieauth", map =>
            {
                var options = new CookieAuthenticationOptions()
                {
                    AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
                    LoginPath = CookieAuthenticationDefaults.LoginPath,
                    LogoutPath = CookieAuthenticationDefaults.LogoutPath,
                };

                map.UseCookieAuthentication(options);

                map.Use(async (context, next) =>
                {
                    if (context.Request.Path.Value.Contains(options.LoginPath.Value))
                    {
                        if (context.Request.Method == "POST")
                        {
                            var form = await context.Request.ReadFormAsync();
                            var userName = form["UserName"];
                            var password = form["Password"];

                            var identity = new ClaimsIdentity(options.AuthenticationType);
                            identity.AddClaim(new Claim(ClaimTypes.Name, userName));
                            context.Authentication.SignIn(identity);
                        }
                    }
                    else
                    {
                        await next();
                    }
                });

                var subConfig = new ConnectionConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR<AuthenticatedEchoConnection>("/echo", subConfig);

                var subHubsConfig = new HubConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR(subHubsConfig);
            });

            app.Map("/fall-back", map =>
            {
                map.Use((context, next) =>
                {
                    if (!context.Request.Path.Value.Contains("negotiate") &&
                        !context.Request.QueryString.Value.Contains("longPolling"))
                    {
                        context.Response.Body = new MemoryStream();
                    }

                    return next();
                });

                map.RunSignalR<FallbackToLongPollingConnection>();
            });

            app.Map("/no-init", map =>
            {
                map.Use((context, next) =>
                {
                    if (context.Request.Path.Value.Contains("connect"))
                    {
                        context.Response.Body = new MemoryStream();
                    }

                    return next();
                });
            });

            app.Map("/force-lp-reconnect", map =>
            {
                map.Use((context, next) =>
                {
                    if (context.Request.Path.Value.Contains("poll"))
                    {
                        context.Response.StatusCode = 500;
                        return TaskAsyncHelper.Empty;
                    }

                    return next();
                });
                map.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config);
                map.MapSignalR(hubConfig);
            });

            // Perf/stress test related
            var performanceConfig = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.MapSignalR<StressConnection>("/echo", performanceConfig);

            performanceConfig.Resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData());

            // IMPORTANT: This needs to run last so that it runs in the "default" part of the pipeline

            // Session is enabled for ASP.NET on the session path
            app.Map("/session", map =>
            {
                map.MapSignalR();
            });
        }
Ejemplo n.º 50
0
        internal static ServiceHubDispatcher PrepareAndGetDispatcher(IAppBuilder builder, HubConfiguration configuration, ServiceOptions options, string applicationName, ILoggerFactory loggerFactory)
        {
            // Ensure we have the conversions for MS.Owin so that
            // the app builder respects the OwinMiddleware base class
            SignatureConversions.AddConversions(builder);

            // ServiceEndpointManager needs the logger
            var hubs = GetAvailableHubNames(configuration);

            var endpoint = new ServiceEndpointManager(options, loggerFactory);

            configuration.Resolver.Register(typeof(IServiceEndpointManager), () => endpoint);

            // Get the one from DI or new a default one
            var router = configuration.Resolver.Resolve <IEndpointRouter>() ?? new DefaultEndpointRouter();

            var serverNameProvider = configuration.Resolver.Resolve <IServerNameProvider>();

            if (serverNameProvider == null)
            {
                serverNameProvider = new DefaultServerNameProvider();
                configuration.Resolver.Register(typeof(IServerNameProvider), () => serverNameProvider);
            }

            var requestIdProvider = configuration.Resolver.Resolve <IConnectionRequestIdProvider>();

            if (requestIdProvider == null)
            {
                requestIdProvider = new DefaultConnectionRequestIdProvider();
                configuration.Resolver.Register(typeof(IConnectionRequestIdProvider), () => requestIdProvider);
            }

            builder.Use <NegotiateMiddleware>(configuration, applicationName, endpoint, router, options, serverNameProvider, requestIdProvider, loggerFactory);

            builder.RunSignalR(configuration);

            // Fetch the trace manager from DI and add logger provider
            var traceManager = configuration.Resolver.Resolve <ITraceManager>();

            if (traceManager != null)
            {
                loggerFactory.AddProvider(new TraceManagerLoggerProvider(traceManager));
            }

            configuration.Resolver.Register(typeof(ILoggerFactory), () => loggerFactory);

            // TODO: Using IOptions looks wierd, thinking of a way removing it
            // share the same object all through
            var serviceOptions = Options.Create(options);

            // For safety, ALWAYS register abstract classes or interfaces
            // Some third-party DI frameworks such as Ninject, implicit self-binding concrete types:
            // https://github.com/ninject/ninject/wiki/dependency-injection-with-ninject#skipping-the-type-binding-bit--implicit-self-binding-of-concrete-types
            configuration.Resolver.Register(typeof(IOptions <ServiceOptions>), () => serviceOptions);

            var serviceProtocol = new ServiceProtocol();

            configuration.Resolver.Register(typeof(IServiceProtocol), () => serviceProtocol);

            // allow override from tests
            var scm = configuration.Resolver.Resolve <IServiceConnectionManager>();

            if (scm == null)
            {
                scm = new ServiceConnectionManager(applicationName, hubs);
                configuration.Resolver.Register(typeof(IServiceConnectionManager), () => scm);
            }

            var ccm = configuration.Resolver.Resolve <IClientConnectionManager>();

            if (ccm == null)
            {
                ccm = new ClientConnectionManager(configuration, loggerFactory);
                configuration.Resolver.Register(typeof(IClientConnectionManager), () => ccm);
            }

            var atm = new AzureTransportManager(configuration.Resolver);

            configuration.Resolver.Register(typeof(ITransportManager), () => atm);

            var parser = new SignalRMessageParser(hubs, configuration.Resolver);

            configuration.Resolver.Register(typeof(IMessageParser), () => parser);

            var smb = new ServiceMessageBus(configuration.Resolver);

            configuration.Resolver.Register(typeof(IMessageBus), () => smb);

            var scf = configuration.Resolver.Resolve <IServiceConnectionFactory>();

            if (scf == null)
            {
                var connectionFactory = new ConnectionFactory(serverNameProvider, loggerFactory);
                scf = new ServiceConnectionFactory(serviceProtocol, ccm, connectionFactory, loggerFactory, serverNameProvider);
                configuration.Resolver.Register(typeof(IServiceConnectionFactory), () => scf);
            }

            var sccf = new ServiceConnectionContainerFactory(scf, endpoint, router, options, loggerFactory);

            if (hubs?.Count > 0)
            {
                return(new ServiceHubDispatcher(hubs, scm, sccf, serviceOptions, loggerFactory));
            }
            else
            {
                loggerFactory.CreateLogger <DispatcherHelper>().Log(LogLevel.Warning, "No hubs found.");
                return(null);
            }
        }
Ejemplo n.º 51
0
        public async Task AuthenticatedUserCanInvokeMethodsWhenAuthenticationRequiredGlobally()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    configuration.Resolver.Resolve<IHubPipeline>().RequireAuthentication();

                    WithUser(app, new GenericPrincipal(new GenericIdentity("test"), new string[] { }));
                    app.MapSignalR("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("NoAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string>("invoked", (id, time) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    await connection.Start(host);

                    hub.InvokeWithTimeout("InvokedFromClient");

                    Assert.True(wh.WaitOne(TimeSpan.FromSeconds(3)));
                }
            }
        }
Ejemplo n.º 52
0
        private static void RunAzureSignalRCore(IAppBuilder builder, string applicationName, HubConfiguration configuration, ServiceOptions options)
        {
            // applicationName is case insensitive, it will be lower cased in the service side
            if (string.IsNullOrEmpty(applicationName))
            {
                throw new ArgumentException("Empty application name is not allowed.", nameof(applicationName));
            }

            options.ApplicationName = applicationName;

            if (configuration == null)
            {
                // Keep the same as SignalR's exception
                throw new ArgumentException("A configuration object must be specified.");
            }

            // MaxPollInterval should be [1,300] seconds
            if (options.MaxPollIntervalInSeconds.HasValue &&
                (options.MaxPollIntervalInSeconds < 1 || options.MaxPollIntervalInSeconds > 300))
            {
                throw new AzureSignalRInvalidServiceOptionsException("MaxPollIntervalInSeconds", "[1,300]");
            }

            var loggerFactory = DispatcherHelper.GetLoggerFactory(configuration) ?? NullLoggerFactory.Instance;

            var dispatcher = DispatcherHelper.PrepareAndGetDispatcher(builder, configuration, options, applicationName, loggerFactory);

            if (dispatcher != null)
            {
                // Start the server->service connection asynchronously
                _ = dispatcher.StartAsync();
            }
        }
Ejemplo n.º 53
0
        public void UnauthorizedUserCannotReceiveHubMessagesFromHubsAuthorizedWithRoles()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity("test"), new string[] { "User", "NotAdmin" }));
                    app.MapSignalR("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("AdminAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string, object>("joined", (id, time, authInfo) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    Assert.Throws<AggregateException>(() => connection.Start(host).Wait());
                }
            }
        }
Ejemplo n.º 54
0
 /// <summary>
 /// Maps Azure SignalR hubs to the app builder pipeline at "/signalr".
 /// </summary>
 /// <param name="builder">The app builder <see cref="IAppBuilder"/>.</param>
 /// <param name="applicationName">The name of your app, it is case-insensitive.</param>
 /// <param name="configuration">The hub configuration <see cref="HubConfiguration"/>.</param>
 /// <returns>The app builder</returns>
 public static IAppBuilder MapAzureSignalR(this IAppBuilder builder, string applicationName, HubConfiguration configuration)
 {
     return(builder.MapAzureSignalR("/signalr", applicationName, configuration));
 }
Ejemplo n.º 55
0
        public async Task UnauthenticatedUserCannotInvokeMethodsInIncomingAuthorizedHubs()
        {
            using (var host = new MemoryHost())
            {
                host.Configure(app =>
                {
                    var configuration = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    WithUser(app, new GenericPrincipal(new GenericIdentity(""), new string[] { "User", "NotAdmin" }));
                    app.MapSignalR("/signalr", configuration);
                });

                var connection = CreateHubConnection("http://foo/");

                using (connection)
                {
                    var hub = connection.CreateHubProxy("IncomingAuthHub");
                    var wh = new ManualResetEvent(false);
                    hub.On<string, string>("invoked", (id, time) =>
                    {
                        Assert.NotNull(id);
                        wh.Set();
                    });

                    await connection.Start(host);

                    Assert.Throws<AggregateException>(() => hub.InvokeWithTimeout("InvokedFromClient"));

                    Assert.False(wh.WaitOne(TimeSpan.FromSeconds(3)));
                }
            }
        }
Ejemplo n.º 56
0
        public async Task GroupsTokenIsPerConnectionId()
        {
            using (var host = new MemoryHost())
            {
                IProtectedData protectedData = null;

                host.Configure(app =>
                {
                    var config = new HubConfiguration
                    {
                        Resolver = new DefaultDependencyResolver()
                    };

                    app.MapSignalR<MyGroupConnection>("/echo", config);

                    protectedData = config.Resolver.Resolve<IProtectedData>();
                });

                var connection = new Client.Connection("http://memoryhost/echo");

                using (connection)
                {
                    var inGroup = new AsyncManualResetEvent();

                    connection.Received += data =>
                    {
                        if (data == "group")
                        {
                            inGroup.Set();
                        }
                    };

                    await connection.Start(host);

                    await inGroup.WaitAsync(TimeSpan.FromSeconds(10));

                    Assert.NotNull(connection.GroupsToken);

                    var spyWh = new AsyncManualResetEvent();
                    var hackerConnection = new Client.Connection(connection.Url)
                    {
                        ConnectionId = "hacker"
                    };

                    var url = GetUrl(protectedData, connection, connection.GroupsToken);
                    var response = await host.Get(url, r => { }, isLongRunning: true);
                    var reader = new EventSourceStreamReader(hackerConnection, response.GetStream());

                    reader.Message = sseEvent =>
                    {
                        if (sseEvent.EventType == EventType.Data &&
                            sseEvent.Data != "initialized" &&
                            sseEvent.Data != "{}")
                        {
                            spyWh.Set();
                        }
                    };

                    reader.Start();
                    await connection.Send("random");

                    Assert.False(await spyWh.WaitAsync(TimeSpan.FromSeconds(5)));
                }
            }
        }
Ejemplo n.º 57
0
        public static IDisposable StressGroups(int max = 100)
        {
            var host = new MemoryHost();

            host.Configure(app =>
            {
                var config = new HubConfiguration()
                {
                    Resolver = new DefaultDependencyResolver()
                };

                app.MapSignalR(config);

                var configuration = config.Resolver.Resolve <IConfigurationManager>();
                // The below effectively sets the heartbeat interval to five seconds.
                configuration.KeepAlive = TimeSpan.FromSeconds(10);
            });

            var countDown  = new CountDownRange <int>(Enumerable.Range(0, max));
            var connection = new HubConnection("http://foo");
            var proxy      = connection.CreateHubProxy("HubWithGroups");

            proxy.On <int>("Do", i =>
            {
                if (!countDown.Mark(i))
                {
                    Debugger.Break();
                }
            });

            try
            {
                connection.Start(new Client.Transports.LongPollingTransport(host)).Wait();

                proxy.Invoke("Join", "foo").Wait();

                for (int i = 0; i < max; i++)
                {
                    proxy.Invoke("Send", "foo", i).Wait();
                }

                proxy.Invoke("Leave", "foo").Wait();

                for (int i = max + 1; i < max + 50; i++)
                {
                    proxy.Invoke("Send", "foo", i).Wait();
                }

                if (!countDown.Wait(TimeSpan.FromSeconds(10)))
                {
                    Console.WriteLine("Didn't receive " + max + " messages. Got " + (max - countDown.Count) + " missed " + String.Join(",", countDown.Left.Select(i => i.ToString())));
                    Debugger.Break();
                }
            }
            finally
            {
                connection.Stop();
            }

            return(host);
        }
Ejemplo n.º 58
0
        public void Configuration(IAppBuilder appBuilder)
        {
            SnLog.Instance = new SnEventLogger(Web.Configuration.LogName, Web.Configuration.LogSourceName);
            SnLog.WriteInformation("Starting TaskManagement.Web", EventId.TaskManagement.Lifecycle);

            // make Web API use the standard ASP.NET error configuration
            ConfigureErrorHandling();

            // Branch the pipeline here for requests that start with "/signalr"
            appBuilder.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);

                var hubConfiguration = new HubConfiguration
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };

                // add SQL server backend if SignalR SQL is enabled
                if (SenseNet.TaskManagement.Web.Configuration.SignalRSqlEnabled)
                {
                    GlobalHost.DependencyResolver.UseSqlServer(SenseNet.TaskManagement.Web.Configuration.SignalRDatabaseConnectionString);
                }

                SnLog.WriteInformation(
                    $"SignalR SQL backplane is{(SenseNet.TaskManagement.Web.Configuration.SignalRSqlEnabled ? string.Empty : " NOT")} enabled.",
                    EventId.TaskManagement.Lifecycle);

                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });

            var httpConfiguration = new HttpConfiguration();

            httpConfiguration.Formatters.Clear();
            httpConfiguration.Formatters.Add(new JsonMediaTypeFormatter());

            httpConfiguration.Formatters.JsonFormatter.SerializerSettings =
                new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            // Web API routes (moved here from WebApiConfig)
            httpConfiguration.MapHttpAttributeRoutes();

            httpConfiguration.Routes.MapHttpRoute(
                name: "TaskManagementRegisterTaskApi",
                routeTemplate: "api/{controller}/{action}/{taskRequest}",
                defaults: new
            {
                taskRequest = RouteParameter.Optional,
                controller  = "Task",
                action      = "RegisterTask"
            }
                );

            httpConfiguration.Routes.MapHttpRoute(
                name: "TaskManagementRegisterAppApi",
                routeTemplate: "api/{controller}/{action}/{appRequest}",
                defaults: new
            {
                taskRequest = RouteParameter.Optional,
                controller  = "Task",
                action      = "RegisterApplication"
            }
                );

            httpConfiguration.Routes.MapHttpRoute(
                name: "TaskManagementApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional });

            // configure global error logging
            httpConfiguration.Services.Add(typeof(IExceptionLogger), new WebExceptionLogger());

            appBuilder.UseWebApi(httpConfiguration);

            // initialize dead task timer
            InitializeDeadTaskTimer();

            SnLog.WriteInformation("SenseNet TaskManagement app started.", EventId.TaskManagement.Lifecycle);

            // load apps
            ApplicationHandler.Initialize();
        }
Ejemplo n.º 59
0
        /// <summary>
        /// Adds Azure SignalR hubs to the app builder pipeline at "/signalr".
        /// </summary>
        /// <param name="builder">The app builder</param>
        /// <param name="applicationName">The name of your app, it is case-insensitive</param>
        /// <param name="configuration">The hub configuration</param>
        /// <param name="optionsConfigure">A callback to configure the <see cref="ServiceOptions"/>.</param>
        public static void RunAzureSignalR(this IAppBuilder builder, string applicationName, HubConfiguration configuration, Action <ServiceOptions> optionsConfigure)
        {
            var serviceOptions = new ServiceOptions();

            optionsConfigure?.Invoke(serviceOptions);
            RunAzureSignalRCore(builder, applicationName, configuration, serviceOptions);
        }
Ejemplo n.º 60
0
        // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ShopOnlineDbContext.Create);

            app.CreatePerOwinContext <ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext <ApplicationSignInManager>(ApplicationSignInManager.Create);
            app.CreatePerOwinContext <ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext <ApplicationRoleManager>(ApplicationRoleManager.Create);
            app.CreatePerOwinContext <UserManager <AppUser> >(CreateManager);

            //Allow Cross origin for API
            app.UseCors(CorsOptions.AllowAll);

            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath         = new PathString("/api/oauth/token"),
                Provider                  = new AuthorizationServerProvider(),
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1440),
                AllowInsecureHttp         = true
            });
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);


            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath          = new PathString("/login.html"),
                Provider           = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity <ApplicationUserManager, AppUser>(
                        validateInterval: TimeSpan.FromMinutes(10080),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie))
                }
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);



            app.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);

                map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
                {
                    Provider = new QueryStringOAuthBearerProvider()
                });

                var hubConfiguration = new HubConfiguration
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    EnableJSONP          = true,
                    EnableDetailedErrors = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });

            // Branch the pipeline here for requests that start with "/signalr"

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            //{
            //    ClientId = "",
            //    ClientSecret = ""
            //});
        }