public async Task RevokeRefreshTokens()
        {
            var customToken = await this.Auth.CreateCustomTokenAsync("testuser");

            var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                customToken, this.fixture.TenantId);

            await this.AssertValidIdTokenAsync(idToken, true);

            await Task.Delay(1000);

            await this.Auth.RevokeRefreshTokensAsync("testuser");

            await this.AssertValidIdTokenAsync(idToken);

            var exception = await Assert.ThrowsAsync <FirebaseAuthException>(
                () => this.Auth.VerifyIdTokenAsync(idToken, true));

            Assert.Equal(ErrorCode.InvalidArgument, exception.ErrorCode);
            Assert.Equal(AuthErrorCode.RevokedIdToken, exception.AuthErrorCode);

            idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                customToken, this.fixture.TenantId);

            await this.AssertValidIdTokenAsync(idToken, true);
        }
        public async Task CreateCustomTokenWithoutServiceAccount()
        {
            var googleCred  = FirebaseApp.DefaultInstance.Options.Credential;
            var serviceAcct = (ServiceAccountCredential)googleCred.UnderlyingCredential;
            var token       = await((ITokenAccess)googleCred).GetAccessTokenForRequestAsync();
            var app         = FirebaseApp.Create(
                new AppOptions()
            {
                Credential       = GoogleCredential.FromAccessToken(token),
                ServiceAccountId = serviceAcct.Id,
                ProjectId        = serviceAcct.ProjectId,
            }, "IAMSignApp");

            try
            {
                var auth = this.fixture.AuthFromApp(app);

                var customToken = await this.Auth.CreateCustomTokenAsync("testuser");

                var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                    customToken, this.fixture.TenantId);

                await this.AssertValidIdTokenAsync(idToken);
            }
            finally
            {
                app.Delete();
            }
        }
        public async Task PasswordResetLink()
        {
            var user = await this.userBuilder.CreateRandomUserAsync();

            var link = await this.Auth.GeneratePasswordResetLinkAsync(
                user.Email, EmailLinkSettings);

            var uri   = new Uri(link);
            var query = HttpUtility.ParseQueryString(uri.Query);

            Assert.Equal(ContinueUrl, query["continueUrl"]);

            var request = new ResetPasswordRequest()
            {
                Email       = user.Email,
                OldPassword = "******",
                NewPassword = "******",
                OobCode     = query["oobCode"],
                TenantId    = this.fixture.TenantId,
            };
            var resetEmail = await AuthIntegrationUtils.ResetPasswordAsync(request);

            Assert.Equal(user.Email, resetEmail);

            // Password reset also verifies the user's email
            user = await this.Auth.GetUserAsync(user.Uid);

            Assert.True(user.EmailVerified);
        }
        public async Task VerifyIdTokenWithTenant()
        {
            var customToken = await this.Auth.CreateCustomTokenAsync("testuser");

            var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                customToken, this.Auth.TenantId);

            // Verifies in FirebaseAuth
            var decoded = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);

            Assert.Equal(this.Auth.TenantId, decoded.TenantId);

            // Verifies in TenantAwareFirebaseAuth(matching-tenant)
            decoded = await this.Auth.VerifyIdTokenAsync(idToken);

            Assert.Equal(this.Auth.TenantId, decoded.TenantId);

            // Does not verify in TenantAwareFirebaseAuth(other-tenant)
            var otherTenantAuth = FirebaseAuth.DefaultInstance.TenantManager
                                  .AuthForTenant("other-tenant");
            var exception = await Assert.ThrowsAsync <FirebaseAuthException>(
                () => otherTenantAuth.VerifyIdTokenAsync(idToken));

            Assert.Equal(AuthErrorCode.TenantIdMismatch, exception.AuthErrorCode);
        }
        public async Task CreateCustomToken()
        {
            var customToken = await this.Auth.CreateCustomTokenAsync("testuser");

            var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                customToken, this.fixture.TenantId);

            await this.AssertValidIdTokenAsync(idToken);
        }
Exemple #6
0
        public OidcProviderConfigFixture()
        {
            var providerId = $"oidc.{AuthIntegrationUtils.GetRandomIdentifier()}";
            var args       = new OidcProviderConfigArgs
            {
                ProviderId  = providerId,
                DisplayName = "OIDC_DISPLAY_NAME",
                Enabled     = true,
                ClientId    = "OIDC_CLIENT_ID",
                Issuer      = "https://oidc.com/issuer",
            };

            this.ProviderConfig = this.Auth.CreateProviderConfigAsync(args).Result;
        }
Exemple #7
0
        public SamlProviderConfigFixture()
        {
            var providerId = $"saml.{AuthIntegrationUtils.GetRandomIdentifier()}";
            var args       = new SamlProviderConfigArgs
            {
                ProviderId       = providerId,
                DisplayName      = "SAML_DISPLAY_NAME",
                Enabled          = true,
                IdpEntityId      = "IDP_ENTITY_ID",
                SsoUrl           = "https://example.com/login",
                X509Certificates = new List <string> {
                    X509Certificates[0]
                },
                RpEntityId  = "RP_ENTITY_ID",
                CallbackUrl = "https://projectId.firebaseapp.com/__/auth/handler",
            };

            this.ProviderConfig = this.Auth.CreateProviderConfigAsync(args).Result;
        }
        public async Task LastRefreshTime()
        {
            var newUserRecord = await this.userBuilder.CreateRandomUserAsync();

            // New users should not have a LastRefreshTimestamp set.
            Assert.Null(newUserRecord.UserMetaData.LastRefreshTimestamp);

            // Login to cause the LastRefreshTimestamp to be set.
            await AuthIntegrationUtils.SignInWithPasswordAsync(
                newUserRecord.Email, "password", this.fixture.TenantId);

            // Attempt to retrieve the user 3 times (with a small delay between each attempt).
            // Occassionally, this call retrieves the user data without the
            // lastLoginTime/lastRefreshTime set; possibly because it's hitting a different
            // server than the login request uses.
            UserRecord userRecord = null;

            for (int i = 0; i < 3; i++)
            {
                userRecord = await this.Auth.GetUserAsync(newUserRecord.Uid);

                if (userRecord.UserMetaData.LastRefreshTimestamp != null)
                {
                    break;
                }

                await Task.Delay(1000 *(int)Math.Pow(2, i));
            }

            // Ensure the LastRefreshTimstamp is approximately "now" (with a tollerance of 10 minutes).
            var now = DateTime.UtcNow;
            int tolleranceMinutes = 10;
            var minTime           = now.AddMinutes(-tolleranceMinutes);
            var maxTime           = now.AddMinutes(tolleranceMinutes);

            Assert.NotNull(userRecord.UserMetaData.LastRefreshTimestamp);
            Assert.InRange(
                userRecord.UserMetaData.LastRefreshTimestamp.Value,
                minTime,
                maxTime);
        }
Exemple #9
0
        public async Task SessionCookie()
        {
            var customToken = await this.Auth.CreateCustomTokenAsync("testuser");

            var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(customToken);

            var options = new SessionCookieOptions()
            {
                ExpiresIn = TimeSpan.FromHours(1),
            };

            var sessionCookie = await this.Auth.CreateSessionCookieAsync(idToken, options);

            var decoded = await this.Auth.VerifySessionCookieAsync(sessionCookie);

            Assert.Equal("testuser", decoded.Uid);

            await Task.Delay(1000);

            await this.Auth.RevokeRefreshTokensAsync("testuser");

            decoded = await this.Auth.VerifySessionCookieAsync(sessionCookie);

            Assert.Equal("testuser", decoded.Uid);

            var exception = await Assert.ThrowsAsync <FirebaseAuthException>(
                async() => await this.Auth.VerifySessionCookieAsync(
                    sessionCookie, true));

            Assert.Equal(ErrorCode.InvalidArgument, exception.ErrorCode);
            Assert.Equal(AuthErrorCode.RevokedSessionCookie, exception.AuthErrorCode);

            idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(customToken);

            sessionCookie = await this.Auth.CreateSessionCookieAsync(idToken, options);

            decoded = await this.Auth.VerifySessionCookieAsync(sessionCookie, true);

            Assert.Equal("testuser", decoded.Uid);
        }
        public async Task SignInWithEmailLink()
        {
            var user = await this.userBuilder.CreateRandomUserAsync();

            var link = await this.Auth.GenerateSignInWithEmailLinkAsync(
                user.Email, EmailLinkSettings);

            var uri   = new Uri(link);
            var query = HttpUtility.ParseQueryString(uri.Query);

            Assert.Equal(ContinueUrl, query["continueUrl"]);

            var idToken = await AuthIntegrationUtils.SignInWithEmailLinkAsync(
                user.Email, query["oobCode"], this.fixture.TenantId);

            Assert.NotEmpty(idToken);

            // Sign in with link also verifies the user's email
            user = await this.Auth.GetUserAsync(user.Uid);

            Assert.True(user.EmailVerified);
        }
        public async Task CreateCustomTokenWithClaims()
        {
            var developerClaims = new Dictionary <string, object>()
            {
                { "admin", true },
                { "package", "gold" },
                { "magicNumber", 42L },
            };

            var customToken = await this.Auth.CreateCustomTokenAsync("testuser", developerClaims);

            var idToken = await AuthIntegrationUtils.SignInWithCustomTokenAsync(
                customToken, this.fixture.TenantId);

            var decoded = await this.AssertValidIdTokenAsync(idToken);

            foreach (var entry in developerClaims)
            {
                object value;
                Assert.True(decoded.Claims.TryGetValue(entry.Key, out value));
                Assert.Equal(entry.Value, value);
            }
        }
        public async Task ImportUsersWithPassword()
        {
            var randomUser = TemporaryUserBuilder.RandomUserRecordArgs();
            var args       = new ImportUserRecordArgs()
            {
                Uid           = randomUser.Uid,
                Email         = randomUser.Email,
                DisplayName   = "Random User",
                PhotoUrl      = "https://example.com/photo.png",
                EmailVerified = true,
                PasswordSalt  = Encoding.ASCII.GetBytes("NaCl"),
                PasswordHash  = Convert.FromBase64String("V358E8LdWJXAO7muq0CufVpEOXaj8aFiC7"
                                                         + "T/rcaGieN04q/ZPJ08WhJEHGjj9lz/2TT+/86N5VjVoc5DdBhBiw=="),
                CustomClaims = new Dictionary <string, object>()
                {
                    { "admin", true },
                },
                UserProviders = new List <UserProvider>
                {
                    new UserProvider()
                    {
                        Uid         = randomUser.Uid,
                        Email       = randomUser.Email,
                        DisplayName = "John Doe",
                        PhotoUrl    = "http://example.com/123/photo.png",
                        ProviderId  = "google.com",
                    },
                    new UserProvider()
                    {
                        Uid         = "fb.uid",
                        Email       = "*****@*****.**",
                        DisplayName = "John Doe",
                        PhotoUrl    = "http://example.com/123/photo.png",
                        ProviderId  = "facebook.com",
                    },
                },
            };

            var options = new UserImportOptions()
            {
                Hash = new Scrypt()
                {
                    Key = Convert.FromBase64String("jxspr8Ki0RYycVU8zykbdLGjFQ3McFUH0uiiTvC"
                                                   + "8pVMXAn210wjLNmdZJzxUECKbm0QsEmYUSDzZvpjeJ9WmXA=="),
                    SaltSeparator = Convert.FromBase64String("Bw=="),
                    Rounds        = 8,
                    MemoryCost    = 14,
                },
            };
            var usersLst = new List <ImportUserRecordArgs>()
            {
                args
            };

            var resp = await this.Auth.ImportUsersAsync(usersLst, options);

            this.userBuilder.AddUid(randomUser.Uid);

            Assert.Equal(1, resp.SuccessCount);
            Assert.Equal(0, resp.FailureCount);

            var user = await this.Auth.GetUserAsync(randomUser.Uid);

            Assert.Equal(randomUser.Email, user.Email);
            var idToken = await AuthIntegrationUtils.SignInWithPasswordAsync(
                randomUser.Email, "password", this.fixture.TenantId);

            Assert.False(string.IsNullOrEmpty(idToken));
        }