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