public async Task <IActionResult> Authenticate(
            [FromQuery()] AuthResourceModel resourceModel,
            [FromBody] AuthCredentialModel credentialModel)
        {
            resourceModel   = resourceModel ?? new AuthResourceModel();
            credentialModel = credentialModel ?? new AuthCredentialModel();

            // Create command from the submitted models and send to application layer:
            var        command    = new AuthenticateCaller(credentialModel, resourceModel);
            AuthResult authResult = await _messagingSrv.SendAsync(command);

            // Based on the result, set the HTTP response code, response header and body:
            if (authResult.IsInvalidCredentialContext)
            {
                return(BadRequest(authResult.Reason));
            }

            if (!authResult.IsAuthenticated)
            {
                return(Unauthorized());
            }

            var resource = IdentityAuthResource.FromResult(command, authResult);

            return(new OkJwtAuthResult(authResult.JwtSignedToken, resource));
        }
        public async Task ProviderResultsReturned_ForValidCredentials()
        {
            // Arrange:
            var resourceModel   = new AuthResourceModel {
            };
            var credentialModel = new AuthCredentialModel {
                Api = "service-api", Credentials = new Dictionary <string, string> {
                }
            };
            var command = new AuthenticateCaller(credentialModel, resourceModel);

            // Create mock token service to return know token value
            var tokenSrv = new MockTokenService {
                ExpectedTokenValue = Guid.NewGuid().ToString()
            };

            // Assume provider also indicates valid submitted authentication request.
            var port = CreatePort(p => {
                p.IsValidRequest = true;
                p.HavingResult   = c => AuthResult.Authenticated();
            }, tokenSrv);

            // Act:
            var result = await port.AuthenticateForService(command);

            // Assert:
            Assert.NotNull(result);
            Assert.False(result.IsInvalidCredentialContext);
            Assert.True(result.IsAuthenticated);
            Assert.Equal(tokenSrv.ExpectedTokenValue, result.JwtSignedToken);
        }
        public async Task SpecifiedCredentials_MustPassProviderValidations()
        {
            // Arrange:
            var resourceModel   = new AuthResourceModel {
            };
            var credentialModel = new AuthCredentialModel {
                Api = "service-api", Credentials = new Dictionary <string, string> {
                }
            };
            var command = new AuthenticateCaller(credentialModel, resourceModel);

            // Assume provider also indicates invalid submitted authentication request.
            var port = CreatePort(p => {
                p.IsValidRequest = false;
                p.HavingResult   = c => throw new InvalidOperationException("Should be called for invalid request credentials");
            });

            // Act:IAuthProvider
            var result = await port.AuthenticateForService(command);

            // Assert:
            Assert.NotNull(result);
            Assert.True(result.IsInvalidCredentialContext);
            Assert.False(result.IsAuthenticated);
        }
Example #4
0
 /// <summary>
 /// Command constructor.
 /// </summary>
 /// <param name="credentialModel">Model containing information about the service API requesting
 /// authentication and a set of key value pairs identifying the caller.</param>
 /// <param name="resourceModel">Model containing information about the resource for which access
 /// is being requested.</param>
 public AuthenticateCaller(
     AuthCredentialModel credentialModel,
     AuthResourceModel resourceModel)
 {
     Context = AuthContext.FromService(credentialModel.Api, credentialModel.Credentials);
     if (resourceModel.IsResourceAccessRequest)
     {
         Context = Context.ForResource(resourceModel.Service, resourceModel.Scope);
     }
 }
        public async Task ResourceContextSet_WhenSpecified()
        {
            // Arrange:
            var resourceModel = new AuthResourceModel
            {
                Service = "resource-owner",
                Scope   = new string[] { @"repository:test/my-app:pull,push", @"repository:test/my-app2:pull" }
            };

            var credentialModel = new AuthCredentialModel {
                Api = "service-api", Credentials = new Dictionary <string, string>()
            };
            var command = new AuthenticateCaller(credentialModel, resourceModel);

            // Have the provider responded with a valid request
            var provider = new MockProvider {
                IsValidRequest = true
            };
            var port = CreatePort(provider);

            // Act:
            var result = await port.AuthenticateForService(command);

            // Assert:
            Assert.NotNull(provider.ReceivedContext);

            Assert.Equal("resource-owner", provider.ReceivedContext.ResourceOwner);
            Assert.True(provider.ReceivedContext.Resources.Length == 2);

            var firstResourceScope  = provider.ReceivedContext.Resources[0];
            var secondResourceScope = provider.ReceivedContext.Resources[1];

            // Assert first resource scope:
            Assert.Equal("repository", firstResourceScope.Type);
            Assert.Equal("test/my-app", firstResourceScope.Name);
            Assert.True(firstResourceScope.Actions.Length == 2);
            Assert.Equal("pull", firstResourceScope.Actions[0]);
            Assert.Equal("push", firstResourceScope.Actions[1]);

            // Assert second resource scope:
            Assert.Equal("repository", secondResourceScope.Type);
            Assert.Equal("test/my-app2", secondResourceScope.Name);
            Assert.True(secondResourceScope.Actions.Length == 1);
            Assert.Equal("pull", secondResourceScope.Actions[0]);
        }
        public async Task Credentials_MustBeSpecified()
        {
            // Arrange:
            var resourceModel   = new AuthResourceModel {
            };
            var credentialModel = new AuthCredentialModel {
                Api = "service-api", Credentials = null
            };
            var command = new AuthenticateCaller(credentialModel, resourceModel);

            var port = CreatePort(p => { });

            // Act:
            var result = await port.AuthenticateForService(command);

            // Assert:
            Assert.NotNull(result);
            Assert.True(result.IsInvalidCredentialContext);
            Assert.Equal("Invalid authentication context and/or credentials.", result.Reason);
            Assert.False(result.IsAuthenticated);
        }