aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core
diff options
context:
space:
mode:
authorGravatar zxu <zxu@google.com>2018-02-27 14:04:39 -0500
committerGravatar GitHub <noreply@github.com>2018-02-27 14:04:39 -0500
commit3e7c062f3baca83fae1937bf60865be0cd18f96d (patch)
treeb9816a635f0deda9601496b0d41f6b064f99d838 /Firestore/core
parent13aeb61de4fac4c0239bcf44a98a7d3aa9203963 (diff)
replacing Auth by C++ auth implementation (#802)
* lazy replacing FST(Firebase)CredentialsProvider by (Firebase)CredentialsProvider * lazy replacing FSTUser by User * adding error-code parameter to TokenListener * actually use const user& instead of pointer; also add an error util * add HashUser and pass into the unordered_map * use User in test * use c++ CredentialsProvider and subclass in test * fix unit test * use explicit capture in lambda instead of capture all by reference * cache currentUser explicitly when reset sync engineer test driver * objc object should be captured by value in lambda * replacing Auth/FSTUser by C++ auth implementation * address changes * replacing FSTGetTokenResult by C++ Token implementation * address changes * fix unintentional change in merging * patch the change in objc Auth up-stream * somehow, the lambda-version of set-user-change-listener does not work... fallback to block * address changes * fix another const& v.s. dispatch bug * fix more const& v.s. dispatch bug zxu123 committed * fix a bad sync line * address changes * address change * address change * fix upstream change from merge * fix upstream changes * Suggested fixes for cpp/port_auth (#846) * Get rid of MockDatastore factory This avoids the need to statically allocate (and leak) a credentials provider * Use absl::make_unique std::make_unique technically does not exist until C++14. * #include <utility> for std::move * Use std::future for the initial user * fix style
Diffstat (limited to 'Firestore/core')
-rw-r--r--Firestore/core/include/firebase/firestore/firestore_errors.h115
-rw-r--r--Firestore/core/src/firebase/firestore/auth/credentials_provider.h7
-rw-r--r--Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc3
-rw-r--r--Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm7
-rw-r--r--Firestore/core/src/firebase/firestore/util/error_apple.h52
-rw-r--r--Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc7
-rw-r--r--Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc8
-rw-r--r--Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm12
8 files changed, 195 insertions, 16 deletions
diff --git a/Firestore/core/include/firebase/firestore/firestore_errors.h b/Firestore/core/include/firebase/firestore/firestore_errors.h
new file mode 100644
index 0000000..7a0ff7c
--- /dev/null
+++ b/Firestore/core/include/firebase/firestore/firestore_errors.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
+#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
+
+namespace firebase {
+namespace firestore {
+
+/**
+ * Error codes used by Cloud Firestore.
+ *
+ * The codes are in sync with the Firestore iOS client SDK header file
+ * FIRFirestoreErrors.h.
+ */
+enum FirestoreErrorCode {
+ /**
+ * The operation completed successfully. NSError objects will never have a
+ * code with this value.
+ */
+ Ok = 0,
+
+ /** The operation was cancelled (typically by the caller). */
+ Cancelled = 1,
+
+ /** Unknown error or an error from a different error domain. */
+ Unknown = 2,
+
+ /**
+ * Client specified an invalid argument. Note that this differs from
+ * FailedPrecondition. InvalidArgument indicates arguments that are
+ * problematic regardless of the state of the system (e.g., an invalid field
+ * name).
+ */
+ InvalidArgument = 3,
+
+ /**
+ * Deadline expired before operation could complete. For operations that
+ * change the state of the system, this error may be returned even if the
+ * operation has completed successfully. For example, a successful response
+ * from a server could have been delayed long enough for the deadline to
+ * expire.
+ */
+ DeadlineExceeded = 4,
+
+ /** Some requested document was not found. */
+ NotFound = 5,
+
+ /** Some document that we attempted to create already exists. */
+ AlreadyExists = 6,
+
+ /** The caller does not have permission to execute the specified operation. */
+ PermissionDenied = 7,
+
+ /**
+ * Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+ * entire file system is out of space.
+ */
+ ResourceExhausted = 8,
+
+ /**
+ * Operation was rejected because the system is not in a state required for
+ * the operation's execution.
+ */
+ FailedPrecondition = 9,
+
+ /**
+ * The operation was aborted, typically due to a concurrency issue like
+ * transaction aborts, etc.
+ */
+ Aborted = 10,
+
+ /** Operation was attempted past the valid range. */
+ OutOfRange = 11,
+
+ /** Operation is not implemented or not supported/enabled. */
+ Unimplemented = 12,
+
+ /**
+ * Internal errors. Means some invariants expected by underlying system has
+ * been broken. If you see one of these errors, something is very broken.
+ */
+ Internal = 13,
+
+ /**
+ * The service is currently unavailable. This is a most likely a transient
+ * condition and may be corrected by retrying with a backoff.
+ */
+ Unavailable = 14,
+
+ /** Unrecoverable data loss or corruption. */
+ DataLoss = 15,
+
+ /** The request does not have valid authentication credentials for the
+ operation. */
+ Unauthenticated = 16
+};
+
+} // namespace firestore
+} // namespace firebase
+
+#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
diff --git a/Firestore/core/src/firebase/firestore/auth/credentials_provider.h b/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
index 917f8e1..b9a8a24 100644
--- a/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
+++ b/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
@@ -20,6 +20,7 @@
#include <functional>
#include <string>
+#include "Firestore/core/include/firebase/firestore/firestore_errors.h"
#include "Firestore/core/src/firebase/firestore/auth/token.h"
#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "absl/strings/string_view.h"
@@ -30,8 +31,10 @@ namespace auth {
// `TokenErrorListener` is a listener that gets a token or an error.
// token: An auth token as a string, or nullptr if error occurred.
-// error: The error if one occurred, or else nullptr.
-typedef std::function<void(Token token, const absl::string_view error)>
+// error_code: The error code if one occurred, or else FirestoreErrorCode::Ok.
+// error_msg: The error if one occurred, or else nullptr.
+typedef std::function<void(
+ Token token, const int64_t error_code, const absl::string_view error_msg)>
TokenListener;
// Listener notified with a User change.
diff --git a/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc b/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
index 6ee7f61..0fa70c0 100644
--- a/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
+++ b/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
@@ -26,7 +26,8 @@ void EmptyCredentialsProvider::GetToken(bool force_refresh,
TokenListener completion) {
UNUSED(force_refresh);
if (completion) {
- completion({"", User::Unauthenticated()}, "");
+ // Invalid token will force the GRPC fallback to use default settings.
+ completion(Token::Invalid(), FirestoreErrorCode::Ok, "");
}
}
diff --git a/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm b/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
index fe3cb24..1babe82 100644
--- a/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
+++ b/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
@@ -53,7 +53,7 @@ FirebaseCredentialsProvider::FirebaseCredentialsProvider(FIRApp* app)
NSString* user_id =
user_info[FIRAuthStateDidChangeInternalNotificationUIDKey];
- User new_user(util::MakeStringView(user_id));
+ User new_user = User::FromUid(user_id);
if (new_user != contents->current_user) {
contents->current_user = new_user;
contents->user_counter++;
@@ -96,11 +96,12 @@ void FirebaseCredentialsProvider::GetToken(bool force_refresh,
// Cancel the request since the user changed while the request was
// outstanding so the response is likely for a previous user (which
// user, we can't be sure).
- completion({"", User::Unauthenticated()},
+ completion(Token::Invalid(), FirestoreErrorCode::Aborted,
"getToken aborted due to user change.");
} else {
completion(
- {util::MakeStringView(token), contents->current_user},
+ Token{util::MakeStringView(token), contents->current_user},
+ error == nil ? FirestoreErrorCode::Ok : error.code,
error == nil ? "" : util::MakeStringView(error.localizedDescription));
}
};
diff --git a/Firestore/core/src/firebase/firestore/util/error_apple.h b/Firestore/core/src/firebase/firestore/util/error_apple.h
new file mode 100644
index 0000000..e31cfd6
--- /dev/null
+++ b/Firestore/core/src/firebase/firestore/util/error_apple.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
+#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
+
+// Everything in this header exists for compatibility with Objective-C.
+#if __OBJC__
+
+#import <Foundation/Foundation.h>
+
+#include "Firestore/Source/Public/FIRFirestoreErrors.h" // for FIRFirestoreErrorDomain
+#include "Firestore/core/include/firebase/firestore/firestore_errors.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+#include "absl/strings/string_view.h"
+
+namespace firebase {
+namespace firestore {
+namespace util {
+
+// Translates a set of error_code and error_msg to an NSError.
+inline NSError* WrapNSError(const int64_t error_code,
+ const absl::string_view error_msg) {
+ if (error_code == FirestoreErrorCode::Ok) {
+ return nil;
+ }
+ return [NSError
+ errorWithDomain:FIRFirestoreErrorDomain
+ code:error_code
+ userInfo:@{NSLocalizedDescriptionKey : WrapNSString(error_msg)}];
+}
+
+} // namespace util
+} // namespace firestore
+} // namespace firebase
+
+#endif // __OBJC__
+
+#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
diff --git a/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc b/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
index 9ae71ba..6895061 100644
--- a/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
+++ b/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
@@ -25,10 +25,11 @@ namespace auth {
#define UNUSED(x) (void)(x)
TEST(CredentialsProvider, Typedef) {
- TokenListener token_listener = [](Token token,
- const absl::string_view error) {
+ TokenListener token_listener = [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
UNUSED(token);
- UNUSED(error);
+ UNUSED(error_code);
+ UNUSED(error_msg);
};
EXPECT_NE(nullptr, token_listener);
EXPECT_TRUE(token_listener);
diff --git a/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc b/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
index 39012f0..3b487f3 100644
--- a/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
+++ b/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
@@ -25,12 +25,14 @@ namespace auth {
TEST(EmptyCredentialsProvider, GetToken) {
EmptyCredentialsProvider credentials_provider;
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
- EXPECT_EQ("", token.token());
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
+ EXPECT_FALSE(token.is_valid());
const User& user = token.user();
EXPECT_EQ("", user.uid());
EXPECT_FALSE(user.is_authenticated());
- EXPECT_EQ("", error);
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code);
+ EXPECT_EQ("", error_msg);
});
}
diff --git a/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm b/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
index a6ccc4a..3660d53 100644
--- a/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
+++ b/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
@@ -42,12 +42,14 @@ TEST(FirebaseCredentialsProviderTest, GetTokenUnauthenticated) {
FirebaseCredentialsProvider credentials_provider(app);
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
EXPECT_EQ("", token.token());
const User& user = token.user();
EXPECT_EQ("", user.uid());
EXPECT_FALSE(user.is_authenticated());
- EXPECT_EQ("", error) << error;
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code) << error_code;
+ EXPECT_EQ("", error_msg) << error_msg;
});
}
@@ -56,12 +58,14 @@ TEST(FirebaseCredentialsProviderTest, GetToken) {
FirebaseCredentialsProvider credentials_provider(app);
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
EXPECT_EQ("", token.token());
const User& user = token.user();
EXPECT_EQ("fake uid", user.uid());
EXPECT_TRUE(user.is_authenticated());
- EXPECT_EQ("", error) << error;
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code) << error_code;
+ EXPECT_EQ("", error_msg) << error_msg;
});
}