public void GetDevicesAndModulesInTargetDeviceScope_UnauthorizedActorTest() { string targetEdgeId = "edge2"; var resultIdentities = new List <ServiceIdentity>(); var authChainMapping = new Dictionary <string, string>(); authChainMapping.Add(targetEdgeId, targetEdgeId + ";edge1;edgeroot"); var controller = MakeController(targetEdgeId, resultIdentities, authChainMapping); var request = new NestedScopeRequest(0, string.Empty, "edge2;edge1"); controller.GetDevicesAndModulesInTargetDeviceScopeAsync("edge1", "notEdgeHub", request).Wait(); Assert.Equal((int)HttpStatusCode.Unauthorized, controller.HttpContext.Response.StatusCode); }
public async Task HandleDevicesAndModulesInTargetDeviceScopeAsyncTest( string actorDeviceId, string actorModuleId, string authChain, string targetDeviceId, string authChainToTarget, HttpStatusCode expectedStatus) { // Setup var request = new NestedScopeRequest(1, string.Empty, authChain); var identitiesCache = new Mock <IDeviceScopeIdentitiesCache>(); identitiesCache.Setup(i => i.GetAuthChain(targetDeviceId)).Returns(Task.FromResult(Option.Some(authChainToTarget))); identitiesCache.Setup(i => i.GetServiceIdentity(targetDeviceId)).Returns(Task.FromResult(Option.None <ServiceIdentity>())); identitiesCache.Setup(i => i.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId)).Returns(Task.FromResult(new List <ServiceIdentity>() as IList <ServiceIdentity>)); // Act EdgeHubScopeResult result = await DeviceScopeController.HandleDevicesAndModulesInTargetDeviceScopeAsync(actorDeviceId, actorModuleId, request, identitiesCache.Object); // Verify Assert.Equal(expectedStatus, result.Status); }
async Task <ScopeResult> GetIdentitiesInTargetScopeInternalAsync(Uri uri, Option <string> continuationToken) { HttpClient client = this.proxy .Map(p => new HttpClient(new HttpClientHandler { Proxy = p }, disposeHandler: true)) .GetOrElse(() => new HttpClient()); client.Timeout = HttpOperationTimeout; using (var msg = new HttpRequestMessage(HttpMethod.Post, uri)) { // Get the auth-chain for the target device Option <string> maybeAuthChain = await this.serviceIdentityHierarchy.GetAuthChain(this.TargetEdgeDeviceId); string authChain = maybeAuthChain.Expect(() => new InvalidOperationException($"No valid authentication chain for {this.TargetEdgeDeviceId}")); var payload = new NestedScopeRequest(this.batchSize, continuationToken.OrDefault(), authChain); string token = await this.edgeHubTokenProvider.GetTokenAsync(Option.None <TimeSpan>()); msg.Headers.Add(HttpRequestHeader.Authorization.ToString(), token); msg.Content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(msg); string content = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var scopeResult = JsonConvert.DeserializeObject <ScopeResult>(content); Events.GotValidResult(); return(scopeResult); } else { throw new DeviceScopeApiException("Error getting device scope result from upstream", response.StatusCode, content); } } }
public async Task GetDevicesAndModulesInTargetDeviceScope_RoundTripTest() { // Setup ServiceIdentity results string parentEdgeId = "edge1"; string childEdgeId = "edge2"; string deviceId = "device1"; string moduleId = "module1"; string deviceScope = "deviceScope1"; string parentScope = "parentScope1"; string generationId = "generation1"; string primaryKey = "t3LtII3CppvtVqycKp9bo043vCEgWbGBJAzXZNmoBXo="; string secondaryKey = "kT4ac4PpH5UY0vA1JpLQWOu2yG6qKoqwvzee3j1Z3bA="; var authentication = new ServiceAuthentication(new SymmetricKeyAuthentication(primaryKey, secondaryKey)); var resultDeviceIdentity = new ServiceIdentity(deviceId, null, deviceScope, new List <string>() { parentScope }, generationId, Enumerable.Empty <string>(), authentication, ServiceIdentityStatus.Enabled); var resultModuleIdentity = new ServiceIdentity(deviceId, moduleId, null, new List <string>() { deviceScope }, generationId, Enumerable.Empty <string>(), authentication, ServiceIdentityStatus.Enabled); var resultIdentities = new List <ServiceIdentity>() { resultDeviceIdentity, resultModuleIdentity }; var authChainMapping = new Dictionary <string, string>(); authChainMapping.Add(childEdgeId, "edge2;edge1;edgeroot"); var controller = MakeController(childEdgeId, resultIdentities, authChainMapping); // Act var request = new NestedScopeRequest(0, string.Empty, "edge2;edge1"); await controller.GetDevicesAndModulesInTargetDeviceScopeAsync(parentEdgeId, "$edgeHub", request); // Verify EdgeHub result types var expectedAuth = new AuthenticationMechanism() { SymmetricKey = new SymmetricKey() { PrimaryKey = primaryKey, SecondaryKey = secondaryKey } }; var expectedDeviceIdentities = new List <EdgeHubScopeDevice>() { new EdgeHubScopeDevice(deviceId, generationId, DeviceStatus.Enabled, expectedAuth, new DeviceCapabilities(), deviceScope, new List <string> { parentScope }) }; var expectedModuleIdentities = new List <EdgeHubScopeModule>() { new EdgeHubScopeModule(moduleId, deviceId, generationId, expectedAuth) }; var responseExpected = new EdgeHubScopeResultSuccess(expectedDeviceIdentities, expectedModuleIdentities); var responseExpectedJson = JsonConvert.SerializeObject(responseExpected); var responseActualBytes = GetResponseBodyBytes(controller); var responseActualJson = Encoding.UTF8.GetString(responseActualBytes); Assert.Equal((int)HttpStatusCode.OK, controller.HttpContext.Response.StatusCode); Assert.Equal(responseExpectedJson, responseActualJson); // Deserialize JSON back to SDK result types var scopeResult = JsonConvert.DeserializeObject <ScopeResult>(responseActualJson); // Convert to original ServiceIdentity type Assert.Equal(1, (int)scopeResult.Devices.Count()); Assert.Equal(1, (int)scopeResult.Modules.Count()); ServiceIdentity device = scopeResult.Devices.First().ToServiceIdentity(); ServiceIdentity module = scopeResult.Modules.First().ToServiceIdentity(); Assert.Equal(resultDeviceIdentity, device); Assert.Equal(resultModuleIdentity, module); }
public async Task GetDevicesAndModulesInTargetDeviceScopeAsync([FromRoute] string actorDeviceId, [FromRoute] string actorModuleId, [FromBody] NestedScopeRequest request) { actorDeviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorDeviceId, nameof(actorDeviceId))); actorModuleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorModuleId, nameof(actorModuleId))); Preconditions.CheckNonWhiteSpace(request.AuthChain, nameof(request.AuthChain)); if (actorModuleId != Constants.EdgeHubModuleId) { // Only child EdgeHubs are allowed to act OnBehalfOf of devices/modules. var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, Events.UnauthorizedActor(actorDeviceId, actorModuleId)); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } string authChain = request.AuthChain; string[] ids = AuthChainHelpers.GetAuthChainIds(authChain); if (ids.Length == 1) { // A child EdgeHub can use its module credentials to calls upstream // OnBehalfOf its device identity, so the auth-chain would just have // one element denoting the target device scope but no actor. // However, the auth stack requires an actor to be specified for OnBehalfOf // connections, so we manually add the actor to the auth-chain for this // special case. authChain = $"{ids[0]}/{Constants.EdgeHubModuleId};{ids[0]}"; } IHttpRequestAuthenticator authenticator = await this.authenticatorGetter; HttpAuthResult authResult = await authenticator.AuthenticateAsync(actorDeviceId, Option.Some(actorModuleId), Option.Some(authChain), this.HttpContext); if (authResult.Authenticated) { EdgeHubScopeResult reqResult = await this.HandleDevicesAndModulesInTargetDeviceScopeAsync(actorDeviceId, actorModuleId, request); await this.SendResponse(reqResult.Status, JsonConvert.SerializeObject(reqResult)); } else { var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, authResult.ErrorMessage); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } }
public static void ReceivedScopeRequest(string actorDeviceId, string actorModuleId, NestedScopeRequest request) { Log.LogInformation((int)EventIds.ReceivedScopeRequest, $"Received get scope request: actorId: {actorDeviceId}/{actorModuleId}, authChain: {request.AuthChain}, continuationLink: {request.ContinuationLink}, pageSize: {request.PageSize}"); }
async Task <EdgeHubScopeResult> HandleDevicesAndModulesInTargetDeviceScopeAsync(string actorDeviceId, string actorModuleId, NestedScopeRequest request) { Events.ReceivedScopeRequest(actorDeviceId, actorModuleId, request); if (!AuthChainHelpers.TryGetTargetDeviceId(request.AuthChain, out string targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.BadRequest, Events.InvalidRequestAuthchain(request.AuthChain))); } // Get the children of the target device and the target device itself; IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); IList <ServiceIdentity> identities = await identitiesCache.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId); Option <ServiceIdentity> targetDevice = await identitiesCache.GetServiceIdentity(targetDeviceId); targetDevice.ForEach(d => identities.Add(d)); // Construct the result from the identities Events.SendingScopeResult(targetDeviceId, identities); return(MakeResultFromIdentities(identities)); }
async Task <EdgeHubScopeResult> HandleDevicesAndModulesInTargetDeviceScopeAsync(string actorDeviceId, string actorModuleId, NestedScopeRequest request) { Events.ReceivedScopeRequest(actorDeviceId, actorModuleId, request); Preconditions.CheckNonWhiteSpace(request.AuthChain, nameof(request.AuthChain)); if (!this.TryGetTargetDeviceId(request.AuthChain, out string targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.BadRequest, Events.InvalidRequestAuthchain(request.AuthChain))); } // Check that the actor device is authorized to act OnBehalfOf the target IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); if (!await this.AuthorizeActorAsync(identitiesCache, actorDeviceId, actorModuleId, targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, Events.UnauthorizedActor(actorDeviceId, actorModuleId, targetDeviceId))); } // Get the children of the target device and the target device itself; IList <ServiceIdentity> identities = await identitiesCache.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId); Option <ServiceIdentity> targetDevice = await identitiesCache.GetServiceIdentity(targetDeviceId); targetDevice.ForEach(d => identities.Add(d)); // Construct the result from the identities Events.SendingScopeResult(targetDeviceId, identities); return(MakeResultFromIdentities(identities)); }
public async Task GetDevicesAndModulesInTargetDeviceScopeAsync([FromRoute] string actorDeviceId, [FromRoute] string actorModuleId, [FromBody] NestedScopeRequest request) { actorDeviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorDeviceId, nameof(actorDeviceId))); actorModuleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorModuleId, nameof(actorModuleId))); IHttpRequestAuthenticator authenticator = await this.authenticatorGetter; HttpAuthResult authResult = await authenticator.AuthenticateAsync(actorDeviceId, Option.Some(actorModuleId), this.HttpContext); if (authResult.Authenticated) { EdgeHubScopeResult reqResult = await this.HandleDevicesAndModulesInTargetDeviceScopeAsync(actorDeviceId, actorModuleId, request); await this.SendResponse(reqResult.Status, JsonConvert.SerializeObject(reqResult)); } else { var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, authResult.ErrorMessage); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } }
internal static async Task <EdgeHubScopeResult> HandleDevicesAndModulesInTargetDeviceScopeAsync(string actorDeviceId, string actorModuleId, NestedScopeRequest request, IDeviceScopeIdentitiesCache identitiesCache) { Events.ReceivedScopeRequest(actorDeviceId, actorModuleId, request); if (!AuthChainHelpers.TryGetTargetDeviceId(request.AuthChain, out string targetDeviceId)) { return(new EdgeHubScopeResultError(HttpStatusCode.BadRequest, Events.InvalidRequestAuthchain(request.AuthChain))); } // Get the children of the target device and the target device itself; Option <string> authChainToTarget = await identitiesCache.GetAuthChain(targetDeviceId); (bool validationResult, string errorMsg) = ValidateAuthChainForRequestor(actorDeviceId, targetDeviceId, authChainToTarget); if (!validationResult) { return(new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, errorMsg)); } IList <ServiceIdentity> identities = await identitiesCache.GetDevicesAndModulesInTargetScopeAsync(targetDeviceId); Option <ServiceIdentity> targetDevice = await identitiesCache.GetServiceIdentity(targetDeviceId); targetDevice.ForEach(d => identities.Add(d)); // Construct the result from the identities Events.SendingScopeResult(targetDeviceId, identities); return(MakeResultFromIdentities(identities)); }
public async Task GetDevicesAndModulesInTargetDeviceScopeAsync([FromRoute] string actorDeviceId, [FromRoute] string actorModuleId, [FromBody] NestedScopeRequest request) { actorDeviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorDeviceId, nameof(actorDeviceId))); actorModuleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(actorModuleId, nameof(actorModuleId))); Preconditions.CheckNonWhiteSpace(request.AuthChain, nameof(request.AuthChain)); if (actorModuleId != Constants.EdgeHubModuleId) { // Only child EdgeHubs are allowed to act OnBehalfOf of devices/modules. var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, Events.UnauthorizedActor(actorDeviceId, actorModuleId)); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } IHttpRequestAuthenticator authenticator = await this.authenticatorGetter; HttpAuthResult authResult = await authenticator.AuthenticateAsync(actorDeviceId, Option.Some(actorModuleId), Option.Some(request.AuthChain), this.HttpContext); if (authResult.Authenticated) { IEdgeHub edgeHub = await this.edgeHubGetter; IDeviceScopeIdentitiesCache identitiesCache = edgeHub.GetDeviceScopeIdentitiesCache(); EdgeHubScopeResult reqResult = await HandleDevicesAndModulesInTargetDeviceScopeAsync(actorDeviceId, actorModuleId, request, identitiesCache); await this.SendResponse(reqResult.Status, JsonConvert.SerializeObject(reqResult)); } else { var result = new EdgeHubScopeResultError(HttpStatusCode.Unauthorized, authResult.ErrorMessage); await this.SendResponse(result.Status, JsonConvert.SerializeObject(result)); } }