1 package versioned.host.exp.exponent.modules.universal
2 
3 import expo.modules.core.ModuleRegistry
4 import expo.modules.filesystem.FilePermissionModule
5 import expo.modules.interfaces.constants.ConstantsInterface
6 import expo.modules.interfaces.filesystem.Permission
7 import host.exp.exponent.utils.ScopedContext
8 import java.io.File
9 import java.io.IOException
10 import java.util.*
11 
12 class ScopedFilePermissionModule(private val scopedContext: ScopedContext) : FilePermissionModule() {
13 
14   private lateinit var moduleRegistry: ModuleRegistry
15 
getExternalPathPermissionsnull16   override fun getExternalPathPermissions(path: String): EnumSet<Permission> {
17     try {
18       // In scoped context we do not allow access to Expo Go's directory,
19       // however accessing other directories is ok as far as we're concerned.
20       val context = scopedContext.context
21       val dataDirCanonicalPath = File(context.applicationInfo.dataDir).canonicalPath
22       val canonicalPath = File(path).canonicalPath
23       val isInDataDir = canonicalPath.startsWith("$dataDirCanonicalPath/") || (canonicalPath == dataDirCanonicalPath)
24       if (shouldForbidAccessToDataDirectory() && isInDataDir) {
25         return EnumSet.noneOf(Permission::class.java)
26       }
27     } catch (e: IOException) {
28       // Something's not right, let's be cautious.
29       return EnumSet.noneOf(Permission::class.java)
30     }
31     return super.getExternalPathPermissions(path)
32   }
33 
shouldForbidAccessToDataDirectorynull34   private fun shouldForbidAccessToDataDirectory(): Boolean {
35     val constantsModule = moduleRegistry.getModule(ConstantsInterface::class.java)
36     // If there's no constants module, or app ownership isn't "expo", we're not in Expo Go.
37     return constantsModule != null && "expo" == constantsModule.appOwnership
38   }
39 
onCreatenull40   override fun onCreate(moduleRegistry: ModuleRegistry) {
41     this.moduleRegistry = moduleRegistry
42   }
43 }
44