added iOS source code
[wl-app.git] / iOS / Pods / Realm / Realm / RLMSyncPermission.mm
1 ////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright 2017 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
19 #import "RLMSyncPermission_Private.hpp"
20 #import "RLMSyncUtil_Private.hpp"
21
22 #import "RLMUtil.hpp"
23
24 using namespace realm;
25 using ConditionType = Permission::Condition::Type;
26
27 #pragma mark - Permission
28
29 @interface RLMSyncPermission () {
30 @private
31     NSString *_identity;
32     NSString *_key;
33     NSString *_value;
34     util::Optional<Permission> _underlying;
35     RLMSyncAccessLevel _accessLevel;
36     NSString *_path;
37     NSDate *_updatedAt;
38 }
39 @end
40
41 @implementation RLMSyncPermission
42
43 - (instancetype)initWithRealmPath:(NSString *)path
44                          identity:(NSString *)identity
45                       accessLevel:(RLMSyncAccessLevel)accessLevel {
46     if (self = [super init]) {
47         _accessLevel = accessLevel;
48         _path = path;
49         _identity = identity;
50         if (!identity) {
51             @throw RLMException(@"A permission value cannot be created without a valid user ID");
52         }
53         _updatedAt = [NSDate date];
54     }
55     return self;
56 }
57
58 - (instancetype)initWithRealmPath:(NSString *)path
59                          username:(NSString *)username
60                       accessLevel:(RLMSyncAccessLevel)accessLevel {
61     if (self = [super init]) {
62         _accessLevel = accessLevel;
63         _path = path;
64         _identity = nil;
65         _key = @"email";
66         _value = username;
67         _updatedAt = [NSDate date];
68     }
69     return self;
70 }
71
72 - (instancetype)initWithPermission:(Permission)permission {
73     if (self = [super init]) {
74         _underlying = util::make_optional<Permission>(std::move(permission));
75         return self;
76     }
77     return nil;
78 }
79
80 - (NSString *)path {
81     if (!_underlying) {
82         REALM_ASSERT(_path);
83         return _path;
84     }
85     return @(_underlying->path.c_str());
86 }
87
88 - (RLMSyncAccessLevel)accessLevel {
89     if (!_underlying) {
90         return _accessLevel;
91     }
92     return objCAccessLevelForAccessLevel(_underlying->access);
93 }
94
95 - (BOOL)mayRead {
96     return self.accessLevel > RLMSyncAccessLevelNone;
97 }
98
99 - (BOOL)mayWrite {
100     return self.accessLevel > RLMSyncAccessLevelRead;
101 }
102
103 - (BOOL)mayManage {
104     return self.accessLevel == RLMSyncAccessLevelAdmin;
105 }
106
107 - (NSString *)identity {
108     if (!_underlying) {
109         return _identity;
110     }
111     if (_underlying->condition.type == ConditionType::UserId) {
112         return @(_underlying->condition.user_id.c_str());
113     }
114     return nil;
115 }
116
117 - (NSString *)key {
118     if (!_underlying) {
119         return _key;
120     }
121     if (_underlying->condition.type == ConditionType::KeyValue) {
122         return @(_underlying->condition.key_value.first.c_str());
123     }
124     return nil;
125 }
126
127 - (NSString *)value {
128     if (!_underlying) {
129         return _value;
130     }
131     if (_underlying->condition.type == ConditionType::KeyValue) {
132         return @(_underlying->condition.key_value.second.c_str());
133     }
134     return nil;
135 }
136
137 - (NSDate *)updatedAt {
138     if (!_underlying) {
139         return _updatedAt;
140     }
141     return RLMTimestampToNSDate(_underlying->updated_at);
142 }
143
144 - (realm::Permission)rawPermission {
145     if (_underlying) {
146         return *_underlying;
147     }
148     auto condition = (_identity
149                       ? Permission::Condition([_identity UTF8String])
150                       : Permission::Condition([_key UTF8String], [_value UTF8String]));
151     return Permission{
152         [_path UTF8String],
153         accessLevelForObjCAccessLevel(_accessLevel),
154         std::move(condition)
155     };
156 }
157
158 - (NSUInteger)hash {
159     return [self.identity hash] ^ self.accessLevel;
160 }
161
162 - (BOOL)isEqual:(id)object {
163     if (self == object) {
164         return YES;
165     }
166     if ([object isKindOfClass:[RLMSyncPermission class]]) {
167         RLMSyncPermission *that = (RLMSyncPermission *)object;
168         return (self.accessLevel == that.accessLevel
169                 && Permission::paths_are_equivalent([self.path UTF8String], [that.path UTF8String],
170                                                     [self.identity UTF8String], [that.identity UTF8String])
171                 && [self.identity isEqualToString:that.identity]);
172     }
173     return NO;
174 }
175
176 - (NSString *)description {
177     NSString *typeDescription = nil;
178     if (self.identity) {
179         typeDescription = [NSString stringWithFormat:@"identity: %@", self.identity];
180     } else {
181         typeDescription = [NSString stringWithFormat:@"key: %@, value: %@", self.key, self.value];
182     }
183     return [NSString stringWithFormat:@"<RLMSyncPermission> %@, path: %@, access level: %@",
184             typeDescription,
185             self.path,
186             @(Permission::description_for_access_level(accessLevelForObjCAccessLevel(self.accessLevel)).c_str())];
187 }
188
189 @end