public async Task DefaultSecurityToken_V1_ValidatedDontGetUserInfoClaim()
        {
            var testEmail = "*****@*****.**";

            var vippsLoginService = A.Fake <IVippsLoginService>();

            A.CallTo(() => vippsLoginService.GetVippsUserInfo(A <ClaimsIdentity> ._))
            .Returns(new VippsUserInfo
            {
                Email = testEmail
            });


            // No contact with subject guid
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            await notifications.DefaultSecurityTokenValidated(context);

            A.CallTo(() => vippsLoginService.GetUserInfoClaims(A <string> ._, A <string> ._))
            .MustNotHaveHappened();
        }
        public async Task DefaultSecurityTokenValidatedSetsEmailAsNameClaim()
        {
            var testEmail            = "*****@*****.**";
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(new CustomerContact()
            {
                UserId = testEmail
            });

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            await notifications.DefaultSecurityTokenValidated(context);

            Assert.True(
                context.AuthenticationTicket.Identity.HasClaim(
                    context.AuthenticationTicket.Identity.NameClaimType,
                    testEmail)
                );
        }
        public async Task DefaultSecurityTokenValidatedThrowsIfNoUserIdFound()
        {
            var testEmail = "*****@*****.**";

            var vippsLoginService = A.Fake <IVippsLoginService>();

            // No contact with subject guid
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            var exception = await Assert.ThrowsAsync <VippsLoginException>(async() =>
                                                                           await notifications.DefaultSecurityTokenValidated(context));
        }
        public async Task DefaultSecurityTokenThrowsIfNoLinkedAccountFound()
        {
            var linkAccountGuid      = Guid.NewGuid();
            var testEmail            = "*****@*****.**";
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContactByLinkAccountToken(linkAccountGuid))
            .Returns(null);
            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            context.AuthenticationTicket.Properties.Dictionary.Add(VippsConstants.LinkAccount,
                                                                   linkAccountGuid.ToString());

            var exception = await Assert.ThrowsAsync <VippsLoginLinkAccountException>(async() =>
                                                                                      await notifications.DefaultSecurityTokenValidated(context));

            Assert.False(exception.UserError);
        }
        public async Task DefaultSecurityTokenValidatedSetsLinkedAccountEmailAsNameClaim()
        {
            var linkAccountGuid      = Guid.NewGuid();
            var testEmail            = "*****@*****.**";
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContactByLinkAccountToken(linkAccountGuid))
            .Returns(new CustomerContact()
            {
                UserId = testEmail
            });
            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            context.AuthenticationTicket.Properties.Dictionary.Add(VippsConstants.LinkAccount,
                                                                   linkAccountGuid.ToString());

            await notifications.DefaultSecurityTokenValidated(context);

            Assert.True(
                context.AuthenticationTicket.Identity.HasClaim(
                    context.AuthenticationTicket.Identity.NameClaimType,
                    testEmail)
                );
        }
        public async Task RedirectToIdentityProviderDoesNotReturn403ForLinkAccount()
        {
            var notifications = new VippsEpiNotifications(
                A.Fake <HttpClient>(),
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                A.Fake <IVippsLoginCommerceService>(),
                A.Fake <IVippsLoginSanityCheck>(),
                A.Fake <MapUserKey>());

            var configurationManager =
                A.Fake <IConfigurationManager <OpenIdConnectConfiguration> >();

            A.CallTo(() => configurationManager.GetConfigurationAsync(A <CancellationToken> ._))
            .Returns(new OpenIdConnectConfiguration());

            var context  = A.Fake <IOwinContext>();
            var response = new OwinResponse()
            {
                StatusCode = 401
            };

            A.CallTo(() => context.Response).Returns(response);
            var request = A.Fake <IOwinRequest>();

            A.CallTo(() => request.Uri).ReturnsLazily(() => new Uri("https://test.com/asdf"));
            A.CallTo(() => context.Request).Returns(request);

            var properties = new AuthenticationProperties();

            properties.Dictionary.Add(VippsConstants.LinkAccount, VippsConstants.LinkAccount);
            A.CallTo(() => context.Authentication.AuthenticationResponseChallenge)
            .Returns(new AuthenticationResponseChallenge(new[] { "" }, properties));

            var notification =
                new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(
                    context,
                    new VippsOpenIdConnectAuthenticationOptions("clientId", "clientSecret", "authority")
            {
                ConfigurationManager = configurationManager
            })
            {
                ProtocolMessage = new OpenIdConnectMessage()
            };

            await notifications.RedirectToIdentityProvider(notification);

            Assert.NotEqual(403, response.StatusCode);
        }
        public async Task DefaultSecurityTokenValidatedSetsFirstCustomerAsNameClaim()
        {
            var testEmail       = "*****@*****.**";
            var testPhoneNumber = "0612345678";

            var vippsLoginService = A.Fake <IVippsLoginService>();

            A.CallTo(() => vippsLoginService.GetVippsUserInfo(A <ClaimsIdentity> ._))
            .Returns(new VippsUserInfo
            {
                Email       = testEmail,
                PhoneNumber = testPhoneNumber
            });

            // No contact with subject guid
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            // Find with phone or by email
            A.CallTo(() => vippsCommerceService.FindCustomerContacts(testEmail, testPhoneNumber))
            .Returns(new[] { new CustomerContact {
                                 UserId = testEmail
                             } });

            var sanityCheck = A.Fake <IVippsLoginSanityCheck>();

            A.CallTo(() => sanityCheck.IsValidContact(A <CustomerContact> ._, A <VippsUserInfo> ._))
            .Returns(true);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                vippsCommerceService,
                sanityCheck,
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            await notifications.DefaultSecurityTokenValidated(context);

            Assert.True(
                context.AuthenticationTicket.Identity.HasClaim(
                    context.AuthenticationTicket.Identity.NameClaimType,
                    testEmail)
                );
        }
        public async Task DefaultSecurityTokenValidatedRewritesRedirectUriToLocal()
        {
            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                A.Fake <IVippsLoginCommerceService>(),
                A.Fake <IVippsLoginSanityCheck>(),
                A.Fake <MapUserKey>()
                );

            var context = CreateContext();
            await notifications.DefaultSecurityTokenValidated(context);

            Assert.Equal("/redirect-url", context.AuthenticationTicket.Properties.RedirectUri);
        }
        public async Task DefaultSecurityTokenValidatedThrowsIfUserInfoIsNull()
        {
            var vippsLoginService = A.Fake <IVippsLoginService>();

            A.CallTo(() => vippsLoginService.GetVippsUserInfo(A <ClaimsIdentity> ._)).Returns(null);
            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                A.Fake <IVippsLoginCommerceService>(),
                A.Fake <IVippsLoginSanityCheck>(),
                A.Fake <MapUserKey>()
                );

            await Assert.ThrowsAsync <VippsLoginException>(async() =>
                                                           await notifications.DefaultSecurityTokenValidated(CreateContext()));
        }
        public async Task RedirectToIdentityProviderReturns403()
        {
            var notifications = new VippsEpiNotifications(
                A.Fake <HttpClient>(),
                A.Fake <ISynchronizingUserService>(),
                A.Fake <IVippsLoginService>(),
                A.Fake <IVippsLoginCommerceService>(),
                A.Fake <IVippsLoginSanityCheck>(),
                A.Fake <MapUserKey>());

            var configurationManager =
                A.Fake <IConfigurationManager <OpenIdConnectConfiguration> >();

            A.CallTo(() => configurationManager.GetConfigurationAsync(A <CancellationToken> ._))
            .Returns(new OpenIdConnectConfiguration());

            var context  = A.Fake <IOwinContext>();
            var response = new OwinResponse()
            {
                StatusCode = 401
            };

            A.CallTo(() => context.Response).Returns(response);
            var request = A.Fake <IOwinRequest>();

            A.CallTo(() => request.Uri).ReturnsLazily(() => new Uri("https://test.com/asdf"));
            A.CallTo(() => context.Request).Returns(request);

            var user = A.Fake <ClaimsPrincipal>();

            A.CallTo(() => context.Authentication.User).Returns(user);
            A.CallTo(() => user.Identity.IsAuthenticated).Returns(true);

            var notification =
                new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(
                    context,
                    new VippsOpenIdConnectAuthenticationOptions("clientId", "clientSecret", "authority")
            {
                ConfigurationManager = configurationManager
            })
            {
                ProtocolMessage = new OpenIdConnectMessage()
            };
            await notifications.RedirectToIdentityProvider(notification);

            Assert.Equal(403, response.StatusCode);
        }
        public async Task DefaultSecurityTokenValidated_V2_GetUserInfoClaims()
        {
            var testEmail = "*****@*****.**";

            var testClaimName  = "testClaimName";
            var testClaimValue = "testClaimValue";

            var vippsLoginService = A.Fake <IVippsLoginService>();

            A.CallTo(() => vippsLoginService.GetUserInfoClaims(A <string> ._, A <string> ._))
            .Returns(Task.FromResult <IEnumerable <Claim> >(new List <Claim>
            {
                new Claim(testClaimName, testClaimValue)
            }));

            A.CallTo(() => vippsLoginService.GetVippsUserInfo(A <ClaimsIdentity> ._))
            .Returns(new VippsUserInfo
            {
                Email = testEmail
            });
            // No contact with subject guid
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                vippsCommerceService,
                A.Fake <IVippsLoginSanityCheck>(),
                GetMapUserKey(testEmail)
                );

            var context = CreateContext(scope: VippsScopes.ApiV2);

            await notifications.DefaultSecurityTokenValidated(context);

            A.CallTo(() => vippsLoginService.GetUserInfoClaims(A <string> ._, A <string> ._))
            .MustHaveHappenedOnceExactly();
            Assert.True(
                context.AuthenticationTicket.Identity.HasClaim(
                    testClaimName,
                    testClaimValue)
                );
        }
        public async Task DefaultSecurityTokenValidatedThrowsIfSanityCheckFails()
        {
            var testEmail       = "*****@*****.**";
            var testPhoneNumber = "0612345678";

            var vippsLoginService = A.Fake <IVippsLoginService>();

            A.CallTo(() => vippsLoginService.GetVippsUserInfo(A <ClaimsIdentity> ._))
            .Returns(new VippsUserInfo
            {
                Email       = testEmail,
                PhoneNumber = testPhoneNumber
            });

            // No contact with subject guid
            var vippsCommerceService = A.Fake <IVippsLoginCommerceService>();

            A.CallTo(() => vippsCommerceService.FindCustomerContact(A <Guid> ._))
            .Returns(null);

            // Find with phone or by email
            A.CallTo(() => vippsCommerceService.FindCustomerContacts(testEmail, testPhoneNumber))
            .Returns(new[] { new CustomerContact {
                                 UserId = testEmail
                             } });

            // Failing sanity check
            var sanityCheck = A.Fake <IVippsLoginSanityCheck>();

            A.CallTo(() => sanityCheck.IsValidContact(A <CustomerContact> ._, A <VippsUserInfo> ._))
            .Returns(false);

            var notifications = new VippsEpiNotifications(
                A.Fake <ISynchronizingUserService>(),
                vippsLoginService,
                vippsCommerceService,
                sanityCheck,
                GetMapUserKey(testEmail)
                );

            var context = CreateContext();

            await Assert.ThrowsAsync <VippsLoginSanityCheckException>(async() =>
                                                                      await notifications.DefaultSecurityTokenValidated(context));
        }