/// <inheritdoc cref="IMqttRepositoryGrain" /> /// <summary> /// Proceeds the connection for one client identifier. /// </summary> /// <param name="context">The context.</param> /// <returns>A value indicating whether the connection is accepted or not.</returns> /// <seealso cref="IMqttRepositoryGrain" /> public async Task <bool> ProceedConnect(SimpleMqttConnectionValidatorContext context) { try { // Handle connect in grain var mqttClientGrain = this.GrainFactory.GetGrain <IMqttClientGrain>(context.ClientId); var connectValid = await mqttClientGrain.ProceedConnect(context); if (!connectValid) { return(false); } // Save connect to the database var eventLog = new EventLog { EventType = EventType.Connect, EventDetails = $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint}," + $" Username = {context.UserName}, Password = {context.Password}," + $" CleanSession = {context.CleanSession}." }; this.eventLogQueue.Enqueue(eventLog); return(true); } catch (Exception ex) { this.logger.Error("An error occurred: {@ex}.", ex); return(false); } }
/// <inheritdoc cref="IMqttValidator"/> /// <summary> /// Validates the connection. /// </summary> /// <param name="context">The context.</param> /// <param name="userRepository">The user repository.</param> /// <param name="users">The users.</param> /// <param name="passwordHasher">The password hasher.</param> /// <returns>A value indicating whether the connection is accepted or not.</returns> /// <seealso cref="IMqttValidator"/> public async Task <bool> ValidateConnection(SimpleMqttConnectionValidatorContext context, IUserRepository userRepository, IDictionary <string, User> users, IPasswordHasher <User> passwordHasher) { Logger.Information("Executed ValidateConnection with parameters: {context}, {users}", context, users); var currentUser = await userRepository.GetUserByName(context.UserName).ConfigureAwait(false); Logger.Information("Current user is {currentUser}.", currentUser); if (currentUser == null) { Logger.Information("Current user was null."); return(false); } if (context.UserName != currentUser.UserName) { Logger.Information("User name in context doesn't match the current user."); return(false); } var hashingResult = passwordHasher.VerifyHashedPassword(currentUser, currentUser.PasswordHash, context.Password); if (hashingResult == PasswordVerificationResult.Failed) { Logger.Information("Password verification failed."); return(false); } if (!currentUser.ValidateClientId) { users[context.ClientId] = currentUser; Logger.Information("Connection valid for {clientId} and {user}.", context.ClientId, currentUser); return(true); } if (string.IsNullOrWhiteSpace(currentUser.ClientIdPrefix)) { if (context.ClientId != currentUser.ClientId) { Logger.Information("Client id in context doesn't match the current user's client id."); return(false); } users[context.ClientId] = currentUser; Logger.Information("Connection valid for {clientId} and {user} when client id prefix was null.", context.ClientId, currentUser); } else { users[currentUser.ClientIdPrefix] = currentUser; Logger.Information("Connection valid for {clientIdPrefix} and {user} when client id prefix was not null.", currentUser.ClientIdPrefix, currentUser); } return(true); }
/// <inheritdoc cref="IMqttClientGrain" /> /// <summary> /// Proceeds the connection for one client identifier. /// </summary> /// <param name="context">The context.</param> /// <returns>A value indicating whether the connection is accepted or not.</returns> /// <seealso cref="IMqttClientGrain" /> public async Task <bool> ProceedConnect(SimpleMqttConnectionValidatorContext context) { try { return(await this.mqttValidator.ValidateConnection(context, this.userRepository, this.users, PasswordHasher)); } catch (Exception ex) { this.logger.Error("An error occured: {ex}.", ex); return(false); } }
/// <inheritdoc cref="IMqttValidator"/> /// <summary> /// Validates the connection. /// </summary> /// <param name="context">The context.</param> /// <param name="user">The user.</param> /// <param name="passwordHasher">The password hasher.</param> /// <returns>A value indicating whether the connection is accepted or not.</returns> /// <seealso cref="IMqttValidator"/> public bool ValidateConnection(SimpleMqttConnectionValidatorContext context, User user, IPasswordHasher <User> passwordHasher) { Logger.Debug("Executed ValidateConnection with parameters: {@context}, {@user}.", context, user); Logger.Debug("Current user is {@currentUser}.", user); if (user == null) { Logger.Debug("Current user was null."); return(false); } if (context.UserName != user.UserName) { Logger.Debug("User name in context doesn't match the current user."); return(false); } var hashingResult = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, context.Password); if (hashingResult == PasswordVerificationResult.Failed) { Logger.Debug("Password verification failed."); return(false); } if (!user.ValidateClientId) { Logger.Debug("Connection valid for {@clientId} and {@user}.", context.ClientId, user); return(true); } if (string.IsNullOrWhiteSpace(user.ClientIdPrefix)) { if (context.ClientId != user.ClientId) { Logger.Debug("Client id in context doesn't match the current user's client id."); return(false); } Logger.Debug("Connection valid for {@clientId} and {@user} when client id prefix was null.", context.ClientId, user); } else { Logger.Debug("Connection valid for {@clientIdPrefix} and {@user} when client id prefix was not null.", user.ClientIdPrefix, user); } return(true); }
public async Task TestValidateConnection() { // Test user var mqttConnectionValidatorContext = new SimpleMqttConnectionValidatorContext { ClientId = "Test", CleanSession = true, Endpoint = "127.0.0.1", Password = "******", UserName = "******" }; var result = await this.mqttValidator.ValidateConnection( mqttConnectionValidatorContext, this.userRepository, new Dictionary <string, User>(), this.passwordHasher); Assert.IsTrue(result); }
/// <inheritdoc cref="IMqttClientGrain" /> /// <summary> /// Proceeds the connection for one client identifier. /// </summary> /// <param name="context">The context.</param> /// <returns>A value indicating whether the connection is accepted or not.</returns> /// <seealso cref="IMqttClientGrain" /> public async Task <bool> ProceedConnect(SimpleMqttConnectionValidatorContext context) { try { this.user = await this.userRepository.GetUserByName(context.UserName); if (this.user == null) { return(false); } await this.RefreshCache(false); return(this.mqttValidator.ValidateConnection(context, this.user, PasswordHasher)); } catch (Exception ex) { this.logger.Error("An error occurred: {@ex}.", ex); return(false); } }