add whitelist of userpolicy

Co-Authored-By: Agent

Signed-off-by: chennian <chennian1@huawei.com>
Change-Id: I3bd50c060cafd67920e40f554529bc387b04b28b
This commit is contained in:
chennian
2026-04-13 17:33:53 +08:00
parent 41b14a2122
commit f283f488ec
31 changed files with 2453 additions and 1140 deletions
+1 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2023-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -14,11 +14,9 @@
*/
# any change to behind files needs to be reviewed by @leonchan5
frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h @leonchan5
frameworks/accesstoken/include/tokensync_callback_ipc_interface_code.h @leonchan5
frameworks/privacy/include/privacy_active_change_ipc_interface_code.h @leonchan5
frameworks/privacy/include/privacy_am_service_ipc_interface_code.h @leonchan5
frameworks/privacy/include/privacy_service_ipc_interface_code.h @leonchan5
frameworks/privacy/include/privacy_state_change_ipc_interface_code.h @leonchan5
frameworks/tokensync/include/token_sync_service_ipc_interface_code.h @leonchan5
interfaces/inner_api/privacy/include/privacy_permission_record_ipc_interface_code.h @leonchan5
@@ -1,85 +0,0 @@
/*
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ACCESSTOKEN_SERVICE_IPC_INTERFACE_CODE_H
#define ACCESSTOKEN_SERVICE_IPC_INTERFACE_CODE_H
namespace OHOS {
namespace Security {
namespace AccessToken {
/* SAID:3503 */
enum class AccessTokenInterfaceCode {
VERIFY_ACCESSTOKEN = 0x0000,
GET_DEF_PERMISSION,
GET_REQ_PERMISSIONS,
GET_PERMISSION_FLAG,
GRANT_PERMISSION,
REVOKE_PERMISSION,
CLEAR_USER_GRANT_PERMISSION,
ALLOC_TOKEN_HAP,
TOKEN_DELETE,
INIT_TOKEN_HAP,
SET_PERMISSION_REQUEST_TOGGLE_STATUS,
GET_PERMISSION_REQUEST_TOGGLE_STATUS,
GRANT_PERMISSION_FOR_SPECIFIEDTIME,
REQUEST_APP_PERM_ON_SETTING,
GET_TOKEN_TYPE = 0x0010,
CHECK_NATIVE_DCAP,
GET_HAP_TOKEN_ID,
ALLOC_LOCAL_TOKEN_ID,
GET_NATIVE_TOKENINFO,
GET_HAP_TOKENINFO,
UPDATE_HAP_TOKEN,
GET_TOKEN_ID_BY_USER_ID,
GET_HAP_TOKEN_FROM_REMOTE = 0x0020,
GET_ALL_NATIVE_TOKEN_FROM_REMOTE,
SET_REMOTE_HAP_TOKEN_INFO,
SET_REMOTE_NATIVE_TOKEN_INFO,
DELETE_REMOTE_TOKEN_INFO,
DELETE_REMOTE_DEVICE_TOKEN,
GET_NATIVE_REMOTE_TOKEN,
REGISTER_TOKEN_SYNC_CALLBACK,
UNREGISTER_TOKEN_SYNC_CALLBACK,
DUMP_TOKENINFO = 0x0030,
GET_PERMISSION_OPER_STATE,
GET_PERMISSIONS_STATUS,
REGISTER_PERM_STATE_CHANGE_CALLBACK,
UNREGISTER_PERM_STATE_CHANGE_CALLBACK,
RELOAD_NATIVE_TOKEN_INFO,
GET_NATIVE_TOKEN_ID,
SET_PERM_DIALOG_CAPABILITY,
GET_USER_GRANTED_PERMISSION_USED_TYPE,
DUMP_PERM_DEFINITION_INFO,
GET_VERSION,
GET_PERMISSION_MANAGER_INFO,
INIT_USER_POLICY,
UPDATE_USER_POLICY,
CLEAR_USER_POLICY,
GET_HAP_TOKENINFO_EXT,
REGISTER_SELF_PERM_STATE_CHANGE_CALLBACK,
UNREGISTER_SELF_PERM_STATE_CHANGE_CALLBACK,
GET_KERNEL_PERMISSIONS,
GET_PERMISSION_BY_NAME,
VERIFY_ACCESSTOKEN_WITH_LIST = 0x0050,
};
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
#endif // ACCESSTOKEN_SERVICE_IPC_INTERFACE_CODE_H
@@ -59,6 +59,7 @@ public:
static bool IsPermissionUsedFlagValid(uint32_t flag);
static bool IsPermissionUsedTypeValid(uint32_t type);
static bool IsEnhancedIdentityValid(const std::string& enhancedIdentity);
static bool IsUpdateWhiteListTypeValid(UpdateWhiteListType type);
static bool IsRemotePermissionUsedFlagValid(uint32_t flag);
static bool IsPolicyTypeValid(uint32_t type);
static bool IsCallerTypeValid(uint32_t type);
+9
View File
@@ -219,6 +219,15 @@ bool DataValidator::IsEnhancedIdentityValid(const std::string& enhancedIdentity)
return true;
}
bool DataValidator::IsUpdateWhiteListTypeValid(UpdateWhiteListType type)
{
if ((type != ADD) && (type != DELETE)) {
LOGE(ATM_DOMAIN, ATM_TAG, "Invalid type(%{public}d).", static_cast<int32_t>(type));
return false;
}
return true;
}
bool DataValidator::IsRemotePermissionUsedFlagValid(uint32_t flag)
{
return ((flag == FLAG_PERMISSION_USAGE_SUMMARY) || (flag == FLAG_PERMISSION_USAGE_DETAIL));
@@ -69,13 +69,13 @@ export default namespace abilityAccessCtrl {
permissionName: Permissions;
}
interface PermissionStatusInfo {
tokenID: int;
permissionName: Permissions;
grantStatus: GrantStatus;
grantFlags: int;
grantTimestamp: long;
}
interface PermissionStatusInfo {
tokenID: int;
permissionName: Permissions;
grantStatus: GrantStatus;
grantFlags: int;
grantTimestamp?: long;
}
export enum PermissionStateChangeType {
PERMISSION_REVOKED_OPER = 0,
@@ -101,13 +101,13 @@ export default namespace abilityAccessCtrl {
tokenID: int;
permissionName: Permissions;
}
class PermissionStatusInfoInner implements PermissionStatusInfo {
tokenID: int;
permissionName: Permissions;
grantStatus: GrantStatus;
grantFlags: int;
grantTimestamp: long;
}
class PermissionStatusInfoInner implements PermissionStatusInfo {
tokenID: int;
permissionName: Permissions;
grantStatus: GrantStatus;
grantFlags: int;
grantTimestamp?: long;
}
function validateRequestParams(context: Context, permissionList: Array<Permissions>): void {
if ((typeof context === "undefined") || (context == null)) {
let err = new BusinessError<string>();
@@ -1006,8 +1006,8 @@ static ani_ref CreatePermissionStatusInfoArray(ani_env* env,
// Set grantFlags property
SetIntProperty(env, aniObject, "grantFlags", static_cast<int32_t>(permStatus.grantFlag));
// Set grantTimestamp property
SetLongProperty(env, aniObject, "grantTimestamp", static_cast<int64_t>(permStatus.timestamp));
// Set optional grantTimestamp property
SetOptionalLongProperty(env, aniObject, "grantTimestamp", static_cast<int64_t>(permStatus.timestamp));
// Set array element
ani_size index = static_cast<ani_size>(i);
@@ -54,6 +54,7 @@ bool SetEnumProperty(
ani_env* env, ani_object& aniObject, const std::string& enumDescription,
const std::string& property, uint32_t value);
bool SetOptionalIntProperty(ani_env* env, ani_object& aniObject, const std::string& property, int32_t in);
bool SetOptionalLongProperty(ani_env* env, ani_object& aniObject, const std::string& property, int64_t in);
bool IsCurrentThread(std::thread::id threadId);
bool AniIsCallbackRefEqual(ani_env* env, const ani_ref& compareRef, const ani_ref& targetRref, std::thread::id threadId,
@@ -67,6 +68,7 @@ std::vector<std::string> ParseAniStringVector(ani_env* env, const ani_array& ani
// native to ani
ani_string CreateAniString(ani_env *env, const std::string& str);
ani_object CreateIntObject(ani_env *env, int32_t value);
ani_object CreateLongObject(ani_env *env, int64_t value);
ani_object CreateBooleanObject(ani_env *env, bool value);
ani_object CreateClassObject(ani_env* env, const std::string& classDescriptor);
ani_object CreateArrayObject(ani_env* env, uint32_t length);
@@ -483,6 +483,32 @@ ani_object CreateIntObject(ani_env* env, int32_t value)
return aniObject;
}
ani_object CreateLongObject(ani_env* env, int64_t value)
{
if (env == nullptr) {
LOGE(ATM_DOMAIN, ATM_TAG, "Env is null.");
return nullptr;
}
ani_class longCls;
ani_status status = ANI_ERROR;
if ((status = env->FindClass("std.core.Long", &longCls)) != ANI_OK) {
LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindClass, status : %{public}u.", status);
return nullptr;
}
ani_method aniMethod;
if ((status = env->Class_FindMethod(longCls, "<ctor>", "l:", &aniMethod)) != ANI_OK) {
LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindMethod, status : %{public}u.", status);
return nullptr;
}
ani_object aniObject;
if ((status = env->Object_New(longCls, aniMethod, &aniObject, value)) != ANI_OK) {
LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_New, status : %{public}u.", status);
return nullptr;
}
return aniObject;
}
ani_object CreateClassObject(ani_env* env, const std::string& classDescriptor)
{
if (env == nullptr) {
@@ -767,6 +793,24 @@ bool SetOptionalIntProperty(ani_env* env, ani_object& aniObject, const std::stri
return true;
}
bool SetOptionalLongProperty(ani_env* env, ani_object& aniObject, const std::string& property, int64_t in)
{
if ((env == nullptr) || (aniObject == nullptr)) {
LOGE(ATM_DOMAIN, ATM_TAG, "Input param is nullptr, property(%{public}s).", property.c_str());
return false;
}
ani_object longObject = CreateLongObject(env, in);
if (longObject == nullptr) {
return false;
}
if (!SetRefProperty(env, aniObject, property.c_str(), longObject)) {
return false;
}
return true;
}
bool SetStringProperty(ani_env* env, ani_object& aniObject, const std::string& property, const std::string& in)
{
if ((env == nullptr) || (aniObject == nullptr)) {
@@ -310,6 +310,14 @@ typedef struct {
std::vector<UserPolicy> userPolicyList;
} UserPermissionPolicy;
/**
* @brief User policy whitelist update type.
*/
typedef enum UpdateWhiteListType {
ADD = 0,
DELETE,
} UpdateWhiteListType;
/**
* @brief PermssionRule
*/
@@ -87,10 +87,13 @@ enum AccessTokenError {
ERR_CREATE_KEY_FAILED,
ERR_PERM_POLICY_ALREADY_SET_BY_OTHER,
ERR_PERM_POLICY_NOT_SET,
ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST,
ERR_TOKENID_NOT_IN_POLICY_WHITELIST,
ERR_TOKENID_NOT_IN_POLICY_USERLIST,
ERR_CAPABILITY_NOT_SUPPORT
};
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
#endif // ACCESS_TOKEN_ERROR_H
#endif // ACCESS_TOKEN_ERROR_H
@@ -491,17 +491,36 @@ public:
*/
static int32_t SetUserPolicy(const std::vector<UserPermissionPolicy>& userPermissionList);
/**
* @brief Clear user permission policy
* @param permissionList list of permission.
* @return error code, see access_token_error.h
*/
static int32_t ClearUserPolicy(const std::vector<std::string>& permissionList);
/**
* @brief Whether it is a system application
* @param tokenId token id.
* @return bool
/**
* @brief Clear user permission policy
* @param permissionList list of permission.
* @return error code, see access_token_error.h
*/
static int32_t ClearUserPolicy(const std::vector<std::string>& permissionList);
/**
* @brief Update user policy whitelist.
* @param tokenId target token id.
* @param permission permission name.
* @param type whitelist update type.
* @return error code, see access_token_error.h
*/
static int32_t UpdatePolicyWhiteList(
AccessTokenID tokenId, const std::string& permission, UpdateWhiteListType type);
/**
* @brief Get user policy whitelist.
* @param permission permission name.
* @param tokenIdList whitelist token id list.
* @return error code, see access_token_error.h
*/
static int32_t GetPolicyWhiteList(
const std::string& permission, std::vector<AccessTokenID>& tokenIdList);
/**
* @brief Whether it is a system application
* @param tokenId token id.
* @return bool
*/
static bool IsSystemAppByFullTokenID(uint64_t tokenId);
@@ -57,6 +57,8 @@
"OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(unsigned int)";
"OHOS::Security::AccessToken::AccessTokenKit::SetUserPolicy(std::__h::vector<OHOS::Security::AccessToken::UserPermissionPolicy, std::__h::allocator<OHOS::Security::AccessToken::UserPermissionPolicy>> const&)";
"OHOS::Security::AccessToken::AccessTokenKit::ClearUserPolicy(std::__h::vector<std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>>, std::__h::allocator<std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>>>> const&)";
"OHOS::Security::AccessToken::AccessTokenKit::UpdatePolicyWhiteList(unsigned int, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, OHOS::Security::AccessToken::UpdateWhiteListType)";
"OHOS::Security::AccessToken::AccessTokenKit::GetPolicyWhiteList(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, std::__h::vector<unsigned int, std::__h::allocator<unsigned int>>&)";
"OHOS::Security::AccessToken::AccessTokenKit::GetSelfPermissionsState(std::__h::vector<OHOS::Security::AccessToken::PermissionListState, std::__h::allocator<OHOS::Security::AccessToken::PermissionListState>>&, OHOS::Security::AccessToken::PermissionGrantInfo&)";
"OHOS::Security::AccessToken::AccessTokenKit::GetPermissionsStatus(unsigned int, std::__h::vector<OHOS::Security::AccessToken::PermissionListState, std::__h::allocator<OHOS::Security::AccessToken::PermissionListState>>&)";
"OHOS::Security::AccessToken::AccessTokenKit::GetVersion(unsigned int&)";
File diff suppressed because it is too large Load Diff
@@ -1182,6 +1182,37 @@ int32_t AccessTokenManagerClient::ClearUserPolicy(const std::vector<std::string>
}
return errCode;
}
int32_t AccessTokenManagerClient::UpdatePolicyWhiteList(
AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type)
{
auto proxy = GetProxy();
if (proxy == nullptr) {
LOGE(ATM_DOMAIN, ATM_TAG, "Proxy is null.");
return AccessTokenError::ERR_SERVICE_ABNORMAL;
}
int32_t errCode = proxy->UpdatePolicyWhiteList(tokenId, permCode, static_cast<int32_t>(type));
if (errCode != RET_SUCCESS) {
errCode = ConvertResult(errCode);
LOGE(ATM_DOMAIN, ATM_TAG, "Request fail, result: %{public}d.", errCode);
}
return errCode;
}
int32_t AccessTokenManagerClient::GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList)
{
auto proxy = GetProxy();
if (proxy == nullptr) {
LOGE(ATM_DOMAIN, ATM_TAG, "Proxy is null.");
return AccessTokenError::ERR_SERVICE_ABNORMAL;
}
int32_t errCode = proxy->GetPolicyWhiteList(permCode, tokenIdList);
if (errCode != RET_SUCCESS) {
errCode = ConvertResult(errCode);
LOGE(ATM_DOMAIN, ATM_TAG, "Request fail, result: %{public}d.", errCode);
}
return errCode;
}
#endif
void AccessTokenManagerClient::ReleaseProxy()
@@ -115,6 +115,8 @@ public:
#ifdef SUPPORT_MANAGE_USER_POLICY
int32_t SetUserPolicy(const std::vector<UserPermissionPolicy>& userPermissionList);
int32_t ClearUserPolicy(const std::vector<std::string>& permissionList);
int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type);
int32_t GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList);
#endif
#ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
int32_t RegisterSecCompEnhance(const SecCompEnhanceData& enhance);
@@ -110,10 +110,17 @@ ohos_executable("QueryPermissionStatus") {
debug = false
}
branch_protector_ret = "pac_ret"
sources = [ "query_permission_status.cpp" ]
sources = [
"query_permission_status.cpp",
"test_common.cpp",
]
include_dirs = [
"${access_token_path}/interfaces/innerkits/token_setproc/include",
]
deps = [
"${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk",
"${access_token_path}/interfaces/innerkits/token_setproc:libtoken_setproc",
]
subsystem_name = "security"
@@ -167,6 +174,7 @@ ohos_executable("VerifyAccessToken") {
subsystem_name = "security"
part_name = "access_token"
}
ohos_executable("Relabel") {
subsystem_name = "security"
part_name = "access_token"
@@ -295,6 +303,35 @@ ohos_executable("DeleteHapToken") {
part_name = "access_token"
}
ohos_executable("UpdateHapToken") {
subsystem_name = "security"
part_name = "access_token"
sanitize = {
cfi = true
cfi_cross_dso = true
debug = false
}
branch_protector_ret = "pac_ret"
sources = [
"update_hap_token.cpp",
"test_common.cpp",
]
include_dirs = [
"${access_token_path}/interfaces/innerkits/nativetoken/include",
"${access_token_path}/interfaces/innerkits/token_setproc/include",
]
deps = [
"${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk",
"${access_token_path}/interfaces/innerkits/nativetoken:libnativetoken",
"${access_token_path}/interfaces/innerkits/token_setproc:libtoken_setproc",
]
subsystem_name = "security"
part_name = "access_token"
}
group("accesstoken_tool") {
deps = [
":CreateHapToken",
@@ -306,6 +343,7 @@ group("accesstoken_tool") {
":Relabel",
":RevokePermission",
":SetPermDialogCap",
":UpdateHapToken",
":VerifyAccessToken",
]
}
@@ -16,25 +16,127 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
#include "test_common.h"
using namespace std;
using namespace OHOS::Security::AccessToken;
namespace {
struct CreateHapTokenOptions final {
std::string bundleName;
std::vector<std::string> reqPerm;
std::vector<std::string> preAuthPerm;
bool isSystemApp = true;
};
void PrintCreateHapTokenHelp()
{
std::cout << "Help: ./CreateHapToken bundleName [reqPermission ...] [--preauth permission ...]\n"
<< "--preauth: switch subsequent arguments to pre-authorized permissions.\n"
<< "--system-app <true|false>: set HapInfoParams.isSystemApp, default true.\n"
<< "Note: every --preauth permission must also appear in the req permission list.\n"
<< "Example1: ./CreateHapToken com.example.demo ohos.permission.CAMERA "
<< "--preauth ohos.permission.CAMERA\n"
<< "Example2: ./CreateHapToken com.example.demo --system-app false "
<< "ohos.permission.CAMERA\n"
<< "Example3: ./CreateHapToken com.example.demo --system-app true "
<< "ohos.permission.CAMERA ohos.permission.MICROPHONE "
<< "--preauth ohos.permission.MICROPHONE\n"
<< std::endl;
}
bool ValidatePreAuthorizedPermissions(const std::vector<std::string>& reqPerm,
const std::vector<std::string>& preAuthPerm)
{
std::unordered_set<std::string> reqPermSet(reqPerm.begin(), reqPerm.end());
for (const auto& permission : preAuthPerm) {
if (reqPermSet.count(permission) == 0) {
std::cout << "CreateHapToken failed, pre-authorized permission must be declared in req permissions: "
<< permission << std::endl << std::endl;
return false;
}
}
return true;
}
bool ParseBoolArg(const std::string& value, bool& result)
{
if ((value == "true") || (value == "1")) {
result = true;
return true;
}
if ((value == "false") || (value == "0")) {
result = false;
return true;
}
return false;
}
bool ParseCreateHapTokenArgs(int argc, char* argv[], CreateHapTokenOptions& options)
{
options.bundleName = argv[1]; // 1: index
bool isPreAuthMode = false;
for (int32_t i = 2; i < argc; ++i) { // 2: start index
std::string arg = argv[i];
if (arg == "--preauth") {
isPreAuthMode = true;
continue;
}
if (arg == "--system-app") {
if ((i + 1) >= argc) {
std::cout << "CreateHapToken failed, missing value for --system-app" << std::endl << std::endl;
return false;
}
if (!ParseBoolArg(argv[i + 1], options.isSystemApp)) {
std::cout << "CreateHapToken failed, invalid --system-app value: " << argv[i + 1]
<< std::endl << std::endl;
return false;
}
++i;
continue;
}
if (!arg.empty() && arg[0] == '-') {
std::cout << "CreateHapToken failed, unsupported option: " << arg << std::endl << std::endl;
return false;
}
if (isPreAuthMode) {
options.preAuthPerm.emplace_back(arg);
continue;
}
options.reqPerm.emplace_back(arg);
}
return ValidatePreAuthorizedPermissions(options.reqPerm, options.preAuthPerm);
}
int32_t RunCreateHapToken(const CreateHapTokenOptions& options)
{
FullTokenID tokenId = GetHapTokenId(
options.bundleName, options.reqPerm, options.preAuthPerm, options.isSystemApp);
if (tokenId == INVALID_TOKENID) {
std::cout << "CreateHapToken failed, bundleName=" << options.bundleName << std::endl << std::endl;
return RET_FAILED;
}
std::cout << "CreateHapToken success, bundleName=" << options.bundleName
<< ", isSystemApp=" << options.isSystemApp
<< ", permissionCount=" << options.reqPerm.size()
<< ", preAuthPermissionCount=" << options.preAuthPerm.size()
<< ", tokenId=" << tokenId << std::endl << std::endl;
return RET_SUCCESS;
}
}
int32_t main(int argc, char *argv[])
{
if (argc < 2) { // 2: size
std::cout << "Help: ./CreateHapToken bundleName [optional]permission1 permission2 ...\n" << std::endl;
PrintCreateHapTokenHelp();
return 0;
}
std::string bundleName = argv[1]; // 1: index
std::vector<std::string> reqPerm;
for (int32_t i = 2; i < argc; ++i) { // 2: start index
reqPerm.emplace_back(argv[i]);
CreateHapTokenOptions options;
if (!ParseCreateHapTokenArgs(argc, argv, options)) {
return RET_FAILED;
}
FullTokenID tokenId = GetHapTokenId(bundleName, reqPerm);
std::cout << "CreateHapToken success, bundleName=" << bundleName
<< ", permissionCount=" << reqPerm.size()
<< ", tokenId=" << tokenId << std::endl << std::endl;
return 0;
return RunCreateHapToken(options);
}
@@ -22,6 +22,8 @@
#include <vector>
#include "accesstoken_kit.h"
#include "test_common.h"
#include "token_setproc.h"
using namespace OHOS::Security::AccessToken;
@@ -35,7 +37,7 @@ constexpr int32_t MILLISECONDS_PER_SECOND = 1000;
constexpr int32_t TM_YEAR_BASE = 1900;
constexpr uint64_t INVALID_TIMESTAMP = 0;
constexpr int32_t SUCCESS_EXIT_CODE = 0;
constexpr bool QUERY_ONLY_HAP = true;
constexpr bool QUERY_ONLY_HAP = false;
constexpr const char* OPTION_PREFIX = "--";
void PrintHelp()
@@ -117,6 +119,9 @@ int32_t main(int argc, char* argv[])
return SUCCESS_EXIT_CODE;
}
AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("privacy_service");
SetSelfTokenID(nativeTokenId);
std::vector<PermissionStatus> permissionInfoList;
int32_t ret = RET_SUCCESS;
if (tokenID != INVALID_TOKENID) {
@@ -16,6 +16,7 @@
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <unordered_set>
#include <sstream>
#include <string>
#include <iostream>
@@ -24,6 +25,17 @@
#include "token_setproc.h"
using namespace OHOS::Security::AccessToken;
static void AppendUniquePermission(const std::string& permission, std::vector<std::string>& permissions,
std::unordered_set<std::string>& uniquePermissions)
{
if (permission.empty()) {
return;
}
if (uniquePermissions.insert(permission).second) {
permissions.emplace_back(permission);
}
}
void PrintCurrentTime()
{
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(
@@ -62,7 +74,49 @@ AccessTokenID GetNativeTokenId(const std::string& process)
return tokenID;
}
FullTokenID GetHapTokenId(const std::string& bundle, const std::vector<std::string>& reqPerm)
void BuildHapPolicyParams(const std::vector<std::string>& reqPerm, const std::vector<std::string>& preAuthPerm,
HapPolicyParams& policyParams)
{
policyParams = {
.apl = APL_NORMAL,
.domain = "accesstoken_test_tool",
};
std::vector<std::string> permissions;
std::unordered_set<std::string> uniquePermissions;
for (const auto& permission : reqPerm) {
AppendUniquePermission(permission, permissions, uniquePermissions);
}
std::unordered_set<std::string> uniquePreAuthPerm(preAuthPerm.begin(), preAuthPerm.end());
for (const auto& permission : permissions) {
PermissionDef permDefResult;
if (AccessTokenKit::GetDefPermission(permission, permDefResult) != RET_SUCCESS) {
continue;
}
PermissionStateFull permState = {
.permissionName = permission,
.isGeneral = true,
.resDeviceID = {"local3"},
.grantStatus = {PermissionState::PERMISSION_DENIED},
.grantFlags = {PermissionFlag::PERMISSION_DEFAULT_FLAG}
};
policyParams.permStateList.emplace_back(permState);
if (uniquePreAuthPerm.count(permission) != 0) {
PreAuthorizationInfo preAuthInfo = {
.permissionName = permission,
.userCancelable = false,
};
policyParams.preAuthorizationInfo.emplace_back(preAuthInfo);
}
if (permDefResult.availableLevel > policyParams.apl) {
policyParams.aclRequestedList.emplace_back(permission);
}
}
}
FullTokenID GetHapTokenId(const std::string& bundle, const std::vector<std::string>& reqPerm,
const std::vector<std::string>& preAuthPerm, bool isSystemApp)
{
uint64_t selfTokenId = GetSelfTokenID();
HapInfoParams infoParams = {
@@ -71,31 +125,12 @@ FullTokenID GetHapTokenId(const std::string& bundle, const std::vector<std::stri
.instIndex = 0,
.appIDDesc = bundle,
.apiVersion = 8, // 8: API VERSION
.isSystemApp = true,
.isSystemApp = isSystemApp,
.appDistributionType = "",
};
HapPolicyParams policyParams = {
.apl = APL_NORMAL,
.domain = "accesstoken_test_tool",
};
for (size_t i = 0; i < reqPerm.size(); ++i) {
PermissionDef permDefResult;
if (AccessTokenKit::GetDefPermission(reqPerm[i], permDefResult) != RET_SUCCESS) {
continue;
}
PermissionStateFull permState = {
.permissionName = reqPerm[i],
.isGeneral = true,
.resDeviceID = {"local3"},
.grantStatus = {PermissionState::PERMISSION_DENIED},
.grantFlags = {PermissionFlag::PERMISSION_DEFAULT_FLAG}
};
policyParams.permStateList.emplace_back(permState);
if (permDefResult.availableLevel > policyParams.apl) {
policyParams.aclRequestedList.emplace_back(reqPerm[i]);
}
}
HapPolicyParams policyParams;
BuildHapPolicyParams(reqPerm, preAuthPerm, policyParams);
AccessTokenIDEx tokenIdEx = {0};
AccessTokenID mockToken = GetNativeTokenId("foundation");
@@ -104,7 +139,9 @@ FullTokenID GetHapTokenId(const std::string& bundle, const std::vector<std::stri
SetSelfTokenID(mockToken);
}
AccessTokenKit::InitHapToken(infoParams, policyParams, tokenIdEx);
if (AccessTokenKit::InitHapToken(infoParams, policyParams, tokenIdEx) != RET_SUCCESS) {
tokenIdEx.tokenIDEx = INVALID_TOKENID;
}
// restore
SetSelfTokenID(selfTokenId);
@@ -18,11 +18,15 @@
#include <string>
#include <vector>
#include "access_token.h"
#include "hap_token_info.h"
void PrintCurrentTime();
OHOS::Security::AccessToken::AccessTokenID GetNativeTokenId(const std::string& process);
void BuildHapPolicyParams(const std::vector<std::string>& reqPerm,
const std::vector<std::string>& preAuthPerm, OHOS::Security::AccessToken::HapPolicyParams& policyParams);
OHOS::Security::AccessToken::FullTokenID GetHapTokenId(
const std::string& bundle, const std::vector<std::string>& reqPerm);
const std::string& bundle, const std::vector<std::string>& reqPerm,
const std::vector<std::string>& preAuthPerm = {}, bool isSystemApp = true);
int32_t DeleteHapTokenID(const std::string& bundleName, bool isReservedTokenId);
#endif // TEST_TOOL_COMMON_H
@@ -0,0 +1,150 @@
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "accesstoken_kit.h"
#include "test_common.h"
#include "token_setproc.h"
using namespace std;
using namespace OHOS::Security::AccessToken;
namespace {
struct UpdateHapTokenOptions final {
uint64_t tokenId = 0;
std::vector<std::string> reqPerm;
};
void PrintUpdateHapTokenHelp()
{
std::cout << "Help: ./UpdateHapToken tokenId [requestPermission ...]\n"
<< "Example1: ./UpdateHapToken 281475008495616 ohos.permission.CAMERA\n"
<< "Example2: ./UpdateHapToken 281475008495616 "
<< "ohos.permission.CAMERA ohos.permission.MICROPHONE\n"
<< std::endl;
}
bool ParseUint64Arg(const std::string& value, uint64_t& result)
{
if (value.empty()) {
return false;
}
char* end = nullptr;
unsigned long long parsed = std::strtoull(value.c_str(), &end, 10);
if ((end == nullptr) || (*end != '\0')) {
return false;
}
result = static_cast<uint64_t>(parsed);
return true;
}
bool ParseUpdateHapTokenArgs(int argc, char* argv[], UpdateHapTokenOptions& options)
{
if (!ParseUint64Arg(argv[1], options.tokenId)) {
std::cout << "UpdateHapToken failed, invalid token id: " << argv[1] << std::endl << std::endl;
return false;
}
for (int32_t i = 2; i < argc; ++i) { // 2: start index
std::string arg = argv[i];
if (!arg.empty() && arg[0] == '-') {
std::cout << "UpdateHapToken failed, unsupported option: " << arg << std::endl << std::endl;
return false;
}
options.reqPerm.emplace_back(arg);
}
return true;
}
bool LoadUpdateContext(AccessTokenIDEx& tokenIdEx, std::string& bundleName, UpdateHapInfoParams& updateInfoParams)
{
if (tokenIdEx.tokenIdExStruct.tokenID == INVALID_TOKENID) {
std::cout << "UpdateHapToken failed, tokenId=" << tokenIdEx.tokenIDEx
<< ", token not found" << std::endl << std::endl;
return false;
}
HapTokenInfo hapInfo;
if (AccessTokenKit::GetHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID, hapInfo) != RET_SUCCESS) {
std::cout << "UpdateHapToken failed, unable to query hap info for tokenId=" << tokenIdEx.tokenIDEx
<< std::endl << std::endl;
return false;
}
tokenIdEx.tokenIdExStruct.tokenAttr = hapInfo.tokenAttr;
bundleName = hapInfo.bundleName;
HapTokenInfoExt hapInfoExt;
if (AccessTokenKit::GetHapTokenInfoExtension(tokenIdEx.tokenIdExStruct.tokenID, hapInfoExt) != RET_SUCCESS) {
std::cout << "UpdateHapToken failed, unable to query hap extension info for bundleName=" << bundleName
<< std::endl << std::endl;
return false;
}
updateInfoParams = {
.appIDDesc = hapInfoExt.appID,
.apiVersion = hapInfo.apiVersion,
.isSystemApp = AccessTokenKit::IsSystemAppByFullTokenID(tokenIdEx.tokenIDEx),
.appDistributionType = "",
};
return true;
}
int32_t RunUpdateHapToken(const UpdateHapTokenOptions& options)
{
uint64_t selfTokenId = GetSelfTokenID();
AccessTokenID mockToken = GetNativeTokenId("foundation");
if (mockToken != selfTokenId) {
SetSelfTokenID(mockToken);
}
AccessTokenIDEx tokenIdEx = {0};
tokenIdEx.tokenIDEx = options.tokenId;
std::string bundleName;
UpdateHapInfoParams updateInfoParams;
if (!LoadUpdateContext(tokenIdEx, bundleName, updateInfoParams)) {
return RET_FAILED;
}
HapPolicyParams policyParams;
BuildHapPolicyParams(options.reqPerm, {}, policyParams);
int32_t ret = AccessTokenKit::UpdateHapToken(tokenIdEx, updateInfoParams, policyParams);
SetSelfTokenID(selfTokenId);
std::cout << "UpdateHapToken end, bundleName=" << bundleName
<< ", apiVersion=" << updateInfoParams.apiVersion
<< ", permissionCount=" << options.reqPerm.size()
<< ", tokenId=" << tokenIdEx.tokenIDEx
<< ", ret=" << ret << std::endl << std::endl;
return (ret == RET_SUCCESS) ? RET_SUCCESS : RET_FAILED;
}
}
int32_t main(int argc, char *argv[])
{
if (argc < 2) { // 2: size
PrintUpdateHapTokenHelp();
return 0;
}
UpdateHapTokenOptions options;
if (!ParseUpdateHapTokenArgs(argc, argv, options)) {
return RET_FAILED;
}
return RunUpdateHapToken(options);
}
@@ -14,6 +14,7 @@
*/
#include "edm_policy_set_test.h"
#include <algorithm>
#include <thread>
#include "accesstoken_kit.h"
@@ -312,6 +313,9 @@ static void InitUserPolicyTestEnviroment()
g_mockUserPolicy1 = MocNativeTokenID("MockUserPolicy1");
g_mockUserPolicy2 = MocNativeTokenID("MockUserPolicy2");
GTEST_LOG_(INFO) << "Before stop service, pidof accesstoken_service:";
std::system("pidof accesstoken_service");
std::system("service_control stop accesstoken_service");
usleep(TIME_500_MS);
GTEST_LOG_(INFO) << "stop service, pidof accesstoken_service:";
@@ -380,7 +384,7 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy002, TestSize.Level1)
/**
* @tc.name: SetUserPolicy003
* @tc.desc: SetUserPolicy failed: 1. invalid userId of userList; 2. invalid permission.
* @tc.desc: SetUserPolicy failed with invalid permission or invalid userId.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
@@ -405,10 +409,6 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy003, TestSize.Level1)
policy.permissionName = "test";
EXPECT_EQ(AccessTokenError::ERR_PARAM_INVALID, AccessTokenKit::SetUserPolicy({ policy }));
// permission is user_grant
policy.permissionName = "ohos.permission.CAMERA";
EXPECT_EQ(AccessTokenError::ERR_PARAM_INVALID, AccessTokenKit::SetUserPolicy({ policy }));
// invalid userId
policy.permissionName = "ohos.permission.INTERNET";
policy.userPolicyList[0].userId = -1; // -1: invalid userId
@@ -1037,6 +1037,516 @@ HWTEST_F(EdmPolicySetTest, ClearUserPolicy004, TestSize.Level1)
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest001
* @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList basic function test.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest001, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET));
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET));
tokenIdList.clear();
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
ASSERT_EQ(1u, tokenIdList.size());
EXPECT_EQ(tokenId, tokenIdList[0]);
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest002
* @tc.desc: UpdatePolicyWhiteList failed when caller is not controller.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest002, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
{
MockNativeToken otherPolicyMock("MockUserPolicy2");
EXPECT_EQ(ERR_PERM_POLICY_ALREADY_SET_BY_OTHER,
AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
}
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest003
* @tc.desc: UpdatePolicyWhiteList returns error when adding duplicated token or deleting absent token.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest003, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
EXPECT_EQ(ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST,
AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_WHITELIST,
AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest004
* @tc.desc: UpdatePolicyWhiteList returns error when user policy is not set.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest004, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(ERR_PERM_POLICY_NOT_SET, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest005
* @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList invalid parameter test.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest005, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(INVALID_TOKENID, INTERNET, ADD));
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(tokenId, "", ADD));
std::string invalidPermName(MAX_LENGTH + 1, 'A');
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(tokenId, invalidPermName, ADD));
EXPECT_EQ(ERR_PARAM_INVALID,
AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, static_cast<UpdateWhiteListType>(2)));
std::vector<AccessTokenID> tokenIdList = {tokenId};
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList("", tokenIdList));
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList(invalidPermName, tokenIdList));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest006
* @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList with multiple tokens.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest006, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
AccessTokenIDEx fullIdUser2;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
testHapInfo.instIndex = 1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2));
AccessTokenID tokenId1 = fullIdUser1.tokenIdExStruct.tokenID;
AccessTokenID tokenId2 = fullIdUser2.tokenIdExStruct.tokenID;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, ADD));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId2, INTERNET, ADD));
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_EQ(2u, tokenIdList.size());
EXPECT_NE(tokenIdList.end(), std::find(tokenIdList.begin(), tokenIdList.end(), tokenId1));
EXPECT_NE(tokenIdList.end(), std::find(tokenIdList.begin(), tokenIdList.end(), tokenId2));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, DELETE));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
ASSERT_EQ(1u, tokenIdList.size());
EXPECT_EQ(tokenId2, tokenIdList[0]);
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
testHapInfo.instIndex = 0;
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId1));
testHapInfo.instIndex = 1;
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId2));
}
/**
* @tc.name: PolicyWhiteListTest007
* @tc.desc: White list only works for target token and is cleared with user policy.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest007, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
AccessTokenIDEx fullIdUser2;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
testHapInfo.instIndex = 1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2));
AccessTokenID tokenId1 = fullIdUser1.tokenIdExStruct.tokenID;
AccessTokenID tokenId2 = fullIdUser2.tokenIdExStruct.tokenID;
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET));
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, ADD));
EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET));
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
std::vector<AccessTokenID> tokenIdList = {tokenId1, tokenId2};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET));
EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET));
testHapInfo.instIndex = 0;
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId1));
testHapInfo.instIndex = 1;
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId2));
}
/**
* @tc.name: PolicyWhiteListTest008
* @tc.desc: UpdatePolicyWhiteList returns error when token user is outside controlled userIds.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest008, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10002;
AccessTokenIDEx fullIdUser2;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2));
AccessTokenID tokenId = fullIdUser2.tokenIdExStruct.tokenID;
EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest009
* @tc.desc: GetPolicyWhiteList clears output list when parameter is invalid.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest009, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
std::vector<AccessTokenID> tokenIdList = {INVALID_TOKENID};
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList("", tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
tokenIdList = {INVALID_TOKENID};
std::string invalidPermName(MAX_LENGTH + 1, 'A');
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList(invalidPermName, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
}
/**
* @tc.name: PolicyWhiteListTest010
* @tc.desc: GetPolicyWhiteList returns empty list when whitelist does not exist.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest010, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
}
/**
* @tc.name: PolicyWhiteListTest011
* @tc.desc: UpdatePolicyWhiteList returns error when tokenId is not hap.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest011, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("foundation");
EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(nativeTokenId, INTERNET, ADD));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
}
/**
* @tc.name: PolicyWhiteListTest012
* @tc.desc: GetPolicyWhiteList clears prefilled output list before valid query.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest012, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
std::vector<AccessTokenID> tokenIdList = {INVALID_TOKENID};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
}
/**
* @tc.name: PolicyWhiteListTest013
* @tc.desc: UpdatePolicyWhiteList returns invalid when permission does not exist.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest013, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(ERR_PARAM_INVALID,
AccessTokenKit::UpdatePolicyWhiteList(tokenId, "ohos.permission.TEST_123", ADD));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: PolicyWhiteListTest014
* @tc.desc: QueryStatusByPermission and QueryStatusByTokenID reflect whitelist final state.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest014, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET, .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
{
MockNativeToken mockNative("privacy_service");
std::vector<PermissionStatus> permissionInfoList1;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByPermission({INTERNET}, permissionInfoList1));
for (const auto& info : permissionInfoList1) {
if (info.tokenID == tokenId) {
EXPECT_EQ(PERMISSION_GRANTED, info.grantStatus);
}
}
std::vector<PermissionStatus> permissionInfoList2;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByTokenID({tokenId}, permissionInfoList2));
for (const auto& info : permissionInfoList2) {
if (info.permissionName == INTERNET) {
EXPECT_EQ(PERMISSION_GRANTED, info.grantStatus);
}
}
}
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
{
MockNativeToken mockNative("privacy_service");
std::vector<PermissionStatus> permissionInfoList1;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByPermission({INTERNET}, permissionInfoList1));
for (const auto& info : permissionInfoList1) {
if (info.tokenID == tokenId) {
EXPECT_EQ(PERMISSION_DENIED, info.grantStatus);
}
}
std::vector<PermissionStatus> permissionInfoList2;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByTokenID({tokenId}, permissionInfoList2));
for (const auto& info : permissionInfoList2) {
if (info.permissionName == INTERNET) {
EXPECT_EQ(PERMISSION_DENIED, info.grantStatus);
}
}
}
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
class CbCustomizeTestForEdm : public PermStateChangeCallbackCustomize {
public:
explicit CbCustomizeTestForEdm(const PermStateChangeScope &scopeInfo)
: PermStateChangeCallbackCustomize(scopeInfo)
{
}
~CbCustomizeTestForEdm()
{}
virtual void PermStateChangeCallback(PermStateChangeInfo& result)
{
GTEST_LOG_(INFO) << "PermStateChangeCallback permissionName: " << result.permissionName;
GTEST_LOG_(INFO) << "PermStateChangeCallback permStateChangeType: " << result.permStateChangeType;
ready_ = true;
changeCnt_++;
}
bool ready_ = false;
uint32_t changeCnt_ = 0;
};
/**
* @tc.name: PolicyWhiteListTest015
* @tc.desc: UpdatePolicyWhiteList triggers permission state change callback on add and delete.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest015, TestSize.Level1)
{
MockNativeToken userPolicyMock("MockUserPolicy1");
UserPermissionPolicy policy = {
.permissionName = INTERNET,
.userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }}
};
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy }));
HapInfoParams testHapInfo = g_testHapInfoParams;
testHapInfo.userID = MOCK_USER_ID_10001;
AccessTokenIDEx fullIdUser1;
EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1));
AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID;
EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET));
PermStateChangeScope scopeInfo;
scopeInfo.permList = { INTERNET };
scopeInfo.tokenIDs = { tokenId };
auto callbackPtr = std::make_shared<CbCustomizeTestForEdm>(scopeInfo);
ASSERT_EQ(RET_SUCCESS, AccessTokenKit::RegisterPermStateChangeCallback(callbackPtr));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD));
usleep(500000); // 500000us = 0.5s
EXPECT_TRUE(callbackPtr->ready_);
EXPECT_EQ(1u, callbackPtr->changeCnt_);
callbackPtr->ready_ = false;
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE));
usleep(500000); // 500000us = 0.5s
EXPECT_TRUE(callbackPtr->ready_);
EXPECT_EQ(2u, callbackPtr->changeCnt_);
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UnRegisterPermStateChangeCallback(callbackPtr));
EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET }));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
/**
* @tc.name: UserPolicyTestForInitHap
* @tc.desc: Set the authorization status based on the user policy during new hap installation
@@ -1135,28 +1645,6 @@ HWTEST_F(EdmPolicySetTest, UserPolicyTestForUpdateHap, TestSize.Level1)
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId));
}
class CbCustomizeTestForEdm : public PermStateChangeCallbackCustomize {
public:
explicit CbCustomizeTestForEdm(const PermStateChangeScope &scopeInfo)
: PermStateChangeCallbackCustomize(scopeInfo)
{
}
~CbCustomizeTestForEdm()
{}
virtual void PermStateChangeCallback(PermStateChangeInfo& result)
{
GTEST_LOG_(INFO) << "PermStateChangeCallback permissionName: " << result.permissionName;
GTEST_LOG_(INFO) << "PermStateChangeCallback permStateChangeType: " << result.permStateChangeType;
ready_ = true;
changeCnt_++;
}
bool ready_ = false;
uint32_t changeCnt_ = 0;
};
/**
* @tc.name: UserPolicyTestForRemove
* @tc.desc: UpdateHapToken and check permission status with user policy.
@@ -1266,6 +1754,21 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy001, TestSize.Level0)
EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, AccessTokenKit::SetUserPolicy(permPolicyListEmpty));
EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, AccessTokenKit::ClearUserPolicy({ INTERNET }));
}
/**
* @tc.name: PolicyWhiteListNotSupport001
* @tc.desc: Not support to UpdatePolicyWhiteList/GetPolicyWhiteList.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(EdmPolicySetTest, PolicyWhiteListNotSupport001, TestSize.Level0)
{
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT,
AccessTokenKit::UpdatePolicyWhiteList(INVALID_TOKENID, INTERNET, ADD));
EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT,
AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList));
}
#endif
/**
@@ -2218,4 +2721,4 @@ HWTEST_F(EdmPolicySetTest, EdmTestUpdateHapToken003, TestSize.Level0)
}
}
}
}
}
@@ -115,6 +115,47 @@ HWTEST_F(AccessTokenDenyTest, SetUserPolicy001, TestSize.Level0)
int32_t ret = AccessTokenKit::SetUserPolicy(permPolicyList);
EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED);
}
/**
* @tc.name: UpdatePolicyWhiteList001
* @tc.desc: UpdatePolicyWhiteList without authorized.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(AccessTokenDenyTest, UpdatePolicyWhiteList001, TestSize.Level0)
{
setuid(g_selfUid);
HapPolicyParams policyPrams = {
.apl = APL_NORMAL,
.domain = "test.domain",
};
AccessTokenIDEx tokenIdEx = {0};
ASSERT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(g_InfoParms, policyPrams, tokenIdEx));
ASSERT_NE(INVALID_TOKENID, tokenIdEx.tokenIdExStruct.tokenID);
EXPECT_EQ(RET_SUCCESS, SetSelfTokenID(g_testTokenIDEx.tokenIDEx));
setuid(1234); // 1234: UID
int32_t ret = AccessTokenKit::UpdatePolicyWhiteList(
tokenIdEx.tokenIdExStruct.tokenID, "ohos.permission.INTERNET", ADD);
EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED);
setuid(g_selfUid);
EXPECT_EQ(RET_SUCCESS, SetSelfTokenID(g_selfTokenId));
EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenIdEx.tokenIdExStruct.tokenID));
}
/**
* @tc.name: GetPolicyWhiteList001
* @tc.desc: GetPolicyWhiteList without authorized.
* @tc.type: FUNC
* @tc.require:Issue Number
*/
HWTEST_F(AccessTokenDenyTest, GetPolicyWhiteList001, TestSize.Level0)
{
std::vector<AccessTokenID> tokenIdList;
int32_t ret = AccessTokenKit::GetPolicyWhiteList("ohos.permission.INTERNET", tokenIdList);
EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED);
}
#endif
/**
@@ -548,4 +589,3 @@ HWTEST_F(AccessTokenDenyTest, GetKernelPermissions001, TestSize.Level0)
} // namespace AccessToken
} // namespace Security
} // namespace OHOS
@@ -734,6 +734,31 @@ HWTEST_F(AccessTokenMockTest, ClearUserPolicy001, TestSize.Level4)
permissionList.emplace_back("ohos.permission.INTERNET");
ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL, AccessTokenKit::ClearUserPolicy(permissionList));
}
/**
* @tc.name: UpdatePolicyWhiteList001
* @tc.desc: UpdatePolicyWhiteList with proxy is null
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(AccessTokenMockTest, UpdatePolicyWhiteList001, TestSize.Level4)
{
ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL,
AccessTokenKit::UpdatePolicyWhiteList(g_testTokenId, "ohos.permission.INTERNET", ADD));
}
/**
* @tc.name: GetPolicyWhiteList001
* @tc.desc: GetPolicyWhiteList with proxy is null
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(AccessTokenMockTest, GetPolicyWhiteList001, TestSize.Level4)
{
std::vector<AccessTokenID> tokenIdList;
ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL,
AccessTokenKit::GetPolicyWhiteList("ohos.permission.INTERNET", tokenIdList));
}
#endif
/**
@@ -79,8 +79,12 @@ interface OHOS.Security.AccessToken.IAccessTokenManager{
[ipccode 58] void GetVersion([out] unsigned int version);
[ipccode 59] void GetPermissionManagerInfo([out] PermissionGrantInfoParcel infoParcel);
[ipccode 61, macrodef SUPPORT_MANAGE_USER_POLICY] void SetUserPolicy([in] List<UserPermissionPolicyIdl> userPermissionList);
[ipccode 63, macrodef SUPPORT_MANAGE_USER_POLICY] void ClearUserPolicy([in] List<String> permissionList);
[ipccode 60, macrodef SUPPORT_MANAGE_USER_POLICY] void SetUserPolicy([in] List<UserPermissionPolicyIdl> userPermissionList);
[ipccode 61, macrodef SUPPORT_MANAGE_USER_POLICY] void ClearUserPolicy([in] List<String> permissionList);
[ipccode 62, macrodef SUPPORT_MANAGE_USER_POLICY] void UpdatePolicyWhiteList(
[in] unsigned int tokenId, [in] unsigned int permCode, [in] int type);
[ipccode 63, macrodef SUPPORT_MANAGE_USER_POLICY] void GetPolicyWhiteList(
[in] unsigned int permCode, [out] List<unsigned int> tokenIdList);
[ipccode 64] void GetHapTokenInfoExtension([in] unsigned int tokenID, [out] HapTokenInfoParcel hapTokenInfoRes, [out] String appID);
[ipccode 65] void RegisterSelfPermStateChangeCallback([in] PermStateChangeScopeParcel scope, [in] IRemoteObject cb);
[ipccode 66] void UnRegisterSelfPermStateChangeCallback([in] IRemoteObject cb);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2025 Huawei Device Co., Ltd.
* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -96,6 +96,8 @@ public:
#ifdef SUPPORT_MANAGE_USER_POLICY
int32_t SetUserPolicy(const std::vector<UserPermissionPolicy>& userPermissionList);
int32_t ClearUserPolicy(const std::vector<std::string>& permissionList);
int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type);
int32_t GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList);
#endif
bool GetPermDialogCap(AccessTokenID tokenID);
void ClearUserGrantedPermissionState(AccessTokenID tokenID);
@@ -181,8 +183,10 @@ private:
void DumpAllNativeTokenName(std::string& dumpInfo);
#ifdef SUPPORT_MANAGE_USER_POLICY
void UpdatePermissionStateToKernel(uint32_t permCode, const std::map<int32_t, bool>& changedUserList);
void UpdatePermissionStateToKernel(AccessTokenID tokenId, uint32_t permCode, bool isActive);
void GetHapTokenInfoListByUserId(
const std::map<int32_t, bool>& changedUserList, std::map<AccessTokenID, bool>& tokenIdList);
bool IsInPolicyWhiteList(AccessTokenID tokenId, uint32_t permCode) const;
#endif
int32_t AddPermRequestToggleStatusToDb(int32_t userID, const std::string& permissionName, int32_t status);
int32_t FindPermRequestToggleStatusFromDb(int32_t userID, const std::string& permissionName);
@@ -217,8 +221,9 @@ private:
#ifdef SUPPORT_MANAGE_USER_POLICY
std::shared_mutex userPolicyLock_;
std::map<uint32_t, std::vector<int32_t>> userPermPolicyList_; // key-permCode
std::map<uint32_t, std::vector<int32_t>> userPermPolicyList_; // key-permCode, value-userid
std::map<uint32_t, uint32_t> policyController_; // key-permCode, value-callerToken
std::map<uint32_t, std::unordered_set<AccessTokenID>> policyWhiteList_; // key-permCode, value-tokenId
#endif
std::shared_ptr<VerifyAccessTokenMonitor> tokenMonitor_;
@@ -133,6 +133,8 @@ public:
#ifdef SUPPORT_MANAGE_USER_POLICY
int32_t SetUserPolicy(const std::vector<UserPermissionPolicyIdl>& userPermissionList) override;
int32_t ClearUserPolicy(const std::vector<std::string>& permissionList) override;
int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, int32_t type) override;
int32_t GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList) override;
#endif
int32_t DumpTokenInfo(const AtmToolsParamInfoParcel& infoParcel, std::string& dumpInfo) override;
int32_t GetVersion(uint32_t& version) override;
@@ -1593,8 +1593,13 @@ bool AccessTokenInfoManager::IsPermissionRestrictedByUserPolicy(AccessTokenID id
}
std::shared_lock<std::shared_mutex> infoGuard(this->userPolicyLock_);
auto iter = userPermPolicyList_.find(permCode);
if (iter != userPermPolicyList_.end() &&
std::find(iter->second.begin(), iter->second.end(), infoPtr->GetUserID()) != iter->second.end()) {
if (iter == userPermPolicyList_.end()) {
return false;
}
if (IsInPolicyWhiteList(id, permCode)) {
return false;
}
if (std::find(iter->second.begin(), iter->second.end(), infoPtr->GetUserID()) != iter->second.end()) {
std::string permissionName = TransferOpcodeToPermission(permCode);
LOGW(ATM_DOMAIN, ATM_TAG, "Perm %{public}s of %{public}u is restricted.", permissionName.c_str(), id);
return true;
@@ -1725,15 +1730,36 @@ void AccessTokenInfoManager::UpdatePermissionStateToKernel(
return;
}
void AccessTokenInfoManager::UpdatePermissionStateToKernel(AccessTokenID tokenId, uint32_t permCode, bool isActive)
{
std::map<std::string, bool> refreshedPermList;
HapTokenInfoInner::RefreshPermStateToKernel(tokenId, permCode, isActive, refreshedPermList);
if (!refreshedPermList.empty()) {
PermissionManager::GetInstance().ParamUpdate(std::string(), 0, true);
}
for (const auto& perm : refreshedPermList) {
LOGI(ATM_DOMAIN, ATM_TAG, "Perm %{public}s refreshed by whitelist, isActive %{public}d.",
perm.first.c_str(), perm.second);
PermStateChangeType change = perm.second ?
PermStateChangeType::STATE_CHANGE_GRANTED : PermStateChangeType::STATE_CHANGE_REVOKED;
CallbackManager::GetInstance().ExecuteCallbackAsync(tokenId, perm.first, change);
}
}
bool AccessTokenInfoManager::IsInPolicyWhiteList(AccessTokenID tokenId, uint32_t permCode) const
{
auto iter = policyWhiteList_.find(permCode);
return (iter != policyWhiteList_.end()) && (iter->second.find(tokenId) != iter->second.end());
}
int32_t AccessTokenInfoManager::SetUserPolicy(const std::vector<UserPermissionPolicy>& userPermissionList)
{
AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
std::vector<UserPolicyInner> userPolist;
std::unique_lock<std::shared_mutex> infoGuard(this->userPolicyLock_);
for (const auto& policy : userPermissionList) {
PermissionBriefDef briefDef;
uint32_t code;
if (!GetPermissionBriefDef(policy.permissionName, briefDef, code) || (briefDef.grantMode != SYSTEM_GRANT)) {
if (!TransferPermissionToOpcode(policy.permissionName, code)) {
LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) is invalid.", policy.permissionName.c_str());
return AccessTokenError::ERR_PARAM_INVALID;
}
@@ -1806,11 +1832,83 @@ int32_t AccessTokenInfoManager::ClearUserPolicy(const std::vector<std::string>&
changedUserList[userId] = false;
}
UpdatePermissionStateToKernel(code, changedUserList);
policyWhiteList_.erase(code);
userPermPolicyList_.erase(code);
policyController_.erase(code);
}
return RET_SUCCESS;
}
int32_t AccessTokenInfoManager::UpdatePolicyWhiteList(
AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type)
{
std::shared_ptr<HapTokenInfoInner> infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenId);
if (infoPtr == nullptr) {
LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is invalid.", tokenId);
return AccessTokenError::ERR_PARAM_INVALID;
}
std::string permission = TransferOpcodeToPermission(permCode);
AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
bool isActive = true;
{
std::unique_lock<std::shared_mutex> infoGuard(this->userPolicyLock_);
if (userPermPolicyList_.find(permCode) == userPermPolicyList_.end()) {
LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) policy is not set.", permission.c_str());
return AccessTokenError::ERR_PERM_POLICY_NOT_SET;
}
if (policyController_.find(permCode) != policyController_.end() && policyController_[permCode] != callerToken) {
LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) is already set by %{public}u, currCaller(%{public}u).",
permission.c_str(), policyController_[permCode], callerToken);
return AccessTokenError::ERR_PERM_POLICY_ALREADY_SET_BY_OTHER;
}
bool isRestricted = std::find(userPermPolicyList_[permCode].begin(), userPermPolicyList_[permCode].end(),
infoPtr->GetUserID()) != userPermPolicyList_[permCode].end();
if (!isRestricted) {
LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u userId %{public}d is not controlled by perm %{public}s.",
tokenId, infoPtr->GetUserID(), permission.c_str());
return AccessTokenError::ERR_TOKENID_NOT_IN_POLICY_USERLIST;
}
auto& whiteList = policyWhiteList_[permCode];
if (type == ADD) {
if (whiteList.find(tokenId) != whiteList.end()) {
LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is already in whitelist.", tokenId);
return AccessTokenError::ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST;
}
whiteList.insert(tokenId);
} else {
if (whiteList.find(tokenId) == whiteList.end()) {
LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is not in whitelist.", tokenId);
return AccessTokenError::ERR_TOKENID_NOT_IN_POLICY_WHITELIST;
}
whiteList.erase(tokenId);
if (whiteList.empty()) {
policyWhiteList_.erase(permCode);
}
}
isActive = !isRestricted || IsInPolicyWhiteList(tokenId, permCode);
}
UpdatePermissionStateToKernel(tokenId, permCode, isActive);
return RET_SUCCESS;
}
int32_t AccessTokenInfoManager::GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList)
{
tokenIdList.clear();
std::string permission = TransferOpcodeToPermission(permCode);
if (permission.empty()) {
LOGE(ATM_DOMAIN, ATM_TAG, "PermCode %{public}u does not exist.", permCode);
return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
}
std::shared_lock<std::shared_mutex> infoGuard(this->userPolicyLock_);
auto iter = policyWhiteList_.find(permCode);
if (iter != policyWhiteList_.end()) {
tokenIdList.assign(iter->second.begin(), iter->second.end());
}
return RET_SUCCESS;
}
#endif
bool AccessTokenInfoManager::GetPermDialogCap(AccessTokenID tokenID)
@@ -24,7 +24,6 @@
#include "accesstoken_common_log.h"
#include "accesstoken_dfx_define.h"
#include "accesstoken_id_manager.h"
#include "accesstoken_service_ipc_interface_code.h"
#include "constant_common.h"
#include "data_usage_dfx.h"
#include "data_validator.h"
@@ -1285,18 +1284,18 @@ int32_t AccessTokenManagerService::GetPermissionManagerInfo(PermissionGrantInfoP
int32_t AccessTokenManagerService::SetUserPolicy(const std::vector<UserPermissionPolicyIdl>& userPermissionList)
{
LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid());
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
size_t policySize = userPermissionList.size();
if ((policySize == 0) || (policySize > MAX_USER_POLICY_SIZE)) {
LOGE(ATM_DOMAIN, ATM_TAG, "PolicySize %{public}zu is invalid.", policySize);
return AccessTokenError::ERR_PARAM_INVALID;
}
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
std::vector<UserPermissionPolicy> policyList;
for (const auto& permPolicyIdl : userPermissionList) {
UserPermissionPolicy permPolicy;
@@ -1315,19 +1314,60 @@ int32_t AccessTokenManagerService::SetUserPolicy(const std::vector<UserPermissio
int32_t AccessTokenManagerService::ClearUserPolicy(const std::vector<std::string>& permissionList)
{
LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid());
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
size_t permSize = permissionList.size();
if ((permSize == 0) || (permSize > MAX_USER_POLICY_SIZE)) {
LOGE(ATM_DOMAIN, ATM_TAG, "PermSize %{public}zu is invalid.", permSize);
return AccessTokenError::ERR_PARAM_INVALID;
}
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
return AccessTokenInfoManager::GetInstance().ClearUserPolicy(permissionList);
}
int32_t AccessTokenManagerService::UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, int32_t type)
{
LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid());
auto updateType = static_cast<UpdateWhiteListType>(type);
if (!DataValidator::IsTokenIDValid(tokenId) || !DataValidator::IsUpdateWhiteListTypeValid(updateType)) {
return AccessTokenError::ERR_PARAM_INVALID;
}
if (this->GetTokenType(tokenId) != TOKEN_HAP) {
LOGE(ATM_DOMAIN, ATM_TAG, "Id=%{public}u is not hap.", tokenId);
return AccessTokenError::ERR_PARAM_INVALID;
}
std::string permission = TransferOpcodeToPermission(permCode);
if (permission.empty()) {
LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permCode: %{public}u.", permCode);
return AccessTokenError::ERR_PARAM_INVALID;
}
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
return AccessTokenInfoManager::GetInstance().UpdatePolicyWhiteList(tokenId, permCode, updateType);
}
int32_t AccessTokenManagerService::GetPolicyWhiteList(uint32_t permCode, std::vector<AccessTokenID>& tokenIdList)
{
LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid());
std::string permission = TransferOpcodeToPermission(permCode);
if (permission.empty()) {
LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permCode: %{public}u.", permCode);
return AccessTokenError::ERR_PARAM_INVALID;
}
uint32_t callingToken = IPCSkeleton::GetCallingTokenID();
if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) {
LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken);
return AccessTokenError::ERR_PERMISSION_DENIED;
}
return AccessTokenInfoManager::GetInstance().GetPolicyWhiteList(permCode, tokenIdList);
}
#endif
void AccessTokenManagerService::AccessTokenServiceParamSet() const
@@ -121,6 +121,70 @@ static PermissionStatus g_permState = {
.grantFlag = PermissionFlag::PERMISSION_DEFAULT_FLAG
};
#ifdef SUPPORT_MANAGE_USER_POLICY
class PolicyWhiteListStateGuard {
public:
PolicyWhiteListStateGuard(AccessTokenInfoManager& manager, uint32_t permCode)
: manager_(manager), permCode_(permCode)
{
std::unique_lock<std::shared_mutex> lock(manager_.userPolicyLock_);
auto userIter = manager_.userPermPolicyList_.find(permCode_);
if (userIter != manager_.userPermPolicyList_.end()) {
hasUserList_ = true;
oldUserList_ = userIter->second;
}
auto whiteIter = manager_.policyWhiteList_.find(permCode_);
if (whiteIter != manager_.policyWhiteList_.end()) {
hasWhiteList_ = true;
oldWhiteList_ = whiteIter->second;
}
auto controllerIter = manager_.policyController_.find(permCode_);
if (controllerIter != manager_.policyController_.end()) {
hasController_ = true;
oldController_ = controllerIter->second;
}
}
~PolicyWhiteListStateGuard()
{
std::unique_lock<std::shared_mutex> lock(manager_.userPolicyLock_);
if (hasUserList_) {
manager_.userPermPolicyList_[permCode_] = oldUserList_;
} else {
manager_.userPermPolicyList_.erase(permCode_);
}
if (hasWhiteList_) {
manager_.policyWhiteList_[permCode_] = oldWhiteList_;
} else {
manager_.policyWhiteList_.erase(permCode_);
}
if (hasController_) {
manager_.policyController_[permCode_] = oldController_;
} else {
manager_.policyController_.erase(permCode_);
}
}
void SetControlledUser(int32_t userId, AccessTokenID controller)
{
std::unique_lock<std::shared_mutex> lock(manager_.userPolicyLock_);
manager_.userPermPolicyList_[permCode_] = { userId };
manager_.policyController_[permCode_] = controller;
manager_.policyWhiteList_.erase(permCode_);
}
private:
AccessTokenInfoManager& manager_;
uint32_t permCode_;
std::vector<int32_t> oldUserList_;
std::unordered_set<AccessTokenID> oldWhiteList_;
AccessTokenID oldController_ = INVALID_TOKENID;
bool hasUserList_ = false;
bool hasWhiteList_ = false;
bool hasController_ = false;
};
#endif
#ifdef TOKEN_SYNC_ENABLE
static uint32_t tokenSyncId_ = 0;
static const int32_t FAKE_SYNC_RET = 0xabcdef;
@@ -2477,6 +2541,71 @@ HWTEST_F(TokenInfoManagerTest, IsPermissionRestrictedByUserPolicy001, TestSize.L
#endif
}
#ifdef SUPPORT_MANAGE_USER_POLICY
/**
* @tc.name: UpdatePolicyWhiteList001
* @tc.desc: UpdatePolicyWhiteList returns error when token user is outside controlled user list.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(TokenInfoManagerTest, UpdatePolicyWhiteList001, TestSize.Level0)
{
AccessTokenIDEx tokenIdEx = {0};
std::vector<GenericValues> undefValues;
ASSERT_EQ(RET_SUCCESS, AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(
g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams1, tokenIdEx, undefValues));
AccessTokenID tokenId = tokenIdEx.tokenIdExStruct.tokenID;
uint32_t permCode;
ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.CAMERA", permCode));
auto& manager = AccessTokenInfoManager::GetInstance();
PolicyWhiteListStateGuard stateGuard(manager, permCode);
stateGuard.SetControlledUser(USER_ID, GetSelfTokenID());
EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST,
manager.UpdatePolicyWhiteList(tokenId, permCode, UpdateWhiteListType::ADD));
EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST,
manager.UpdatePolicyWhiteList(tokenId, permCode, UpdateWhiteListType::DELETE));
std::vector<AccessTokenID> tokenIdList;
EXPECT_EQ(RET_SUCCESS, manager.GetPolicyWhiteList(permCode, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
EXPECT_EQ(RET_SUCCESS, manager.RemoveHapTokenInfo(tokenId));
}
/**
* @tc.name: UpdatePolicyWhiteList002
* @tc.desc: UpdatePolicyWhiteList returns error for invalid tokenId.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(TokenInfoManagerTest, UpdatePolicyWhiteList002, TestSize.Level0)
{
uint32_t permCode;
ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.CAMERA", permCode));
auto& manager = AccessTokenInfoManager::GetInstance();
EXPECT_EQ(ERR_PARAM_INVALID, manager.UpdatePolicyWhiteList(INVALID_TOKENID, permCode, UpdateWhiteListType::ADD));
}
/**
* @tc.name: GetPolicyWhiteList001
* @tc.desc: GetPolicyWhiteList clears output list and returns error for invalid permCode.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(TokenInfoManagerTest, GetPolicyWhiteList001, TestSize.Level0)
{
auto& manager = AccessTokenInfoManager::GetInstance();
std::vector<AccessTokenID> tokenIdList = {RANDOM_TOKENID};
EXPECT_EQ(ERR_PERMISSION_NOT_EXIST, manager.GetPolicyWhiteList(UINT32_MAX, tokenIdList));
EXPECT_TRUE(tokenIdList.empty());
}
#endif
/**
* @tc.name: ReservedHapInfo001
* @tc.desc: RemoveReservedHapInfo
@@ -18,6 +18,7 @@
#include <gtest/hwext/gtest-multithread.h>
#include "accesstoken_callbacks.h"
#include "accesstoken_kit.h"
#include "access_token_db_operator.h"
#include "access_token_db.h"
#include "access_token_error.h"
@@ -2216,6 +2217,61 @@ HWTEST_F(AccessTokenManagerServiceTest, AccessTokenServiceCoverageTest001, TestS
ret = atManagerService_->GetPermissionsStatus(RANDOM_TOKENID, reqPermList);
EXPECT_NE(RET_SUCCESS, ret);
}
#ifdef SUPPORT_MANAGE_USER_POLICY
/**
* @tc.name: PolicyWhiteListServiceTest001
* @tc.desc: Test UpdatePolicyWhiteList service param validation.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(AccessTokenManagerServiceTest, PolicyWhiteListServiceTest001, TestSize.Level1)
{
HapInfoParcel infoParcel;
infoParcel.hapInfoParameter = g_info;
HapPolicyParcel policyParcel;
policyParcel.hapPolicy.apl = APL_SYSTEM_BASIC;
policyParcel.hapPolicy.domain = "test.domain";
PermissionStatus internetState = {
.permissionName = "ohos.permission.INTERNET",
.grantStatus = static_cast<int32_t>(PermissionState::PERMISSION_GRANTED),
.grantFlag = static_cast<uint32_t>(PermissionFlag::PERMISSION_DEFAULT_FLAG)
};
policyParcel.hapPolicy.permStateList = {internetState};
AccessTokenID tokenId;
std::map<int32_t, TokenIdInfo> tokenIdAplMap;
CreateHapToken(infoParcel, policyParcel, tokenId, tokenIdAplMap);
uint32_t permCode = 0;
ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.INTERNET", permCode));
EXPECT_EQ(ERR_PARAM_INVALID,
atManagerService_->UpdatePolicyWhiteList(INVALID_TOKENID, permCode, static_cast<int32_t>(ADD)));
EXPECT_EQ(ERR_PARAM_INVALID,
atManagerService_->UpdatePolicyWhiteList(tokenId, permCode, 2)); // 2: invalid enum value
EXPECT_EQ(ERR_PARAM_INVALID,
atManagerService_->UpdatePolicyWhiteList(tokenId, UINT32_MAX, static_cast<int32_t>(ADD)));
AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("foundation");
EXPECT_EQ(ERR_PARAM_INVALID,
atManagerService_->UpdatePolicyWhiteList(nativeTokenId, permCode, static_cast<int32_t>(ADD)));
DelTestDataAndRestoreOri(tokenId, {});
}
/**
* @tc.name: PolicyWhiteListServiceTest002
* @tc.desc: Test GetPolicyWhiteList service param validation.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(AccessTokenManagerServiceTest, PolicyWhiteListServiceTest002, TestSize.Level1)
{
std::vector<AccessTokenID> tokenIdList = {RANDOM_TOKENID};
EXPECT_EQ(ERR_PARAM_INVALID, atManagerService_->GetPolicyWhiteList(UINT32_MAX, tokenIdList));
}
#endif
} // namespace AccessToken
} // namespace Security
} // namespace OHOS