Skip to content
Merged
1 change: 1 addition & 0 deletions FirebaseAuth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Unreleased
- [added] Added support for multi-tenancy (#6142).
- [added] Added basic watchOS support. (#4621)

# v6.8.0
Expand Down
10 changes: 10 additions & 0 deletions FirebaseAuth/Sources/Auth/FIRAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ - (nullable instancetype)initWithAPIKey:(NSString *)APIKey appName:(NSString *)a
if (!storedUserAccessGroup) {
FIRUser *user;
if ([strongSelf getUser:&user error:&error]) {
strongSelf.tenantID = user.tenantID;
[strongSelf updateCurrentUser:user byForce:NO savingToDisk:NO error:&error];
self->_lastNotifiedUserToken = user.rawAccessToken;
} else {
Expand Down Expand Up @@ -1975,6 +1976,15 @@ - (BOOL)updateCurrentUser:(nullable FIRUser *)user
[self possiblyPostAuthStateChangeNotification];
return YES;
}
if (user) {
if ((user.tenantID || self.tenantID) && ![self.tenantID isEqualToString:user.tenantID]) {
if (error) {
*error = [FIRAuthErrorUtils tenantIDMismatchError];
}
return NO;
}
}

BOOL success = YES;
if (saveToDisk) {
success = [self saveUser:user error:error];
Expand Down
19 changes: 19 additions & 0 deletions FirebaseAuth/Sources/Backend/FIRAuthBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,17 @@
*/
static NSString *const kCaptchaCheckFailedErrorMessage = @"CAPTCHA_CHECK_FAILED";

/** @var kTenantIDMismatch
@brief This is the error message the server will respond with if the tenant id mismatches.
*/
static NSString *const kTenantIDMismatch = @"TENANT_ID_MISMATCH";

/** @var kUnsupportedTenantOperation
@brief This is the error message the server will respond with if the operation does not support
multi-tenant.
*/
static NSString *const kUnsupportedTenantOperation = @"UNSUPPORTED_TENANT_OPERATION";

/** @var kMissingMFAPendingCredentialErrorMessage
@brief This is the error message the server will respond with if the MFA pending credential is
missing.
Expand Down Expand Up @@ -1380,6 +1391,14 @@ + (nullable NSError *)clientErrorWithServerErrorMessage:(NSString *)serverErrorM
message:serverErrorMessage];
}

if ([shortErrorMessage isEqualToString:kTenantIDMismatch]) {
return [FIRAuthErrorUtils tenantIDMismatchError];
}

if ([shortErrorMessage isEqualToString:kUnsupportedTenantOperation]) {
return [FIRAuthErrorUtils unsupportedTenantOperationError];
}

// In this case we handle an error that might be specified in the underlying errors dictionary,
// the error message in determined based on the @c reason key in the dictionary.
if (errorDictionary[kErrorsKey]) {
Expand Down
5 changes: 5 additions & 0 deletions FirebaseAuth/Sources/Backend/FIRIdentityToolkitRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, copy, readonly) NSString *APIKey;

/** @property tenantID
@brief The tenant ID of the request. nil if none is available.
*/
@property(nonatomic, copy, readonly, nullable) NSString *tenantID;

/** @fn init
@brief Please use initWithEndpoint:APIKey:
*/
Expand Down
10 changes: 10 additions & 0 deletions FirebaseAuth/Sources/Backend/FIRIdentityToolkitRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#import "FirebaseAuth/Sources/Backend/FIRIdentityToolkitRequest.h"

#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuth.h"

NS_ASSUME_NONNULL_BEGIN

static NSString *const kFirebaseAuthAPIURLFormat =
Expand Down Expand Up @@ -48,6 +50,14 @@ - (nullable instancetype)initWithEndpoint:(NSString *)endpoint
_requestConfiguration = requestConfiguration;
_useIdentityPlatform = NO;
_useStaging = NO;

// Automatically set the tenant ID. If the request is initialized before FIRAuth is configured,
// set tenant ID to nil.
@try {
_tenantID = [FIRAuth auth].tenantID;
} @catch (NSException *e) {
_tenantID = nil;
}
}
return self;
}
Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRCreateAuthURIRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
*/
static NSString *const kAppIDKey = @"appId";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRCreateAuthURIRequest

- (nullable instancetype)initWithIdentifier:(NSString *)identifier
Expand Down Expand Up @@ -89,6 +94,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_appID) {
postBody[kAppIDKey] = _appID;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@
*/
static NSString *const kVerifyBeforeUpdateEmailRequestTypeValue = @"VERIFY_AND_CHANGE_EMAIL";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@interface FIRGetOOBConfirmationCodeRequest ()

/** @fn initWithRequestType:email:APIKey:
Expand Down Expand Up @@ -279,6 +284,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_dynamicLinkDomain) {
body[kDynamicLinkDomainKey] = _dynamicLinkDomain;
}
if (self.tenantID) {
body[kTenantIDKey] = self.tenantID;
}

return body;
}
Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRResetPasswordRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
*/
static NSString *const kCurrentPasswordKey = @"newPassword";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRResetPasswordRequest

- (nullable instancetype)initWithOobCode:(NSString *)oobCode
Expand All @@ -52,6 +57,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_updatedPassword) {
postBody[kCurrentPasswordKey] = _updatedPassword;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
*/
static NSString *const kreCAPTCHATokenKey = @"recaptchaToken";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRSendVerificationCodeRequest {
}

Expand Down Expand Up @@ -76,6 +81,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_reCAPTCHAToken) {
postBody[kreCAPTCHATokenKey] = _reCAPTCHAToken;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRSetAccountInfoRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
*/
static NSString *const kReturnSecureTokenKey = @"returnSecureToken";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRSetAccountInfoRequest

- (nullable instancetype)initWithRequestConfiguration:
Expand Down Expand Up @@ -171,6 +176,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_returnSecureToken) {
postBody[kReturnSecureTokenKey] = @YES;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRSignUpNewUserRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
*/
static NSString *const kReturnSecureTokenKey = @"returnSecureToken";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRSignUpNewUserRequest

- (nullable instancetype)initWithEmail:(nullable NSString *)email
Expand Down Expand Up @@ -82,6 +87,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_returnSecureToken) {
postBody[kReturnSecureTokenKey] = @YES;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRVerifyAssertionRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
*/
static NSString *const kSessionIDKey = @"sessionId";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRVerifyAssertionRequest

- (nullable instancetype)initWithProviderID:(NSString *)providerID
Expand Down Expand Up @@ -166,6 +171,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_sessionID) {
body[kSessionIDKey] = _sessionID;
}
if (self.tenantID) {
body[kTenantIDKey] = self.tenantID;
}

body[kAutoCreateKey] = @(_autoCreate);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
*/
static NSString *const kReturnSecureTokenKey = @"returnSecureToken";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRVerifyCustomTokenRequest

- (nullable instancetype)initWithToken:(NSString *)token
Expand All @@ -51,6 +56,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_returnSecureToken) {
body[kReturnSecureTokenKey] = @YES;
}
if (self.tenantID) {
body[kTenantIDKey] = self.tenantID;
}
return body;
}

Expand Down
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/Backend/RPC/FIRVerifyPasswordRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
*/
static NSString *const kReturnSecureTokenKey = @"returnSecureToken";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRVerifyPasswordRequest

- (nullable instancetype)initWithEmail:(NSString *)email
Expand Down Expand Up @@ -87,6 +92,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)
if (_returnSecureToken) {
postBody[kReturnSecureTokenKey] = @YES;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
*/
static NSString *const kOperationKey = @"operation";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRVerifyPhoneNumberRequest

- (nullable instancetype)initWithTemporaryProof:(NSString *)temporaryProof
Expand Down Expand Up @@ -123,6 +128,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Null
if (_phoneNumber) {
postBody[kPhoneNumberKey] = _phoneNumber;
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
NSString *operation = FIRAuthOperationString(_operation);
postBody[kOperationKey] = operation;
return [postBody copy];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

static NSString *const kFinalizeMFAEnrollmentEndPoint = @"accounts/mfaEnrollment:finalize";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRFinalizeMFAEnrollmentRequest

- (nullable instancetype)initWithIDToken:(NSString *)IDToken
Expand Down Expand Up @@ -49,6 +54,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Null
postBody[@"phoneVerificationInfo"] = [_verificationInfo dictionary];
}
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@

static NSString *const kStartMFAEnrollmentEndPoint = @"accounts/mfaEnrollment:start";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRStartMFAEnrollmentRequest

- (nullable instancetype)initWithIDToken:(NSString *)IDToken
Expand All @@ -46,6 +51,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Null
postBody[@"phoneEnrollmentInfo"] = [_enrollmentInfo dictionary];
}
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

static NSString *const kFinalizeMFASignInEndPoint = @"accounts/mfaSignIn:finalize";

/** @var kTenantIDKey
@brief The key for the tenant id value in the request.
*/
static NSString *const kTenantIDKey = @"tenantId";

@implementation FIRFinalizeMFASignInRequest

- (nullable instancetype)
Expand Down Expand Up @@ -45,6 +50,9 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Null
postBody[@"phoneVerificationInfo"] = [_verificationInfo dictionary];
}
}
if (self.tenantID) {
postBody[kTenantIDKey] = self.tenantID;
}
return [postBody copy];
}

Expand Down
Loading