RLMSyncUtil.mm 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #import "RLMSyncUtil_Private.hpp"
  19. #import "RLMJSONModels.h"
  20. #import "RLMObject_Private.hpp"
  21. #import "RLMRealmConfiguration+Sync.h"
  22. #import "RLMRealmConfiguration_Private.hpp"
  23. #import "RLMRealm_Private.hpp"
  24. #import "RLMSyncConfiguration_Private.hpp"
  25. #import "RLMSyncUser_Private.hpp"
  26. #import "RLMUtil.hpp"
  27. #import "shared_realm.hpp"
  28. #import "sync/sync_user.hpp"
  29. RLMIdentityProvider const RLMIdentityProviderAccessToken = @"_access_token";
  30. NSString *const RLMSyncErrorDomain = @"io.realm.sync";
  31. NSString *const RLMSyncAuthErrorDomain = @"io.realm.sync.auth";
  32. NSString *const RLMSyncPermissionErrorDomain = @"io.realm.sync.permission";
  33. NSString *const kRLMSyncPathOfRealmBackupCopyKey = @"recovered_realm_location_path";
  34. NSString *const kRLMSyncErrorActionTokenKey = @"error_action_token";
  35. NSString *const kRLMSyncAppIDKey = @"app_id";
  36. NSString *const kRLMSyncDataKey = @"data";
  37. NSString *const kRLMSyncErrorJSONKey = @"json";
  38. NSString *const kRLMSyncErrorStatusCodeKey = @"statusCode";
  39. NSString *const kRLMSyncIdentityKey = @"identity";
  40. NSString *const kRLMSyncIsAdminKey = @"is_admin";
  41. NSString *const kRLMSyncNewPasswordKey = @"new_password";
  42. NSString *const kRLMSyncPasswordKey = @"password";
  43. NSString *const kRLMSyncPathKey = @"path";
  44. NSString *const kRLMSyncProviderKey = @"provider";
  45. NSString *const kRLMSyncProviderIDKey = @"provider_id";
  46. NSString *const kRLMSyncRegisterKey = @"register";
  47. NSString *const kRLMSyncTokenKey = @"token";
  48. NSString *const kRLMSyncUnderlyingErrorKey = @"underlying_error";
  49. NSString *const kRLMSyncUserIDKey = @"user_id";
  50. uint8_t RLMGetComputedPermissions(RLMRealm *realm, id _Nullable object) {
  51. if (!object) {
  52. return static_cast<unsigned char>(realm->_realm->get_privileges());
  53. }
  54. if ([object isKindOfClass:[NSString class]]) {
  55. return static_cast<unsigned char>(realm->_realm->get_privileges([object UTF8String]));
  56. }
  57. if (auto obj = RLMDynamicCast<RLMObjectBase>(object)) {
  58. RLMVerifyAttached(obj);
  59. return static_cast<unsigned char>(realm->_realm->get_privileges(obj->_row));
  60. }
  61. return 0;
  62. }
  63. #pragma mark - C++ APIs
  64. SyncSessionStopPolicy translateStopPolicy(RLMSyncStopPolicy stopPolicy) {
  65. switch (stopPolicy) {
  66. case RLMSyncStopPolicyImmediately: return SyncSessionStopPolicy::Immediately;
  67. case RLMSyncStopPolicyLiveIndefinitely: return SyncSessionStopPolicy::LiveIndefinitely;
  68. case RLMSyncStopPolicyAfterChangesUploaded: return SyncSessionStopPolicy::AfterChangesUploaded;
  69. }
  70. REALM_UNREACHABLE(); // Unrecognized stop policy.
  71. }
  72. RLMSyncStopPolicy translateStopPolicy(SyncSessionStopPolicy stop_policy) {
  73. switch (stop_policy) {
  74. case SyncSessionStopPolicy::Immediately: return RLMSyncStopPolicyImmediately;
  75. case SyncSessionStopPolicy::LiveIndefinitely: return RLMSyncStopPolicyLiveIndefinitely;
  76. case SyncSessionStopPolicy::AfterChangesUploaded: return RLMSyncStopPolicyAfterChangesUploaded;
  77. }
  78. REALM_UNREACHABLE();
  79. }
  80. std::shared_ptr<SyncSession> sync_session_for_realm(RLMRealm *realm) {
  81. Realm::Config realmConfig = realm.configuration.config;
  82. if (auto config = realmConfig.sync_config) {
  83. std::shared_ptr<SyncUser> user = config->user;
  84. if (user && user->state() != SyncUser::State::Error) {
  85. return user->session_for_on_disk_path(realmConfig.path);
  86. }
  87. }
  88. return nullptr;
  89. }
  90. CocoaSyncUserContext& context_for(const std::shared_ptr<realm::SyncUser>& user)
  91. {
  92. return *std::static_pointer_cast<CocoaSyncUserContext>(user->binding_context());
  93. }
  94. NSError *make_auth_error_bad_response(NSDictionary *json) {
  95. return [NSError errorWithDomain:RLMSyncAuthErrorDomain
  96. code:RLMSyncAuthErrorBadResponse
  97. userInfo:json ? @{kRLMSyncErrorJSONKey: json} : nil];
  98. }
  99. NSError *make_auth_error_http_status(NSInteger status) {
  100. return [NSError errorWithDomain:RLMSyncAuthErrorDomain
  101. code:RLMSyncAuthErrorHTTPStatusCodeError
  102. userInfo:@{kRLMSyncErrorStatusCodeKey: @(status)}];
  103. }
  104. NSError *make_auth_error_client_issue() {
  105. return [NSError errorWithDomain:RLMSyncAuthErrorDomain
  106. code:RLMSyncAuthErrorClientSessionError
  107. userInfo:nil];
  108. }
  109. NSError *make_auth_error(RLMSyncErrorResponseModel *model) {
  110. NSMutableDictionary<NSString *, NSString *> *userInfo = [NSMutableDictionary dictionaryWithCapacity:2];
  111. if (NSString *description = model.title) {
  112. [userInfo setObject:description forKey:NSLocalizedDescriptionKey];
  113. }
  114. if (NSString *hint = model.hint) {
  115. [userInfo setObject:hint forKey:NSLocalizedRecoverySuggestionErrorKey];
  116. }
  117. return [NSError errorWithDomain:RLMSyncAuthErrorDomain code:model.code userInfo:userInfo];
  118. }
  119. NSError *make_sync_error(RLMSyncSystemErrorKind kind, NSString *description, NSInteger code, NSDictionary *custom) {
  120. NSMutableDictionary *buffer = [custom ?: @{} mutableCopy];
  121. buffer[NSLocalizedDescriptionKey] = description;
  122. if (code != NSNotFound) {
  123. buffer[kRLMSyncErrorStatusCodeKey] = @(code);
  124. }
  125. RLMSyncError errorCode;
  126. switch (kind) {
  127. case RLMSyncSystemErrorKindClientReset:
  128. errorCode = RLMSyncErrorClientResetError;
  129. break;
  130. case RLMSyncSystemErrorKindPermissionDenied:
  131. errorCode = RLMSyncErrorPermissionDeniedError;
  132. break;
  133. case RLMSyncSystemErrorKindUser:
  134. errorCode = RLMSyncErrorClientUserError;
  135. break;
  136. case RLMSyncSystemErrorKindSession:
  137. errorCode = RLMSyncErrorClientSessionError;
  138. break;
  139. case RLMSyncSystemErrorKindConnection:
  140. case RLMSyncSystemErrorKindClient:
  141. case RLMSyncSystemErrorKindUnknown:
  142. errorCode = RLMSyncErrorClientInternalError;
  143. break;
  144. }
  145. return [NSError errorWithDomain:RLMSyncErrorDomain
  146. code:errorCode
  147. userInfo:[buffer copy]];
  148. }
  149. NSError *make_sync_error(NSError *wrapped_auth_error) {
  150. return [NSError errorWithDomain:RLMSyncErrorDomain
  151. code:RLMSyncErrorUnderlyingAuthError
  152. userInfo:@{kRLMSyncUnderlyingErrorKey: wrapped_auth_error}];
  153. }
  154. NSError *make_sync_error(std::error_code sync_error, RLMSyncSystemErrorKind kind) {
  155. return [NSError errorWithDomain:RLMSyncErrorDomain
  156. code:kind
  157. userInfo:@{
  158. NSLocalizedDescriptionKey: @(sync_error.message().c_str()),
  159. kRLMSyncErrorStatusCodeKey: @(sync_error.value())
  160. }];
  161. }