Exemplo n.º 1
0
        public void GetServiceUriTest()
        {
            // Arrange
            string iothubHostName       = "foo.azure-devices.net";
            string deviceId             = "d1";
            string moduleId             = "$edgeHub";
            int    batchSize            = 10;
            var    tokenProvider        = Mock.Of <ITokenProvider>();
            var    deviceScopeApiClient = new DeviceScopeApiClient(iothubHostName, deviceId, moduleId, batchSize, tokenProvider);
            string expectedUri          = "https://foo.azure-devices.net/devices/d1/modules/$edgeHub/devicesAndModulesInDeviceScope?deviceCount=10&continuationToken=&api-version=2018-08-30-preview";

            // Act
            Uri uri = deviceScopeApiClient.GetServiceUri(Option.None <string>());

            // Assert
            Assert.NotNull(uri);
            Assert.Equal(expectedUri, uri.ToString());
        }
Exemplo n.º 2
0
        public void GetServiceUriWithContinuationTokenTest()
        {
            // Arrange
            string iothubHostName       = "foo.azure-devices.net";
            string deviceId             = "d1";
            string moduleId             = "$edgeHub";
            int    batchSize            = 10;
            var    tokenProvider        = Mock.Of <ITokenProvider>();
            var    deviceScopeApiClient = new DeviceScopeApiClient(iothubHostName, deviceId, moduleId, batchSize, tokenProvider);
            string continuationToken    = "/devices/d301/modules/%24edgeHub/devicesAndModulesInDeviceScope?deviceCount=10&continuationToken=cccccDDDDDRRRRRsssswJmxhc3Q9bGQyXzE1&api-version=2018-08-30-preview";
            string expectedToken        = "https://foo.azure-devices.net/devices/d301/modules/%24edgeHub/devicesAndModulesInDeviceScope?deviceCount=10&continuationToken=cccccDDDDDRRRRRsssswJmxhc3Q9bGQyXzE1&api-version=2018-08-30-preview";

            // Act
            Uri uri = deviceScopeApiClient.GetServiceUri(Option.Some(continuationToken));

            // Assert
            Assert.NotNull(uri);
            Assert.Equal(expectedToken, uri.ToString());
        }
Exemplo n.º 3
0
        public void GetServiceUriForTargetModuleTest()
        {
            // Arrange
            string iothubHostName       = "foo.azure-devices.net";
            string deviceId             = "d1";
            string moduleId             = "$edgeHub";
            int    batchSize            = 10;
            var    tokenProvider        = Mock.Of <ITokenProvider>();
            var    deviceScopeApiClient = new DeviceScopeApiClient(iothubHostName, deviceId, moduleId, batchSize, tokenProvider);
            string targetDeviceId       = "dev1";
            string targetModuleId       = "mod1";
            string expectedToken        = "https://foo.azure-devices.net/devices/d1/modules/$edgeHub/deviceAndModuleInDeviceScope?targetDeviceId=dev1&targetModuleId=mod1&api-version=2018-08-30-preview";

            // Act
            Uri uri = deviceScopeApiClient.GetServiceUri(targetDeviceId, targetModuleId);

            // Assert
            Assert.NotNull(uri);
            Assert.Equal(expectedToken, uri.ToString());
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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, Service.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 Storage.RocksDb.RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance))
            .As <Storage.RocksDb.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 = Storage.RocksDb.DbStoreProvider.Create(c.Resolve <Storage.RocksDb.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<IEncryptionProvider>
            builder.Register(
                async c =>
            {
                IEncryptionProvider encryptionProvider = await this.workloadUri.Map(
                    async uri => await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        Service.Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Service.Constants.InitializationVectorFileName) as IEncryptionProvider)
                                                         .GetOrElse(() => Task.FromResult <IEncryptionProvider>(NullEncryptionProvider.Instance));
                return(encryptionProvider);
            })
            .As <Task <IEncryptionProvider> >()
            .SingleInstance();

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

            // ITokenProvider
            builder.Register(c => new ModuleTokenProvider(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 ModuleTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            // Task<IKeyValueStore<string, string>> - EncryptedStore
            builder.Register(
                async c =>
            {
                var storeProvider = c.Resolve <IStoreProvider>();
                IEncryptionProvider encryptionProvider         = await c.Resolve <Task <IEncryptionProvider> >();
                IEntityStore <string, string> entityStore      = storeProvider.GetEntityStore <string, string>("SecurityScopeCache");
                IKeyValueStore <string, string> encryptedStore = new EncryptedStore <string, string>(entityStore, encryptionProvider);
                return(encryptedStore);
            })
            .Named <Task <IKeyValueStore <string, string> > >("EncryptedStore")
            .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 c.ResolveNamed <Task <IKeyValueStore <string, string> > >("EncryptedStore");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

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

            // Task<IAuthenticator>
            builder.Register(async c =>
            {
                IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                IAuthenticator tokenAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    if (this.cacheTokens)
                    {
                        ICredentialsStore credentialsStore = await c.Resolve <Task <ICredentialsStore> >();
                        IAuthenticator authenticator       = new CloudTokenAuthenticator(connectionManager);
                        tokenAuthenticator = new TokenCacheAuthenticator(authenticator, credentialsStore, this.iothubHostName);
                    }
                    else
                    {
                        tokenAuthenticator = new CloudTokenAuthenticator(connectionManager);
                    }
                    break;

                case AuthenticationMode.Scope:
                    deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                    tokenAuthenticator         = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), connectionManager);
                    break;

                default:
                    deviceScopeIdentitiesCache        = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                    IAuthenticator cloudAuthenticator = new CloudTokenAuthenticator(connectionManager);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudAuthenticator, connectionManager);
                    break;
                }

                return(new Authenticator(tokenAuthenticator, this.edgeDeviceId, connectionManager) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

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

            base.Load(builder);
        }