diff --git a/frameworks/innerkitsimpl/media_library_manager/BUILD.gn b/frameworks/innerkitsimpl/media_library_manager/BUILD.gn index 8c23f60b162d6e114e9f8352d2800512cd7a9e66..4c673441f96cd6ad0208984c1107eb9942afa137 100644 --- a/frameworks/innerkitsimpl/media_library_manager/BUILD.gn +++ b/frameworks/innerkitsimpl/media_library_manager/BUILD.gn @@ -34,6 +34,8 @@ ohos_shared_library("media_library_manager") { "ability_base:zuri", "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", + "access_token:libaccesstoken_sdk", + "access_token:libprivacy_sdk", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn index 90a22dda0f1f02f2b89367a3437aedf1f2baf502..d7d1cf82947f6488bdfacaaf6647fcfdd91df516 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn @@ -241,6 +241,7 @@ ohos_shared_library("medialibrary_data_extension") { "ability_runtime:runtime", "ability_runtime:uri_permission_mgr", "access_token:libaccesstoken_sdk", + "access_token:libprivacy_sdk", "app_file_service:sandbox_helper_native", "background_task_mgr:bgtaskmgr_innerkits", "bundle_framework:appexecfwk_core", diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/media_datashare_ext_ability.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/media_datashare_ext_ability.cpp index 4acfc344ad2b60bc91dab0385227225530a51875..8c0347665d4b6069749e1fbb25c830cca7643fa6 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/media_datashare_ext_ability.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/media_datashare_ext_ability.cpp @@ -59,12 +59,15 @@ using namespace OHOS::NativeRdb; using namespace OHOS::DistributedKv; using namespace OHOS::Media; using namespace OHOS::DataShare; +using namespace OHOS::Security::AccessToken; namespace OHOS { namespace AbilityRuntime { using namespace OHOS::AppExecFwk; using DataObsMgrClient = OHOS::AAFwk::DataObsMgrClient; +const string secuityComponentMode = "rw"; + MediaDataShareExtAbility* MediaDataShareExtAbility::Create(const unique_ptr& runtime) { return new MediaDataShareExtAbility(static_cast(*runtime)); @@ -208,6 +211,19 @@ static inline bool ContainsFlag(const string &mode, const char flag) return mode.find(flag) != string::npos; } +static void CollectPermissionInfo(MediaLibraryCommand &cmd, const string &mode, + const bool permGranted, PermissionUsedType type) +{ + if ((cmd.GetOprnObject() == OperationObject::FILESYSTEM_PHOTO)) { + if (mode.find("r") != string::npos) { + PermissionUtils::CollectPermissionInfo(PERM_READ_IMAGEVIDEO, permGranted, type); + } + if (mode.find("w") != string::npos) { + PermissionUtils::CollectPermissionInfo(PERM_WRITE_IMAGEVIDEO, permGranted, type); + } + } +} + static int32_t CheckOpenFilePermission(MediaLibraryCommand &cmd, string &mode) { MEDIA_DEBUG_LOG("uri: %{private}s mode: %{private}s", cmd.GetUri().ToString().c_str(), mode.c_str()); @@ -217,6 +233,9 @@ static int32_t CheckOpenFilePermission(MediaLibraryCommand &cmd, string &mode) vector perms; FillV10Perms(mediaType, containsRead, containsWrite, perms); + if ((cmd.GetOprnObject() == OperationObject::FILESYSTEM_PHOTO)) { + return PermissionUtils::CheckPhotoCallerPermission(perms)? E_SUCCESS : E_PERMISSION_DENIED; + } int32_t err = (mediaType == MEDIA_TYPE_FILE) ? (PermissionUtils::CheckHasPermission(perms) ? E_SUCCESS : E_PERMISSION_DENIED) : (PermissionUtils::CheckCallerPermission(perms) ? E_SUCCESS : E_PERMISSION_DENIED); @@ -532,6 +551,8 @@ static bool CheckIsOwner(const Uri &uri, MediaLibraryCommand &cmd) queryResultSet->GetRowCount(count); if (count != 0) { ret = true; + CollectPermissionInfo(cmd, secuityComponentMode, true, + PermissionUsedTypeValue::SECURITY_COMPONENT_TYPE); } } return ret; @@ -566,12 +587,16 @@ int MediaDataShareExtAbility::OpenFile(const Uri &uri, const string &mode) auto& uriPermissionClient = AAFwk::UriPermissionManagerClient::GetInstance(); if (uriPermissionClient.VerifyUriPermission(Uri(command.GetUriStringWithoutSegment()), GetFlagFromMode(unifyMode), IPCSkeleton::GetCallingTokenID())) { + CollectPermissionInfo(command, unifyMode, true, PermissionUsedTypeValue::PICKER_TYPE); err = E_OK; } } if (err != E_OK) { + CollectPermissionInfo(command, unifyMode, false, PermissionUsedTypeValue::PICKER_TYPE); if (!CheckIsOwner(uri, command)) { MEDIA_ERR_LOG("Permission Denied! err = %{public}d", err); + CollectPermissionInfo(command, secuityComponentMode, false, + PermissionUsedTypeValue::SECURITY_COMPONENT_TYPE); return err; } } diff --git a/frameworks/innerkitsimpl/test/unittest/medialibrary_common_utils_test/BUILD.gn b/frameworks/innerkitsimpl/test/unittest/medialibrary_common_utils_test/BUILD.gn index e468ecb71d174a33886f857dbd851260e0edfa9c..aedf7f8c3cd61000a9cce5d7b0d10f8815401a5b 100644 --- a/frameworks/innerkitsimpl/test/unittest/medialibrary_common_utils_test/BUILD.gn +++ b/frameworks/innerkitsimpl/test/unittest/medialibrary_common_utils_test/BUILD.gn @@ -42,6 +42,8 @@ ohos_unittest("medialibrary_common_utils_test") { "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", "ability_runtime:app_context", + "access_token:libaccesstoken_sdk", + "access_token:libprivacy_sdk", "bundle_framework:appexecfwk_core", "c_utils:utils", "common_event_service:cesfwk_innerkits", diff --git a/frameworks/utils/include/permission_utils.h b/frameworks/utils/include/permission_utils.h index ea0fc224c2a8fdf1fa570afe42ae64e94406284a..42e7ab378fc5a613743340170c993aa65decc547 100644 --- a/frameworks/utils/include/permission_utils.h +++ b/frameworks/utils/include/permission_utils.h @@ -19,9 +19,14 @@ #include #include #include +#include +#include #include "bundle_mgr_interface.h" #include "userfile_manager_types.h" +#include "permission_used_type.h" +#include "privacy_kit.h" +#include "tokenid_kit.h" namespace OHOS { namespace Media { @@ -55,6 +60,10 @@ public: static bool CheckIsSystemAppByUid(); static std::string GetPackageNameByBundleName(const std::string &bundleName); static std::string GetAppIdByBundleName(const std::string &bundleName); + static bool CheckPhotoCallerPermission(const std::vector &perms); + static bool CheckPhotoCallerPermission(const std::string &permission); + static void CollectPermissionInfo(const std::string &permission, const bool permGranted, + const Security::AccessToken::PermissionUsedType type); private: static sptr GetSysBundleManager(); diff --git a/frameworks/utils/src/permission_utils.cpp b/frameworks/utils/src/permission_utils.cpp index 0c41bfa6412a9d30bd0f3860087bc478d312bac6..da66a9d39d00545ccbc99ef389301a4baefe2e6d 100644 --- a/frameworks/utils/src/permission_utils.cpp +++ b/frameworks/utils/src/permission_utils.cpp @@ -35,6 +35,11 @@ using namespace std; using namespace OHOS::Security::AccessToken; using namespace OHOS::AppExecFwk::Constants; +bool g_hasDelayTask; +std::mutex AddPhotoPermissionRecordLock_; +std::thread DelayTask_; +std::vector infos; + sptr PermissionUtils::bundleMgr_ = nullptr; mutex PermissionUtils::bundleMgrMutex_; sptr PermissionUtils::GetSysBundleManager() @@ -102,6 +107,98 @@ void AddPermissionRecord(const AccessTokenID &token, const string &perm, const b } } +vector GetPermissionRecord() +{ + lock_guard lock(AddPhotoPermissionRecordLock_); + vector result = infos; + infos.clear(); + return result; +} + +void AddPermissionRecord() +{ + vector infos = GetPermissionRecord(); + for (const auto &info : infos) { + int32_t ret = PrivacyKit::AddPermissionUsedRecord(info, true); + if (ret != 0) { + /* Failed to add permission used record, not fatal */ + MEDIA_WARN_LOG("Failed to add permission used record: %{public}s, permGranted: %{public}d, err: %{public}d", + info.permissionName.c_str(), info.successCount, ret); + } + } + infos.clear(); +} + +void DelayAddPermissionRecord() +{ + string name("DelayAddPermissionRecord"); + pthread_setname_np(pthread_self(), name.c_str()); + MEDIA_DEBUG_LOG("DelayTask start"); + std::this_thread::sleep_for(std::chrono::minutes(1)); + AddPermissionRecord(); + g_hasDelayTask = false; + MEDIA_DEBUG_LOG("DelayTask end"); +} + +void DelayTaskInit() +{ + if (!g_hasDelayTask) { + MEDIA_DEBUG_LOG("DelayTaskInit"); + DelayTask_ = thread(DelayAddPermissionRecord); + DelayTask_.detach(); + g_hasDelayTask = true; + } +} + +void CollectPermissionRecord(const AccessTokenID &token, const string &perm, + const bool permGranted, const PermissionUsedType type) +{ + lock_guard lock(AddPhotoPermissionRecordLock_); + DelayTaskInit(); + + if (!ShouldAddPermissionRecord(token)) { + return; + } + + AddPermParamInfo info = {token, perm, permGranted, !permGranted, type}; + infos.push_back(info); +} + +void PermissionUtils::CollectPermissionInfo(const string &permission, + const bool permGranted, const PermissionUsedType type) +{ + AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); + CollectPermissionRecord(tokenCaller, permission, permGranted, type); +} + +bool PermissionUtils::CheckPhotoCallerPermission(const string &permission) +{ + PermissionUsedType type = PermissionUsedTypeValue::NORMAL_TYPE; + AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); + int res = AccessTokenKit::VerifyAccessToken(tokenCaller, permission); + if (res != PermissionState::PERMISSION_GRANTED) { + MEDIA_ERR_LOG("Have no media permission: %{public}s", permission.c_str()); + CollectPermissionRecord(tokenCaller, permission, false, type); + return false; + } + CollectPermissionRecord(tokenCaller, permission, true, type); + return true; +} + +bool PermissionUtils::CheckPhotoCallerPermission(const vector &perms) +{ + if (perms.empty()) { + return false; + } + + for (const auto &perm : perms) { + if (!CheckPhotoCallerPermission(perm)) { + return false; + } + } + return true; +} + bool PermissionUtils::CheckCallerPermission(const string &permission) { MediaLibraryTracer tracer; diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index c221aa9b6b8e67b2b8ff66649fbfa399afffccdd..b4a37dcfcee94f199a8658591962b1f3205ec9bc 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -150,6 +150,7 @@ ohos_shared_library("medialibrary_nutils") { "ability_runtime:service_extension", "ability_runtime:ui_extension", "access_token:libaccesstoken_sdk", + "access_token:libprivacy_sdk", "access_token:libtokenid_sdk", "app_file_service:fileuri_native", "bundle_framework:appexecfwk_core",