Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 3
0
 /// <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);
            }
        }