--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2017 Realm Inc.
+//
+// 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.
+//
+////////////////////////////////////////////////////////////////////////////
+
+#import "RLMJSONModels.h"
+#import "RLMSyncUtil_Private.h"
+#import "RLMSyncUser.h"
+
+#pragma mark - Constants
+
+static const NSString *const kRLMSyncAccessTokenKey = @"access_token";
+static const NSString *const kRLMSyncAccountsKey = @"accounts";
+static const NSString *const kRLMSyncErrorCodeKey = @"code";
+static const NSString *const kRLMSyncExpiresKey = @"expires";
+static const NSString *const kRLMSyncErrorHintKey = @"hint";
+static const NSString *const kRLMSyncIdKey = @"id";
+static const NSString *const kRLMSyncKeyKey = @"key";
+static const NSString *const kRLMSyncMetadataKey = @"metadata";
+static const NSString *const kRLMSyncRefreshTokenKey = @"refresh_token";
+static const NSString *const kRLMSyncErrorStatusKey = @"status";
+static const NSString *const kRLMSyncErrorTitleKey = @"title";
+static const NSString *const kRLMSyncTokenDataKey = @"token_data";
+static const NSString *const kRLMSyncUserKey = @"user";
+static const NSString *const kRLMSyncValueKey = @"value";
+
+#pragma mark - RLMTokenDataModel
+
+@interface RLMTokenDataModel ()
+
+@property (nonatomic, readwrite) NSString *identity;
+@property (nonatomic, readwrite) NSString *appID;
+@property (nonatomic, readwrite) NSString *path;
+@property (nonatomic, readwrite) NSTimeInterval expires;
+@property (nonatomic, readwrite) BOOL isAdmin;
+//@property (nonatomic, readwrite) NSArray *access;
+
+@end
+
+@implementation RLMTokenDataModel
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary {
+ if (self = [super init]) {
+ self.isAdmin = NO;
+ RLM_SYNC_PARSE_STRING_OR_ABORT(jsonDictionary, kRLMSyncIdentityKey, identity);
+ RLM_SYNC_PARSE_OPTIONAL_STRING(jsonDictionary, kRLMSyncAppIDKey, appID);
+ RLM_SYNC_PARSE_OPTIONAL_STRING(jsonDictionary, kRLMSyncPathKey, path);
+ RLM_SYNC_PARSE_OPTIONAL_BOOL(jsonDictionary, kRLMSyncIsAdminKey, isAdmin);
+ RLM_SYNC_PARSE_DOUBLE_OR_ABORT(jsonDictionary, kRLMSyncExpiresKey, expires);
+ return self;
+ }
+ return nil;
+}
+
+@end
+
+#pragma mark - RLMTokenModel
+
+@interface RLMTokenModel ()
+
+@property (nonatomic, readwrite) NSString *token;
+@property (nonatomic, nullable, readwrite) NSString *path;
+@property (nonatomic, readwrite) RLMTokenDataModel *tokenData;
+
+@end
+
+@implementation RLMTokenModel
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary {
+ if (self = [super init]) {
+ RLM_SYNC_PARSE_STRING_OR_ABORT(jsonDictionary, kRLMSyncTokenKey, token);
+ RLM_SYNC_PARSE_OPTIONAL_STRING(jsonDictionary, kRLMSyncPathKey, path);
+ RLM_SYNC_PARSE_MODEL_OR_ABORT(jsonDictionary, kRLMSyncTokenDataKey, RLMTokenDataModel, tokenData);
+ return self;
+ }
+ return nil;
+}
+
+@end
+
+#pragma mark - RLMAuthResponseModel
+
+@interface RLMAuthResponseModel ()
+
+@property (nonatomic, readwrite) RLMTokenModel *accessToken;
+@property (nonatomic, readwrite) RLMTokenModel *refreshToken;
+
+@end
+
+@implementation RLMAuthResponseModel
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary
+ requireAccessToken:(BOOL)requireAccessToken
+ requireRefreshToken:(BOOL)requireRefreshToken {
+ if (self = [super init]) {
+ // Get the access token.
+ if (requireAccessToken) {
+ RLM_SYNC_PARSE_MODEL_OR_ABORT(jsonDictionary, kRLMSyncAccessTokenKey, RLMTokenModel, accessToken);
+ } else {
+ RLM_SYNC_PARSE_OPTIONAL_MODEL(jsonDictionary, kRLMSyncAccessTokenKey, RLMTokenModel, accessToken);
+ }
+ // Get the refresh token.
+ if (requireRefreshToken) {
+ RLM_SYNC_PARSE_MODEL_OR_ABORT(jsonDictionary, kRLMSyncRefreshTokenKey, RLMTokenModel, refreshToken);
+ } else {
+ RLM_SYNC_PARSE_OPTIONAL_MODEL(jsonDictionary, kRLMSyncRefreshTokenKey, RLMTokenModel, refreshToken);
+ }
+ return self;
+ }
+ return nil;
+}
+
+@end
+
+#pragma mark - RLMUserInfoResponseModel
+
+@interface RLMSyncUserAccountInfo ()
+@property (nonatomic, readwrite) NSString *provider;
+@property (nonatomic, readwrite) NSString *providerUserIdentity;
+@end
+
+@implementation RLMSyncUserAccountInfo
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary {
+ if (self = [super init]) {
+ RLM_SYNC_PARSE_STRING_OR_ABORT(jsonDictionary, kRLMSyncProviderKey, provider);
+ RLM_SYNC_PARSE_STRING_OR_ABORT(jsonDictionary, kRLMSyncProviderIDKey, providerUserIdentity);
+ return self;
+ }
+ return nil;
+}
+
+@end
+
+@interface RLMUserResponseModel ()
+
+@property (nonatomic, readwrite) NSString *identity;
+@property (nonatomic, readwrite) NSArray *accounts;
+@property (nonatomic, readwrite) NSDictionary *metadata;
+@property (nonatomic, readwrite) BOOL isAdmin;
+
+@end
+
+@implementation RLMUserResponseModel
+
+- (void)parseMetadataFromJSON:(NSDictionary *)jsonDictionary {
+ NSMutableDictionary *buffer = [NSMutableDictionary dictionary];
+ NSArray *metadataArray = jsonDictionary[kRLMSyncMetadataKey];
+ if (![metadataArray isKindOfClass:[NSArray class]]) {
+ self.metadata = @{};
+ return;
+ }
+ for (NSDictionary *object in metadataArray) {
+ if (![object isKindOfClass:[NSDictionary class]]) {
+ continue;
+ }
+ NSString *key = object[kRLMSyncKeyKey];
+ NSString *value = object[kRLMSyncValueKey];
+ if (!key || !value) {
+ continue;
+ }
+ buffer[key] = value;
+ }
+ self.metadata = [buffer copy];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary {
+ if (self = [super init]) {
+ self.isAdmin = NO;
+ RLM_SYNC_PARSE_STRING_OR_ABORT(jsonDictionary, kRLMSyncUserIDKey, identity);
+ RLM_SYNC_PARSE_OPTIONAL_BOOL(jsonDictionary, kRLMSyncIsAdminKey, isAdmin);
+ RLM_SYNC_PARSE_MODEL_ARRAY_OR_ABORT(jsonDictionary, kRLMSyncAccountsKey, RLMSyncUserAccountInfo, accounts);
+ [self parseMetadataFromJSON:jsonDictionary];
+ return self;
+ }
+ return nil;
+}
+
+@end
+
+#pragma mark - RLMSyncErrorResponseModel
+
+@interface RLMSyncErrorResponseModel ()
+
+@property (nonatomic, readwrite) NSInteger status;
+@property (nonatomic, readwrite) NSInteger code;
+@property (nonatomic, readwrite) NSString *title;
+@property (nonatomic, readwrite) NSString *hint;
+
+@end
+
+@implementation RLMSyncErrorResponseModel
+
+- (instancetype)initWithDictionary:(NSDictionary *)jsonDictionary {
+ if (self = [super init]) {
+ RLM_SYNC_PARSE_DOUBLE_OR_ABORT(jsonDictionary, kRLMSyncErrorStatusKey, status);
+ RLM_SYNC_PARSE_DOUBLE_OR_ABORT(jsonDictionary, kRLMSyncErrorCodeKey, code);
+ RLM_SYNC_PARSE_OPTIONAL_STRING(jsonDictionary, kRLMSyncErrorTitleKey, title);
+ RLM_SYNC_PARSE_OPTIONAL_STRING(jsonDictionary, kRLMSyncErrorHintKey, hint);
+ return self;
+ }
+ return nil;
+}
+
+@end