1// Copyright 2019-present 650 Industries. All rights reserved. 2 3#import "EXPermissionsManager.h" 4#import "EXEnvironment.h" 5 6NSString * const EXPermissionsKey = @"ExpoPermissions"; 7 8@interface EXPermissionsManager () 9 10@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary *> *permissionsCache; 11 12@end 13 14@implementation EXPermissionsManager 15 16- (instancetype)init 17{ 18 if (self = [super init]) { 19 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 20 NSDictionary *expoPermissions = [userDefaults dictionaryForKey:EXPermissionsKey]; 21 _permissionsCache = expoPermissions ? [[NSMutableDictionary alloc] initWithDictionary:expoPermissions] : [NSMutableDictionary new]; 22 } 23 return self; 24} 25 26UM_REGISTER_SINGLETON_MODULE(Permissions) 27 28- (EXPermissionStatus)getPermission:(NSString *)permissionType forExperience:(NSString *)experienceId 29{ 30 NSString *experienceIdKey = [EXPermissionsManager escapedResourceName:experienceId]; 31 NSDictionary *experiencePermissions = _permissionsCache[experienceIdKey]; 32 if (!experiencePermissions) { 33 return EXPermissionStatusUndetermined; 34 } 35 36 NSDictionary *permissionData = experiencePermissions[permissionType]; 37 if (!permissionData) { 38 return EXPermissionStatusUndetermined; 39 } 40 41 if ([permissionData[@"status"] isEqualToString:[EXPermissions permissionStringForStatus:EXPermissionStatusGranted]]) { 42 return EXPermissionStatusGranted; 43 } 44 45 return EXPermissionStatusDenied; 46} 47 48- (BOOL)hasGrantedPermission:(NSString *)permission forExperience:(NSString *)experienceId 49{ 50 if ([EXEnvironment sharedEnvironment].isDetached) { 51 return YES; 52 } 53 54 return [self getPermission:permission forExperience:experienceId] == EXPermissionStatusGranted; 55} 56 57- (BOOL)savePermission:(NSDictionary *)permission ofType:(NSString *)type forExperience:(NSString *)experienceId 58{ 59 NSString *experienceIdKey = [EXPermissionsManager escapedResourceName:experienceId]; 60 NSMutableDictionary *experiencePermissions; 61 if ([_permissionsCache objectForKey:experienceIdKey] == nil) { 62 experiencePermissions = [[NSMutableDictionary alloc] init]; 63 } else { 64 experiencePermissions = [[NSMutableDictionary alloc] initWithDictionary:_permissionsCache[experienceIdKey]]; 65 } 66 67 experiencePermissions[type] = permission; 68 _permissionsCache[experienceIdKey] = experiencePermissions; 69 [self synchronizeWithPermissions:_permissionsCache]; 70 return YES; 71} 72 73- (void)synchronizeWithPermissions:(NSDictionary *)permissions 74{ 75 [[NSUserDefaults standardUserDefaults] setObject:permissions forKey:EXPermissionsKey]; 76} 77 78+ (NSString *)escapedResourceName:(NSString *)name 79{ 80 NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]"; 81 NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet]; 82 return [name stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; 83} 84 85@end 86 87 88