[Service] APIRouter - xwalk.util.checkPrivilegeAccess 20/243720/8 submit/tizen/20200924.160008
authorDongHyun Song <dh81.song@samsung.com>
Wed, 9 Sep 2020 09:31:38 +0000 (18:31 +0900)
committerDongHyun Song <dh81.song@samsung.com>
Thu, 24 Sep 2020 04:27:02 +0000 (13:27 +0900)
xwalk.util.checkPrivilegeAccess() is an internal API of webapis
for checking the app has proper privilege.
If the app hasn't required privilege, it will throw exception.

For example, When 'tizen.filesystem.listStorages' is handled
  xwalk.utils.checkPrivilegeAccess(
      xwalk.utils.privilege.FILESYSTEM_READ);
it checks if the app has 'filesystem.read' privilege, then,
this overrided checkPrivilegeAccess() can inspect its privileges
defined in config.xml. (not wrt-service's privileges)

This is different from AccessControlManager's webapis drops.

In webapis, there are two ways of privilege checking.
  1) by xwalk.util.checkPrivilegeAccess()
  2) by cynara inspection directly

AccessControlManager purpose should be considered way #2.
webapis's cynara DB checking, it always inspects on wrt-service's.
Then, AccessControlManager should be able to disable webapis which
the app doesn't have required privileges.

Change-Id: I84ce85a580a483c209d354ca2f1b7c3d17c08fb3
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
wrt_app/common/service_manager.ts
wrt_app/common/service_runner.ts
wrt_app/common/wrt_xwalk_extension.ts
wrt_app/service/device_api_router.ts

index 1ce2ea5..3038364 100644 (file)
@@ -5,15 +5,16 @@ interface WorkerMap {
   [id: string]: any;
 }
 let workers: WorkerMap = {};
-let serviceType: string = wrt.getServiceModel();
 let runner: any;
 
-function isGlobalService() {
-  return serviceType === 'DAEMON';
-}
+global.serviceType = wrt.getServiceModel();
 
 function isStandalone() {
-  return serviceType === 'STANDALONE';
+  return global.serviceType === 'STANDALONE';
+}
+
+function isGlobalService() {
+  return global.serviceType === 'DAEMON';
 }
 
 function createWorker(id: string, startService: string, filename: string) {
index 7ea5bca..286297a 100644 (file)
@@ -4,14 +4,12 @@ import { DeviceAPIRouter } from '../service/device_api_router';
 import { isMainThread, parentPort, workerData } from 'worker_threads';
 import { wrt } from '../browser/wrt';
 
-let serviceType: string = wrt.getServiceModel();
-
 function isServiceApplication() {
-  return serviceType !== 'UI';
+  return global.serviceType !== 'UI';
 }
 
 function isGlobalService() {
-  return serviceType === 'DAEMON';
+  return global.serviceType === 'DAEMON';
 }
 
 function registerExtensionResolver(id: string) {
@@ -41,7 +39,7 @@ export function start(id: string, filename: string) {
     }
   });
 
-  console.log('serviceType : '+serviceType)
+  console.log(`serviceType : ${global.serviceType}`)
   new DeviceAPIRouter(id, isGlobalService());
 
   if (isServiceApplication()) {
index 461e7dd..f7ba13d 100644 (file)
@@ -117,14 +117,19 @@ class XWalkExtension {
     this.createNamespace(global, ext.name);
 
     var api = (ext.use_trampoline) ? api_ : global;
-
+    var extension_api = ext.jsapi;
+    if (global.serviceType === 'DAEMON' && ext.name === 'xwalk') {
+      console.log(`Delete freeze exports.utils for override method`);
+      extension_api = extension_api.replace('Object.freeze(exports.utils);', '');
+      extension_api = extension_api.replace('Object.freeze(Utils.prototype);', '');
+    }
     const jscode =
       '(function(extension) {' +
       '  extension.internal = {};' +
       '  extension.internal.sendSyncMessage = extension.sendSyncMessage;' +
       '  delete extension.sendSyncMessage;' +
       '  var exports = {}; ' +
-      '  (function() {\'use strict\'; ' + ext.jsapi + '})();' +
+      '  (function() {\'use strict\'; ' + extension_api + '})();' +
       '  api.' + ext.name + ' = exports; ' +
       '});';
 
index 5d65aa3..b7a6e0f 100644 (file)
@@ -14,6 +14,7 @@ export class DeviceAPIRouter {
   serviceId: string;
   packageId: string;
   callerAppId: string;
+  permissions: string[];
 
   constructor(id: string, isGlobal: boolean) {
     this.id = id;
@@ -21,6 +22,7 @@ export class DeviceAPIRouter {
     this.serviceId = ids[0];
     this.callerAppId = ids[1] ?? '';
     this.packageId = this.serviceId.split('.')[0];
+    this.permissions = wrt.getPrivileges(this.id);
 
     this.initWebapis();
     if (isGlobal) {
@@ -28,6 +30,7 @@ export class DeviceAPIRouter {
       this.refinePackageApis();
       this.refineFilesystemApis()
       this.initAccessControlManager();
+      this.refineXwalkUtilApis();
     }
   }
 
@@ -50,10 +53,9 @@ export class DeviceAPIRouter {
   }
 
   initAccessControlManager() {
-    const permissions = wrt.getPrivileges(this.id);
-    console.log(`permissions : ${permissions}`);
+    console.log(`permissions : ${this.permissions}`);
     const AccessControlManager = require('./access_control_manager');
-    AccessControlManager.initialize(permissions);
+    AccessControlManager.initialize(this.permissions);
   }
 
   getServiceId() {
@@ -152,4 +154,12 @@ export class DeviceAPIRouter {
     global.tizen.filesystem.isDirectory = this.injectVirtualRootResolver(global.tizen.filesystem.isDirectory);
     global.tizen.filesystem.pathExists = this.injectVirtualRootResolver(global.tizen.filesystem.pathExists);
   }
+
+  refineXwalkUtilApis() {
+    global.xwalk.utils.checkPrivilegeAccess = (privilege: string) => {
+      if (!this.permissions.includes(privilege)) {
+        throw 'Permission denied';
+      }
+    }
+  }
 }