Unify privilege representation
[platform/core/test/security-tests.git] / src / security-manager-tests / test_cases_privacy_manager.cpp
index 99faed9..ac72b73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
 #include <utility>
 #include <vector>
 
-#include <privilege_info.h>
-
 #include <app_install_helper.h>
 #include <cynara_test_admin.h>
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_runner_child.h>
+#include <pkg_privacy_privileges.h>
 #include <policy_configuration.h>
 #include <scoped_installer.h>
 #include <sm_api.h>
 #include <synchronization_pipe.h>
 #include <temp_test_user.h>
 #include <tests_common.h>
+#include <privilege_names.h>
+#include <app_def_privilege.h>
 
 using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
 namespace {
 struct UserInfo {
     std::string userName;
@@ -48,61 +50,32 @@ struct UserInfo {
 };
 
 // Privileges required for having permission to self/admin get/set policies.
-const std::string SELF_PRIVILEGE = "http://tizen.org/privilege/notexist";
-const std::string ADMIN_PRIVILEGE = "http://tizen.org/privilege/internal/usermanagement";
-
-typedef std::vector<std::string> Privileges;
-const std::vector<Privileges> TEST_PRIVILEGES = {
-    {
-        "http://tizen.org/privilege/internet",
-        "http://tizen.org/privilege/display"
-    },
-    {
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/datasharing"
-    },
-    {
-        "http://tizen.org/privilege/content.write",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/email"
-    },
-    {
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/email",
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/datasharing"
-    },
-    {
-        "http://tizen.org/privilege/internet",
-        "http://tizen.org/privilege/display",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/email"
-    }
+const std::string& SELF_PRIVILEGE = PRIV_NOTEXIST;
+const std::string& ADMIN_PRIVILEGE = PRIV_INTERNAL_USERMANAGEMENT;
+
+const std::vector<PrivilegeVector> TEST_PRIVILEGES = {
+    {PRIV_INTERNET, PRIV_DISPLAY},
+    {PRIV_TELEPHONY, PRIV_DATASHARING},
+    {PRIV_CONTENT_WRITE, PRIV_LED, PRIV_EMAIL},
+    {PRIV_LED, PRIV_EMAIL, PRIV_TELEPHONY, PRIV_DATASHARING},
+    {PRIV_INTERNET, PRIV_DISPLAY, PRIV_LED, PRIV_EMAIL}
 };
 
-const std::vector<Privileges> TEST_PRIVACY_PRIVILEGES = {
+const PrivilegeVector TEST_PRIVACY_PRIVILEGES[] = {
     {
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/callhistory.read", // privacy-related privileges start here
-        "http://tizen.org/privilege/account.read",
-        "http://tizen.org/privilege/healthinfo"
+        Privilege(PRIV_TELEPHONY),
+        Privilege(PRIV_LED),
+        Privilege(PRIV_CALLHISTORY_READ, Privilege::PRIVACY),
+        Privilege(PRIV_ACCOUNT_READ, Privilege::PRIVACY),
+        Privilege(PRIV_HEALTHINFO, Privilege::PRIVACY),
     },
     {
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/callhistory.read" // privacy-related privileges start here
+        Privilege(PRIV_TELEPHONY),
+        Privilege(PRIV_LED),
+        Privilege(PRIV_CALLHISTORY_READ, Privilege::PRIVACY),
     }
 };
 
-bool isPrivilegePrivacy(const Privilege &priv) {
-    return (1 == privilege_info_is_privacy(priv));
-}
-
-int countPrivacyPrivileges(const PrivilegeVector &privs) {
-    return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
-}
-
 }
 
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_PRIVACY_MANAGER)
@@ -160,7 +133,7 @@ RUNNER_CHILD_TEST(security_manager_10_privacy_manager_fetch_whole_policy_for_sel
             RUNNER_ASSERT_MSG(appIt != appIdToAIH.end(), "Policy returned unexpected app: " << app);
 
             AppInstallHelper &aih = appIt->second;
-            auto appPrivileges = aih.getPrivilegesNames();
+            auto& appPrivileges = aih.getPrivileges();
             auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
             RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
                               "Unexpected privilege " << privilege << " for app " << app);
@@ -241,7 +214,7 @@ RUNNER_CHILD_TEST(security_manager_11_privacy_manager_fetch_whole_policy_for_adm
             AppInstallHelper &aih = userAppIdToAIHIt->second;
             auto privs = aih.getPrivileges();
 
-            auto appPrivileges = aih.getPrivilegesNames();
+            auto& appPrivileges = aih.getPrivileges();
             auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
             RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
                               "Unexpected privilege " << privilege << " for app " << app);
@@ -333,7 +306,7 @@ RUNNER_CHILD_TEST(security_manager_12_privacy_manager_fetch_whole_policy_for_adm
             AppInstallHelper &aih = userAppIdToAIHIt->second;
             auto privs = aih.getPrivileges();
 
-            auto appPrivileges = aih.getPrivilegesNames();
+            auto& appPrivileges = aih.getPrivileges();
             auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
             RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
                               "Unexpected privilege " << privilege << " for app " << app);
@@ -398,7 +371,7 @@ RUNNER_CHILD_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_
                 normalUser.getUidString(),
                 app1.getPrivileges()[0]
                 );
-        policyEntry.setLevel("Deny");
+        policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
 
         policyRequest.addEntry(policyEntry);
         policyEntry = PolicyEntry(
@@ -406,7 +379,7 @@ RUNNER_CHILD_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_
                 normalUser.getUidString(),
                 app1.getPrivileges()[1]
                 );
-        policyEntry.setLevel("Deny");
+        policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
         policyRequest.addEntry(policyEntry);
         Api::sendPolicy(policyRequest);
 
@@ -473,15 +446,12 @@ RUNNER_CHILD_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_fo
         PolicyRequest setPolicyRequest;
         std::vector<PolicyEntry> policyEntries;
 
-        const std::string internetPriv = "http://tizen.org/privilege/internet";
-        const std::string displayPriv = "http://tizen.org/privilege/display";
-
-        PolicyEntry internetPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, internetPriv);
-        internetPolicyEntry.setMaxLevel("Deny");
+        PolicyEntry internetPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, PRIV_INTERNET);
+        internetPolicyEntry.setMaxLevel(PolicyEntry::LEVEL_DENY);
         setPolicyRequest.addEntry(internetPolicyEntry);
 
-        PolicyEntry displayPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, displayPriv);
-        displayPolicyEntry.setMaxLevel("Deny");
+        PolicyEntry displayPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, PRIV_DISPLAY);
+        displayPolicyEntry.setMaxLevel(PolicyEntry::LEVEL_DENY);
         setPolicyRequest.addEntry(displayPolicyEntry);
 
         Api::sendPolicy(setPolicyRequest);
@@ -510,7 +480,7 @@ RUNNER_CHILD_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_fo
 
 RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin)
 {
-    const std::string updatePriv = "http://tizen.org/privilege/led";
+    const std::string& updatePriv = PRIV_LED;
 
     TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
     adminUser.create();
@@ -537,7 +507,7 @@ RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_adm
                                 "drop_root_privileges failed");
 
         PolicyEntry entry(updatedApp.getAppId(), adminUser.getUidString(), updatePriv);
-        entry.setMaxLevel("Allow");
+        entry.setMaxLevel(PolicyEntry::LEVEL_ALLOW);
         PolicyRequest addPolicyRequest;
         addPolicyRequest.addEntry(entry);
         Api::sendPolicy(addPolicyRequest);
@@ -547,7 +517,7 @@ RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_adm
 
 RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin_wildcard)
 {
-    const std::string updatePriv = "http://tizen.org/privilege/led";
+    const std::string& updatePriv = PRIV_LED;
 
     TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
     adminUser.create();
@@ -573,7 +543,7 @@ RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_adm
                           "drop_root_privileges failed");
 
         PolicyEntry entry(SECURITY_MANAGER_ANY, adminUser.getUidString(), updatePriv);
-        entry.setMaxLevel("Allow");
+        entry.setMaxLevel(PolicyEntry::LEVEL_ALLOW);
 
         PolicyRequest addPolicyRequest;
         addPolicyRequest.addEntry(entry);
@@ -584,7 +554,7 @@ RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_adm
 
 RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_self)
 {
-    const std::string updatePriv = "http://tizen.org/privilege/led";
+    const std::string& updatePriv = PRIV_LED;
 
     TemporaryTestUser user("sm_test_15_username", GUM_USERTYPE_NORMAL);
     user.create();
@@ -609,7 +579,7 @@ RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_sel
                           "drop_root_privileges failed");
 
         PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
-        entry.setLevel("Allow");
+        entry.setLevel(PolicyEntry::LEVEL_ALLOW);
 
         PolicyRequest addPolicyRequest;
         addPolicyRequest.addEntry(entry);
@@ -646,11 +616,11 @@ RUNNER_CHILD_TEST(security_manager_16_policy_levels_get)
         std::string allowPolicy = std::string(levels[count-1]);
 
         // first should always be Deny
-        RUNNER_ASSERT_MSG(denyPolicy.compare("Deny") == 0,
+        RUNNER_ASSERT_MSG(denyPolicy.compare(PolicyEntry::LEVEL_DENY) == 0,
                 "Invalid first policy level. Should be Deny, instead there is: " << levels[0]);
 
         // last should always be Allow
-        RUNNER_ASSERT_MSG(allowPolicy.compare("Allow") == 0,
+        RUNNER_ASSERT_MSG(allowPolicy.compare(PolicyEntry::LEVEL_ALLOW) == 0,
                 "Invalid last policy level. Should be Allow, instead there is: " << levels[count-1]);
         exit(0);
     }
@@ -658,7 +628,7 @@ RUNNER_CHILD_TEST(security_manager_16_policy_levels_get)
 
 RUNNER_CHILD_TEST(security_manager_17a_privacy_manager_delete_policy_for_self)
 {
-    const std::string updatePriv = "http://tizen.org/privilege/led";
+    const std::string& updatePriv = PRIV_LED;
 
     TemporaryTestUser user("sm_test_17a_username", GUM_USERTYPE_NORMAL);
     user.create();
@@ -688,7 +658,7 @@ RUNNER_CHILD_TEST(security_manager_17a_privacy_manager_delete_policy_for_self)
                                             "drop_root_privileges failed");
 
         PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
-        entry.setLevel("Allow");
+        entry.setLevel(PolicyEntry::LEVEL_ALLOW);
         PolicyRequest addPolicyRequest;
         addPolicyRequest.addEntry(entry);
         Api::sendPolicy(addPolicyRequest);
@@ -708,7 +678,7 @@ RUNNER_CHILD_TEST(security_manager_17a_privacy_manager_delete_policy_for_self)
 
 RUNNER_CHILD_TEST(security_manager_17b_privacy_manager_delete_policy_for_self)
 {
-    const std::string updatePriv = "http://tizen.org/privilege/led";
+    const std::string& updatePriv = PRIV_LED;
 
     TemporaryTestUser user("sm_test_17b_username", GUM_USERTYPE_NORMAL);
     user.create();
@@ -743,7 +713,7 @@ RUNNER_CHILD_TEST(security_manager_17b_privacy_manager_delete_policy_for_self)
                                 "drop_root_privileges failed");
 
         PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
-        entry.setLevel("Allow");
+        entry.setLevel(PolicyEntry::LEVEL_ALLOW);
         PolicyRequest addPolicyRequest;
         addPolicyRequest.addEntry(entry);
         Api::sendPolicy(addPolicyRequest);
@@ -836,7 +806,6 @@ RUNNER_CHILD_TEST(security_manager_17_privacy_manager_fetch_whole_policy_for_sel
 
 RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges_policy_install_remove)
 {
-    const std::string askUserDescription = "Ask user";
     TemporaryTestUser user("sm_test_18_username", GUM_USERTYPE_NORMAL);
     user.create();
 
@@ -846,6 +815,7 @@ RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges
     PolicyEntry filter (app.getAppId(), user.getUidString(), SECURITY_MANAGER_ANY);
     std::vector<PolicyEntry> policyEntries;
     {
+        PkgPrivacyPrivileges setupPrivacyPrivs(app);
         ScopedInstaller installer(app);
         unsigned int privacyNum = countPrivacyPrivileges(app.getPrivileges());
 
@@ -859,7 +829,7 @@ RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges
             unsigned int privacyActNum = 0;
             for (auto &entry : policyEntries)
                 if (isPrivilegePrivacy(entry.getPrivilege())) {
-                    RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+                    RUNNER_ASSERT_MSG(entry.getCurrentLevel() == PolicyEntry::LEVEL_ASK_USER,
                                       "Invalid policy setup; policy should be \"Ask user\" but is "
                                       << entry.getCurrentLevel());
                     ++privacyActNum;
@@ -878,7 +848,6 @@ RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges
 }
 
 void test_privacy_related_privileges(bool isHybrid) {
-    const std::string askUserDescription = "Ask user";
     TemporaryTestUser user("sm_test_19_username", GUM_USERTYPE_NORMAL);
     user.create();
 
@@ -888,12 +857,14 @@ void test_privacy_related_privileges(bool isHybrid) {
     if (isHybrid)
         app1.setHybrid();
     app1.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
+    PkgPrivacyPrivileges setupPrivacyPrivs1(app1);
     ScopedInstaller installer1(app1);
 
     AppInstallHelper app2("sm_test_19_app_id_2", pkgId, user.getUid());
     if (isHybrid)
         app2.setHybrid();
     app2.addPrivileges(TEST_PRIVACY_PRIVILEGES[1]);
+    PkgPrivacyPrivileges setupPrivacyPrivs2(app2);
     ScopedInstaller installer2(app2);
 
     int privacyCount1, privacyCount2;
@@ -917,7 +888,7 @@ void test_privacy_related_privileges(bool isHybrid) {
                           "Invalid appId: should be either " << app1.getAppId() << " or "
                           << app2.getAppId() << " but is " << entry.getAppId());
         if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(entry.getPrivilege())) {
-            RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+            RUNNER_ASSERT_MSG(entry.getCurrentLevel() == PolicyEntry::LEVEL_ASK_USER,
                               "Invalid policy setup; policy should be \"Ask user\" but is "
                               << entry.getCurrentLevel());
             if (entry.getAppId() == app1.getAppId())
@@ -944,20 +915,20 @@ RUNNER_CHILD_TEST(security_manager_19b_privacy_manager_privacy_related_privilege
 
 RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges_policy_admin_check)
 {
-    const std::string askUserDescription = "Ask user";
     TemporaryTestUser user("sm_test_20_username", GUM_USERTYPE_NORMAL);
     user.create();
 
     AppInstallHelper app("sm_test_20", user.getUid());
     app.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
 
+    PkgPrivacyPrivileges setupPrivacyPrivs(app);
     ScopedInstaller installer(app);
 
     CynaraTestAdmin::Admin admin;
     int policyType = CYNARA_ADMIN_ALLOW;
     int privacyPolicyType = -1;
     if (PolicyConfiguration::getIsAskuserEnabled())
-        admin.getPolicyTypeForDescription(askUserDescription, privacyPolicyType);
+        admin.getPolicyTypeForDescription(PolicyEntry::LEVEL_ASK_USER, privacyPolicyType);
 
     for (auto &priv : app.getPrivileges()) {
         if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(priv)) {
@@ -970,3 +941,311 @@ RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges
         }
     }
 }
+
+RUNNER_CHILD_TEST(security_manager_21_fetch_app_manifest_invalid_params)
+{
+    int ret = security_manager_get_app_manifest_policy(nullptr, 0, nullptr, nullptr);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_INPUT_PARAM, "Expected invalid input param, returned " << ret);
+}
+
+
+RUNNER_CHILD_TEST(security_manager_22_fetch_app_manifest_no_app)
+{
+    char **privileges;
+    size_t nPrivs = 0;
+    int ret = security_manager_get_app_manifest_policy("not_existing_app_id", 0, &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "Expected no such object error, returned " << ret);
+}
+
+RUNNER_CHILD_TEST(security_manager_23_fetch_app_manifest_invalid_user)
+{
+    TemporaryTestUser user("sm_test_23_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_23_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges(TEST_PRIVACY_PRIVILEGES[1]);
+    ScopedInstaller appInstall(app);
+
+    char **privileges;
+    size_t nPrivs = 0;
+    int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), 0, &privileges, &nPrivs);
+    // Should security-manager check if user exists?
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    RUNNER_ASSERT_MSG(nPrivs == 0, "Expected empty set of privileges, returned " << nPrivs);
+}
+
+static void check_privileges_from_manifest(const AppInstallHelper &aih, char **privileges, size_t nPrivs)
+{
+    auto& aihPrivs = aih.getPrivileges();
+    RUNNER_ASSERT_MSG(nPrivs == aihPrivs.size(), "Expected privileges number: " << aihPrivs.size() << ", got " << nPrivs);
+    for (size_t i = 0; i < nPrivs; ++i) {
+        RUNNER_ASSERT_MSG(std::find(aihPrivs.begin(), aihPrivs.end(), std::string(privileges[i])) != aihPrivs.end(),
+                          "Privilege " << privileges[i] << " not found");
+    }
+}
+
+RUNNER_CHILD_TEST(security_manager_24_fetch_app_manifest_global_app)
+{
+    TemporaryTestUser user("sm_test_24_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_24_fetch");
+    app.setInstallType(SM_APP_INSTALL_GLOBAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    char **privileges;
+    size_t nPrivs = 0;
+
+    int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), 0, &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    check_privileges_from_manifest(app, privileges, nPrivs);
+    security_manager_privileges_free(privileges, nPrivs);
+
+    // since app is installed globally, also for our temporary user the returned list should be the same
+    nPrivs = 0;
+    ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    check_privileges_from_manifest(app, privileges, nPrivs);
+    security_manager_privileges_free(privileges, nPrivs);
+}
+
+RUNNER_CHILD_TEST(security_manager_25_fetch_app_manifest_local_app)
+{
+    TemporaryTestUser user("sm_test_25_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_25_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    char **privileges;
+    size_t nPrivs = 0;
+
+    int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    check_privileges_from_manifest(app, privileges, nPrivs);
+    security_manager_privileges_free(privileges, nPrivs);
+
+    // since app is installed locally, if we ask for other user (ie. root), we should get empty list of privileges
+    nPrivs = 0;
+    ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), 0, &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    RUNNER_ASSERT_MSG(nPrivs == 0, "Expected empty set of privileges, returned " << nPrivs);
+}
+
+RUNNER_CHILD_TEST(security_manager_26_fetch_app_manifest_both_apps)
+{
+    TemporaryTestUser user("sm_test_26_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper appGlobal("security_manager_26_fetch");
+    appGlobal.setInstallType(SM_APP_INSTALL_GLOBAL);
+    appGlobal.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
+    ScopedInstaller appGlobalInstall(appGlobal);
+
+    AppInstallHelper appLocal("security_manager_26_fetch", user.getUid());
+    appLocal.setInstallType(SM_APP_INSTALL_LOCAL);
+    appLocal.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appLocalInstall(appLocal);
+
+
+    char **privileges;
+    size_t nPrivs = 0;
+
+    int ret = security_manager_get_app_manifest_policy(appLocal.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+    check_privileges_from_manifest(appLocal, privileges, nPrivs);
+    security_manager_privileges_free(privileges, nPrivs);
+
+    nPrivs = 0;
+    ret = security_manager_get_app_manifest_policy(appGlobal.getAppId().c_str(), 0, &privileges, &nPrivs);
+    RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected succes, returned " << ret);
+    check_privileges_from_manifest(appGlobal, privileges, nPrivs);
+    security_manager_privileges_free(privileges, nPrivs);
+}
+
+RUNNER_CHILD_TEST(security_manager_27_fetch_app_manifest_app_context_local_positive)
+{
+    TemporaryTestUser user("sm_test_27_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_27_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+    if (pid != 0) { //parent process
+        waitPid(pid);
+    } else { //child process
+        Api::setProcessLabel(app.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(
+                drop_root_privileges(user.getUid(), user.getGid()) == 0,
+                "drop_root_privileges failed");
+        char **privileges;
+        size_t nPrivs = 0;
+        int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+        exit(0);
+    }
+}
+
+RUNNER_CHILD_TEST(security_manager_28_fetch_app_manifest_app_context_global_positive)
+{
+    TemporaryTestUser user("sm_test_28_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_28_fetch");
+    app.setInstallType(SM_APP_INSTALL_GLOBAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+    if (pid != 0) { //parent process
+        waitPid(pid);
+    } else { //child process
+        Api::setProcessLabel(app.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(
+                drop_root_privileges(user.getUid(), user.getGid()) == 0,
+                "drop_root_privileges failed");
+        char **privileges;
+        size_t nPrivs = 0;
+        int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+        exit(0);
+    }
+}
+
+RUNNER_CHILD_TEST(security_manager_29_fetch_app_manifest_app_context_local_different_uid)
+{
+    TemporaryTestUser user("sm_test_29_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    TemporaryTestUser user1("sm_test_29_fetch_username_1", GUM_USERTYPE_NORMAL);
+    user1.create();
+
+    AppInstallHelper app("security_manager_29_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    AppInstallHelper app1("security_manager_29_fetch", user1.getUid());
+    app1.setInstallType(SM_APP_INSTALL_LOCAL);
+    app1.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
+    ScopedInstaller appInstall1(app1);
+
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+    if (pid != 0) { //parent process
+        waitPid(pid);
+    } else { //child process
+        Api::setProcessLabel(app1.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(
+                drop_root_privileges(user1.getUid(), user1.getGid()) == 0,
+                "drop_root_privileges failed");
+        char **privileges;
+        size_t nPrivs = 0;
+        int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "Expected auth failed, returned " << ret);
+
+        nPrivs = 0;
+        ret = security_manager_get_app_manifest_policy(app1.getAppId().c_str(), user1.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app1, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+        exit(0);
+    }
+}
+
+RUNNER_CHILD_TEST(security_manager_30_fetch_app_manifest_app_context_local_different_label)
+{
+    TemporaryTestUser user("sm_test_30_fetch_username", GUM_USERTYPE_NORMAL);
+    user.create();
+
+    AppInstallHelper app("security_manager_30_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    AppInstallHelper app1("security_manager_30_fetch_1", user.getUid());
+    app1.setInstallType(SM_APP_INSTALL_LOCAL);
+    app1.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
+    ScopedInstaller appInstall1(app1);
+
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+    if (pid != 0) { //parent process
+        waitPid(pid);
+    } else { //child process
+        Api::setProcessLabel(app1.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(
+                drop_root_privileges(user.getUid(), user.getGid()) == 0,
+                "drop_root_privileges failed");
+        char **privileges;
+        size_t nPrivs = 0;
+        int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "Expected auth failed, returned " << ret);
+
+        nPrivs = 0;
+        ret = security_manager_get_app_manifest_policy(app1.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app1, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+        exit(0);
+    }
+}
+
+RUNNER_CHILD_TEST(security_manager_31_fetch_app_manifest_app_context_local_different_label_with_privilege)
+{
+    TemporaryTestUser user("sm_test_31_fetch_username", GUM_USERTYPE_ADMIN);
+    user.create();
+
+    AppInstallHelper app("security_manager_31_fetch", user.getUid());
+    app.setInstallType(SM_APP_INSTALL_LOCAL);
+    app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
+    ScopedInstaller appInstall(app);
+
+    AppInstallHelper app1("security_manager_31_fetch_1", user.getUid());
+    app1.setInstallType(SM_APP_INSTALL_LOCAL);
+    app1.addPrivileges({PRIV_CALENDAR_READ,
+                        PRIV_CALENDAR_WRITE,
+                        PRIV_CONTACTS_READ,
+                        PRIV_INTERNAL_USERMANAGEMENT});
+    ScopedInstaller appInstall1(app1);
+
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+    if (pid != 0) { //parent process
+        waitPid(pid);
+    } else { //child process
+        Api::setProcessLabel(app1.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(
+                drop_root_privileges(user.getUid(), user.getGid()) == 0,
+                "drop_root_privileges failed");
+        char **privileges;
+        size_t nPrivs = 0;
+        int ret = security_manager_get_app_manifest_policy(app.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+
+        nPrivs = 0;
+        ret = security_manager_get_app_manifest_policy(app1.getAppId().c_str(), user.getUid(), &privileges, &nPrivs);
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "Expected success, returned " << ret);
+        check_privileges_from_manifest(app1, privileges, nPrivs);
+        security_manager_privileges_free(privileges, nPrivs);
+        exit(0);
+    }
+}