Exemple #1
0
        public async Task RoundtripTest()
        {
            // Arrange
            var underlyingCredentialsCache = new NullCredentialsCache();
            var credentialsCache           = new CredentialsCache(underlyingCredentialsCache);
            var identity1 = Mock.Of <IIdentity>(i => i.Id == "d1");
            var identity2 = Mock.Of <IIdentity>(i => i.Id == "d2/m2");
            var creds1    = Mock.Of <ITokenCredentials>(c => c.Identity == identity1);
            var creds2    = Mock.Of <IClientCredentials>(c => c.Identity == identity2);

            // Act
            await credentialsCache.Add(creds1);

            await credentialsCache.Add(creds2);

            Option <IClientCredentials> receivedClientCredentials1 = await credentialsCache.Get(identity1);

            Option <IClientCredentials> receivedClientCredentials2 = await credentialsCache.Get(identity2);

            // Assert
            Assert.True(receivedClientCredentials1.HasValue);
            Assert.True(receivedClientCredentials2.HasValue);
            Assert.Equal(creds1, receivedClientCredentials1.OrDefault());
            Assert.Equal(creds2, receivedClientCredentials2.OrDefault());
        }
Exemple #2
0
      /// <summary>return WebProxy to be used.</summary>
      internal WebProxy Select()
      {
         Debug.Assert(_proxies.Count > 0);

         Proxy proxy = GetProxyForConnection();

         // If there is no responsive proxy (i.e. all proxies are down),
         // set all to responsive irrespective of their last retry time 
         // and start from the first one again.
         if (proxy == null)
         {
            SetAllResponsive();
            proxy = GetProxyForConnection();
         }

         WebProxy webProxy = proxy.GetWebProxy();
         //If it was previously determined that the proxy supports integrated authentication,
         //set the appropriate property of the WebProxy object.
         if (SupportsIntegratedAuthentication(webProxy))
            webProxy.Credentials = CredentialCache.DefaultCredentials;
         // Get credentials from cache and set it in WebProxy that we are going to return.
         // In case connection is direct (without proxy), there can not be any proxy credentials
         else if (webProxy.Address != null)
            webProxy.Credentials = CredentialsCache.GetInstance().GetCredentials(webProxy.Address);

         return webProxy;
      }
        public async Task GetCloudProxyTest()
        {
            // Arrange
            string edgeDeviceId       = "edgeDevice";
            string module1Id          = "module1";
            string iotHub             = "foo.azure-devices.net";
            string token              = TokenHelper.CreateSasToken(iotHub);
            var    module1Credentials = new TokenCredentials(new ModuleIdentity(iotHub, edgeDeviceId, module1Id), token, DummyProductInfo, true);

            IClient client1 = GetDeviceClient();
            IClient client2 = GetDeviceClient();
            var     messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var     deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.SetupSequence(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Returns(client1)
            .Returns(client2);

            ICredentialsCache credentialsCache = new CredentialsCache(new NullCredentialsCache());
            await credentialsCache.Add(module1Credentials);

            var productInfoStore        = Mock.Of <IProductInfoStore>();
            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                new ModuleIdentity(iotHub, edgeDeviceId, "$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            // Act
            Option <ICloudProxy> getCloudProxyTask = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(getCloudProxyTask.HasValue);
            Assert.True(getCloudProxyTask.OrDefault().IsActive);

            // Act
            await getCloudProxyTask.OrDefault().CloseAsync();

            Option <ICloudProxy> newCloudProxyTask1 = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(newCloudProxyTask1.HasValue);
            Assert.NotEqual(newCloudProxyTask1.OrDefault(), getCloudProxyTask.OrDefault());

            Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
            Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
        }
Exemple #4
0
        internal Credentials GetCredentials(Uri uri, bool cacheAllowed, bool hidePasswordField)
        {
            // Synchronized access to the GetCredentials() method prevents multiple login dialogs when loading multiple files at once
            // (e.g. on startup). So the user only needs to enter credentials once for the same host.
            lock (this)
            {
                string userName = null;
                string password = null;
                if (uri.UserInfo != null && uri.UserInfo.Length > 0)
                {
                    string[] split = uri.UserInfo.Split(new char[] { ':' });
                    if (split.Length > 0)
                    {
                        userName = split[0];
                    }

                    if (split.Length > 1)
                    {
                        password = split[1];
                    }
                }

                IList <string> usersForHost = CredentialsCache.GetUsersForHost(uri.Host);
                if (userName == null && cacheAllowed)
                {
                    if (usersForHost.Count == 1)
                    {
                        userName = usersForHost[0];
                    }
                }

                if (userName != null && password == null && cacheAllowed)
                {
                    Credentials cred = CredentialsCache.GetCredentials(uri.Host, userName);
                    if (cred != null)
                    {
                        return(cred);
                    }
                }

                if (userName == null || password == null)
                {
                    LoginDialog dlg = new LoginDialog(uri.Host, usersForHost, hidePasswordField);
                    dlg.UserName = userName;
                    if (DialogResult.OK == dlg.ShowDialog())
                    {
                        password = dlg.Password;
                        userName = dlg.UserName;
                    }

                    dlg.Dispose();
                }

                Credentials credentials = new Credentials(uri.Host, userName, password);
                CredentialsCache.Add(credentials);
                return(credentials);
            }
        }
        private async void OkButton_Click(object?sender, RoutedEventArgs e)
        {
            var info = CredentialRequestInfo;

            if (info == null || _username == null || _password == null)
            {
                return;
            }

            if (info.AuthenticationType == AuthenticationType.Token)
            {
                if (info.ServiceUri == null)
                {
                    return;
                }

                try
                {
                    Credential = await AuthenticationManager.Current.GenerateCredentialAsync(info.ServiceUri, _username.Text, ConvertToUnsecureString(_password.SecurePassword), info.GenerateTokenOptions);
                }
                catch (System.Exception ex)
                {
                    CreateCredentialError?.Invoke(this, ex);
                    return;
                }
            }
            else if (info.AuthenticationType == AuthenticationType.NetworkCredential)
            {
                Credential = new ArcGISNetworkCredential()
                {
                    Credentials = new System.Net.NetworkCredential(_username.Text, _password.SecurePassword)
                };
            }
            else
            {
                CreateCredentialError?.Invoke(this, new NotSupportedException("Authentication type not supported"));
            }

            if (EnableCredentialCache)
            {
                var host = (_serverInfo == null ? info.ServiceUri : _serverInfo.ServerUri) !;
                if (_rememberCredentialsButton != null && _rememberCredentialsButton.IsChecked.HasValue && _rememberCredentialsButton.IsChecked.Value)
                {
                    CredentialsCache.SaveCredential(_username.Text, _password.SecurePassword, host);
                }
                else
                {
                    CredentialsCache.DeleteCredential(host);
                }
            }

            if (Credential != null)
            {
                Completed?.Invoke(this, Credential);
            }
        }
Exemple #6
0
        private void PopulateFields()
        {
            if (_rememberCredentialsButton != null)
            {
                _rememberCredentialsButton.IsChecked = false;
            }

            if (_username != null)
            {
                _username.Text = string.Empty;
            }

            if (_password != null)
            {
                _password.Password = string.Empty;
            }

            if (ServerHost != null && EnableCredentialCache)
            {
                var credential = CredentialsCache.ReadCredential(ServerHost);
                if (credential != null)
                {
                    if (_username != null)
                    {
                        _username.Text = credential.Username;
                    }

                    if (_password != null)
                    {
                        _password.Password = ConvertToUnsecureString(credential.Password);
                    }

                    if (_rememberCredentialsButton != null)
                    {
                        _rememberCredentialsButton.IsChecked = true;
                    }
                }
            }
        }
Exemple #7
0
        public async Task GetFromPersistedCacheTest()
        {
            // Arrange
            var identity1 = Mock.Of <IIdentity>(i => i.Id == "d1");
            var identity2 = Mock.Of <IIdentity>(i => i.Id == "d2/m2");
            var creds1    = Mock.Of <ITokenCredentials>(c => c.Identity == identity1);
            var creds2    = Mock.Of <IClientCredentials>(c => c.Identity == identity2);
            var underlyingCredentialsCache = new Mock <ICredentialsCache>();

            underlyingCredentialsCache.Setup(u => u.Get(identity1)).ReturnsAsync(Option.Some((IClientCredentials)creds1));
            underlyingCredentialsCache.Setup(u => u.Get(identity2)).ReturnsAsync(Option.Some(creds2));
            var credentialsCache = new CredentialsCache(underlyingCredentialsCache.Object);

            // Act
            Option <IClientCredentials> receivedClientCredentials1_1 = await credentialsCache.Get(identity1);

            Option <IClientCredentials> receivedClientCredentials2_1 = await credentialsCache.Get(identity2);

            Option <IClientCredentials> receivedClientCredentials1_2 = await credentialsCache.Get(identity1);

            Option <IClientCredentials> receivedClientCredentials2_2 = await credentialsCache.Get(identity2);

            // Assert
            Assert.True(receivedClientCredentials1_1.HasValue);
            Assert.True(receivedClientCredentials2_1.HasValue);
            Assert.Equal(creds1, receivedClientCredentials1_1.OrDefault());
            Assert.Equal(creds2, receivedClientCredentials2_1.OrDefault());

            Assert.True(receivedClientCredentials1_2.HasValue);
            Assert.True(receivedClientCredentials2_2.HasValue);
            Assert.Equal(creds1, receivedClientCredentials1_2.OrDefault());
            Assert.Equal(creds2, receivedClientCredentials2_2.OrDefault());

            underlyingCredentialsCache.Verify(u => u.Get(identity1), Times.Once);
            underlyingCredentialsCache.Verify(u => u.Get(identity2), Times.Once);
        }
Exemple #8
0
        protected override void Load(ContainerBuilder builder)
        {
            // ISignatureProvider
            builder.Register(
                c =>
            {
                ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                    cs =>
                {
                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                    return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider);
                })
                                                       .GetOrElse(
                    () =>
                {
                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                    string workloadUri         = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                    return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, Constants.WorkloadApiVersion) as ISignatureProvider);
                });
                return(signatureProvider);
            })
            .As <ISignatureProvider>()
            .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
            .As <ISystemEnvironment>()
            .SingleInstance();

            // DataBase options
            builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance))
            .As <IRocksDbOptionsProvider>()
            .SingleInstance();

            // IDbStoreProvider
            builder.Register(
                c =>
            {
                var loggerFactory = c.Resolve <ILoggerFactory>();
                ILogger logger    = loggerFactory.CreateLogger(typeof(RoutingModule));

                if (this.usePersistentStorage)
                {
                    // Create partitions for messages and twins
                    var partitionsList = new List <string> {
                        Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey
                    };
                    try
                    {
                        IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                            c.Resolve <IRocksDbOptionsProvider>(),
                            this.storagePath,
                            partitionsList);
                        logger.LogInformation($"Created persistent store at {this.storagePath}");
                        return(dbStoreprovider);
                    }
                    catch (Exception ex) when(!ExceptionEx.IsFatal(ex))
                    {
                        logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                        return(new InMemoryDbStoreProvider());
                    }
                }
                else
                {
                    logger.LogInformation($"Using in-memory store");
                    return(new InMemoryDbStoreProvider());
                }
            })
            .As <IDbStoreProvider>()
            .SingleInstance();

            // Task<Option<IEncryptionProvider>>
            builder.Register(
                async c =>
            {
                Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri
                                                                        .Map(
                    async uri =>
                {
                    var encryptionProvider = await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Constants.InitializationVectorFileName) as IEncryptionProvider;
                    return(Option.Some(encryptionProvider));
                })
                                                                        .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>()));
                return(encryptionProviderOption);
            })
            .As <Task <Option <IEncryptionProvider> > >()
            .SingleInstance();

            // IStoreProvider
            builder.Register(c => new StoreProvider(c.Resolve <IDbStoreProvider>()))
            .As <IStoreProvider>()
            .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
            .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider")
            .SingleInstance();

            // ITokenProvider
            builder.Register(
                c =>
            {
                string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                async c =>
            {
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                {
                    var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                    IDeviceScopeApiClient securityScopesApiClient = new DeviceScopeApiClient(this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider);
                    IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClient);
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

                return(deviceScopeIdentitiesCache);
            })
            .As <Task <IDeviceScopeIdentitiesCache> >()
            .AutoActivate()
            .SingleInstance();

            // Task<ICredentialsCache>
            builder.Register(
                async c =>
            {
                ICredentialsCache underlyingCredentialsCache;
                if (this.persistTokens)
                {
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache");
                    return(new PersistedTokenCredentialsCache(encryptedStore));
                }
                else
                {
                    underlyingCredentialsCache = new NullCredentialsCache();
                }

                ICredentialsCache credentialsCache = new CredentialsCache(underlyingCredentialsCache);
                return(credentialsCache);
            })
            .As <Task <ICredentialsCache> >()
            .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(
                async c =>
            {
                IAuthenticator tokenAuthenticator;
                IAuthenticator certificateAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >();
                // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped
                deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                certificateAuthenticator   = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true);
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    tokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    break;

                case AuthenticationMode.Scope:
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true);
                    break;

                default:
                    IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true);
                    break;
                }

                ICredentialsCache credentialsCache = await credentialsCacheTask;
                return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo))
            .As <IClientCredentialsFactory>()
            .SingleInstance();

            // ConnectionReauthenticator
            builder.Register(
                async c =>
            {
                var edgeHubCredentials               = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                var connectionManagerTask            = c.Resolve <Task <IConnectionManager> >();
                var authenticatorTask                = c.Resolve <Task <IAuthenticator> >();
                var credentialsCacheTask             = c.Resolve <Task <ICredentialsCache> >();
                var deviceScopeIdentitiesCacheTask   = c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                var deviceConnectivityManager        = c.Resolve <IDeviceConnectivityManager>();
                IConnectionManager connectionManager = await connectionManagerTask;
                IAuthenticator authenticator         = await authenticatorTask;
                ICredentialsCache credentialsCache   = await credentialsCacheTask;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                var connectionReauthenticator = new ConnectionReauthenticator(
                    connectionManager,
                    authenticator,
                    credentialsCache,
                    deviceScopeIdentitiesCache,
                    TimeSpan.FromMinutes(5),
                    edgeHubCredentials.Identity,
                    deviceConnectivityManager);
                return(connectionReauthenticator);
            })
            .As <Task <ConnectionReauthenticator> >()
            .SingleInstance();

            base.Load(builder);
        }
        public async Task CloudConnectionTest()
        {
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceCredentials1 = Mock.Of <ITokenCredentials>(c => c.Identity == Mock.Of <IIdentity>(d => d.Id == "Device1"));
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceCredentials2 = Mock.Of <ITokenCredentials>(c => c.Identity == Mock.Of <IIdentity>(d => d.Id == "Device2"));

            string  edgeDeviceId             = "edgeDevice";
            IClient client1                  = GetDeviceClient();
            IClient client2                  = GetDeviceClient();
            var     messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var     deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.SetupSequence(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Returns(client1)
            .Returns(client2);

            var productInfoStore = Mock.Of <IProductInfoStore>();
            ICredentialsCache credentialsCache = new CredentialsCache(new NullCredentialsCache());

            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                new ModuleIdentity(IotHubHostName, edgeDeviceId, "$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());

            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            Option <ICloudProxy> returnedValue = await connectionManager.GetCloudConnection(deviceCredentials1.Identity.Id);

            Assert.False(returnedValue.HasValue);

            Try <ICloudProxy> cloudProxy1 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials1);

            Assert.True(cloudProxy1.Success);
            Assert.True(cloudProxy1.Value.IsActive);

            returnedValue = await connectionManager.GetCloudConnection(deviceCredentials1.Identity.Id);

            Assert.True(returnedValue.HasValue);
            Assert.Equal(((RetryingCloudProxy)cloudProxy1.Value).InnerCloudProxy, ((RetryingCloudProxy)returnedValue.OrDefault()).InnerCloudProxy);

            Try <ICloudProxy> cloudProxy2 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials2);

            Assert.True(cloudProxy2.Success);
            Assert.True(cloudProxy2.Value.IsActive);

            await connectionManager.RemoveDeviceConnection(deviceCredentials2.Identity.Id);

            returnedValue = await connectionManager.GetCloudConnection(deviceCredentials2.Identity.Id);

            Assert.True(returnedValue.HasValue);
        }
        public async Task GetMultipleCloudProxiesTest()
        {
            // Arrange
            string  edgeDeviceId             = "edgeDevice";
            string  module1Id                = "module1";
            string  token                    = TokenHelper.CreateSasToken(IotHubHostName);
            var     module1Credentials       = new TokenCredentials(new ModuleIdentity(IotHubHostName, edgeDeviceId, module1Id), token, DummyProductInfo, true);
            IClient client1                  = GetDeviceClient();
            IClient client2                  = GetDeviceClient();
            var     messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var     deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.SetupSequence(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Returns(client1)
            .Returns(client2);

            ICredentialsCache credentialsCache = new CredentialsCache(new NullCredentialsCache());
            await credentialsCache.Add(module1Credentials);

            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                new ModuleIdentity(IotHubHostName, edgeDeviceId, "$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20));

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            // Act
            Task <Option <ICloudProxy> > getCloudProxyTask1 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask2 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask3 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask4 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            Option <ICloudProxy>[] cloudProxies = await Task.WhenAll(getCloudProxyTask1, getCloudProxyTask2, getCloudProxyTask3, getCloudProxyTask4);

            // Assert
            Assert.True(cloudProxies[0].HasValue);
            Assert.True(cloudProxies[1].HasValue);
            Assert.True(cloudProxies[2].HasValue);
            Assert.True(cloudProxies[3].HasValue);
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[1].OrDefault());
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[2].OrDefault());
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[3].OrDefault());

            // Act
            await cloudProxies[0].OrDefault().CloseAsync();
            Option <ICloudProxy> newCloudProxyTask1 = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(newCloudProxyTask1.HasValue);
            Assert.NotEqual(newCloudProxyTask1.OrDefault(), cloudProxies[0].OrDefault());
            Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
            Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
        }
Exemple #11
0
 /// <summary>Singleton pattern. A method to return instance of the class.</summary>
 /// <returns></returns>
 internal static CredentialsCache GetInstance()
 {
    return _instance ?? (_instance = new CredentialsCache());
 }
Exemple #12
0
 /// <summary>Set the credentials in the Cache.</summary>
 /// <param name="webProxy"></param>
 /// <param name="networkCredentials"></param>
 internal void SetCredentials(WebProxy webProxy, NetworkCredential networkCredentials)
 {
    CredentialsCache.GetInstance().SetCredentials(webProxy.Address, networkCredentials);
 }
Exemple #13
0
        protected override void Load(ContainerBuilder builder)
        {
            // IMetricsListener
            builder.Register(
                c =>
                this.metricsConfig.Enabled
                            ? new MetricsListener(this.metricsConfig.ListenerConfig, c.Resolve <IMetricsProvider>())
                            : new NullMetricsListener() as IMetricsListener)
            .As <IMetricsListener>()
            .SingleInstance();

            // IMetricsProvider
            builder.Register(
                c =>
                this.metricsConfig.Enabled
                            ? new MetricsProvider(MetricsConstants.EdgeHubMetricPrefix, this.iothubHostName, this.edgeDeviceId, this.metricsConfig.HistogramMaxAge)
                            : new NullMetricsProvider() as IMetricsProvider)
            .As <IMetricsProvider>()
            .SingleInstance();

            // ISignatureProvider
            builder.Register(
                c =>
            {
                ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                    cs =>
                {
                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                    return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider);
                })
                                                       .GetOrElse(
                    () =>
                {
                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                    string workloadUri         = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                    string workloadApiVersion  = this.workloadApiVersion.Expect(() => new InvalidOperationException("workloadUri version is missing"));
                    return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, workloadApiVersion, Constants.WorkloadApiVersion) as ISignatureProvider);
                });
                return(signatureProvider);
            })
            .As <ISignatureProvider>()
            .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
            .As <ISystemEnvironment>()
            .SingleInstance();

            // DataBase options
            builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance, this.storageMaxTotalWalSize, this.storageMaxOpenFiles, this.storageLogLevel))
            .As <IRocksDbOptionsProvider>()
            .SingleInstance();

            if (!this.usePersistentStorage && this.useBackupAndRestore)
            {
                // Backup and restore serialization
                builder.Register(c => new ProtoBufDataBackupRestore())
                .As <IDataBackupRestore>()
                .SingleInstance();
            }

            // IStorageSpaceChecker
            builder.Register(
                c =>
            {
                IStorageSpaceChecker spaceChecker = !this.usePersistentStorage
                       ? new MemorySpaceChecker(() => 0L) as IStorageSpaceChecker
                       : new NullStorageSpaceChecker();
                return(spaceChecker);
            })
            .As <IStorageSpaceChecker>()
            .SingleInstance();

            // IDbStoreProvider
            builder.Register(
                async c =>
            {
                var loggerFactory = c.Resolve <ILoggerFactory>();
                ILogger logger    = loggerFactory.CreateLogger(typeof(RoutingModule));

                if (this.usePersistentStorage)
                {
                    // Create partitions for messages and twins
                    var partitionsList = new List <string> {
                        Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey
                    };
                    try
                    {
                        IDbStoreProvider dbStoreProvider = DbStoreProvider.Create(
                            c.Resolve <IRocksDbOptionsProvider>(),
                            this.storagePath,
                            partitionsList);
                        logger.LogInformation($"Created persistent store at {this.storagePath}");
                        return(dbStoreProvider);
                    }
                    catch (Exception ex) when(!ex.IsFatal())
                    {
                        logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                        IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                        return(dbStoreProvider);
                    }
                }
                else
                {
                    logger.LogInformation($"Using in-memory store");
                    IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                    return(dbStoreProvider);
                }
            })
            .As <Task <IDbStoreProvider> >()
            .SingleInstance();

            // Task<Option<IEncryptionProvider>>
            builder.Register(
                async c =>
            {
                Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri
                                                                        .Map(
                    async uri =>
                {
                    var encryptionProvider = await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")),
                        Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Constants.InitializationVectorFileName) as IEncryptionProvider;
                    return(Option.Some(encryptionProvider));
                })
                                                                        .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>()));
                return(encryptionProviderOption);
            })
            .As <Task <Option <IEncryptionProvider> > >()
            .SingleInstance();

            // Task<IStoreProvider>
            builder.Register(async c =>
            {
                var dbStoreProvider          = await c.Resolve <Task <IDbStoreProvider> >();
                IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                return(storeProvider);
            })
            .As <Task <IStoreProvider> >()
            .SingleInstance();

            // Task<IMetadataStore>
            builder.Register(
                async c =>
            {
                var storeProvider = await c.Resolve <Task <IStoreProvider> >();
                IKeyValueStore <string, string> entityStore = storeProvider.GetEntityStore <string, string>("ProductInfo", "MetadataStore");
                IMetadataStore metadataStore = new MetadataStore(entityStore, this.productInfo);
                return(metadataStore);
            })
            .As <Task <IMetadataStore> >()
            .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
            .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider")
            .SingleInstance();

            // ITokenProvider
            builder.Register(
                c =>
            {
                string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            builder.Register(
                c =>
            {
                var loggerFactory = c.Resolve <ILoggerFactory>();
                var logger        = loggerFactory.CreateLogger <RoutingModule>();
                return(Proxy.Parse(this.proxy, logger));
            })
            .As <Option <IWebProxy> >()
            .SingleInstance();

            // IServiceIdentityHierarchy
            builder.Register <IServiceIdentityHierarchy>(
                c =>
            {
                if (this.nestedEdgeEnabled)
                {
                    return(new ServiceIdentityTree(this.edgeDeviceId));
                }
                else
                {
                    return(new ServiceIdentityDictionary(this.edgeDeviceId));
                }
            })
            .As <IServiceIdentityHierarchy>()
            .SingleInstance();

            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                async c =>
            {
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                {
                    var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                    var proxy = c.Resolve <Option <IWebProxy> >();

                    IServiceIdentityHierarchy serviceIdentityHierarchy = c.Resolve <IServiceIdentityHierarchy>();

                    string hostName = this.gatewayHostName.GetOrElse(this.iothubHostName);
                    IDeviceScopeApiClientProvider securityScopesApiClientProvider = new DeviceScopeApiClientProvider(hostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider, serviceIdentityHierarchy, proxy);
                    IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClientProvider, this.nestedEdgeEnabled);
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceIdentityHierarchy, serviceProxy, encryptedStore, this.scopeCacheRefreshRate, this.scopeCacheRefreshDelay);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

                return(deviceScopeIdentitiesCache);
            })
            .As <Task <IDeviceScopeIdentitiesCache> >()
            .AutoActivate()
            .SingleInstance();

            // IRegistryApiClient
            builder.Register(
                c =>
            {
                string upstreamHostname = this.gatewayHostName.GetOrElse(this.iothubHostName);
                var proxy = c.Resolve <Option <IWebProxy> >();
                var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                return(new RegistryOnBehalfOfApiClient(upstreamHostname, proxy, edgeHubTokenProvider));
            })
            .As <IRegistryOnBehalfOfApiClient>()
            .SingleInstance();

            // Task<ICredentialsCache>
            builder.Register(
                async c =>
            {
                ICredentialsCache underlyingCredentialsCache;
                if (this.persistTokens)
                {
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache");
                    return(new PersistedTokenCredentialsCache(encryptedStore));
                }
                else
                {
                    underlyingCredentialsCache = new NullCredentialsCache();
                }

                ICredentialsCache credentialsCache;

                if (this.nestedEdgeEnabled)
                {
                    credentialsCache = new NestedCredentialsCache(underlyingCredentialsCache);
                }
                else
                {
                    credentialsCache = new CredentialsCache(underlyingCredentialsCache);
                }

                return(credentialsCache);
            })
            .As <Task <ICredentialsCache> >()
            .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(
                async c =>
            {
                IAuthenticator tokenAuthenticator;
                IAuthenticator certificateAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >();
                // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped
                deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                certificateAuthenticator   = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true, this.nestedEdgeEnabled);
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    tokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    break;

                case AuthenticationMode.Scope:
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true, this.nestedEdgeEnabled);
                    break;

                default:
                    IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true, this.nestedEdgeEnabled);
                    break;
                }

                ICredentialsCache credentialsCache = await credentialsCacheTask;
                return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo))
            .As <IClientCredentialsFactory>()
            .SingleInstance();

            // IClientCredentials "EdgeHubCredentials"
            builder.Register(
                c =>
            {
                var identityFactory = c.Resolve <IClientCredentialsFactory>();
                IClientCredentials edgeHubCredentials = this.edgeHubConnectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse(
                    () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeHubModuleId));
                return(edgeHubCredentials);
            })
            .Named <IClientCredentials>("EdgeHubCredentials")
            .SingleInstance();

            // ServiceIdentity "EdgeHubIdentity"
            builder.Register(
                c =>
            {
                return(new ServiceIdentity(
                           this.edgeDeviceId,
                           this.edgeHubModuleId,
                           deviceScope: null,
                           parentScopes: new List <string>(),
                           this.edgeHubGenerationId.GetOrElse("0"),
                           capabilities: new List <string>(),
                           new ServiceAuthentication(ServiceAuthenticationType.None),
                           ServiceIdentityStatus.Enabled));
            })
            .Named <ServiceIdentity>("EdgeHubIdentity")
            .SingleInstance();

            // ConnectionReauthenticator
            builder.Register(
                async c =>
            {
                var edgeHubCredentials               = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                var connectionManagerTask            = c.Resolve <Task <IConnectionManager> >();
                var authenticatorTask                = c.Resolve <Task <IAuthenticator> >();
                var credentialsCacheTask             = c.Resolve <Task <ICredentialsCache> >();
                var deviceScopeIdentitiesCacheTask   = c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                var deviceConnectivityManager        = c.Resolve <IDeviceConnectivityManager>();
                IConnectionManager connectionManager = await connectionManagerTask;
                IAuthenticator authenticator         = await authenticatorTask;
                ICredentialsCache credentialsCache   = await credentialsCacheTask;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                var connectionReauthenticator = new ConnectionReauthenticator(
                    connectionManager,
                    authenticator,
                    credentialsCache,
                    deviceScopeIdentitiesCache,
                    TimeSpan.FromMinutes(5),
                    edgeHubCredentials.Identity,
                    deviceConnectivityManager);
                return(connectionReauthenticator);
            })
            .As <Task <ConnectionReauthenticator> >()
            .SingleInstance();

            base.Load(builder);
        }
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

            IClientCredentials GetClientCredentials(TimeSpan tokenExpiryDuration)
            {
                string token    = TokenHelper.CreateSasToken(hostname, DateTime.UtcNow.AddSeconds(tokenExpiryDuration.TotalSeconds));
                var    identity = new DeviceIdentity(hostname, deviceId);

                return(new TokenCredentials(identity, token, string.Empty, false));
            }

            IDeviceProxy GetMockDeviceProxy()
            {
                var deviceProxyMock1 = new Mock <IDeviceProxy>();

                deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
                deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                return(deviceProxyMock1.Object);
            }

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(() =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            IAuthenticationMethod authenticationMethod = null;
            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <IAuthenticationMethod>(), It.IsAny <ITransportSettings[]>()))
            .Callback <IIdentity, IAuthenticationMethod, ITransportSettings[]>((s, a, t) => authenticationMethod = a)
            .Returns(() => GetMockedDeviceClient());

            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60), true);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var credentialsCache = new CredentialsCache(new NullCredentialsCache());
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache);

            IClientCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
            await credentialsCache.Add(clientCredentials1);

            Try <ICloudProxy> cloudProxyTry1 = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);

            Assert.True(cloudProxyTry1.Success);

            IDeviceProxy deviceProxy1 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials1.Identity, deviceProxy1);

            await Task.Delay(TimeSpan.FromSeconds(10));

            Assert.NotNull(authenticationMethod);
            var deviceTokenRefresher = authenticationMethod as DeviceAuthenticationWithTokenRefresh;

            Assert.NotNull(deviceTokenRefresher);
            Task <string> tokenGetter = deviceTokenRefresher.GetTokenAsync(hostname);

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials2 = GetClientCredentials(TimeSpan.FromMinutes(2));
            await credentialsCache.Add(clientCredentials2);

            Try <ICloudProxy> cloudProxyTry2 = await connectionManager.CreateCloudConnectionAsync(clientCredentials2);

            Assert.True(cloudProxyTry2.Success);

            IDeviceProxy deviceProxy2 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials2.Identity, deviceProxy2);

            await Task.Delay(TimeSpan.FromSeconds(3));

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials3 = GetClientCredentials(TimeSpan.FromMinutes(10));
            await credentialsCache.Add(clientCredentials3);

            Try <ICloudProxy> cloudProxyTry3 = await connectionManager.CreateCloudConnectionAsync(clientCredentials3);

            Assert.True(cloudProxyTry3.Success);

            IDeviceProxy deviceProxy3 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials3.Identity, deviceProxy3);

            await Task.Delay(TimeSpan.FromSeconds(23));

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, (clientCredentials3 as ITokenCredentials)?.Token);
        }