From 08c58a1984d90ac93c25f51ac6a566ab08ca441f Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Mon, 12 Jun 2017 16:01:32 +0200 Subject: [PATCH 01/16] AppQueryInterface logic export IsPkgInstalled() and GetPkgId() have the same implementation for wgt-backend and tpk-backend, so only GetPkgIdFromPath() should be overrided in each backend. Submit together: - https://review.tizen.org/gerrit/#/c/133520/ - https://review.tizen.org/gerrit/#/c/133518/ Change-Id: I40b61fbea37838ccd372b964fe3cf54eb5f5f5a6 Signed-off-by: Damian Pietruchowski --- src/wgt/wgt_app_query_interface.cc | 62 +++++++++++++------------------------- src/wgt/wgt_app_query_interface.h | 19 +++--------- 2 files changed, 25 insertions(+), 56 deletions(-) diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 7b2eee4..908cd6b 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -37,20 +37,26 @@ namespace { const char kHybridConfigLocation[] = "res/wgt/config.xml"; const char kTizenManifestLocation[] = "tizen-manifest.xml"; -std::string GetPkgIdFromPath(const std::string& path) { - if (!bf::exists(path)) - return {}; - bf::path tmp_path = common_installer::GenerateTmpDir("/tmp"); - bs::error_code code; - bf::create_directories(tmp_path, code); - if (code) - return {}; - if (!common_installer::ExtractToTmpDir(path.c_str(), tmp_path, - "config.xml")) { - ci::RemoveAll(tmp_path); +std::string ReadPkgidFromRecovery(const std::string& recovery_path) { + std::unique_ptr recovery_file = + ci::recovery::RecoveryFile::OpenRecoveryFileForPath(recovery_path); + recovery_file->Detach(); + return recovery_file->pkgid(); +} + +} // namespace + +namespace wgt { + +std::string WgtAppQueryInterface::GetManifestFileName() const { + return "config.xml"; +} + +std::string WgtAppQueryInterface::GetPkgIdFromPath( + const std::string& path) const { + bf::path tmp_path = ExtractManifest(path); + if (tmp_path.empty()) return {}; - } - bf::path config_path = tmp_path / "config.xml"; std::vector> handlers = { std::make_shared(), std::make_shared() @@ -59,6 +65,7 @@ std::string GetPkgIdFromPath(const std::string& path) { new parser::ManifestHandlerRegistry(handlers)); std::unique_ptr parser( new parser::ManifestParser(std::move(registry))); + bf::path config_path = tmp_path / GetManifestFileName(); if (!parser->ParseManifest(config_path)) { ci::RemoveAll(tmp_path); return {}; @@ -76,31 +83,8 @@ std::string GetPkgIdFromPath(const std::string& path) { return pkg_id; } -std::string ReadPkgidFromRecovery(const std::string& recovery_path) { - std::unique_ptr recovery_file = - ci::recovery::RecoveryFile::OpenRecoveryFileForPath(recovery_path); - recovery_file->Detach(); - return recovery_file->pkgid(); -} - -} // namespace - -namespace wgt { - -bool WgtAppQueryInterface::IsPkgInstalled(const std::string& arg, uid_t uid) { - // argument from commandline is package id - if (ci::QueryIsPackageInstalled(arg, ci::GetRequestMode(uid), uid)) - return true; - - // argument from commandline is path to file - std::string pkg_id = GetPkgIdFromPath(arg); - if (pkg_id.empty()) - return false; - return ci::QueryIsPackageInstalled(pkg_id, ci::GetRequestMode(uid), uid); -} - bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, - uid_t uid) { + uid_t uid) const { std::string info; bool is_recovery = arg.find("wgt-recovery-") != std::string::npos; if (is_recovery) @@ -128,8 +112,4 @@ bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, return false; } -std::string WgtAppQueryInterface::GetPkgId(const std::string& arg) { - return GetPkgIdFromPath(arg); -} - } // namespace wgt diff --git a/src/wgt/wgt_app_query_interface.h b/src/wgt/wgt_app_query_interface.h index 3610da9..c19d46a 100644 --- a/src/wgt/wgt_app_query_interface.h +++ b/src/wgt/wgt_app_query_interface.h @@ -21,27 +21,16 @@ namespace wgt { class WgtAppQueryInterface : public common_installer::AppQueryInterface { public: /** - * \brief method for checking if package is installed based - * on argv - * - * \return true if package is installed - */ - bool IsPkgInstalled(const std::string& arg, uid_t uid) override; - - /** * \brief This method is workaround for detecting installation of hybrid * application. * * \return true if package is hybrid */ - bool IsHybridApplication(const std::string& arg, uid_t uid); + bool IsHybridApplication(const std::string& arg, uid_t uid) const; - /** - * \brief method for getting package id from package file - * - * \return package id - */ - std::string GetPkgId(const std::string& arg) override; + private: + std::string GetPkgIdFromPath(const std::string& path) const override; + std::string GetManifestFileName() const override; }; } // namespace wgt -- 2.7.4 From e235b5f6469dff0d5baaaf4a4d87e4749f525a38 Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Tue, 18 Jul 2017 13:37:28 +0200 Subject: [PATCH 02/16] Adapter interface for external PkgMgr module Submit together: - https://review.tizen.org/gerrit/#/c/138998/ - https://review.tizen.org/gerrit/#/c/139346/ Change-Id: Ia27cf4fa824258cb1df1a8a48b8601ddacc66f89 Signed-off-by: Damian Pietruchowski --- src/unit_tests/smoke_test.cc | 16 ++++++++-------- src/unit_tests/smoke_utils.cc | 22 +++++++++++----------- src/wgt/step/configuration/step_parse.cc | 14 ++++++-------- src/wgt/wgt_app_query_interface.cc | 4 ++-- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index d907386..b55392a 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -120,9 +120,8 @@ TEST_F(SmokeTest, EnablePkg) { ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK); - ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid, - ci::GetRequestMode(kTestUserId), - kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_TRUE(pkg_query.IsPackageInstalled(ci::GetRequestMode(kTestUserId))); } TEST_F(SmokeTest, DisablePkg) { @@ -559,7 +558,8 @@ TEST_F(SmokeTest, UserDefinedPlugins) { ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); ASSERT_TRUE(ValidatePackage(pkgid, {appid})); std::vector res; - ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_TRUE(pkg_query.PrivilegesForPkgId(&res)); ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end()); ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege) != res.end()); @@ -641,8 +641,8 @@ TEST_F(PreloadSmokeTest, ManifestDirectInstallMode) { bf::path pkg_path = ci::GetRootAppPath(false, kTestUserId); CopyDir(src_path / pkgid, pkg_path / pkgid); - ASSERT_FALSE(QueryIsPackageInstalled(pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_FALSE(pkg_query.IsPackageInstalled(ci::GetRequestMode(kTestUserId))); ASSERT_EQ(ManifestDirectInstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK); ASSERT_TRUE(ValidatePackage(pkgid, {appid})); @@ -702,8 +702,8 @@ TEST_F(PreloadSmokeTest, ManifestDirectInstallMode_Hybrid) { bf::path pkg_path = ci::GetRootAppPath(false, kTestUserId); CopyDir(src_path / pkgid, pkg_path / pkgid); - ASSERT_FALSE(QueryIsPackageInstalled(pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_FALSE(pkg_query.IsPackageInstalled(ci::GetRequestMode(kTestUserId))); ASSERT_EQ(ManifestDirectInstall(pkgid, PackageType::HYBRID), ci::AppInstaller::Result::OK); ASSERT_TRUE(ValidatePackage(pkgid, {appid})); diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index fabb37c..41c777d 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -377,8 +377,9 @@ void PackageCheckCleanup(const std::string& pkgid, bool ValidatePackage(const std::string& pkgid, const std::vector& appids, bool is_readonly) { - EXTENDED_ASSERT_TRUE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + EXTENDED_ASSERT_TRUE(pkg_query.IsPackageInstalled( + ci::GetRequestMode(kTestUserId))); EXTENDED_ASSERT_TRUE(ValidatePackageFS( pkgid, appids, kTestUserId, kTestGroupId, is_readonly)); if (kTestUserId == kGlobalUserUid) { @@ -403,10 +404,9 @@ void ValidateExternalPackageFS(const std::string& pkgid, void ValidateExternalPackage(const std::string& pkgid, const std::vector& appids) { - ASSERT_TRUE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); - std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_TRUE(pkg_query.IsPackageInstalled(ci::GetRequestMode(kTestUserId))); + std::string storage = pkg_query.StorageForPkgId(); bf::path ext_mount_path = ci::GetExternalCardPath(); if (bf::is_empty(ext_mount_path)) { LOG(INFO) << "Sdcard not exists!"; @@ -426,9 +426,9 @@ void ValidateExternalPackage(const std::string& pkgid, bool CheckPackageNonExistance(const std::string& pkgid, const std::vector& appids) { - EXTENDED_ASSERT_FALSE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), - kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + EXTENDED_ASSERT_FALSE(pkg_query.IsPackageInstalled( + ci::GetRequestMode(kTestUserId))); PackageCheckCleanup(pkgid, appids); if (kTestUserId == kGlobalUserUid) { ci::UserList list = ci::GetUserList(); @@ -445,8 +445,8 @@ bool CheckPackageNonExistance(const std::string& pkgid, void CheckPackageReadonlyNonExistance(const std::string& pkgid, const std::vector& appids) { - ASSERT_FALSE(ci::QueryIsPackageInstalled( - pkgid, ci::GetRequestMode(kTestUserId), kTestUserId)); + ci::PkgQueryInterface pkg_query(pkgid, kTestUserId); + ASSERT_FALSE(pkg_query.IsPackageInstalled(ci::GetRequestMode(kTestUserId))); PackageCheckCleanup(pkgid, appids, true); } diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index 9045043..c339a8f 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -314,19 +314,17 @@ bool StepParse::FillWidgetInfo(manifest_x* manifest) { if (!context_->pkgid.get().empty()) { // set update true if package is updated preload package ci::RequestType req_type = context_->request_type.get(); - if (ci::QueryIsUpdatedPackage(context_->pkgid.get(), context_->uid.get())) + ci::PkgQueryInterface pkg_query(manifest->package, context_->uid.get()); + if (pkg_query.IsUpdatedPackage()) manifest->update = strdup("true"); - else if (ci::QueryIsPreloadPackage(context_->pkgid.get(), - context_->uid.get()) && + else if (pkg_query.IsPreloadPackage() && (req_type == ci::RequestType::Update || - req_type == ci::RequestType::Delta || - req_type == ci::RequestType::MountUpdate || - req_type == ci::RequestType::ReadonlyUpdateInstall)) + req_type == ci::RequestType::Delta || + req_type == ci::RequestType::MountUpdate || + req_type == ci::RequestType::ReadonlyUpdateInstall)) manifest->update = strdup("true"); else manifest->update = strdup("false"); - } else { - manifest->update = strdup("false"); } return true; diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 908cd6b..5f931e0 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -91,8 +91,8 @@ bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, info = ReadPkgidFromRecovery(arg); else info = arg; - - if (ci::QueryIsPackageInstalled(info, ci::GetRequestMode(uid), uid)) { + ci::PkgQueryInterface pkg_query(info, uid); + if (pkg_query.IsPackageInstalled(ci::GetRequestMode(uid))) { bf::path package_directory(ci::GetRootAppPath(false, uid)); if (bf::exists(package_directory / info / kTizenManifestLocation) && bf::exists(package_directory / info / kHybridConfigLocation)) -- 2.7.4 From 10701396f2b48b43317db12bcbf43733d0fbde8d Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Tue, 29 Aug 2017 13:53:56 +0900 Subject: [PATCH 03/16] Release version 0.7.0 Changes: - Perform code style checking fixes - Merge "Perform code style checking fixes" into tizen - AppQueryInterface logic export - Adapter interface for external PkgMgr module Change-Id: I11e9458090277484b8176e5dbabd7a7328c3b291 Signed-off-by: Sangyoon Jang --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index 8530831..e0c49df 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.6.2 +Version: 0.7.0 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From 0f0538eafbb2361498066f8c1671adf6728e9764 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Mon, 4 Sep 2017 17:09:17 +0900 Subject: [PATCH 04/16] Fix codes for ManifestDirectInstall in Hybrid pkg - Backend couldn't detect hybrid pkg if pkginfo doesn't exist in db. - ManifestDirectInstall cannot be performed because of reason above. - So change if statement to check designated directory even if there are no information in db. - RO path will be checked only if given uid is privileged one. Change-Id: Ic4855cfa1090b1e5bac1b98d6ca69507657de357 Signed-off-by: Junghyun Yeon --- src/wgt/wgt_app_query_interface.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 5f931e0..4afdc3d 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -91,11 +91,14 @@ bool WgtAppQueryInterface::IsHybridApplication(const std::string& arg, info = ReadPkgidFromRecovery(arg); else info = arg; - ci::PkgQueryInterface pkg_query(info, uid); - if (pkg_query.IsPackageInstalled(ci::GetRequestMode(uid))) { - bf::path package_directory(ci::GetRootAppPath(false, uid)); - if (bf::exists(package_directory / info / kTizenManifestLocation) && - bf::exists(package_directory / info / kHybridConfigLocation)) + bf::path rw_package_directory(ci::GetRootAppPath(false, uid)); + bf::path ro_package_directory; + if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) || uid == 0) + ro_package_directory = ci::GetRootAppPath(true, uid); + if ((bf::exists(rw_package_directory / info / kTizenManifestLocation) && + bf::exists(rw_package_directory / info / kHybridConfigLocation)) || + (bf::exists(ro_package_directory / info / kTizenManifestLocation) && + bf::exists(ro_package_directory / info / kHybridConfigLocation))) { return true; } else if (!is_recovery) { bool tizen_manifest_found = false; -- 2.7.4 From 21e72ace3b7b3df228173ffc839bbf02b7219e9b Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Tue, 19 Sep 2017 18:39:34 +0900 Subject: [PATCH 05/16] Fix build fail Signed-off-by: Seungha Son Change-Id: Ia0aaccb503d49a56d7af6598276853bc1b770acb --- src/wgt/wgt_app_query_interface.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 4afdc3d..87252a0 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include -- 2.7.4 From df344f8339869ac75e4d04ca48275888a72ff9d7 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Tue, 26 Sep 2017 15:52:18 +0900 Subject: [PATCH 06/16] Release version 0.7.1 Changes: - Fix codes for ManifestDirectInstall in Hybrid pkg Change-Id: Id90a2cf250611c181d66cc5c6ab195807c731258 Signed-off-by: Junghyun Yeon --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index e0c49df..fa09ad8 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.7.0 +Version: 0.7.1 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From b0e4ad894443261c61a6611f5a62cc63e93caa23 Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Fri, 1 Sep 2017 09:29:54 +0900 Subject: [PATCH 07/16] Add step for privacy privilege Signed-off-by: Seungha Son Change-Id: I699da12a566354021361202c68b6567a162f78ec --- src/wgt/wgt_installer.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 1e09e65..3a8956b 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -233,6 +234,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -281,6 +284,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -311,6 +316,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Uninstall); AddStep(); AddStep(); AddStep(); @@ -336,6 +343,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep(); AddStep(); @@ -385,6 +394,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -445,6 +456,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -490,6 +503,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -517,6 +532,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep(ci::Plugin::ActionType::Install); AddStep( @@ -548,6 +565,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -591,6 +610,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep(ci::Plugin::ActionType::Upgrade); AddStep(); @@ -620,6 +641,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep(); AddStep(ci::Plugin::ActionType::Upgrade); @@ -637,6 +660,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep(ci::Plugin::ActionType::Install); AddStep( @@ -660,6 +685,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -682,6 +709,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Uninstall); AddStep(); } -- 2.7.4 From 5dc947088c5f35dead54268b60226c51c72a8fbc Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Thu, 28 Sep 2017 13:46:37 +0900 Subject: [PATCH 08/16] Release version 0.7.2 Changes: - Add step for privacy privilege Signed-off-by: Seungha Son Change-Id: I1967ce52af6a2951f6a8aa728eb101bd4ed336be --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index fa09ad8..45e107b 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.7.1 +Version: 0.7.2 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From 89e87396cc8312f2ac3e5bb08f6ab9f04841cb8c Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Tue, 10 Oct 2017 21:22:21 +0900 Subject: [PATCH 09/16] Fix appdefined privilege parsing Requires: - https://review.tizen.org/gerrit/154530 Change-Id: If9add359f17bc952b86498c06f5dd3525d3130a5 Signed-off-by: Sangyoon Jang --- .../config.xml | 4 +- .../config.xml | 4 +- .../config.xml | 4 +- .../config.xml | 4 +- .../config.xml | 6 +-- .../config.xml | 4 +- .../config.xml | 4 +- .../config.xml | 6 +-- .../config.xml | 4 +- src/wgt/step/configuration/step_parse.cc | 43 +++++++++++----------- 10 files changed, 32 insertions(+), 51 deletions(-) diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_InvalidName/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_InvalidName/config.xml index 78ca65a..948de8c 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_InvalidName/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_InvalidName/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml index 748f827..1fce6a4 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoURI/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoURI/config.xml index 68e32f7..cfdfa4a 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoURI/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_NoURI/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_OverLength/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_OverLength/config.xml index 201ebd7..8897072 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_OverLength/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_Invalid_OverLength/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ManyElements/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ManyElements/config.xml index f01fb27..9eecba2 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ManyElements/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ManyElements/config.xml @@ -1,8 +1,6 @@ - - - - + + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_MissingName/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_MissingName/config.xml index bb84800..1be2518 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_MissingName/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_MissingName/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ValidName/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ValidName/config.xml index 613eae7..64572e9 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ValidName/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_ValidName/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseManyElements/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseManyElements/config.xml index 297cbdf..ad2ce75 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseManyElements/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseManyElements/config.xml @@ -1,8 +1,6 @@ - - - - + + diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseValidName/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseValidName/config.xml index 7d85238..7985282 100644 --- a/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseValidName/config.xml +++ b/src/unit_tests/test_samples/manifest/ManifestTest.ProvidesAppDefinedPrivilegeElement_WithLicenseValidName/config.xml @@ -1,7 +1,5 @@ - - - + diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index c339a8f..aa62f48 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -645,14 +646,13 @@ bool StepParse::FillPrivileges(manifest_x* manifest) { } bool StepParse::FillAppDefinedPrivileges(manifest_x* manifest) { - auto priv_info = - GetManifestDataForKey( + auto priv_info_list = + GetManifestDataForKey( app_keys::kTizenAppDefinedPrivilegeKey); - if (!priv_info) + if (!priv_info_list) return true; - const auto& privileges = priv_info->GetAppDefinedPrivilegeList(); - for (auto& priv : privileges) { + for (auto& priv : priv_info_list->appdefined_privileges) { appdefined_privilege_x* privilege = reinterpret_cast(calloc(1, sizeof(appdefined_privilege_x))); @@ -660,14 +660,14 @@ bool StepParse::FillAppDefinedPrivileges(manifest_x* manifest) { LOG(ERROR) << "Memory alloc failure"; return false; } - privilege->value = strdup(priv.privilege.c_str()); + privilege->value = strdup(priv.name().c_str()); privilege->type = strdup(common_installer::kWebPrivilegeType); - if (!priv.license.empty()) { - if (bf::path(priv.license).is_absolute()) - privilege->license = strdup(priv.license.c_str()); + if (!priv.license().empty()) { + if (bf::path(priv.license()).is_absolute()) + privilege->license = strdup(priv.license().c_str()); else privilege->license = strdup((context_->root_application_path.get() - / manifest->package / priv.license).c_str()); + / manifest->package / priv.license()).c_str()); } manifest->appdefined_privileges = g_list_append(manifest->appdefined_privileges, privilege); @@ -676,14 +676,13 @@ bool StepParse::FillAppDefinedPrivileges(manifest_x* manifest) { } bool StepParse::FillProvidesAppDefinedPrivileges(manifest_x* manifest) { - auto priv_info = - GetManifestDataForKey( - app_keys::kTizenProvidesAppDefinedPrivilegesKey); - if (!priv_info) + auto priv_info_list = + GetManifestDataForKey( + app_keys::kTizenProvidesAppDefinedPrivilegeKey); + if (!priv_info_list) return true; - const auto& privileges = priv_info->GetAppDefinedPrivilegeList(); - for (auto& priv : privileges) { + for (auto& priv : priv_info_list->appdefined_privileges) { appdefined_privilege_x* privilege = reinterpret_cast(calloc(1, sizeof(appdefined_privilege_x))); @@ -691,14 +690,14 @@ bool StepParse::FillProvidesAppDefinedPrivileges(manifest_x* manifest) { LOG(ERROR) << "Memory alloc failure"; return false; } - privilege->value = strdup(priv.privilege.c_str()); + privilege->value = strdup(priv.name().c_str()); privilege->type = strdup(common_installer::kWebPrivilegeType); - if (!priv.license.empty()) { - if (bf::path(priv.license).is_absolute()) - privilege->license = strdup(priv.license.c_str()); + if (!priv.license().empty()) { + if (bf::path(priv.license()).is_absolute()) + privilege->license = strdup(priv.license().c_str()); else privilege->license = strdup((context_->root_application_path.get() - / manifest->package / priv.license).c_str()); + / manifest->package / priv.license()).c_str()); } manifest->provides_appdefined_privileges = g_list_append(manifest->provides_appdefined_privileges, privilege); -- 2.7.4 From e21f1383ac2b2c2a787d0787a7b927b1f820eed9 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Tue, 10 Oct 2017 23:00:13 +0900 Subject: [PATCH 10/16] Fix smoke test We don't need to validate pkgid of appdefined-privilege for client. Change-Id: I5ee7f12398e682a1071d92c37091025573c12f2d Signed-off-by: Sangyoon Jang --- src/unit_tests/manifest_test.cc | 5 ----- .../config.xml | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 src/unit_tests/test_samples/manifest/ManifestTest.AppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml diff --git a/src/unit_tests/manifest_test.cc b/src/unit_tests/manifest_test.cc index 90c9ed6..051d2f3 100644 --- a/src/unit_tests/manifest_test.cc +++ b/src/unit_tests/manifest_test.cc @@ -223,11 +223,6 @@ TEST_F(ManifestTest, AppDefinedPrivilegeElement_Invalid_NotURI) { ASSERT_FALSE(runner.Run()); } -TEST_F(ManifestTest, AppDefinedPrivilegeElement_Invalid_NoPKGID) { - StepParseRunner runner(GetMyName()); - ASSERT_FALSE(runner.Run()); -} - TEST_F(ManifestTest, AppDefinedPrivilegeElement_Invalid_OverLength) { StepParseRunner runner(GetMyName()); ASSERT_FALSE(runner.Run()); diff --git a/src/unit_tests/test_samples/manifest/ManifestTest.AppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml b/src/unit_tests/test_samples/manifest/ManifestTest.AppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml deleted file mode 100644 index 4cb239b..0000000 --- a/src/unit_tests/test_samples/manifest/ManifestTest.AppDefinedPrivilegeElement_Invalid_NoPKGID/config.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - -- 2.7.4 From ed442f20db110d4754826bd523026254bf35b72a Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 11 Oct 2017 21:34:21 +0900 Subject: [PATCH 11/16] Release version 0.7.3 Changes: - Fix appdefined privilege parsing - Fix smoke test Change-Id: Iebcf9a186cdd05a5955cce40cf76ffe20776a5af Signed-off-by: Sangyoon Jang --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index 45e107b..aaa8808 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.7.2 +Version: 0.7.3 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From 8177294c286d2c288ad48855ee2057f833dd7da3 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Tue, 17 Oct 2017 11:40:02 +0900 Subject: [PATCH 12/16] Fix static analysis issue - Check if new operator has failed. Change-Id: I840874abdac89bb91f6e5aca26df2ac265a541ac Signed-off-by: Junghyun Yeon --- src/wgt/step/configuration/step_parse.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index aa62f48..0fe8083 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -200,7 +200,11 @@ bool StepParse::FillIconPaths(manifest_x* manifest) { GetManifestDataForKey( app_keys::kIconsKey); if (!icons_info) { - icons_info.reset(new wgt::parse::ApplicationIconsInfo()); + icons_info.reset(new(std::nothrow) wgt::parse::ApplicationIconsInfo()); + if (!icons_info) { + LOG(ERROR) << "Out of memory"; + return false; + } } wgt::parse::LocalizedApplicationIconsInfo localized_list = wgt::parse::GetLocalizedIconList(*icons_info, widget_path_); @@ -867,7 +871,11 @@ common_installer::Step::Status StepParse::process() { return common_installer::Step::Status::MANIFEST_NOT_FOUND; } - parser_.reset(new wgt::parse::WidgetConfigParser()); + parser_.reset(new(std::nothrow) wgt::parse::WidgetConfigParser()); + if (!parser_) { + LOG(ERROR) << "Out of memory"; + return common_installer::Step::Status::CONFIG_ERROR; + } if (!parser_->ParseManifest(widget_path_ / kConfigFileName)) { LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage(); return common_installer::Step::Status::PARSE_ERROR; -- 2.7.4 From 4160fc656c905e15a179dc4c758b774a4a428c31 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 14 Sep 2017 10:31:17 +0900 Subject: [PATCH 13/16] Change behavior of trust anchor - Trust anchor certificate dir has fixed so it will not defined at manifest. - Remove get/set codes about certificate directory. - Enable trust-anchor on hybrid package. Please note that if both tpk and wgt package have trust-anchor node, wgt's setting will be appliced. Related changes: [pkgmgr-info] : https://review.tizen.org/gerrit/149784 [app-installers] : https://review.tizen.org/gerrit/149836 [tpk-manifest-handlers] : https://review.tizen.org/gerrit/150060 [wgt-manifest-handlers] : https://review.tizen.org/gerrit/150136 Change-Id: Ie110eb1b52695c985495f03b834c9bfd9e5bf960 Signed-off-by: Junghyun Yeon --- src/hybrid/hybrid_installer.cc | 22 +++++++++++++++++ src/hybrid/step/pkgmgr/step_generate_xml.cc | 1 + src/wgt/step/configuration/step_parse.cc | 4 ---- src/wgt/step/pkgmgr/step_generate_xml.cc | 6 +---- src/wgt/wgt_installer.cc | 37 +++++++++++++++++++---------- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 5a6e342..2a28e39 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -70,6 +70,8 @@ #include #include #include +#include +#include #include #include @@ -148,6 +150,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -201,6 +205,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -229,6 +235,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -285,6 +292,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep(); AddStep(); AddStep( @@ -351,6 +360,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -403,6 +414,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -434,6 +447,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -468,6 +483,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -488,6 +505,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -513,6 +532,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -535,6 +556,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); break; } diff --git a/src/hybrid/step/pkgmgr/step_generate_xml.cc b/src/hybrid/step/pkgmgr/step_generate_xml.cc index 00e4e5d..89772c2 100644 --- a/src/hybrid/step/pkgmgr/step_generate_xml.cc +++ b/src/hybrid/step/pkgmgr/step_generate_xml.cc @@ -34,6 +34,7 @@ const std::vector kBlackListNodes = { {"profile"}, {"privileges"}, {"provides-appdefined-privileges"}, + {"trust-anchor"}, }; const std::vector kNeedMergeNodes = { {"manifest"}, diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index 0fe8083..05a3b5d 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -592,10 +592,6 @@ bool StepParse::FillTrustAnchorInfo(manifest_x* manifest) { if (!trust_anchor) return true; - std::string certs_dir = trust_anchor->get_certs_dir(); - if (!certs_dir.empty()) - manifest->pkg_certs_dir = strdup(certs_dir.c_str()); - std::string use_system_certs = trust_anchor->get_use_system_certs(); if (!use_system_certs.empty()) manifest->use_system_certs = strdup(use_system_certs.c_str()); diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 404b5c8..91d9f56 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -677,14 +677,10 @@ void StepGenerateXml::GenerateShortcuts(xmlTextWriterPtr writer) { } void StepGenerateXml::GenerateTrustAnchor(xmlTextWriterPtr writer) { - if (!context_->manifest_data.get()->pkg_certs_dir || - !context_->manifest_data.get()->use_system_certs) + if (!context_->manifest_data.get()->use_system_certs) return; xmlTextWriterStartElement(writer, BAD_CAST "trust-anchor"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "pkg-certs-dir", - BAD_CAST context_->manifest_data.get()->pkg_certs_dir); - xmlTextWriterWriteAttribute(writer, BAD_CAST "use-system-certs", BAD_CAST context_->manifest_data.get()->use_system_certs); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 3a8956b..130c597 100755 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -80,7 +80,6 @@ #include #include #include -#include #include @@ -233,7 +232,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); @@ -283,7 +283,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -342,7 +343,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -393,7 +395,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -455,7 +458,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); @@ -502,7 +506,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -531,7 +536,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); @@ -564,7 +570,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -609,7 +616,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -640,7 +648,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); @@ -659,7 +668,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); @@ -684,7 +694,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); AddStep( ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); -- 2.7.4 From bfbcb071cd2bfec45d1c83ebab42fd5225c6b104 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Fri, 13 Oct 2017 16:54:21 +0900 Subject: [PATCH 14/16] Add smoke test for extended storage installation Change-Id: I4a222b770cffe7a70b69143a4893beb7a38317e3 Signed-off-by: Sangyoon Jang --- src/unit_tests/smoke_test.cc | 12 +++++++- src/unit_tests/smoke_utils.cc | 31 +++++++++++++++++++-- src/unit_tests/smoke_utils.h | 11 +++++++- .../test_samples/smoke/InstallExtendedMode.wgt | Bin 0 -> 37975 bytes 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/unit_tests/test_samples/smoke/InstallExtendedMode.wgt diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index b55392a..bf44401 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -571,7 +571,7 @@ TEST_F(SmokeTest, InstallExternalMode) { bf::path path = kSmokePackagesDirectory / "InstallExternalMode.wgt"; std::string pkgid = "smokewgt35"; std::string appid = "smokewgt35.web"; - ASSERT_EQ(InstallExternal(path, PackageType::WGT), + ASSERT_EQ(InstallWithStorage(path, PackageType::WGT, StorageType::EXTERNAL), ci::AppInstaller::Result::OK); ValidateExternalPackage(pkgid, {appid}); } @@ -794,6 +794,16 @@ TEST_F(SmokeTest, SharedRes30HybridDelta) { ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1")); // NOLINT } +TEST_F(SmokeTest, InstallExtendedMode) { + ASSERT_TRUE(CheckAvailableExtendedStorage()); + bf::path path = kSmokePackagesDirectory / "InstallExtendedMode.wgt"; + std::string pkgid = "smokewgt44"; + std::string appid = "smokewgt44.web"; + ASSERT_EQ(InstallWithStorage(path, PackageType::WGT, StorageType::EXTENDED), + ci::AppInstaller::Result::OK); + ValidatePackage(pkgid, {appid}); +} + } // namespace common_installer int main(int argc, char** argv) { diff --git a/src/unit_tests/smoke_utils.cc b/src/unit_tests/smoke_utils.cc index 41c777d..3730ad0 100644 --- a/src/unit_tests/smoke_utils.cc +++ b/src/unit_tests/smoke_utils.cc @@ -585,13 +585,37 @@ bool CheckAvailableExternalPath() { return true; } -ci::AppInstaller::Result InstallExternal(const bf::path& path, +bool CheckAvailableExtendedStorage() { + bf::path extended_path = bf::path(tzplatform_getenv(TZ_SYS_EXTENDEDSD)); + LOG(DEBUG) << "extended_path :" << extended_path; + // TODO(jeremy.jang): It should be checked by libstorage API. + if (!bf::exists(extended_path)) { + LOG(ERROR) << "Extended storage not exists!"; + return false; + } + return true; +} + +ci::AppInstaller::Result InstallWithStorage(const bf::path& path, PackageType type, + StorageType storage_type, RequestResult mode) { int default_storage = 0; + int storage = 0; + switch (storage_type) { + case StorageType::EXTERNAL: + storage = 1; + break; + case StorageType::EXTENDED: + storage = 2; + break; + default: + LOG(ERROR) << "Unknown storage type"; + break; + } vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, &default_storage); - vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1); + vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, storage); const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()}; ci::AppInstaller::Result result = @@ -607,7 +631,8 @@ ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, const bf::path& legacy_path, PackageType type, RequestResult mode) { - if (InstallExternal(path, type) != ci::AppInstaller::Result::OK) { + if (InstallWithStorage(path, type, StorageType::EXTERNAL) != + ci::AppInstaller::Result::OK) { LOG(ERROR) << "Failed to install application. Cannot perform Migrate"; return ci::AppInstaller::Result::ERROR; } diff --git a/src/unit_tests/smoke_utils.h b/src/unit_tests/smoke_utils.h index b709b19..b87da34 100644 --- a/src/unit_tests/smoke_utils.h +++ b/src/unit_tests/smoke_utils.h @@ -143,6 +143,12 @@ enum class PackageType { HYBRID }; +enum class StorageType { + INTERNAL, + EXTERNAL, + EXTENDED +}; + ci::RequestMode ParseRequestMode(int argc, char** argv); bool TouchFile(const bf::path& path); @@ -226,8 +232,11 @@ ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type, bool CheckAvailableExternalPath(); -ci::AppInstaller::Result InstallExternal(const bf::path& path, +bool CheckAvailableExtendedStorage(); + +ci::AppInstaller::Result InstallWithStorage(const bf::path& path, PackageType type, + StorageType storage = StorageType::INTERNAL, RequestResult mode = RequestResult::NORMAL); ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid, diff --git a/src/unit_tests/test_samples/smoke/InstallExtendedMode.wgt b/src/unit_tests/test_samples/smoke/InstallExtendedMode.wgt new file mode 100644 index 0000000000000000000000000000000000000000..677b33797466dc7939aa22384ece1e8f20a8ad2d GIT binary patch literal 37975 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 literal 0 HcmV?d00001 -- 2.7.4 From b6b064851415758a249944812fbc31da76f55401 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Tue, 17 Oct 2017 15:56:44 +0900 Subject: [PATCH 15/16] Release version 0.7.4 Changes: - Fix static analysis issue - Change behavior of trust anchor - Add smoke test for extended storage installation Change-Id: I06e50d6cefbe861e59b70145a476dbbd48236f29 Signed-off-by: Junghyun Yeon --- packaging/wgt-backend.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index aaa8808..03eb167 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -1,6 +1,6 @@ Name: wgt-backend Summary: Application installer backend for WGT -Version: 0.7.3 +Version: 0.7.4 Release: 1 Group: Application Framework/Package Management License: Apache-2.0 -- 2.7.4 From d89ab97f406c76b2e98542db1b8010d84f692e65 Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Mon, 23 Oct 2017 16:56:34 +0900 Subject: [PATCH 16/16] Add privacy privilege step for hybrid Signed-off-by: Seungha Son Change-Id: Ia90177a7fdcec552183b496e48436b42e947c747 --- src/hybrid/hybrid_installer.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 2a28e39..2df59cc 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -207,6 +210,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -236,6 +241,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Uninstall); AddStep(); AddStep(); AddStep(); @@ -294,6 +301,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep(); AddStep( @@ -362,6 +371,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -416,6 +427,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -449,6 +462,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -485,6 +500,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -507,6 +524,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::INSTALL); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Install); AddStep(); AddStep( ci::Plugin::ActionType::Install); @@ -534,6 +553,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep( ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Update); AddStep(); AddStep( ci::Plugin::ActionType::Upgrade); @@ -557,6 +578,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::security::StepPrivacyPrivilege::ActionType::Uninstall); AddStep(); break; } -- 2.7.4