diff --git a/app/app_resources/build.gradle b/app/app_resources/build.gradle index 1bab2ab974..66b5d152c4 100644 --- a/app/app_resources/build.gradle +++ b/app/app_resources/build.gradle @@ -47,6 +47,9 @@ android { } } } + lintOptions { + abortOnError false + } } dependencies { diff --git a/app/google_api_resources/build.gradle b/app/google_api_resources/build.gradle index 368b6dd157..f47ccf3263 100644 --- a/app/google_api_resources/build.gradle +++ b/app/google_api_resources/build.gradle @@ -50,6 +50,9 @@ android { } } } + lintOptions { + abortOnError false + } } dependencies { diff --git a/app/invites_resources/build.gradle b/app/invites_resources/build.gradle index e4903e3716..785c926eaf 100644 --- a/app/invites_resources/build.gradle +++ b/app/invites_resources/build.gradle @@ -46,6 +46,9 @@ android { } } } + lintOptions { + abortOnError false + } } dependencies { diff --git a/app_check/app_check_resources/build.gradle b/app_check/app_check_resources/build.gradle index 744d8edcaa..507b7f994e 100644 --- a/app_check/app_check_resources/build.gradle +++ b/app_check/app_check_resources/build.gradle @@ -46,6 +46,9 @@ android { } } } + lintOptions { + abortOnError false + } } dependencies { diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 7b588dbb9b..a5e0945aaa 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -43,6 +43,10 @@ using util::JniStringToString; "()Ljava/lang/String;"), \ X(SetLanguageCode, "setLanguageCode", \ "(Ljava/lang/String;)V"), \ + X(GetTenantId, "getTenantId", \ + "()Ljava/lang/String;"), \ + X(SetTenantId, "setTenantId", \ + "(Ljava/lang/String;)V"), \ X(UseAppLanguage, "useAppLanguage", "()V"), \ X(AddAuthStateListener, "addAuthStateListener", \ "(Lcom/google/firebase/auth/FirebaseAuth$AuthStateListener;)V"), \ @@ -756,6 +760,34 @@ void Auth::set_language_code(const char* language_code) { } } +std::string Auth::tenant_id() const { + if (!auth_data_) return nullptr; + JNIEnv* env = Env(auth_data_); + jobject j_pending_result = env->CallObjectMethod( + AuthImpl(auth_data_), auth::GetMethodId(auth::kGetTenantId)); + if (firebase::util::CheckAndClearJniExceptions(env) || + j_pending_result == nullptr) { + return nullptr; + } + return util::JniStringToString(env, j_pending_result); +} + +void Auth::set_tenant_id(const char* tenant_id) { + if (!auth_data_) return; + JNIEnv* env = Env(auth_data_); + jstring j_tenant_id = nullptr; + if (tenant_id != nullptr) { + j_tenant_id = env->NewStringUTF(tenant_id); + } + env->CallVoidMethod(AuthImpl(auth_data_), + auth::GetMethodId(auth::kSetTenantId), + j_tenant_id); + firebase::util::CheckAndClearJniExceptions(env); + if (j_tenant_id != nullptr) { + env->DeleteLocalRef(j_tenant_id); + } +} + void Auth::UseAppLanguage() { if (!auth_data_) return; JNIEnv* env = Env(auth_data_); diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index e4251b43ae..01f4a92e40 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -372,7 +372,8 @@ Future Auth::SignInWithCustomToken(const char* custom_token) { // Note: std::make_unique is not supported by Visual Studio 2012, which is // among our target compilers. auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_), custom_token)); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), + custom_token, GetTenantId(*auth_data_))); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow); @@ -391,7 +392,7 @@ Future Auth::SignInWithCustomToken_DEPRECATED( // Note: std::make_unique is not supported by Visual Studio 2012, which is // among our target compilers. auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_), custom_token)); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), custom_token, nullptr)); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow_DEPRECATED); @@ -468,7 +469,8 @@ Future Auth::SignInAnonymously() { typedef SignUpNewUserRequest RequestT; auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_))); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), + nullptr, nullptr, nullptr, GetTenantId(*auth_data_))); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow); @@ -493,7 +495,8 @@ Future Auth::SignInAnonymously_DEPRECATED() { typedef SignUpNewUserRequest RequestT; auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_))); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), + GetTenantId(*auth_data_))); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow_DEPRECATED); @@ -509,7 +512,8 @@ Future Auth::SignInWithEmailAndPassword( typedef VerifyPasswordRequest RequestT; auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email, password)); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), + email, password, GetTenantId(*auth_data_))); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow); @@ -525,7 +529,8 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( typedef VerifyPasswordRequest RequestT; auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email, password)); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), + email, password, nullptr)); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow_DEPRECATED); @@ -542,7 +547,7 @@ Future Auth::CreateUserWithEmailAndPassword( typedef SignUpNewUserRequest RequestT; auto request = std::unique_ptr( // NOLINT new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email, password, - "")); + "", GetTenantId(*auth_data_))); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow); @@ -559,7 +564,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( typedef SignUpNewUserRequest RequestT; auto request = std::unique_ptr( // NOLINT new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email, password, - "")); + "", nullptr)); return CallAsync(auth_data_, promise, std::move(request), PerformSignInFlow_DEPRECATED); @@ -592,7 +597,8 @@ Future Auth::FetchProvidersForEmail( typedef CreateAuthUriRequest RequestT; auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email)); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), email, + GetTenantId(*auth_data_))); const auto callback = [](AuthDataHandle* handle) { @@ -709,6 +715,23 @@ void Auth::set_language_code(const char* language_code) { auth_impl->language_code = code; } +void Auth::set_tenant_id(const char* tenant_id) { + if (!auth_data_) return; + + auto auth_impl = static_cast(auth_data_->auth_impl); + std::string code; + if (tenant_id != nullptr) { + code.assign(tenant_id); + } + auth_impl->tenant_id = code; +} + +std::string Auth::tenant_id() const { + if (!auth_data_) return nullptr; + auto auth_impl = static_cast(auth_data_->auth_impl); + return auth_impl->tenant_id; +} + void Auth::UseAppLanguage() { if (!auth_data_) return; auto auth_impl = static_cast(auth_data_->auth_impl); diff --git a/auth/src/desktop/auth_desktop.h b/auth/src/desktop/auth_desktop.h index 67639fef0a..190c741eed 100644 --- a/auth/src/desktop/auth_desktop.h +++ b/auth/src/desktop/auth_desktop.h @@ -187,6 +187,9 @@ struct AuthImpl { // The current user language code. This can be set to the app’s current // language by calling SetLanguageCode. std::string language_code; + + // The tenant id used for multi tenant authentication + std::string tenant_id; }; // Constant, describing how often we automatically fetch a new auth token. diff --git a/auth/src/desktop/auth_providers/facebook_auth_credential.h b/auth/src/desktop/auth_providers/facebook_auth_credential.h index 37c30fec35..f31059442d 100644 --- a/auth/src/desktop/auth_providers/facebook_auth_credential.h +++ b/auth/src/desktop/auth_providers/facebook_auth_credential.h @@ -34,9 +34,10 @@ class FacebookAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return kFacebookAuthProviderId; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, + char const* tenant_id) const override { return VerifyAssertionRequest::FromAccessToken( - app, api_key, GetProvider().c_str(), access_token_.c_str()); + app, api_key, GetProvider().c_str(), access_token_.c_str(), tenant_id); } private: diff --git a/auth/src/desktop/auth_providers/github_auth_credential.h b/auth/src/desktop/auth_providers/github_auth_credential.h index 27fc52ae41..10d15810f9 100644 --- a/auth/src/desktop/auth_providers/github_auth_credential.h +++ b/auth/src/desktop/auth_providers/github_auth_credential.h @@ -34,9 +34,10 @@ class GitHubAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return kGitHubAuthProviderId; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, + const char* tenant_id) const override { return VerifyAssertionRequest::FromAccessToken( - app, api_key, GetProvider().c_str(), token_.c_str()); + app, api_key, GetProvider().c_str(), token_.c_str(), tenant_id); } private: diff --git a/auth/src/desktop/auth_providers/google_auth_credential.h b/auth/src/desktop/auth_providers/google_auth_credential.h index a8d11ba7cc..ac1a9f405b 100644 --- a/auth/src/desktop/auth_providers/google_auth_credential.h +++ b/auth/src/desktop/auth_providers/google_auth_credential.h @@ -34,13 +34,14 @@ class GoogleAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return kGoogleAuthProviderId; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, + const char* tenant_id) const override { if (!id_token_.empty()) { return VerifyAssertionRequest::FromIdToken( - app, api_key, GetProvider().c_str(), id_token_.c_str()); + app, api_key, GetProvider().c_str(), id_token_.c_str(), tenant_id); } else { return VerifyAssertionRequest::FromAccessToken( - app, api_key, GetProvider().c_str(), access_token_.c_str()); + app, api_key, GetProvider().c_str(), access_token_.c_str(), tenant_id); } } diff --git a/auth/src/desktop/auth_providers/oauth_auth_credential.h b/auth/src/desktop/auth_providers/oauth_auth_credential.h index 72dedb0e4f..51e72b0a02 100644 --- a/auth/src/desktop/auth_providers/oauth_auth_credential.h +++ b/auth/src/desktop/auth_providers/oauth_auth_credential.h @@ -34,15 +34,18 @@ class OAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return provider_id_; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, + const char* tenant_id) const override { const char* raw_nonce = (!raw_nonce_.empty()) ? raw_nonce_.c_str() : nullptr; if (!id_token_.empty()) { return VerifyAssertionRequest::FromIdToken( - app, api_key, provider_id_.c_str(), id_token_.c_str(), raw_nonce); + app, api_key, provider_id_.c_str(), id_token_.c_str(), raw_nonce, + tenant_id); } else { return VerifyAssertionRequest::FromAccessToken( - app, api_key, provider_id_.c_str(), access_token_.c_str(), raw_nonce); + app, api_key, provider_id_.c_str(), access_token_.c_str(), raw_nonce, + tenant_id); } } diff --git a/auth/src/desktop/auth_providers/playgames_auth_credential.h b/auth/src/desktop/auth_providers/playgames_auth_credential.h index 0642fc4170..965c21dfa3 100644 --- a/auth/src/desktop/auth_providers/playgames_auth_credential.h +++ b/auth/src/desktop/auth_providers/playgames_auth_credential.h @@ -34,9 +34,9 @@ class PlayGamesAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return kPlayGamesAuthProviderId; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, const char* tenant_id) const override { return VerifyAssertionRequest::FromAuthCode( - app, api_key, GetProvider().c_str(), server_auth_code_.c_str()); + app, api_key, GetProvider().c_str(), server_auth_code_.c_str(), tenant_id); } private: diff --git a/auth/src/desktop/auth_providers/twitter_auth_credential.h b/auth/src/desktop/auth_providers/twitter_auth_credential.h index 81043c3ed8..542df9f288 100644 --- a/auth/src/desktop/auth_providers/twitter_auth_credential.h +++ b/auth/src/desktop/auth_providers/twitter_auth_credential.h @@ -34,9 +34,11 @@ class TwitterAuthCredential : public IdentityProviderCredential { std::string GetProvider() const override { return kTwitterAuthProviderId; } std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* const api_key) const override { + ::firebase::App& app, const char* const api_key, + const char* tenant_id) const override { return VerifyAssertionRequest::FromAccessTokenAndOAuthSecret( - app, api_key, GetProvider().c_str(), token_.c_str(), secret_.c_str()); + app, api_key, GetProvider().c_str(), token_.c_str(), secret_.c_str(), + tenant_id); } private: diff --git a/auth/src/desktop/auth_util.cc b/auth/src/desktop/auth_util.cc index 4c0d2334e9..f2c47d0b96 100644 --- a/auth/src/desktop/auth_util.cc +++ b/auth/src/desktop/auth_util.cc @@ -29,6 +29,15 @@ const char* GetApiKey(const AuthData& auth_data) { return static_cast(auth_data.auth_impl)->api_key.c_str(); } +const char* GetTenantId(const AuthData& auth_data){ + FIREBASE_ASSERT_RETURN(nullptr, auth_data.auth_impl); + auto auth_impl = static_cast(auth_data.auth_impl); + if (auth_impl->tenant_id.empty()){ + return auth_impl->tenant_id.c_str(); + } + return nullptr; +} + void CompletePromise(Promise* const promise, const SignInResult& sign_in_result) { FIREBASE_ASSERT_RETURN_VOID(promise); diff --git a/auth/src/desktop/auth_util.h b/auth/src/desktop/auth_util.h index 6ff7d090e2..237edfd0e7 100644 --- a/auth/src/desktop/auth_util.h +++ b/auth/src/desktop/auth_util.h @@ -44,6 +44,9 @@ using firebase::callback::NewCallback; const char* GetApiKey(const AuthData& auth_data); +const char* GetTenantId(const AuthData& auth_data); + + /// @deprecated // Completes the given promise by translating the AuthenticationResult. If the // AuthenticationResult is successful, promise will be completed successfully diff --git a/auth/src/desktop/credential_util.cc b/auth/src/desktop/credential_util.cc index 0b573a78a9..3255fefb89 100644 --- a/auth/src/desktop/credential_util.cc +++ b/auth/src/desktop/credential_util.cc @@ -31,7 +31,8 @@ std::unique_ptr CreateVerifyAssertionRequest( const auto* idp_credential = static_cast( credential_impl->auth_credential.get()); return idp_credential->CreateVerifyAssertionRequest(*auth_data.app, - GetApiKey(auth_data)); + GetApiKey(auth_data), + GetTenantId(auth_data)); } std::unique_ptr CreateRequestFromCredential( @@ -48,7 +49,8 @@ std::unique_ptr CreateRequestFromCredential( return std::unique_ptr( // NOLINT new VerifyPasswordRequest(*auth_data->app, GetApiKey(*auth_data), email_credential->GetEmail().c_str(), - email_credential->GetPassword().c_str())); + email_credential->GetPassword().c_str(), + GetTenantId(*auth_data))); } return CreateVerifyAssertionRequest(*auth_data, raw_credential); diff --git a/auth/src/desktop/identity_provider_credential.h b/auth/src/desktop/identity_provider_credential.h index 89a8137e4a..ef8fa14ad5 100644 --- a/auth/src/desktop/identity_provider_credential.h +++ b/auth/src/desktop/identity_provider_credential.h @@ -41,7 +41,7 @@ namespace auth { class IdentityProviderCredential : public AuthCredential { public: virtual std::unique_ptr CreateVerifyAssertionRequest( - ::firebase::App& app, const char* api_key) const = 0; + ::firebase::App& app, const char* api_key, const char* tenant_id) const = 0; }; } // namespace auth diff --git a/auth/src/desktop/rpcs/create_auth_uri_request.cc b/auth/src/desktop/rpcs/create_auth_uri_request.cc index 04ee9efc2e..63d133cc9e 100644 --- a/auth/src/desktop/rpcs/create_auth_uri_request.cc +++ b/auth/src/desktop/rpcs/create_auth_uri_request.cc @@ -23,7 +23,8 @@ namespace auth { CreateAuthUriRequest::CreateAuthUriRequest(::firebase::App& app, const char* api_key, - const char* identifier) + const char* identifier, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -42,6 +43,10 @@ CreateAuthUriRequest::CreateAuthUriRequest(::firebase::App& app, LogError("No identifier given."); } + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } + // This parameter is only relevant for the web SDK; for desktop, it can have // any value as long as it passes the backend validation for a valid URL. application_data_->continueUri = "http://localhost"; diff --git a/auth/src/desktop/rpcs/create_auth_uri_request.h b/auth/src/desktop/rpcs/create_auth_uri_request.h index e6db809ab8..613df7fe1a 100644 --- a/auth/src/desktop/rpcs/create_auth_uri_request.h +++ b/auth/src/desktop/rpcs/create_auth_uri_request.h @@ -28,7 +28,7 @@ namespace auth { class CreateAuthUriRequest : public AuthRequest { public: CreateAuthUriRequest(::firebase::App& app, const char* api_key, - const char* identifier); + const char* identifier, const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/rpcs/delete_account_request.cc b/auth/src/desktop/rpcs/delete_account_request.cc index efe3935738..49319b7197 100644 --- a/auth/src/desktop/rpcs/delete_account_request.cc +++ b/auth/src/desktop/rpcs/delete_account_request.cc @@ -21,7 +21,8 @@ namespace firebase { namespace auth { DeleteAccountRequest::DeleteAccountRequest(::firebase::App& app, - const char* const api_key) + const char* const api_key, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -34,6 +35,10 @@ DeleteAccountRequest::DeleteAccountRequest(::firebase::App& app, url.append(api_key); set_url(url.c_str()); + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } + UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/delete_account_request.h b/auth/src/desktop/rpcs/delete_account_request.h index c10cfd2361..6699633659 100644 --- a/auth/src/desktop/rpcs/delete_account_request.h +++ b/auth/src/desktop/rpcs/delete_account_request.h @@ -28,7 +28,8 @@ namespace auth { class DeleteAccountRequest : public AuthRequest { public: - explicit DeleteAccountRequest(::firebase::App& app, const char* api_key); + explicit DeleteAccountRequest(::firebase::App& app, const char* api_key, + const char* tenantId); void SetIdToken(const char* const id_token) { if (id_token) { diff --git a/auth/src/desktop/rpcs/get_account_info_request.cc b/auth/src/desktop/rpcs/get_account_info_request.cc index 0dad730f18..43c93d0245 100644 --- a/auth/src/desktop/rpcs/get_account_info_request.cc +++ b/auth/src/desktop/rpcs/get_account_info_request.cc @@ -21,17 +21,25 @@ namespace firebase { namespace auth { GetAccountInfoRequest::GetAccountInfoRequest(::firebase::App& app, - const char* const api_key) + const char* const api_key, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { SetUrl(api_key); + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } UpdatePostFields(); } GetAccountInfoRequest::GetAccountInfoRequest(::firebase::App& app, const char* const api_key, - const char* const id_token) + const char* const id_token, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { SetUrl(api_key); + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } SetIdToken(id_token); UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/get_account_info_request.h b/auth/src/desktop/rpcs/get_account_info_request.h index 24f0b52533..5eddc1e1f4 100644 --- a/auth/src/desktop/rpcs/get_account_info_request.h +++ b/auth/src/desktop/rpcs/get_account_info_request.h @@ -28,9 +28,10 @@ namespace auth { class GetAccountInfoRequest : public AuthRequest { public: - explicit GetAccountInfoRequest(::firebase::App& app, const char* api_key); + explicit GetAccountInfoRequest(::firebase::App& app, const char* api_key, + const char* tenant_id); GetAccountInfoRequest(::firebase::App& app, const char* api_key, - const char* id_token); + const char* id_token, const char* tenant_id); void SetIdToken(const char* const id_token) { // This is actually access token, named ID token for backward compatibility. diff --git a/auth/src/desktop/rpcs/get_oob_confirmation_code_request.cc b/auth/src/desktop/rpcs/get_oob_confirmation_code_request.cc index 3087837a6a..5642075ca6 100644 --- a/auth/src/desktop/rpcs/get_oob_confirmation_code_request.cc +++ b/auth/src/desktop/rpcs/get_oob_confirmation_code_request.cc @@ -21,7 +21,7 @@ namespace firebase { namespace auth { GetOobConfirmationCodeRequest::GetOobConfirmationCodeRequest( - ::firebase::App& app, const char* api_key) + ::firebase::App& app, const char* api_key, const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -32,14 +32,18 @@ GetOobConfirmationCodeRequest::GetOobConfirmationCodeRequest( url.reserve(strlen(api_host) + strlen(api_key)); url.append(api_host); url.append(api_key); + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } set_url(url.c_str()); } std::unique_ptr GetOobConfirmationCodeRequest::CreateSendEmailVerificationRequest( - ::firebase::App& app, const char* api_key, const char* language_code) { + ::firebase::App& app, const char* api_key, const char* language_code, + const char* tenant_id) { auto request = std::unique_ptr( // NOLINT - new GetOobConfirmationCodeRequest(app, api_key)); + new GetOobConfirmationCodeRequest(app, api_key, tenant_id)); request->application_data_->requestType = "VERIFY_EMAIL"; if (language_code != nullptr) { request->add_header(kHeaderFirebaseLocale, language_code); @@ -51,9 +55,9 @@ GetOobConfirmationCodeRequest::CreateSendEmailVerificationRequest( std::unique_ptr GetOobConfirmationCodeRequest::CreateSendPasswordResetEmailRequest( ::firebase::App& app, const char* api_key, const char* email, - const char* language_code) { + const char* language_code, const char* tenant_id) { auto request = std::unique_ptr( // NOLINT - new GetOobConfirmationCodeRequest(app, api_key)); + new GetOobConfirmationCodeRequest(app, api_key, tenant_id)); request->application_data_->requestType = "PASSWORD_RESET"; if (language_code != nullptr) { request->add_header(kHeaderFirebaseLocale, language_code); diff --git a/auth/src/desktop/rpcs/get_oob_confirmation_code_request.h b/auth/src/desktop/rpcs/get_oob_confirmation_code_request.h index 02c678a074..0869c64d97 100644 --- a/auth/src/desktop/rpcs/get_oob_confirmation_code_request.h +++ b/auth/src/desktop/rpcs/get_oob_confirmation_code_request.h @@ -32,12 +32,14 @@ class GetOobConfirmationCodeRequest : public AuthRequest { public: static std::unique_ptr CreateSendEmailVerificationRequest(::firebase::App& app, const char* api_key, - const char* language_code = nullptr); + const char* language_code = nullptr, + const char* tenant_id = nullptr); static std::unique_ptr CreateSendPasswordResetEmailRequest(::firebase::App& app, const char* api_key, const char* email, - const char* language_code = nullptr); + const char* language_code = nullptr, + const char* tenant_id = nullptr); void SetIdToken(const char* const id_token) { if (id_token) { @@ -50,7 +52,8 @@ class GetOobConfirmationCodeRequest : public AuthRequest { private: explicit GetOobConfirmationCodeRequest(::firebase::App& app, - const char* api_key); + const char* api_key, + const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/rpcs/request.fbs b/auth/src/desktop/rpcs/request.fbs index 4fafa6e64e..d190dae7e5 100644 --- a/auth/src/desktop/rpcs/request.fbs +++ b/auth/src/desktop/rpcs/request.fbs @@ -57,6 +57,8 @@ table Request { deleteProvider:[string]; nonce:string; + + tenantId:string; } root_type Request; diff --git a/auth/src/desktop/rpcs/reset_password_request.cc b/auth/src/desktop/rpcs/reset_password_request.cc index b8fc65654e..80d04da87f 100644 --- a/auth/src/desktop/rpcs/reset_password_request.cc +++ b/auth/src/desktop/rpcs/reset_password_request.cc @@ -24,7 +24,8 @@ namespace auth { ResetPasswordRequest::ResetPasswordRequest(::firebase::App& app, const char* api_key, const char* oob_code, - const char* new_password) + const char* new_password, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -47,6 +48,9 @@ ResetPasswordRequest::ResetPasswordRequest(::firebase::App& app, } else { LogError("No new password given."); } + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/reset_password_request.h b/auth/src/desktop/rpcs/reset_password_request.h index e31821fc4e..8292b82425 100644 --- a/auth/src/desktop/rpcs/reset_password_request.h +++ b/auth/src/desktop/rpcs/reset_password_request.h @@ -28,7 +28,8 @@ namespace auth { class ResetPasswordRequest : public AuthRequest { public: ResetPasswordRequest(::firebase::App& app, const char* api_key, - const char* oob_code, const char* new_password); + const char* oob_code, const char* new_password, + const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/rpcs/set_account_info_request.cc b/auth/src/desktop/rpcs/set_account_info_request.cc index 48105661b1..3901bdfefb 100644 --- a/auth/src/desktop/rpcs/set_account_info_request.cc +++ b/auth/src/desktop/rpcs/set_account_info_request.cc @@ -21,7 +21,8 @@ namespace firebase { namespace auth { SetAccountInfoRequest::SetAccountInfoRequest(::firebase::App& app, - const char* const api_key) + const char* const api_key, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -35,13 +36,18 @@ SetAccountInfoRequest::SetAccountInfoRequest(::firebase::App& app, set_url(url.c_str()); application_data_->returnSecureToken = true; + + if (tenant_id != nullptr){ + application_data_->tenantId =tenant_id; + } } std::unique_ptr SetAccountInfoRequest::CreateUpdateEmailRequest(::firebase::App& app, const char* const api_key, - const char* const email) { - auto request = CreateRequest(app, api_key); + const char* const email, + const char* tenant_id) { + auto request = CreateRequest(app, api_key, tenant_id); if (email) { request->application_data_->email = email; } else { @@ -54,8 +60,8 @@ SetAccountInfoRequest::CreateUpdateEmailRequest(::firebase::App& app, std::unique_ptr SetAccountInfoRequest::CreateUpdatePasswordRequest( ::firebase::App& app, const char* const api_key, const char* const password, - const char* const language_code) { - auto request = CreateRequest(app, api_key); + const char* const language_code, const char* tenant_id) { + auto request = CreateRequest(app, api_key, tenant_id); if (language_code != nullptr) { request->add_header(kHeaderFirebaseLocale, language_code); } @@ -71,8 +77,8 @@ SetAccountInfoRequest::CreateUpdatePasswordRequest( std::unique_ptr SetAccountInfoRequest::CreateLinkWithEmailAndPasswordRequest( ::firebase::App& app, const char* const api_key, const char* const email, - const char* const password) { - auto request = CreateRequest(app, api_key); + const char* const password, const char* tenant_id) { + auto request = CreateRequest(app, api_key, tenant_id); if (email) { request->application_data_->email = email; } else { @@ -90,8 +96,9 @@ SetAccountInfoRequest::CreateLinkWithEmailAndPasswordRequest( std::unique_ptr SetAccountInfoRequest::CreateUpdateProfileRequest( ::firebase::App& app, const char* const api_key, - const char* const set_display_name, const char* const set_photo_url) { - auto request = CreateRequest(app, api_key); + const char* const set_display_name, const char* const set_photo_url, + const char* tenant_id) { + auto request = CreateRequest(app, api_key, tenant_id); // It's fine for either set_photo_url or set_photo_url to be null. if (set_display_name) { @@ -119,8 +126,9 @@ SetAccountInfoRequest::CreateUpdateProfileRequest( std::unique_ptr SetAccountInfoRequest::CreateUnlinkProviderRequest(::firebase::App& app, const char* const api_key, - const char* const provider) { - auto request = CreateRequest(app, api_key); + const char* const provider, + const char* tenant_id) { + auto request = CreateRequest(app, api_key, tenant_id); if (provider) { request->application_data_->deleteProvider.push_back(provider); } @@ -130,9 +138,9 @@ SetAccountInfoRequest::CreateUnlinkProviderRequest(::firebase::App& app, } std::unique_ptr SetAccountInfoRequest::CreateRequest( - ::firebase::App& app, const char* const api_key) { + ::firebase::App& app, const char* const api_key, const char* tenant_id) { return std::unique_ptr( - new SetAccountInfoRequest(app, api_key)); // NOLINT + new SetAccountInfoRequest(app, api_key, tenant_id)); // NOLINT } } // namespace auth diff --git a/auth/src/desktop/rpcs/set_account_info_request.h b/auth/src/desktop/rpcs/set_account_info_request.h index a96f5b595e..33e0eb5c45 100644 --- a/auth/src/desktop/rpcs/set_account_info_request.h +++ b/auth/src/desktop/rpcs/set_account_info_request.h @@ -32,19 +32,21 @@ namespace auth { class SetAccountInfoRequest : public AuthRequest { public: static std::unique_ptr CreateUpdateEmailRequest( - ::firebase::App& app, const char* api_key, const char* email); + ::firebase::App& app, const char* api_key, const char* email, + const char* tenant_id); static std::unique_ptr CreateUpdatePasswordRequest( ::firebase::App& app, const char* api_key, const char* password, - const char* language_code = nullptr); + const char* language_code = nullptr, const char* tenant_id = nullptr); static std::unique_ptr CreateLinkWithEmailAndPasswordRequest(::firebase::App& app, const char* api_key, const char* email, - const char* password); + const char* password, const char* tenant_id); static std::unique_ptr CreateUpdateProfileRequest( ::firebase::App& app, const char* api_key, const char* set_display_name, - const char* set_photo_url); + const char* set_photo_url, const char* tenant_id); static std::unique_ptr CreateUnlinkProviderRequest( - ::firebase::App& app, const char* api_key, const char* provider); + ::firebase::App& app, const char* api_key, const char* provider, + const char* tenant_id); void SetIdToken(const char* const id_token) { if (id_token) { @@ -56,9 +58,10 @@ class SetAccountInfoRequest : public AuthRequest { } private: - explicit SetAccountInfoRequest(::firebase::App& app, const char* api_key); + explicit SetAccountInfoRequest(::firebase::App& app, const char* api_key, + const char* tenant_id); static std::unique_ptr CreateRequest( - ::firebase::App& app, const char* api_key); + ::firebase::App& app, const char* api_key, const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/rpcs/sign_up_new_user_request.cc b/auth/src/desktop/rpcs/sign_up_new_user_request.cc index 5a098b4b10..e05878c77f 100644 --- a/auth/src/desktop/rpcs/sign_up_new_user_request.cc +++ b/auth/src/desktop/rpcs/sign_up_new_user_request.cc @@ -21,9 +21,13 @@ namespace firebase { namespace auth { SignUpNewUserRequest::SignUpNewUserRequest(::firebase::App& app, - const char* api_key) + const char* api_key, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { SetUrl(api_key); + if (tenant_id != nullptr) { + application_data_->tenantId = tenant_id; + } application_data_->returnSecureToken = true; UpdatePostFields(); } @@ -32,7 +36,8 @@ SignUpNewUserRequest::SignUpNewUserRequest(::firebase::App& app, const char* api_key, const char* email, const char* password, - const char* display_name) + const char* display_name, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { SetUrl(api_key); // It's fine for any of the additional parameters to be null, in case it's an @@ -46,6 +51,9 @@ SignUpNewUserRequest::SignUpNewUserRequest(::firebase::App& app, if (display_name) { application_data_->displayName = display_name; } + if (tenant_id != nullptr) { + application_data_->tenantId = tenant_id; + } application_data_->returnSecureToken = true; UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/sign_up_new_user_request.h b/auth/src/desktop/rpcs/sign_up_new_user_request.h index 806f85b513..3ef41025d6 100644 --- a/auth/src/desktop/rpcs/sign_up_new_user_request.h +++ b/auth/src/desktop/rpcs/sign_up_new_user_request.h @@ -31,12 +31,13 @@ namespace auth { class SignUpNewUserRequest : public AuthRequest { public: // Initializer for anonymous sign-in. - explicit SignUpNewUserRequest(::firebase::App& app, const char* api_key); + explicit SignUpNewUserRequest(::firebase::App& app, const char* api_key, + const char* tenant_id); // initializer for sign-in with email and password. SignUpNewUserRequest(::firebase::App& app, const char* api_key, const char* email, const char* password, - const char* display_name); + const char* display_name, const char* tenant_id); private: void SetUrl(const char* api_key); diff --git a/auth/src/desktop/rpcs/verify_assertion_request.cc b/auth/src/desktop/rpcs/verify_assertion_request.cc index 84dc5e4f70..17eaa1cca7 100644 --- a/auth/src/desktop/rpcs/verify_assertion_request.cc +++ b/auth/src/desktop/rpcs/verify_assertion_request.cc @@ -22,7 +22,8 @@ namespace auth { VerifyAssertionRequest::VerifyAssertionRequest(::firebase::App& app, const char* const api_key, - const char* const provider_id) + const char* const provider_id, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -41,21 +42,25 @@ VerifyAssertionRequest::VerifyAssertionRequest(::firebase::App& app, } else { LogError("No provider id given"); } + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } application_data_->returnSecureToken = true; } std::unique_ptr VerifyAssertionRequest::FromIdToken( ::firebase::App& app, const char* const api_key, - const char* const provider_id, const char* const id_token) { - return FromIdToken(app, api_key, provider_id, id_token, /*nonce=*/nullptr); + const char* const provider_id, const char* const id_token, const char* tenant_id) { + return FromIdToken(app, api_key, provider_id, id_token, /*nonce=*/nullptr, + tenant_id); } std::unique_ptr VerifyAssertionRequest::FromIdToken( ::firebase::App& app, const char* const api_key, const char* const provider_id, const char* const id_token, - const char* nonce) { + const char* nonce, const char* tenant_id) { auto request = std::unique_ptr( - new VerifyAssertionRequest{app, api_key, provider_id}); // NOLINT + new VerifyAssertionRequest{app, api_key, provider_id, tenant_id}); // NOLINT if (id_token) { request->post_body_ += std::string("&id_token=") + id_token; @@ -66,7 +71,6 @@ std::unique_ptr VerifyAssertionRequest::FromIdToken( if (nonce) { request->post_body_ += std::string("&nonce=") + nonce; } - request->application_data_->postBody = request->post_body_; request->UpdatePostFields(); return request; @@ -74,17 +78,18 @@ std::unique_ptr VerifyAssertionRequest::FromIdToken( std::unique_ptr VerifyAssertionRequest::FromAccessToken( ::firebase::App& app, const char* const api_key, - const char* const provider_id, const char* const access_token) { + const char* const provider_id, const char* const access_token, + const char* tenant_id) { return FromAccessToken(app, api_key, provider_id, access_token, - /*nonce=*/nullptr); + /*nonce=*/nullptr, tenant_id); } std::unique_ptr VerifyAssertionRequest::FromAccessToken( ::firebase::App& app, const char* const api_key, const char* const provider_id, const char* const access_token, - const char* nonce) { + const char* nonce, const char* tenant_id) { auto request = std::unique_ptr( - new VerifyAssertionRequest{app, api_key, provider_id}); // NOLINT + new VerifyAssertionRequest{app, api_key, provider_id, tenant_id}); // NOLINT if (access_token) { request->post_body_ += std::string("&access_token=") + access_token; @@ -105,9 +110,10 @@ std::unique_ptr VerifyAssertionRequest::FromAccessTokenAndOAuthSecret( ::firebase::App& app, const char* const api_key, const char* const provider_id, const char* const access_token, - const char* const oauth_secret) { + const char* const oauth_secret, + const char* tenant_id) { auto request = std::unique_ptr( - new VerifyAssertionRequest{app, api_key, provider_id}); // NOLINT + new VerifyAssertionRequest{app, api_key, provider_id, tenant_id}); // NOLINT if (access_token) { request->post_body_ += std::string("&access_token=") + access_token; @@ -131,9 +137,10 @@ static std::unique_ptr FromAuthCode( std::unique_ptr VerifyAssertionRequest::FromAuthCode( ::firebase::App& app, const char* const api_key, - const char* const provider_id, const char* const auth_code) { + const char* const provider_id, const char* const auth_code, + const char* tenant_id) { auto request = std::unique_ptr( - new VerifyAssertionRequest{app, api_key, provider_id}); // NOLINT + new VerifyAssertionRequest{app, api_key, provider_id, tenant_id}); // NOLINT if (auth_code) { request->post_body_ += std::string("&code=") + auth_code; diff --git a/auth/src/desktop/rpcs/verify_assertion_request.h b/auth/src/desktop/rpcs/verify_assertion_request.h index ea5f987794..44797146db 100644 --- a/auth/src/desktop/rpcs/verify_assertion_request.h +++ b/auth/src/desktop/rpcs/verify_assertion_request.h @@ -33,22 +33,22 @@ class VerifyAssertionRequest : public AuthRequest { public: static std::unique_ptr FromIdToken( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* id_token); + const char* id_token, const char* tenant_id); static std::unique_ptr FromIdToken( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* id_token, const char* nonce); + const char* id_token, const char* nonce, const char* tenant_id); static std::unique_ptr FromAccessToken( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* access_token); + const char* access_token, const char* tenant_id); static std::unique_ptr FromAccessToken( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* access_token, const char* nonce); + const char* access_token, const char* nonce, const char* tenant_id); static std::unique_ptr FromAccessTokenAndOAuthSecret( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* access_token, const char* oauth_secret); + const char* access_token, const char* oauth_secret, const char* tenant_id); static std::unique_ptr FromAuthCode( ::firebase::App& app, const char* api_key, const char* provider_id, - const char* auth_code); + const char* auth_code, const char* tenant_id); void SetIdToken(const char* const id_token) { if (id_token) { @@ -61,7 +61,7 @@ class VerifyAssertionRequest : public AuthRequest { private: VerifyAssertionRequest(::firebase::App& app, const char* api_key, - const char* provider_id); + const char* provider_id, const char* tenant_id); std::string post_body_; }; diff --git a/auth/src/desktop/rpcs/verify_custom_token_request.cc b/auth/src/desktop/rpcs/verify_custom_token_request.cc index 83754219f0..90fc446c82 100644 --- a/auth/src/desktop/rpcs/verify_custom_token_request.cc +++ b/auth/src/desktop/rpcs/verify_custom_token_request.cc @@ -23,7 +23,8 @@ namespace auth { VerifyCustomTokenRequest::VerifyCustomTokenRequest(::firebase::App& app, const char* api_key, - const char* token) + const char* token, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -41,6 +42,9 @@ VerifyCustomTokenRequest::VerifyCustomTokenRequest(::firebase::App& app, } else { LogError("No token given."); } + if (tenant_id != nullptr) { + application_data_->tenantId = tenant_id; + } application_data_->returnSecureToken = true; UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/verify_custom_token_request.h b/auth/src/desktop/rpcs/verify_custom_token_request.h index 699d427db1..f4762182f5 100644 --- a/auth/src/desktop/rpcs/verify_custom_token_request.h +++ b/auth/src/desktop/rpcs/verify_custom_token_request.h @@ -28,7 +28,7 @@ namespace auth { class VerifyCustomTokenRequest : public AuthRequest { public: VerifyCustomTokenRequest(::firebase::App& app, const char* api_key, - const char* token); + const char* token, const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/rpcs/verify_password_request.cc b/auth/src/desktop/rpcs/verify_password_request.cc index bbfddfa338..2ebca629d3 100644 --- a/auth/src/desktop/rpcs/verify_password_request.cc +++ b/auth/src/desktop/rpcs/verify_password_request.cc @@ -24,7 +24,8 @@ namespace auth { VerifyPasswordRequest::VerifyPasswordRequest(::firebase::App& app, const char* api_key, const char* email, - const char* password) + const char* password, + const char* tenant_id) : AuthRequest(app, request_resource_data, true) { FIREBASE_ASSERT_RETURN_VOID(api_key); @@ -47,6 +48,9 @@ VerifyPasswordRequest::VerifyPasswordRequest(::firebase::App& app, } else { LogError("No password given"); } + if (tenant_id != nullptr){ + application_data_->tenantId = tenant_id; + } application_data_->returnSecureToken = true; UpdatePostFields(); } diff --git a/auth/src/desktop/rpcs/verify_password_request.h b/auth/src/desktop/rpcs/verify_password_request.h index c6a752a7c3..b1906a38f2 100644 --- a/auth/src/desktop/rpcs/verify_password_request.h +++ b/auth/src/desktop/rpcs/verify_password_request.h @@ -28,7 +28,8 @@ namespace auth { class VerifyPasswordRequest : public AuthRequest { public: VerifyPasswordRequest(::firebase::App& app, const char* api_key, - const char* email, const char* password); + const char* email, const char* password, + const char* tenant_id); }; } // namespace auth diff --git a/auth/src/desktop/sign_in_flow.cc b/auth/src/desktop/sign_in_flow.cc index 9fed420bca..466f7d00a6 100644 --- a/auth/src/desktop/sign_in_flow.cc +++ b/auth/src/desktop/sign_in_flow.cc @@ -28,7 +28,7 @@ GetAccountInfoResult GetAccountInfo(const GetAccountInfoRequest& request) { GetAccountInfoResult GetAccountInfo(const AuthData& auth_data, const std::string& access_token) { const GetAccountInfoRequest request(*auth_data.app, GetApiKey(auth_data), - access_token.c_str()); + access_token.c_str(), GetTenantId(auth_data)); return GetAccountInfo(request); } diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index 83e2643ceb..de72889d2d 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -310,7 +310,8 @@ Future DoLinkWithEmailAndPassword( auto request = RequestT::CreateLinkWithEmailAndPasswordRequest( *auth_data->app, GetApiKey(*auth_data), email_credential->GetEmail().c_str(), - email_credential->GetPassword().c_str()); + email_credential->GetPassword().c_str(), + GetTenantId(*auth_data)); return CallAsyncWithFreshToken(auth_data, promise, std::move(request), PerformSetAccountInfoFlow); @@ -333,7 +334,8 @@ Future DoLinkWithEmailAndPassword_DEPRECATED( auto request = RequestT::CreateLinkWithEmailAndPasswordRequest( *auth_data->app, GetApiKey(*auth_data), email_credential->GetEmail().c_str(), - email_credential->GetPassword().c_str()); + email_credential->GetPassword().c_str(), + GetTenantId(*auth_data)); return CallAsyncWithFreshToken(auth_data, promise, std::move(request), PerformSetAccountInfoFlow_DEPRECATED); @@ -863,7 +865,7 @@ Future User::Delete() { // Note: make_unique can't be used because it's not supported by Visual Studio // 2012. auto request = std::unique_ptr( // NOLINT - new RequestT(*auth_data_->app, GetApiKey(*auth_data_))); + new RequestT(*auth_data_->app, GetApiKey(*auth_data_), GetTenantId(*auth_data_))); const auto callback = [](AuthDataHandle* const handle) { const auto response = GetResponse(*handle->request); @@ -894,7 +896,8 @@ Future User::SendEmailVerification() { typedef GetOobConfirmationCodeRequest RequestT; auto request = RequestT::CreateSendEmailVerificationRequest( - *auth_data_->app, GetApiKey(*auth_data_), language_code); + *auth_data_->app, GetApiKey(*auth_data_), language_code, + GetTenantId(*auth_data_)); const auto callback = [](AuthDataHandle* const handle) { const auto response = @@ -928,7 +931,7 @@ Future User::Reload() { typedef GetAccountInfoRequest RequestT; auto request = std::unique_ptr( new RequestT(*auth_data_->app, GetApiKey(*auth_data_), - id_token.c_str())); // NOLINT + id_token.c_str(), GetTenantId(*auth_data_))); // NOLINT const auto callback = [](AuthDataHandle* const handle) { const GetAccountInfoResult account_info = GetAccountInfo(*handle->request); @@ -968,7 +971,7 @@ Future User::UpdateEmail(const char* const email) { typedef SetAccountInfoRequest RequestT; auto request = RequestT::CreateUpdateEmailRequest( - *auth_data_->app, GetApiKey(*auth_data_), email); + *auth_data_->app, GetApiKey(*auth_data_), email, GetTenantId(*auth_data_)); return CallAsyncWithFreshToken(auth_data_, promise, std::move(request), PerformSetAccountInfoFlow); } @@ -990,7 +993,8 @@ Future User::UpdatePassword(const char* const password) { typedef SetAccountInfoRequest RequestT; auto request = RequestT::CreateUpdatePasswordRequest( - *auth_data_->app, GetApiKey(*auth_data_), password, language_code); + *auth_data_->app, GetApiKey(*auth_data_), password, language_code, + GetTenantId(*auth_data_)); return CallAsyncWithFreshToken(auth_data_, promise, std::move(request), PerformSetAccountInfoFlow); @@ -1005,7 +1009,7 @@ Future User::UpdateUserProfile(const UserProfile& profile) { typedef SetAccountInfoRequest RequestT; auto request = RequestT::CreateUpdateProfileRequest( *auth_data_->app, GetApiKey(*auth_data_), profile.display_name, - profile.photo_url); + profile.photo_url, GetTenantId(*auth_data_)); return CallAsyncWithFreshToken(auth_data_, promise, std::move(request), PerformSetAccountInfoFlow); @@ -1037,7 +1041,7 @@ Future User::Unlink(const char* const provider) { typedef SetAccountInfoRequest RequestT; auto request = RequestT::CreateUnlinkProviderRequest( - *auth_data_->app, GetApiKey(*auth_data_), provider); + *auth_data_->app, GetApiKey(*auth_data_), provider, GetTenantId(*auth_data_)); return CallAsyncWithFreshToken(auth_data_, promise, std::move(request), PerformSetAccountInfoFlow); @@ -1069,7 +1073,7 @@ Future User::Unlink_DEPRECATED(const char* const provider) { typedef SetAccountInfoRequest RequestT; auto request = RequestT::CreateUnlinkProviderRequest( - *auth_data_->app, GetApiKey(*auth_data_), provider); + *auth_data_->app, GetApiKey(*auth_data_), provider, GetTenantId(*auth_data_)); return CallAsyncWithFreshToken(auth_data_, promise, std::move(request), PerformSetAccountInfoFlow_DEPRECATED); diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index bec3ce8ff8..ba90484305 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -185,6 +185,12 @@ class Auth { /// language code should follow the conventions defined by the IETF in BCP 47. void set_language_code(const char* language_code); + /// Get tenant id + std::string tenant_id() const; + + /// Set tenant id for multi-tenant authentication + void set_tenant_id(const char* tenant_id); + /// Sets the user-facing language code to be the default app language. This /// uses a language associated with the device's locale data. On desktop /// this will set the language code to the Firebase service's default. You diff --git a/auth/tests/desktop/auth_desktop_test.cc b/auth/tests/desktop/auth_desktop_test.cc index d34f3cb5f8..66d6a89563 100644 --- a/auth/tests/desktop/auth_desktop_test.cc +++ b/auth/tests/desktop/auth_desktop_test.cc @@ -86,6 +86,16 @@ void VerifyUser(const User& user) { EXPECT_FALSE(user.is_email_verified()); VerifyProviderData(user); } +void VerifyResult(const AuthResult& result) { + EXPECT_EQ("localid123", result.user.uid()); + EXPECT_EQ("testsignin@example.com", result.user.email()); + EXPECT_EQ("", result.user.display_name()); + EXPECT_EQ("", result.user.photo_url()); + EXPECT_EQ("Firebase", result.user.provider_id()); + EXPECT_EQ("", result.user.phone_number()); + EXPECT_FALSE(result.user.is_email_verified()); + VerifyProviderData(result.user); +} std::string GetFakeProviderInfo() { return "\"providerUserInfo\": [" @@ -636,7 +646,7 @@ TEST_F(AuthDesktopTest, TestCreateUserWithEmailAndPassword) { } // Test Auth::SignInWithCustomToken. -TEST_F(AuthDesktopTest, TestSignInWithCustomToken) { +TEST_F(AuthDesktopTest, TestSignInWithCustomTokenDEPRECATED) { FakeSetT fakes; fakes[GetUrlForApi(API_KEY, "verifyCustomToken")] = FakeSuccessfulResponse("VerifyCustomTokenResponse", @@ -657,6 +667,66 @@ TEST_F(AuthDesktopTest, TestSignInWithCustomToken) { VerifyUser(*user); } +TEST_F(AuthDesktopTest, TestSignInWithCustomToken) { + FakeSetT fakes; + fakes[GetUrlForApi(API_KEY, "verifyCustomToken")] = + FakeSuccessfulResponse("VerifyCustomTokenResponse", + "\"isNewUser\": true," + "\"localId\": \"localid123\"," + "\"idToken\": \"idtoken123\"," + "\"refreshToken\": \"refreshtoken123\"," + "\"expiresIn\": \"3600\""); + fakes[GetUrlForApi(API_KEY, "getAccountInfo")] = CreateGetAccountInfoFake(); + InitializeConfigWithFakes(fakes); + + id_token_listener.ExpectChanges(2); + auth_state_listener.ExpectChanges(2); + AuthResult result = WaitForFuture( + firebase_auth_->SignInWithCustomToken("fake_custom_token")); + VerifyResult(result); +} + +TEST_F(AuthDesktopTest, TestSignInWithCustomTokenWithTenant) { + FakeSetT fakes; + fakes[GetUrlForApi(API_KEY, "verifyCustomToken")] = + FakeSuccessfulResponse("VerifyCustomTokenResponse", + "\"isNewUser\": true," + "\"localId\": \"localid123\"," + "\"idToken\": \"idtoken123\"," + "\"refreshToken\": \"refreshtoken123\"," + "\"expiresIn\": \"3600\""); + fakes[GetUrlForApi(API_KEY, "getAccountInfo")] = CreateGetAccountInfoFake(); + InitializeConfigWithFakes(fakes); + + id_token_listener.ExpectChanges(2); + auth_state_listener.ExpectChanges(2); + firebase_auth_->set_tenant_id("tenant123"); + AuthResult result = WaitForFuture( + firebase_auth_->SignInWithCustomToken("fake_custom_token")); + VerifyResult(result); +} + +TEST_F(AuthDesktopTest, TestSignInWithCustomTokenWithTenantAndDeleteTenant) { + FakeSetT fakes; + fakes[GetUrlForApi(API_KEY, "verifyCustomToken")] = + FakeSuccessfulResponse("VerifyCustomTokenResponse", + "\"isNewUser\": true," + "\"localId\": \"localid123\"," + "\"idToken\": \"idtoken123\"," + "\"refreshToken\": \"refreshtoken123\"," + "\"expiresIn\": \"3600\""); + fakes[GetUrlForApi(API_KEY, "getAccountInfo")] = CreateGetAccountInfoFake(); + InitializeConfigWithFakes(fakes); + + id_token_listener.ExpectChanges(2); + auth_state_listener.ExpectChanges(2); + firebase_auth_->set_tenant_id("tenant123"); + firebase_auth_->set_tenant_id(nullptr); + AuthResult result = WaitForFuture( + firebase_auth_->SignInWithCustomToken("fake_custom_token")); + VerifyResult(result); +} + // Test Auth::TestSignInWithCredential. TEST_F(AuthDesktopTest, TestSignInWithCredential_GoogleIdToken) { diff --git a/auth/tests/desktop/rpcs/auth_request_heartbeat_test.cc b/auth/tests/desktop/rpcs/auth_request_heartbeat_test.cc index d327397b62..16b3e04c41 100644 --- a/auth/tests/desktop/rpcs/auth_request_heartbeat_test.cc +++ b/auth/tests/desktop/rpcs/auth_request_heartbeat_test.cc @@ -59,7 +59,7 @@ class AuthRequestHeartbeatTest : public ::testing::Test { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestCreateAuthUriRequestHasHeartbeat) { - CreateAuthUriRequest request(*app_, "APIKEY", "email"); + CreateAuthUriRequest request(*app_, "APIKEY", "email", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -70,7 +70,7 @@ TEST_F(AuthRequestHeartbeatTest, TestCreateAuthUriRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestDeleteAccountRequestHasHeartbeat) { - DeleteAccountRequest request(*app_, "APIKEY"); + DeleteAccountRequest request(*app_, "APIKEY", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -81,7 +81,7 @@ TEST_F(AuthRequestHeartbeatTest, TestDeleteAccountRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestGetAccountInfoRequestHasHeartbeat) { - GetAccountInfoRequest request(*app_, "APIKEY"); + GetAccountInfoRequest request(*app_, "APIKEY", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -118,7 +118,7 @@ TEST_F(AuthRequestHeartbeatTest, TestOobSendPasswordResetRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestResetPasswordRequestHasHeartbeat) { - ResetPasswordRequest request(*app_, "APIKEY", "oob", "password"); + ResetPasswordRequest request(*app_, "APIKEY", "oob", "password", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -141,7 +141,7 @@ TEST_F(AuthRequestHeartbeatTest, TestSecureTokenRequestDoesNotHaveHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdatePasswordRequestHasHeartbeat) { auto request = SetAccountInfoRequest::CreateUpdatePasswordRequest( - *app_, "APIKEY", "fakepassword"); + *app_, "APIKEY", "fakepassword", nullptr); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -153,7 +153,7 @@ TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdatePasswordRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdateEmailRequestHasHeartbeat) { auto request = - SetAccountInfoRequest::CreateUpdateEmailRequest(*app_, "APIKEY", "email"); + SetAccountInfoRequest::CreateUpdateEmailRequest(*app_, "APIKEY", "email", nullptr); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -165,7 +165,7 @@ TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdateEmailRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdateProfileRequestHasHeartbeat) { auto request = SetAccountInfoRequest::CreateUpdateProfileRequest( - *app_, "APIKEY", "New Name", "new_url"); + *app_, "APIKEY", "New Name", "new_url", nullptr); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -177,7 +177,7 @@ TEST_F(AuthRequestHeartbeatTest, TestSetInfoUpdateProfileRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestSetInfoUnlinkProviderRequestHasHeartbeat) { auto request = SetAccountInfoRequest::CreateUnlinkProviderRequest( - *app_, "APIKEY", "provider"); + *app_, "APIKEY", "provider", nullptr); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -188,7 +188,18 @@ TEST_F(AuthRequestHeartbeatTest, TestSetInfoUnlinkProviderRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestSignUpNewUserRequestHasHeartbeat) { - SignUpNewUserRequest request(*app_, "APIKEY"); + SignUpNewUserRequest request(*app_, "APIKEY", nullptr); + + // The request headers should include both hearbeat payload and GMP App ID. + EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); + EXPECT_EQ("com.google.firebase.testing", + request.options().header[app_common::kXFirebaseGmpIdHeader]); +} +#endif // FIREBASE_PLATFORM_DESKTOP + +#if FIREBASE_PLATFORM_DESKTOP +TEST_F(AuthRequestHeartbeatTest, TestSignUpNewUserRequestHasHeartbeatTenant) { + SignUpNewUserRequest request(*app_, "APIKEY", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -201,7 +212,8 @@ TEST_F(AuthRequestHeartbeatTest, TestSignUpNewUserRequestHasHeartbeat) { TEST_F(AuthRequestHeartbeatTest, TestVerifyAssertionFromIdTokenRequestHasHeartbeat) { auto request = VerifyAssertionRequest::FromIdToken(*app_, "APIKEY", - "provider", "id_token"); + "provider", "id_token", + "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -214,7 +226,7 @@ TEST_F(AuthRequestHeartbeatTest, TEST_F(AuthRequestHeartbeatTest, TestVerifyAssertionFromAccessTokenRequestHasHeartbeat) { auto request = VerifyAssertionRequest::FromAccessToken( - *app_, "APIKEY", "provider", "access_token"); + *app_, "APIKEY", "provider", "access_token", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -227,7 +239,7 @@ TEST_F(AuthRequestHeartbeatTest, TEST_F(AuthRequestHeartbeatTest, TestVerifyAssertionFromAccessTokenAndOauthRequestHasHeartbeat) { auto request = VerifyAssertionRequest::FromAccessTokenAndOAuthSecret( - *app_, "APIKEY", "provider", "access_token", "oauth_secret"); + *app_, "APIKEY", "provider", "access_token", "oauth_secret", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request->options().header[app_common::kApiClientHeader]); @@ -238,7 +250,7 @@ TEST_F(AuthRequestHeartbeatTest, #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestVerifyCustomTokenRequestHasHeartbeat) { - VerifyCustomTokenRequest request(*app_, "APIKEY", "email"); + VerifyCustomTokenRequest request(*app_, "APIKEY", "email", nullptr); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); @@ -249,7 +261,18 @@ TEST_F(AuthRequestHeartbeatTest, TestVerifyCustomTokenRequestHasHeartbeat) { #if FIREBASE_PLATFORM_DESKTOP TEST_F(AuthRequestHeartbeatTest, TestVerifyPasswordRequestHasHeartbeat) { - VerifyPasswordRequest request(*app_, "APIKEY", "abc@email", "pwd"); + VerifyPasswordRequest request(*app_, "APIKEY", "abc@email", "pwd", nullptr); + + // The request headers should include both hearbeat payload and GMP App ID. + EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); + EXPECT_EQ("com.google.firebase.testing", + request.options().header[app_common::kXFirebaseGmpIdHeader]); +} +#endif // FIREBASE_PLATFORM_DESKTOP + +#if FIREBASE_PLATFORM_DESKTOP +TEST_F(AuthRequestHeartbeatTest, TestVerifyPasswordRequestHasHeartbeatTenant) { + VerifyPasswordRequest request(*app_, "APIKEY", "abc@email", "pwd", "tenant123"); // The request headers should include both hearbeat payload and GMP App ID. EXPECT_NE("", request.options().header[app_common::kApiClientHeader]); diff --git a/auth/tests/desktop/rpcs/create_auth_uri_test.cc b/auth/tests/desktop/rpcs/create_auth_uri_test.cc index e46b5bb49a..8c8e0cd4d0 100644 --- a/auth/tests/desktop/rpcs/create_auth_uri_test.cc +++ b/auth/tests/desktop/rpcs/create_auth_uri_test.cc @@ -29,7 +29,7 @@ namespace auth { // Test CreateAuthUriRequest TEST(CreateAuthUriTest, TestCreateAuthUriRequest) { std::unique_ptr app(testing::CreateApp()); - CreateAuthUriRequest request(*app, "APIKEY", "email"); + CreateAuthUriRequest request(*app, "APIKEY", "email", "tenant123"); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "createAuthUri?key=APIKEY", @@ -37,7 +37,8 @@ TEST(CreateAuthUriTest, TestCreateAuthUriRequest) { EXPECT_EQ( "{\n" " identifier: \"email\",\n" - " continueUri: \"http://localhost\"\n" + " continueUri: \"http://localhost\",\n" + " tenantId: \"tenant123\"\n" "}\n", request.options().post_fields); } diff --git a/auth/tests/desktop/rpcs/delete_account_test.cc b/auth/tests/desktop/rpcs/delete_account_test.cc index d24c72be6b..311a3d2309 100644 --- a/auth/tests/desktop/rpcs/delete_account_test.cc +++ b/auth/tests/desktop/rpcs/delete_account_test.cc @@ -29,7 +29,7 @@ namespace auth { // Test DeleteAccountRequest TEST(DeleteAccountTest, TestDeleteAccountRequest) { std::unique_ptr app(testing::CreateApp()); - DeleteAccountRequest request(*app, "APIKEY"); + DeleteAccountRequest request(*app, "APIKEY", nullptr); request.SetIdToken("token"); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" @@ -42,6 +42,23 @@ TEST(DeleteAccountTest, TestDeleteAccountRequest) { request.options().post_fields); } +// Test DeleteAccountRequestTenant +TEST(DeleteAccountTest, TestDeleteAccountTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + DeleteAccountRequest request(*app, "APIKEY", "tenant123"); + request.SetIdToken("token"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "deleteAccount?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " idToken: \"token\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test DeleteAccountResponse TEST(DeleteAccountTest, TestDeleteAccountResponse) { std::unique_ptr app(testing::CreateApp()); diff --git a/auth/tests/desktop/rpcs/get_account_info_test.cc b/auth/tests/desktop/rpcs/get_account_info_test.cc index 4822bd2e9c..716895f216 100644 --- a/auth/tests/desktop/rpcs/get_account_info_test.cc +++ b/auth/tests/desktop/rpcs/get_account_info_test.cc @@ -26,10 +26,11 @@ namespace firebase { namespace auth { + // Test GetAccountInfoRequest TEST(GetAccountInfoTest, TestGetAccountInfoRequest) { std::unique_ptr app(testing::CreateApp()); - GetAccountInfoRequest request(*app, "APIKEY", "token"); + GetAccountInfoRequest request(*app, "APIKEY", "token", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "getAccountInfo?key=APIKEY", @@ -41,6 +42,22 @@ TEST(GetAccountInfoTest, TestGetAccountInfoRequest) { request.options().post_fields); } +// Test TestGetAccountInfoTenantRequest +TEST(GetAccountInfoTest, TestGetAccountInfoTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + GetAccountInfoRequest request(*app, "APIKEY", "token", "tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "getAccountInfo?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " idToken: \"token\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test GetAccountInfoResponse TEST(GetAccountInfoTest, TestGetAccountInfoResponse) { std::unique_ptr app(App::Create(AppOptions())); diff --git a/auth/tests/desktop/rpcs/reset_password_test.cc b/auth/tests/desktop/rpcs/reset_password_test.cc index 480168b9d3..61b0e23cc2 100644 --- a/auth/tests/desktop/rpcs/reset_password_test.cc +++ b/auth/tests/desktop/rpcs/reset_password_test.cc @@ -28,7 +28,7 @@ namespace auth { // Test ResetPasswordRequest TEST(ResetPasswordTest, TestResetPasswordRequest) { std::unique_ptr app(testing::CreateApp()); - ResetPasswordRequest request(*app, "APIKEY", "oob", "password"); + ResetPasswordRequest request(*app, "APIKEY", "oob", "password", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "resetPassword?key=APIKEY", @@ -41,6 +41,23 @@ TEST(ResetPasswordTest, TestResetPasswordRequest) { request.options().post_fields); } +// Test ResetPasswordRequestTenant +TEST(ResetPasswordTest, TestResetPasswordTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + ResetPasswordRequest request(*app, "APIKEY", "oob", "password", "tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "resetPassword?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " oobCode: \"oob\",\n" + " newPassword: \"password\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test ResetPasswordResponse TEST(ResetPasswordTest, TestResetPasswordResponse) { std::unique_ptr app(testing::CreateApp()); diff --git a/auth/tests/desktop/rpcs/set_account_info_test.cc b/auth/tests/desktop/rpcs/set_account_info_test.cc index 0a591ea44f..c18430037a 100644 --- a/auth/tests/desktop/rpcs/set_account_info_test.cc +++ b/auth/tests/desktop/rpcs/set_account_info_test.cc @@ -32,7 +32,7 @@ typedef SetAccountInfoResponse ResponseT; TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateEmail) { std::unique_ptr app(testing::CreateApp()); auto request = - RequestT::CreateUpdateEmailRequest(*app, "APIKEY", "fakeemail"); + RequestT::CreateUpdateEmailRequest(*app, "APIKEY", "fakeemail", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -48,10 +48,30 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateEmail) { request->options().post_fields); } +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_UpdateEmail) { + std::unique_ptr app(testing::CreateApp()); + auto request = + RequestT::CreateUpdateEmailRequest(*app, "APIKEY", "fakeemail", "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " email: \"fakeemail\",\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdatePassword) { std::unique_ptr app(testing::CreateApp()); auto request = - RequestT::CreateUpdatePasswordRequest(*app, "APIKEY", "fakepassword"); + RequestT::CreateUpdatePasswordRequest(*app, "APIKEY", "fakepassword", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -67,10 +87,31 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdatePassword) { request->options().post_fields); } +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_UpdatePassword) { + std::unique_ptr app(testing::CreateApp()); + auto request = + RequestT::CreateUpdatePasswordRequest(*app, "APIKEY", "fakepassword", nullptr, "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " password: \"fakepassword\",\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_Full) { std::unique_ptr app(testing::CreateApp()); auto request = RequestT::CreateUpdateProfileRequest(*app, "APIKEY", - "New Name", "new_url"); + "New Name", "new_url", + nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -87,10 +128,33 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_Full) { request->options().post_fields); } + +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_UpdateProfile_Full) { + std::unique_ptr app(testing::CreateApp()); + auto request = RequestT::CreateUpdateProfileRequest(*app, "APIKEY", + "New Name", "new_url", + "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " displayName: \"New Name\",\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " photoUrl: \"new_url\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_Partial) { std::unique_ptr app(testing::CreateApp()); auto request = - RequestT::CreateUpdateProfileRequest(*app, "APIKEY", nullptr, "new_url"); + RequestT::CreateUpdateProfileRequest(*app, "APIKEY", nullptr, "new_url", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -106,9 +170,29 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_Partial) { request->options().post_fields); } +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_UpdateProfile_Partial) { + std::unique_ptr app(testing::CreateApp()); + auto request = + RequestT::CreateUpdateProfileRequest(*app, "APIKEY", nullptr, "new_url", "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " photoUrl: \"new_url\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_DeleteFields) { std::unique_ptr app(testing::CreateApp()); - auto request = RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", ""); + auto request = RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", "", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -127,11 +211,33 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_DeleteFields) { request->options().post_fields); } +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_UpdateProfile_DeleteFields) { + std::unique_ptr app(testing::CreateApp()); + auto request = RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", "", "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " deleteAttribute: [\n" + " \"DISPLAY_NAME\",\n" + " \"PHOTO_URL\"\n" + " ],\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_UpdateProfile_DeleteAndUpdate) { std::unique_ptr app(testing::CreateApp()); auto request = - RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", "new_url"); + RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", "new_url", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -150,10 +256,34 @@ TEST(SetAccountInfoTest, request->options().post_fields); } +TEST(SetAccountInfoTest, + TestSetAccountInfoRequest_UpdateProfileTenant_DeleteAndUpdate) { + std::unique_ptr app(testing::CreateApp()); + auto request = + RequestT::CreateUpdateProfileRequest(*app, "APIKEY", "", "new_url", "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " photoUrl: \"new_url\",\n" + " deleteAttribute: [\n" + " \"DISPLAY_NAME\"\n" + " ],\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + TEST(SetAccountInfoTest, TestSetAccountInfoRequest_Unlink) { std::unique_ptr app(testing::CreateApp()); auto request = - RequestT::CreateUnlinkProviderRequest(*app, "APIKEY", "fakeprovider"); + RequestT::CreateUnlinkProviderRequest(*app, "APIKEY", "fakeprovider", nullptr); request->SetIdToken("token"); EXPECT_EQ( @@ -171,5 +301,27 @@ TEST(SetAccountInfoTest, TestSetAccountInfoRequest_Unlink) { request->options().post_fields); } +TEST(SetAccountInfoTest, TestSetAccountInfoRequestTenant_Unlink) { + std::unique_ptr app(testing::CreateApp()); + auto request = + RequestT::CreateUnlinkProviderRequest(*app, "APIKEY", "fakeprovider", "tenant123"); + request->SetIdToken("token"); + + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "setAccountInfo?key=APIKEY", + request->options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " idToken: \"token\",\n" + " deleteProvider: [\n" + " \"fakeprovider\"\n" + " ],\n" + " tenantId: \"tenant123\"\n" + "}\n", + request->options().post_fields); +} + } // namespace auth } // namespace firebase diff --git a/auth/tests/desktop/rpcs/sign_up_new_user_test.cc b/auth/tests/desktop/rpcs/sign_up_new_user_test.cc index 870deb0fd5..bdfb9bdf9d 100644 --- a/auth/tests/desktop/rpcs/sign_up_new_user_test.cc +++ b/auth/tests/desktop/rpcs/sign_up_new_user_test.cc @@ -28,7 +28,7 @@ namespace auth { // Test SignUpNewUserRequest for making anonymous signin TEST(SignUpNewUserTest, TestAnonymousSignInRequest) { std::unique_ptr app(testing::CreateApp()); - SignUpNewUserRequest request(*app, "APIKEY"); + SignUpNewUserRequest request(*app, "APIKEY", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "signupNewUser?key=APIKEY", @@ -40,10 +40,26 @@ TEST(SignUpNewUserTest, TestAnonymousSignInRequest) { request.options().post_fields); } +// Test SignUpNewUserRequest for making anonymous signin with tenant id +TEST(SignUpNewUserTest, TestAnonymousSignInTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + SignUpNewUserRequest request(*app, "APIKEY","tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "signupNewUser?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test SignUpNewUserRequest for using password signin TEST(SignUpNewUserTest, TestEmailPasswordSignInRequest) { std::unique_ptr app(testing::CreateApp()); - SignUpNewUserRequest request(*app, "APIKEY", "e@mail", "pwd", "rabbit"); + SignUpNewUserRequest request(*app, "APIKEY", "e@mail", "pwd", "rabbit", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "signupNewUser?key=APIKEY", @@ -58,6 +74,25 @@ TEST(SignUpNewUserTest, TestEmailPasswordSignInRequest) { request.options().post_fields); } +// Test SignUpNewUserRequest for using password signin with tenant id +TEST(SignUpNewUserTest, TestEmailPasswordSignInTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + SignUpNewUserRequest request(*app, "APIKEY", "e@mail", "pwd", "rabbit", "tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "signupNewUser?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " email: \"e@mail\",\n" + " password: \"pwd\",\n" + " displayName: \"rabbit\",\n" + " returnSecureToken: true,\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test SignUpNewUserResponse TEST(SignUpNewUserTest, TestSignUpNewUserResponse) { std::unique_ptr app(testing::CreateApp()); diff --git a/auth/tests/desktop/rpcs/test_util.cc b/auth/tests/desktop/rpcs/test_util.cc index 7025ed56ae..1ebed57282 100644 --- a/auth/tests/desktop/rpcs/test_util.cc +++ b/auth/tests/desktop/rpcs/test_util.cc @@ -25,7 +25,7 @@ namespace auth { bool GetNewUserLocalIdAndIdToken(::firebase::App& app, const char* const api_key, std::string* local_id, std::string* id_token) { - SignUpNewUserRequest request(app, api_key); + SignUpNewUserRequest request(app, api_key,nullptr); SignUpNewUserResponse response; firebase::rest::CreateTransport()->Perform(request, &response); @@ -43,7 +43,7 @@ bool GetNewUserLocalIdAndRefreshToken(::firebase::App& app, const char* const api_key, std::string* local_id, std::string* refresh_token) { - SignUpNewUserRequest request(app, api_key); + SignUpNewUserRequest request(app, api_key,nullptr); SignUpNewUserResponse response; firebase::rest::CreateTransport()->Perform(request, &response); @@ -60,7 +60,7 @@ bool GetNewUserLocalIdAndRefreshToken(::firebase::App& app, std::string SignUpNewUserAndGetIdToken(::firebase::App& app, const char* const api_key, const char* const email) { - SignUpNewUserRequest request(app, api_key, email, "fake_password", ""); + SignUpNewUserRequest request(app, api_key, email, "fake_password", "", nullptr); SignUpNewUserResponse response; firebase::rest::CreateTransport()->Perform(request, &response); diff --git a/auth/tests/desktop/rpcs/verify_assertion_test.cc b/auth/tests/desktop/rpcs/verify_assertion_test.cc index ba7139a6d6..895010d04e 100644 --- a/auth/tests/desktop/rpcs/verify_assertion_test.cc +++ b/auth/tests/desktop/rpcs/verify_assertion_test.cc @@ -38,21 +38,21 @@ namespace auth { TEST(VerifyAssertionTest, TestVerifyAssertionRequest_FromIdToken) { std::unique_ptr app(testing::CreateApp()); auto request = VerifyAssertionRequest::FromIdToken(*app, "APIKEY", "provider", - "id_token"); + "id_token", "tenant123"); CheckUrl(*request); } TEST(VerifyAssertionTest, TestVerifyAssertionRequest_FromAccessToken) { std::unique_ptr app(testing::CreateApp()); auto request = VerifyAssertionRequest::FromAccessToken( - *app, "APIKEY", "provider", "access_token"); + *app, "APIKEY", "provider", "access_token", "tenant123"); CheckUrl(*request); } TEST(VerifyAssertionTest, TestVerifyAssertionRequest_FromAccessTokenAndSecret) { std::unique_ptr app(testing::CreateApp()); auto request = VerifyAssertionRequest::FromAccessTokenAndOAuthSecret( - *app, "APIKEY", "provider", "access_token", "oauth_secret"); + *app, "APIKEY", "provider", "access_token", "oauth_secret", "tenant123"); CheckUrl(*request); } diff --git a/auth/tests/desktop/rpcs/verify_custom_token_test.cc b/auth/tests/desktop/rpcs/verify_custom_token_test.cc index 49241c9ef0..43b538f437 100644 --- a/auth/tests/desktop/rpcs/verify_custom_token_test.cc +++ b/auth/tests/desktop/rpcs/verify_custom_token_test.cc @@ -29,7 +29,7 @@ namespace auth { // Test VerifyCustomTokenRequest TEST(VerifyCustomTokenTest, TestVerifyCustomTokenRequest) { std::unique_ptr app(testing::CreateApp()); - VerifyCustomTokenRequest request(*app, "APIKEY", "token123"); + VerifyCustomTokenRequest request(*app, "APIKEY", "token123", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "verifyCustomToken?key=APIKEY", @@ -42,6 +42,23 @@ TEST(VerifyCustomTokenTest, TestVerifyCustomTokenRequest) { request.options().post_fields); } +// Test VerifyCustomTokenRequest with tenant +TEST(VerifyCustomTokenTest, TestVerifyCustomTokenTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + VerifyCustomTokenRequest request(*app, "APIKEY", "token123", "tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "verifyCustomToken?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " returnSecureToken: true,\n" + " token: \"token123\",\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + // Test VerifyCustomTokenResponse TEST(VerifyCustomTokenTest, TestVerifyCustomTokenResponse) { std::unique_ptr app(testing::CreateApp()); diff --git a/auth/tests/desktop/rpcs/verify_password_test.cc b/auth/tests/desktop/rpcs/verify_password_test.cc index 8fe1b1ee25..322ccfbfce 100644 --- a/auth/tests/desktop/rpcs/verify_password_test.cc +++ b/auth/tests/desktop/rpcs/verify_password_test.cc @@ -28,7 +28,7 @@ namespace auth { // Test VerifyPasswordRequest TEST(VerifyPasswordTest, TestVerifyPasswordRequest) { std::unique_ptr app(testing::CreateApp()); - VerifyPasswordRequest request(*app, "APIKEY", "abc@email", "pwd"); + VerifyPasswordRequest request(*app, "APIKEY", "abc@email", "pwd", nullptr); EXPECT_EQ( "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" "verifyPassword?key=APIKEY", @@ -42,6 +42,25 @@ TEST(VerifyPasswordTest, TestVerifyPasswordRequest) { request.options().post_fields); } +// Test VerifyPasswordRequest with tenant +TEST(VerifyPasswordTest, TestVerifyPasswordTenantRequest) { + std::unique_ptr app(testing::CreateApp()); + VerifyPasswordRequest request(*app, "APIKEY", "abc@email", "pwd", "tenant123"); + EXPECT_EQ( + "https://www.googleapis.com/identitytoolkit/v3/relyingparty/" + "verifyPassword?key=APIKEY", + request.options().url); + EXPECT_EQ( + "{\n" + " email: \"abc@email\",\n" + " password: \"pwd\",\n" + " returnSecureToken: true,\n" + " tenantId: \"tenant123\"\n" + "}\n", + request.options().post_fields); +} + + // Test VerifyPasswordResponse TEST(VerifyPasswordTest, TestVerifyPasswordResponse) { std::unique_ptr app(testing::CreateApp()); diff --git a/gma/gma_resources/build.gradle b/gma/gma_resources/build.gradle index d1da919049..77b40e2c99 100644 --- a/gma/gma_resources/build.gradle +++ b/gma/gma_resources/build.gradle @@ -42,6 +42,9 @@ android { } } } + lintOptions { + abortOnError false + } } dependencies {