From c17830e288c2a74d8e6afc99723776596bcd821f Mon Sep 17 00:00:00 2001 From: zhouyan Date: Mon, 22 Aug 2022 16:25:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E7=B3=8A=E6=9D=83=E9=99=90=E4=B8=8E?= =?UTF-8?q?=E7=B2=BE=E5=87=86=E6=9D=83=E9=99=90native=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyan Change-Id: I1ec8d022f7767e756233cacb40d9b28f3d286d43 --- .../src/accesstoken_manager_proxy.cpp | 4 - .../unittest/src/accesstoken_kit_test.cpp | 2 +- .../include/permission/permission_manager.h | 18 +- .../cpp/src/permission/permission_manager.cpp | 174 +++++++++++++++++- .../service/accesstoken_manager_service.cpp | 33 +++- 5 files changed, 219 insertions(+), 12 deletions(-) diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp index 98692fa75..0d50cf13a 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp @@ -280,10 +280,6 @@ PermissionOper AccessTokenManagerProxy::GetSelfPermissionsState( } PermissionOper result = static_cast(reply.ReadInt32()); - if (result == INVALID_OPER) { - ACCESSTOKEN_LOG_ERROR(LABEL, "result from server is invalid!"); - return result; - } size_t size = reply.ReadUint32(); if (size != permListParcel.size()) { ACCESSTOKEN_LOG_ERROR(LABEL, "permListParcel size from server is invalid!"); diff --git a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp index 23d4c9803..9ae54a82a 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp @@ -2041,7 +2041,7 @@ HWTEST_F(AccessTokenKitTest, UpdateHapToken007, TestSize.Level1) backup = g_infoManagerTestPolicyPrams.permList[0].permissionName; g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.test3"; - ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, DEFAULT_API_VERSION, g_infoManagerTestPolicyPrams); + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); ASSERT_EQ(RET_SUCCESS, ret); g_infoManagerTestPolicyPrams.permList[0].permissionName = backup; diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h index 30f6d542a..6ba1da9eb 100644 --- a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h @@ -24,6 +24,7 @@ #include "iremote_broker.h" #include "permission_def.h" #include "permission_list_state.h" +#include "permission_list_state_parcel.h" #include "permission_state_change_info.h" #include "permission_state_full.h" @@ -33,6 +34,11 @@ namespace OHOS { namespace Security { namespace AccessToken { +constexpr const char* VAGUE_LOCATION_PERMISSION_NAME = "ohos.permission.APPROXIMATELY_LOCATION"; +constexpr const char* ACCURATE_LOCATION_PERMISSION_NAME = "ohos.permission.LOCATION"; +const int32_t ELEMENT_NOT_FOUND = -1; +const int32_t ACCURATE_LOCATION_API_VERSION = 9; + class PermissionManager final { public: static PermissionManager& GetInstance(); @@ -54,16 +60,26 @@ public: void RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); void ClearUserGrantedPermissionState(AccessTokenID tokenID); void GetSelfPermissionState( - std::vector permsList, PermissionListState &permState); + std::vector permsList, PermissionListState &permState, int32_t apiVersion); int32_t AddPermStateChangeCallback( const PermStateChangeScope& scope, const sptr& callback); int32_t RemovePermStateChangeCallback(const sptr& callback); + bool GetApiVersionByTokenId(AccessTokenID tokenID, int32_t& apiVersion); + void GetLocationPermissionIndex(std::vector& reqPermList, int& vagueIndex, + int& accurateIndex); + void LocationPermissionSpecialHandle(std::vector& reqPermList, int32_t apiVersion, + std::vector permsList, int vagueIndex, int accurateIndex, bool& needRes); private: PermissionManager(); void UpdateTokenPermissionState( AccessTokenID tokenID, const std::string& permissionName, bool isGranted, int flag); std::string TransferPermissionDefToString(const PermissionDef& inPermissionDef); + bool IsPermissionVaild(const std::string& permissionName); + bool GetPermissionStatusAndFlag(const std::string& permissionName, + const std::vector& permsList, int32_t& status, uint32_t& flag); + void AllLocationPermissionHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex); DISALLOW_COPY_AND_MOVE(PermissionManager); }; diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp index 4819bf776..7fdd6503f 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -239,15 +239,23 @@ int PermissionManager::GetReqPermissions( } void PermissionManager::GetSelfPermissionState(std::vector permsList, - PermissionListState &permState) + PermissionListState &permState, int32_t apiVersion) { bool foundGoal = false; int32_t goalGrantStatus; uint32_t goalGrantFlags; + + // api8 require vague location permission refuse directlty beause there is no vague location permission in api8 + if ((permState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) && + (apiVersion < ACCURATE_LOCATION_API_VERSION)) { + permState.state = INVALID_OPER; + return; + } + for (const auto& perm : permsList) { if (perm.permissionName == permState.permissionName) { - ACCESSTOKEN_LOG_INFO(LABEL, - "find goal permission: %{public}s!", permState.permissionName.c_str()); + ACCESSTOKEN_LOG_INFO(LABEL, "find goal permission: %{public}s, status: %{public}d, flag: %{public}d", + permState.permissionName.c_str(), perm.grantStatus[0], perm.grantFlags[0]); foundGoal = true; goalGrantStatus = perm.grantStatus[0]; goalGrantFlags = static_cast(perm.grantFlags[0]); @@ -405,6 +413,166 @@ int32_t PermissionManager::RemovePermStateChangeCallback(const sptr(&tokenID); + ATokenTypeEnum tokenType = (ATokenTypeEnum)(idInner->type); + if (tokenType != TOKEN_HAP) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid token type %{public}d", tokenType); + return false; + } + + HapTokenInfo hapInfo; + int ret = AccessTokenInfoManager::GetInstance().GetHapTokenInfo(tokenID, hapInfo); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "get hap token info error!"); + return false; + } + + apiVersion = hapInfo.apiVersion; + + return true; +} + +void PermissionManager::GetLocationPermissionIndex(std::vector& reqPermList, + int& vagueIndex, int& accurateIndex) +{ + int index = 0; + + for (const auto& perm : reqPermList) { + if (perm.permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) { + vagueIndex = index; + } + + if (perm.permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME) { + accurateIndex = index; + } + + index++; + + if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + break; + } + } + + ACCESSTOKEN_LOG_INFO(LABEL, "vague location permission index is %{public}d!", vagueIndex); + ACCESSTOKEN_LOG_INFO(LABEL, "accurate location permission index is %{public}d!", accurateIndex); +} + +bool PermissionManager::IsPermissionVaild(const std::string& permissionName) +{ + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid permissionName %{public}s", permissionName.c_str()); + return false; + } + + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "permission %{public}s has no definition ", permissionName.c_str()); + return false; + } + return true; +} + +bool PermissionManager::GetPermissionStatusAndFlag(const std::string& permissionName, + const std::vector& permsList, int32_t& status, uint32_t& flag) +{ + if (!IsPermissionVaild(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid permission %{public}s", permissionName.c_str()); + return false; + } + + for (const auto& perm : permsList) { + if (perm.permissionName == permissionName) { + status = perm.grantStatus[0]; + flag = static_cast(perm.grantFlags[0]); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "permission:%{public}s, status:%{public}d, flag:%{public}d!", + permissionName.c_str(), status, flag); + return true; + } + } + return false; +} + +void PermissionManager::AllLocationPermissionHandle(std::vector& reqPermList, + std::vector permsList, int vagueIndex, int accurateIndex) +{ + int32_t vagueStatus = PERMISSION_DENIED; + uint32_t vagueFlag = PERMISSION_DEFAULT_FLAG; + int32_t vagueState = INVALID_OPER; + int32_t accurateStatus = PERMISSION_DENIED; + uint32_t accurateFlag = PERMISSION_DEFAULT_FLAG; + int32_t accurateState = INVALID_OPER; + + if (!GetPermissionStatusAndFlag(VAGUE_LOCATION_PERMISSION_NAME, permsList, vagueStatus, vagueFlag) || + !GetPermissionStatusAndFlag(ACCURATE_LOCATION_PERMISSION_NAME, permsList, accurateStatus, accurateFlag)) { + return; + } + + // vague location status -1 means vague location permission has been refused + if (vagueStatus == PERMISSION_DENIED) { + if ((vagueFlag == PERMISSION_DEFAULT_FLAG) || ((vagueFlag & PERMISSION_USER_SET) != 0)) { + // vague location flag 0 or 1 means permission has not been operated or valid only once + vagueState = DYNAMIC_OPER; + accurateState = DYNAMIC_OPER; + } else if ((vagueFlag & PERMISSION_USER_FIXED) != 0) { + // vague location flag 2 means vague location has been operated, only can be changed by settings + // so that accurate location is no need to operate + vagueState = SETTING_OPER; + accurateState = SETTING_OPER; + } + } else if (vagueStatus == PERMISSION_GRANTED) { + // vague location status 0 means vague location permission has been accepted + // now flag 1 is not in use so return PASS_OPER, otherwise should judge by flag + vagueState = PASS_OPER; + + if (accurateStatus == PERMISSION_DENIED) { + if ((accurateFlag == PERMISSION_DEFAULT_FLAG) || ((accurateFlag & PERMISSION_USER_SET) != 0)) { + accurateState = DYNAMIC_OPER; + } else if ((accurateFlag & PERMISSION_USER_FIXED) != 0) { + accurateState = SETTING_OPER; + } + } else if (accurateStatus == PERMISSION_GRANTED) { + accurateState = PASS_OPER; + } + } + + ACCESSTOKEN_LOG_INFO(LABEL, "vague location permission state is %{public}d", vagueState); + ACCESSTOKEN_LOG_INFO(LABEL, "accurate location permission state is %{public}d", accurateState); + + reqPermList[vagueIndex].permsState.state = vagueState; + reqPermList[accurateIndex].permsState.state = accurateState; +} + +void PermissionManager::LocationPermissionSpecialHandle(std::vector& reqPermList, + int32_t apiVersion, std::vector permsList, int vagueIndex, int accurateIndex, bool& needRes) +{ + if ((vagueIndex != ELEMENT_NOT_FOUND) && (accurateIndex == ELEMENT_NOT_FOUND)) { + // only vague location permission + GetSelfPermissionState(permsList, reqPermList[vagueIndex].permsState, apiVersion); + if (reqPermList[vagueIndex].permsState.state == DYNAMIC_OPER) { + needRes = true; + } + return; + } + + if ((vagueIndex == ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + // only accurate location permission refuse directly + ACCESSTOKEN_LOG_ERROR(LABEL, "operate invaild, accurate location permission base on vague location permission"); + reqPermList[accurateIndex].permsState.state = INVALID_OPER; + return; + } + + // all location permissions + AllLocationPermissionHandle(reqPermList, permsList, vagueIndex, accurateIndex); + if (reqPermList[vagueIndex].permsState.state == DYNAMIC_OPER || + reqPermList[accurateIndex].permsState.state == DYNAMIC_OPER) { + needRes = true; + } + return; +} + void PermissionManager::ClearUserGrantedPermissionState(AccessTokenID tokenID) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: %{public}u", __func__, tokenID); diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp index ce1a55351..fa76a73f5 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -145,7 +145,13 @@ PermissionOper AccessTokenManagerService::GetSelfPermissionsState( std::vector& reqPermList) { AccessTokenID callingTokenID = IPCSkeleton::GetCallingTokenID(); - ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); + + int32_t apiVersion = 0; + if (!PermissionManager::GetInstance().GetApiVersionByTokenId(callingTokenID, apiVersion)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "get api version error"); + return INVALID_OPER; + } + ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d, apiVersion: %{public}d", callingTokenID, apiVersion); bool needRes = false; std::vector permsList; @@ -158,10 +164,26 @@ PermissionOper AccessTokenManagerService::GetSelfPermissionsState( return INVALID_OPER; } + int vagueIndex = ELEMENT_NOT_FOUND; + int accurateIndex = ELEMENT_NOT_FOUND; + + if (apiVersion >= ACCURATE_LOCATION_API_VERSION) { + PermissionManager::GetInstance().GetLocationPermissionIndex(reqPermList, vagueIndex, accurateIndex); + if ((vagueIndex != ELEMENT_NOT_FOUND) || (accurateIndex != ELEMENT_NOT_FOUND)) { + PermissionManager::GetInstance().LocationPermissionSpecialHandle(reqPermList, apiVersion, permsList, + vagueIndex, accurateIndex, needRes); // api9 location permission handle here + } + } + uint32_t size = reqPermList.size(); for (uint32_t i = 0; i < size; i++) { - PermissionManager::GetInstance().GetSelfPermissionState( - permsList, reqPermList[i].permsState); + if (((reqPermList[i].permsState.permissionName == VAGUE_LOCATION_PERMISSION_NAME) || + (reqPermList[i].permsState.permissionName == ACCURATE_LOCATION_PERMISSION_NAME)) && + (apiVersion >= ACCURATE_LOCATION_API_VERSION)) { + continue; // api9 location permission special handle above + } + + PermissionManager::GetInstance().GetSelfPermissionState(permsList, reqPermList[i].permsState, apiVersion); if (reqPermList[i].permsState.state == DYNAMIC_OPER) { needRes = true; } @@ -170,6 +192,11 @@ PermissionOper AccessTokenManagerService::GetSelfPermissionsState( } if (needRes) { return DYNAMIC_OPER; + } else { + if ((vagueIndex == ELEMENT_NOT_FOUND) && (accurateIndex != ELEMENT_NOT_FOUND)) { + // only accurate location permission without other DYNAMIC_OPER state return INVALID_OPER + return INVALID_OPER; + } } return PASS_OPER; } -- Gitee