/// <summary> /// The main method of the program. /// </summary> public static void Main() { AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); Console.WriteLine("Setting up the database..."); var context = new MqttContext( new DatabaseConnectionSettings { Host = "localhost", Database = "mqtt", Port = 5432, Username = "******", Password = "******" }); Console.WriteLine("Delete database..."); context.Database.EnsureDeleted(); Console.WriteLine("Create database..."); context.Database.EnsureCreated(); Console.WriteLine("Adding seed data..."); SeedData(context); Console.WriteLine("Press any key to close this window..."); Console.ReadKey(); }
/// <summary> /// Initializes a new instance of the <see cref="UserController"/> class. /// </summary> /// <param name="databaseContext">The database context.</param> /// <param name="userManager">The user manager.</param> /// <param name="autoMapper">The automapper service.</param> // ReSharper disable once StyleCop.SA1650 public UserController(MqttContext databaseContext, UserManager <User> userManager, IMapper autoMapper) { this.databaseContext = databaseContext; this.userManager = userManager; this.autoMapper = autoMapper; this.passwordHasher = new PasswordHasher <User>(); }
/// <summary> /// The main method of the program. /// </summary> /// <param name="args">Some parameters, currently unused.</param> public static void Main(string[] args) { Console.WriteLine("Setting up the database..."); var context = new MqttContext(new DatabaseConnectionSettings { Host = "localhost", Database = "mqtt", Port = 5432, Username = "******", Password = "******" }); Console.WriteLine("Delete database..."); context.Database.EnsureDeleted(); Console.WriteLine("Create database..."); context.Database.EnsureCreated(); Console.WriteLine("Adding seed data..."); SeedData(context); Console.WriteLine("Press any key to close this window..."); Console.ReadKey(); }
public ClaimController(MqttContext databaseContext, IMapper autoMapper) { this.databaseContext = databaseContext; this.autoMapper = autoMapper; }
/// <summary> /// Seeds the database with some data. Use this method to add custom data as needed. /// </summary> /// <param name="context">The <see cref="MqttContext" /> to use.</param> private static void SeedData(MqttContext context) { var version = new DbVersion { Version = "1.0.0.0", VersionName = "Sicario", CreatedAt = DateTimeOffset.Now }; if (context.DbVersions is null) { return; } context.DbVersions.Add(version); context.SaveChanges(); var user = new User { UserName = "******", AccessFailedCount = 0, ConcurrencyStamp = new Guid().ToString(), CreatedAt = DateTimeOffset.Now, Email = "*****@*****.**", EmailConfirmed = true, LockoutEnabled = false, NormalizedEmail = "*****@*****.**", NormalizedUserName = "******", PhoneNumber = "01234567890", SecurityStamp = new Guid().ToString(), TwoFactorEnabled = false, PhoneNumberConfirmed = true, ValidateClientId = true, ThrottleUser = true, MonthlyByteLimit = 10000 }; context.Users.Add(user); user.PasswordHash = new PasswordHasher <User>().HashPassword(user, "Hans"); context.SaveChanges(); context.UserClaims.Add(new UserClaim { ClaimType = "SubscriptionBlacklist", ClaimValue = JsonConvert.SerializeObject(new List <string> { "a", "b/+", "c/#" }), UserId = 1, CreatedAt = DateTimeOffset.Now }); context.UserClaims.Add(new UserClaim { ClaimType = "SubscriptionWhitelist", ClaimValue = JsonConvert.SerializeObject(new List <string> { "d", "e/+", "f/#" }), UserId = 1, CreatedAt = DateTimeOffset.Now }); context.UserClaims.Add(new UserClaim { ClaimType = "PublishBlacklist", ClaimValue = JsonConvert.SerializeObject(new List <string> { "a", "b/+", "c/#" }), UserId = 1, CreatedAt = DateTimeOffset.Now }); context.UserClaims.Add(new UserClaim { ClaimType = "PublishWhitelist", ClaimValue = JsonConvert.SerializeObject(new List <string> { "d", "e/+", "f/#" }), UserId = 1, CreatedAt = DateTimeOffset.Now }); context.SaveChanges(); }
/// <summary> /// Configures the services. /// </summary> /// <param name="services">The services.</param> public void ConfigureServices(IServiceCollection services) { // Added the custom configuration options services.Configure <DatabaseConnectionSettings>(this.Configuration.GetSection("DatabaseConnectionSettings")); services.Configure <MqttSettings>(this.Configuration.GetSection("MqttSettings")); // Load database connection settings var databaseConnection = this.Configuration.GetSection("DatabaseConnectionSettings").Get <DatabaseConnectionSettings>() ?? new DatabaseConnectionSettings(); // Load MQTT configuration settings var mqttSettings = this.Configuration.GetSection("MqttSettings").Get <MqttSettings>(); // Configure database context databaseContext = new MqttContext(databaseConnection); // Added the identity stuff and the database connection services.AddDbContext <MqttContext>(options => options.UseNpgsql(databaseConnection.ToConnectionString())); services.AddIdentity <User, Role>().AddEntityFrameworkStores <MqttContext>().AddDefaultTokenProviders(); // Add response compression services.AddResponseCompression(); // Add AutoMapper services.AddAutoMapper(typeof(UserClaimsProfile), typeof(UserProfile)); // Add swagger // Add swagger document for the API services.AddSwaggerDocument( config => { var version = Assembly.GetExecutingAssembly().GetName().Version; config.DocumentName = $"NetCoreMQTTExampleIdentityConfig {version}"; config.PostProcess = document => { document.Info.Version = $"{version}"; document.Info.Title = "NetCoreMQTTExampleIdentityConfig"; document.Info.Description = "NetCoreMQTTExampleIdentityConfig"; }; }); // Read certificate var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var certificate = new X509Certificate2( Path.Combine(currentPath, "certificate.pfx"), "test", X509KeyStorageFlags.Exportable); // Add MQTT stuff services.AddHostedMqttServer( builder => builder //// .WithDefaultEndpoint().WithDefaultEndpointPort(1883) // For testing purposes only .WithDefaultEndpoint().WithDefaultEndpointPort(1883) // For testing purposes only // .WithoutDefaultEndpoint() .WithEncryptedEndpoint().WithEncryptedEndpointPort(mqttSettings.Port) .WithEncryptionCertificate(certificate.Export(X509ContentType.Pfx)) .WithEncryptionSslProtocol(SslProtocols.Tls12).WithConnectionValidator( c => { var currentUser = databaseContext.Users.FirstOrDefault(u => u.UserName == c.Username); if (currentUser == null) { c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword; return; } if (c.Username != currentUser.UserName) { c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword; return; } var hashingResult = Hasher.VerifyHashedPassword( currentUser, currentUser.PasswordHash, c.Password); if (hashingResult == PasswordVerificationResult.Failed) { c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword; return; } if (string.IsNullOrWhiteSpace(currentUser.ClientIdPrefix)) { if (c.ClientId != currentUser.ClientId) { c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword; return; } c.SessionItems.Add(currentUser.ClientId, currentUser); } else { c.SessionItems.Add(currentUser.ClientIdPrefix, currentUser); } c.ReasonCode = MqttConnectReasonCode.Success; }).WithSubscriptionInterceptor( c => { var clientIdPrefix = GetClientIdPrefix(c.ClientId); User currentUser; bool userFound; if (clientIdPrefix == null) { userFound = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject); currentUser = currentUserObject as User; } else { userFound = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject); currentUser = currentUserObject as User; } if (!userFound || currentUser == null) { c.AcceptSubscription = false; return; } var topic = c.TopicFilter.Topic; // Get blacklist var subscriptionBlackList = databaseContext.UserClaims.FirstOrDefault( uc => uc.UserId == currentUser.Id && uc.ClaimType == ClaimType.SubscriptionBlacklist.ToString()); var blacklist = JsonConvert.DeserializeObject <List <string> >(subscriptionBlackList?.ClaimValue) ?? new List <string>(); // Get whitelist var subscriptionWhitelist = databaseContext.UserClaims.FirstOrDefault( uc => uc.UserId == currentUser.Id && uc.ClaimType == ClaimType.SubscriptionWhitelist.ToString()); var whitelist = JsonConvert.DeserializeObject <List <string> >(subscriptionWhitelist?.ClaimValue) ?? new List <string>(); // Check matches if (blacklist.Contains(topic)) { c.AcceptSubscription = false; return; } if (whitelist.Contains(topic)) { c.AcceptSubscription = true; return; } foreach (var forbiddenTopic in blacklist) { var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic); if (!doesTopicMatch) { continue; } c.AcceptSubscription = false; return; } foreach (var allowedTopic in whitelist) { var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic); if (!doesTopicMatch) { continue; } c.AcceptSubscription = true; return; } c.AcceptSubscription = false; }).WithApplicationMessageInterceptor( c => { var clientIdPrefix = GetClientIdPrefix(c.ClientId); User currentUser; bool userFound; if (clientIdPrefix == null) { userFound = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject); currentUser = currentUserObject as User; } else { userFound = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject); currentUser = currentUserObject as User; } if (!userFound || currentUser == null) { c.AcceptPublish = false; return; } var topic = c.ApplicationMessage.Topic; // Get blacklist var subscriptionBlackList = databaseContext.UserClaims.FirstOrDefault( uc => uc.UserId == currentUser.Id && uc.ClaimType == ClaimType.PublishBlacklist.ToString()); var blacklist = JsonConvert.DeserializeObject <List <string> >(subscriptionBlackList?.ClaimValue) ?? new List <string>(); // Get whitelist var subscriptionWhitelist = databaseContext.UserClaims.FirstOrDefault( uc => uc.UserId == currentUser.Id && uc.ClaimType == ClaimType.PublishWhitelist.ToString()); var whitelist = JsonConvert.DeserializeObject <List <string> >(subscriptionWhitelist?.ClaimValue) ?? new List <string>(); // Check matches if (blacklist.Contains(topic)) { c.AcceptPublish = false; return; } if (whitelist.Contains(topic)) { c.AcceptPublish = true; return; } foreach (var forbiddenTopic in blacklist) { var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic); if (!doesTopicMatch) { continue; } c.AcceptPublish = false; return; } foreach (var allowedTopic in whitelist) { var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic); if (!doesTopicMatch) { continue; } c.AcceptPublish = true; return; } c.AcceptPublish = false; })); services.AddMqttConnectionHandler(); // Add the MVC stuff services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
/// <summary> /// Initializes a new instance of the <see cref="ClaimController" /> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="databaseContext">The database context.</param> /// <param name="autoMapper">The auto mapper service.</param> public ClaimController(ILogger logger, MqttContext databaseContext, IMapper autoMapper) { this.logger = logger; this.databaseContext = databaseContext; this.autoMapper = autoMapper; }