diff --git a/frameworks/accesstoken/src/permission_def_parcel.cpp b/frameworks/accesstoken/src/permission_def_parcel.cpp index 94226a443bb58dd5feee8f55317f45814dc4eb89..4f8c02a3208fe69c61efee76d898f155fb171b6c 100644 --- a/frameworks/accesstoken/src/permission_def_parcel.cpp +++ b/frameworks/accesstoken/src/permission_def_parcel.cpp @@ -34,6 +34,8 @@ bool PermissionDefParcel::Marshalling(Parcel& out) const RETURN_IF_FALSE(out.WriteString(this->permissionDef.description)); RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.descriptionId)); RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.availableType)); + RETURN_IF_FALSE(out.WriteBool(this->permissionDef.isKernelEffect)); + RETURN_IF_FALSE(out.WriteBool(this->permissionDef.hasValue)); return true; } @@ -61,6 +63,8 @@ PermissionDefParcel* PermissionDefParcel::Unmarshalling(Parcel& in) int32_t availableType; RELEASE_IF_FALSE(in.ReadInt32(availableType), permissionDefParcel); permissionDefParcel->permissionDef.availableType = ATokenAvailableTypeEnum(availableType); + RELEASE_IF_FALSE(in.ReadBool(permissionDefParcel->permissionDef.isKernelEffect), permissionDefParcel); + RELEASE_IF_FALSE(in.ReadBool(permissionDefParcel->permissionDef.hasValue), permissionDefParcel); return permissionDefParcel; } } // namespace AccessToken diff --git a/interfaces/innerkits/accesstoken/include/permission_def.h b/interfaces/innerkits/accesstoken/include/permission_def.h index 811e97999eb822da66834a8ea8fb1a8b6ded0a3f..238df3fed4251a05d1030fd36c89b26a27f303b6 100644 --- a/interfaces/innerkits/accesstoken/include/permission_def.h +++ b/interfaces/innerkits/accesstoken/include/permission_def.h @@ -74,6 +74,8 @@ public: std::string description = ""; int descriptionId = 0; ATokenAvailableTypeEnum availableType = NORMAL; + bool isKernelEffect = false; + bool hasValue = false; }; /** diff --git a/services/accesstokenmanager/main/cpp/include/database/access_token_db.h b/services/accesstokenmanager/main/cpp/include/database/access_token_db.h index 58a5512956ed0593a0e289fcdf85825debe6e93f..41c5d9dfb2da806e7c185dc499df5ca655e4ad8c 100644 --- a/services/accesstokenmanager/main/cpp/include/database/access_token_db.h +++ b/services/accesstokenmanager/main/cpp/include/database/access_token_db.h @@ -62,6 +62,8 @@ private: int32_t AddValues(const AtmDataType type, const std::vector& addValues); int32_t RemoveValues(const AtmDataType type, const GenericValues& conditionValue); + int32_t RestoreAndCommitIfCorrupt(const int32_t resultCode, const std::shared_ptr& db); + OHOS::Utils::RWLock rwLock_; std::shared_ptr db_ = nullptr; std::mutex dbLock_; diff --git a/services/accesstokenmanager/main/cpp/include/database/access_token_db_util.h b/services/accesstokenmanager/main/cpp/include/database/access_token_db_util.h index 6f74f7a202094a4acd6a6a5bbb59e9a23ae77731..8bf18666cd4774537ddf993c776b95455c05e61e 100644 --- a/services/accesstokenmanager/main/cpp/include/database/access_token_db_util.h +++ b/services/accesstokenmanager/main/cpp/include/database/access_token_db_util.h @@ -30,10 +30,10 @@ namespace Security { namespace AccessToken { enum AtmDataType { ACCESSTOKEN_HAP_INFO, - ACCESSTOKEN_NATIVE_INFO, ACCESSTOKEN_PERMISSION_DEF, ACCESSTOKEN_PERMISSION_STATE, ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS, + ACCESSTOKEN_PERMISSION_EXTEND_VALUE, }; class AccessTokenDbUtil final { diff --git a/services/accesstokenmanager/main/cpp/include/database/access_token_open_callback.h b/services/accesstokenmanager/main/cpp/include/database/access_token_open_callback.h index 77c4ea63a4c9de1b84dd9764d61575bd4e7d5636..ad7cb6128fa3370f022aaec4285ca2916270274f 100644 --- a/services/accesstokenmanager/main/cpp/include/database/access_token_open_callback.h +++ b/services/accesstokenmanager/main/cpp/include/database/access_token_open_callback.h @@ -30,6 +30,7 @@ static constexpr const int32_t DATABASE_VERSION_1 = 1; static constexpr const int32_t DATABASE_VERSION_2 = 2; static constexpr const int32_t DATABASE_VERSION_3 = 3; static constexpr const int32_t DATABASE_VERSION_4 = 4; +static constexpr const int32_t DATABASE_VERSION_5 = 5; class AccessTokenOpenCallback : public NativeRdb::RdbOpenCallback { public: @@ -52,19 +53,23 @@ public: private: // OnCreate int32_t CreateHapTokenInfoTable(NativeRdb::RdbStore& rdbStore); - int32_t CreateNativeTokenInfoTable(NativeRdb::RdbStore& rdbStore); int32_t CreatePermissionDefinitionTable(NativeRdb::RdbStore& rdbStore); int32_t CreatePermissionStateTable(NativeRdb::RdbStore& rdbStore); int32_t CreatePermissionRequestToggleStatusTable(NativeRdb::RdbStore& rdbStore); + int32_t CreatePermissionExtendValueTable(NativeRdb::RdbStore& rdbStore); // OnUpdate int32_t AddAvailableTypeColumn(NativeRdb::RdbStore& rdbStore); int32_t AddRequestToggleStatusColumn(NativeRdb::RdbStore& rdbStore); int32_t AddPermDialogCapColumn(NativeRdb::RdbStore& rdbStore); + int32_t RemoveIsGeneralFromPermissionState(NativeRdb::RdbStore& rdbStore); + int32_t RemoveUnusedTableAndColumn(NativeRdb::RdbStore& rdbStore); + int32_t AddKernelEffectAndHasValueColumn(NativeRdb::RdbStore& rdbStore); int32_t HandleUpdateWithFlag(NativeRdb::RdbStore& rdbStore, uint32_t flag); int32_t UpdateFromVersionOne(NativeRdb::RdbStore& rdbStore, int32_t targetVersion); int32_t UpdateFromVersionTwo(NativeRdb::RdbStore& rdbStore, int32_t targetVersion); int32_t UpdateFromVersionThree(NativeRdb::RdbStore& rdbStore, int32_t targetVersion); + int32_t UpdateFromVersionFour(NativeRdb::RdbStore& rdbStore, int32_t targetVersion); }; } // namespace AccessToken } // namespace Security diff --git a/services/accesstokenmanager/main/cpp/include/database/token_field_const.h b/services/accesstokenmanager/main/cpp/include/database/token_field_const.h index 5ec731a96998d4cf1bbef448d1b71aea079adcc3..74bb061e6f35087f6e399a0606e0cf3411c40b65 100644 --- a/services/accesstokenmanager/main/cpp/include/database/token_field_const.h +++ b/services/accesstokenmanager/main/cpp/include/database/token_field_const.h @@ -52,6 +52,9 @@ public: const static std::string FIELD_GRANT_STATE; const static std::string FIELD_GRANT_FLAG; const static std::string FIELD_REQUEST_TOGGLE_STATUS; + const static std::string FIELD_KERNEL_EFFECT; + const static std::string FIELD_HAS_VALUE; + const static std::string FIELD_VALUE; }; } // namespace AccessToken } // namespace Security diff --git a/services/accesstokenmanager/main/cpp/src/database/access_token_db.cpp b/services/accesstokenmanager/main/cpp/src/database/access_token_db.cpp index e120ba381306631aca9eff2c8808185f756b9e2f..cbcbd7400900aae00fb294791d611cee47717157 100644 --- a/services/accesstokenmanager/main/cpp/src/database/access_token_db.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/access_token_db.cpp @@ -90,7 +90,7 @@ void AccessTokenDb::InitRdb() AccessTokenOpenCallback callback; int32_t res = NativeRdb::E_OK; // pragma user_version will done by rdb, they store path and db_ as pair in RdbStoreManager - db_ = NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_VERSION_4, callback, res); + db_ = NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_VERSION_5, callback, res); if ((res != NativeRdb::E_OK) || (db_ == nullptr)) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to init rdb, res is %{public}d.", res); } @@ -370,6 +370,30 @@ int32_t AccessTokenDb::Find(AtmDataType type, const GenericValues& conditionValu return 0; } +int32_t AccessTokenDb::RestoreAndCommitIfCorrupt(const int32_t resultCode, + const std::shared_ptr& db) +{ + if (resultCode != NativeRdb::E_SQLITE_CORRUPT) { + return resultCode; + } + + LOGW(ATM_DOMAIN, ATM_TAG, "Detech database corrupt, restore from backup!"); + int32_t res = db->Restore(""); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Db restore failed, res is %{public}d.", res); + return res; + } + LOGI(ATM_DOMAIN, ATM_TAG, "Database restore success, try commit again!"); + + res = db->Commit(); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Commit again, res is %{public}d.", res); + return res; + } + + return NativeRdb::E_OK; +} + int32_t AccessTokenDb::DeleteAndInsertValues( const std::vector& delDataTypes, const std::vector& delValues, const std::vector& addDataTypes, const std::vector>& addValues) @@ -405,7 +429,14 @@ int32_t AccessTokenDb::DeleteAndInsertValues( } } - db->Commit(); + res = db->Commit(); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to commit, res is %{public}d.", res); + int32_t result = RestoreAndCommitIfCorrupt(res, db); + if (result != NativeRdb::E_OK) { + return result; + } + } } int64_t endTime = TimeUtil::GetCurrentTimestamp(); diff --git a/services/accesstokenmanager/main/cpp/src/database/access_token_db_util.cpp b/services/accesstokenmanager/main/cpp/src/database/access_token_db_util.cpp index 3f9c4164d1814a5ff13b9a0f0efe967f58f24327..220109c9cfcd12822e62f43eb03a3ad48f6271fb 100644 --- a/services/accesstokenmanager/main/cpp/src/database/access_token_db_util.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/access_token_db_util.cpp @@ -25,15 +25,15 @@ namespace AccessToken { namespace { static const std::vector g_StringTypeColumns = { "description", "permission_name", "device_id", "bundle_name", - "app_id", "process_name", "dcap", "native_acls", "label", + "app_id", "process_name", "dcap", "native_acls", "label", "value", }; static const std::map g_DateTypeToTableName = { {AtmDataType::ACCESSTOKEN_HAP_INFO, "hap_token_info_table"}, - {AtmDataType::ACCESSTOKEN_NATIVE_INFO, "native_token_info_table"}, {AtmDataType::ACCESSTOKEN_PERMISSION_DEF, "permission_definition_table"}, {AtmDataType::ACCESSTOKEN_PERMISSION_STATE, "permission_state_table"}, {AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS, "permission_request_toggle_status_table"}, + {AtmDataType::ACCESSTOKEN_PERMISSION_EXTEND_VALUE, "permission_extend_value_table"}, }; } diff --git a/services/accesstokenmanager/main/cpp/src/database/access_token_open_callback.cpp b/services/accesstokenmanager/main/cpp/src/database/access_token_open_callback.cpp index 6136237d8ff094c703d688c47a23f11d09facd3e..d78a428ae7c3f095b27955dd9fc84c431e229635 100644 --- a/services/accesstokenmanager/main/cpp/src/database/access_token_open_callback.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/access_token_open_callback.cpp @@ -32,6 +32,7 @@ constexpr const char* DATABASE_NAME_BACK = "access_token_slave.db"; constexpr const uint32_t FLAG_HANDLE_FROM_ONE_TO_TWO = 1; constexpr const uint32_t FLAG_HANDLE_FROM_TWO_TO_THREE = 1 << 1; constexpr const uint32_t FLAG_HANDLE_FROM_THREE_TO_FOUR = 1 << 2; +constexpr const uint32_t FLAG_HANDLE_FROM_FOUR_TO_FIVE = 1 << 3; } int32_t AccessTokenOpenCallback::CreateHapTokenInfoTable(NativeRdb::RdbStore& rdbStore) @@ -72,34 +73,6 @@ int32_t AccessTokenOpenCallback::CreateHapTokenInfoTable(NativeRdb::RdbStore& rd return rdbStore.ExecuteSql(sql); } -int32_t AccessTokenOpenCallback::CreateNativeTokenInfoTable(NativeRdb::RdbStore& rdbStore) -{ - std::string tableName; - AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_NATIVE_INFO, tableName); - - std::string sql = "create table if not exists " + tableName; - sql.append(" (") - .append(TokenFiledConst::FIELD_TOKEN_ID) - .append(INTEGER_STR) - .append(TokenFiledConst::FIELD_PROCESS_NAME) - .append(TEXT_STR) - .append(TokenFiledConst::FIELD_TOKEN_VERSION) - .append(INTEGER_STR) - .append(TokenFiledConst::FIELD_TOKEN_ATTR) - .append(INTEGER_STR) - .append(TokenFiledConst::FIELD_DCAP) - .append(TEXT_STR) - .append(TokenFiledConst::FIELD_NATIVE_ACLS) - .append(TEXT_STR) - .append(TokenFiledConst::FIELD_APL) - .append(INTEGER_STR) - .append("primary key(") - .append(TokenFiledConst::FIELD_TOKEN_ID) - .append("))"); - - return rdbStore.ExecuteSql(sql); -} - int32_t AccessTokenOpenCallback::CreatePermissionDefinitionTable(NativeRdb::RdbStore& rdbStore) { std::string tableName; @@ -131,6 +104,10 @@ int32_t AccessTokenOpenCallback::CreatePermissionDefinitionTable(NativeRdb::RdbS .append(INTEGER_STR) .append(TokenFiledConst::FIELD_AVAILABLE_TYPE) .append(INTEGER_STR) + .append(TokenFiledConst::FIELD_KERNEL_EFFECT) + .append(INTEGER_STR) + .append(TokenFiledConst::FIELD_HAS_VALUE) + .append(INTEGER_STR) .append("primary key(") .append(TokenFiledConst::FIELD_TOKEN_ID) .append(",") @@ -153,8 +130,6 @@ int32_t AccessTokenOpenCallback::CreatePermissionStateTable(NativeRdb::RdbStore& .append(TEXT_STR) .append(TokenFiledConst::FIELD_DEVICE_ID) .append(TEXT_STR) - .append(TokenFiledConst::FIELD_GRANT_IS_GENERAL) - .append(INTEGER_STR) .append(TokenFiledConst::FIELD_GRANT_STATE) .append(INTEGER_STR) .append(TokenFiledConst::FIELD_GRANT_FLAG) @@ -192,6 +167,30 @@ int32_t AccessTokenOpenCallback::CreatePermissionRequestToggleStatusTable(Native return rdbStore.ExecuteSql(sql); } +int32_t AccessTokenOpenCallback::CreatePermissionExtendValueTable(NativeRdb::RdbStore& rdbStore) +{ + std::string tableName; + AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_EXTEND_VALUE, tableName); + + std::string sql = "create table if not exists " + tableName; + sql.append(" (") + .append(TokenFiledConst::FIELD_TOKEN_ID) + .append(INTEGER_STR) + .append(TokenFiledConst::FIELD_PERMISSION_NAME) + .append(TEXT_STR) + .append(TokenFiledConst::FIELD_VALUE) + .append(INTEGER_STR) + .append("primary key(") + .append(TokenFiledConst::FIELD_TOKEN_ID) + .append(",") + .append(TokenFiledConst::FIELD_PERMISSION_NAME) + .append(",") + .append(TokenFiledConst::FIELD_VALUE) + .append("))"); + + return rdbStore.ExecuteSql(sql); +} + int32_t AccessTokenOpenCallback::OnCreate(NativeRdb::RdbStore& rdbStore) { LOGI(ATM_DOMAIN, ATM_TAG, "DB OnCreate."); @@ -202,12 +201,6 @@ int32_t AccessTokenOpenCallback::OnCreate(NativeRdb::RdbStore& rdbStore) return res; } - res = CreateNativeTokenInfoTable(rdbStore); - if (res != NativeRdb::E_OK) { - LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table native_token_info_table."); - return res; - } - res = CreatePermissionDefinitionTable(rdbStore); if (res != NativeRdb::E_OK) { LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_definition_table."); @@ -322,6 +315,173 @@ int32_t AccessTokenOpenCallback::AddPermDialogCapColumn(NativeRdb::RdbStore& rdb return res; } +static void CreateNewPermissionStateTable(std::string& newTableName, std::string& newCreateSql) +{ + newCreateSql = "create table if not exists " + newTableName; + newCreateSql.append(" (") + .append(TokenFiledConst::FIELD_TOKEN_ID) + .append(INTEGER_STR) + .append(TokenFiledConst::FIELD_PERMISSION_NAME) + .append(TEXT_STR) + .append(TokenFiledConst::FIELD_DEVICE_ID) + .append(TEXT_STR) + .append(TokenFiledConst::FIELD_GRANT_STATE) + .append(INTEGER_STR) + .append(TokenFiledConst::FIELD_GRANT_FLAG) + .append(INTEGER_STR) + .append("primary key(") + .append(TokenFiledConst::FIELD_TOKEN_ID) + .append(",") + .append(TokenFiledConst::FIELD_PERMISSION_NAME) + .append(",") + .append(TokenFiledConst::FIELD_DEVICE_ID) + .append("))"); +} + +int32_t AccessTokenOpenCallback::RemoveIsGeneralFromPermissionState(NativeRdb::RdbStore& rdbStore) +{ + std::string tableName = "permission_state_table"; + AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_STATE, tableName); + std::string newTableName = tableName + "_new"; + std::string newCreateSql; + + CreateNewPermissionStateTable(newTableName, newCreateSql); + + // 1. create new permission_state_table without column is_general + int32_t res = rdbStore.ExecuteSql(newCreateSql); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table %{public}s, errCode is %{public}d.", + newCreateSql.c_str(), res); + return res; + } + + // 2. copy data from permission_state_table to permission_state_table_new + std::string copyDataSql = "insert into " + newTableName + " select "; + copyDataSql.append(TokenFiledConst::FIELD_TOKEN_ID + ", "); + copyDataSql.append(TokenFiledConst::FIELD_PERMISSION_NAME + ", "); + copyDataSql.append(TokenFiledConst::FIELD_DEVICE_ID + ", "); + copyDataSql.append(TokenFiledConst::FIELD_GRANT_STATE + ", "); + copyDataSql.append(TokenFiledConst::FIELD_GRANT_FLAG + " from " + tableName); + res = rdbStore.ExecuteSql(copyDataSql); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to copy data from old table to new, errCode is %{public}d.", res); + return res; + } + + // 3. drop permission_state_table + std::string dropOldSql = "drop table " + tableName; + res = rdbStore.ExecuteSql(dropOldSql); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to drop table %{public}s, errCode is %{public}d.", tableName.c_str(), res); + return res; + } + + // 4. rename permission_state_table_new to permission_state_table + std::string renameSql = "alter table " + newTableName + " rename to " + tableName; + res = rdbStore.ExecuteSql(renameSql); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to rename new table to old, errCode is %{public}d.", res); + return res; + } + + return NativeRdb::E_OK; +} + +// remove is_general from permission_state_table and remove native_token_info_table +int32_t AccessTokenOpenCallback::RemoveUnusedTableAndColumn(NativeRdb::RdbStore& rdbStore) +{ + rdbStore.BeginTransaction(); + + int32_t res = RemoveIsGeneralFromPermissionState(rdbStore); + if (res != NativeRdb::E_OK) { + rdbStore.RollBack(); + return res; + } + + // drop native_token_info_table + std::string dropOldSql = "drop table native_token_info_table"; + res = rdbStore.ExecuteSql(dropOldSql); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to drop native_token_info_table, errCode is %{public}d.", res); + rdbStore.RollBack(); + return res; + } + + res = rdbStore.Commit(); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to commit, errCode is %{public}d.", res); + if (res != NativeRdb::E_SQLITE_CORRUPT) { + return res; + } + + LOGW(ATM_DOMAIN, ATM_TAG, "Detech database corrupt, restore from backup!"); + int32_t res = rdbStore.Restore(""); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Db restore failed, res is %{public}d.", res); + return res; + } + + res = rdbStore.Commit(); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to commit again, res is %{public}d.", res); + return res; + } + } + + return NativeRdb::E_OK; +} + +int32_t AccessTokenOpenCallback::AddKernelEffectAndHasValueColumn(NativeRdb::RdbStore& rdbStore) +{ + std::string tableName; + AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_DEF, tableName); + + // check if column kernel_effect exsit + std::string checkSql = "SELECT 1 FROM " + tableName + " WHERE " + TokenFiledConst::FIELD_KERNEL_EFFECT + "=" + + std::to_string(0); + + int32_t checkRes = rdbStore.ExecuteSql(checkSql); + if (checkRes == NativeRdb::E_OK) { + return NativeRdb::E_OK; // success means there exsit column kernel_effect in table + } + + // alter table add column kernel_effect + std::string executeSql = "alter table " + tableName + " add column " + TokenFiledConst::FIELD_KERNEL_EFFECT + + " integer default " + std::to_string(false); + + int32_t executeRes = rdbStore.ExecuteSql(executeSql); + if (executeRes != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column kernel_effect to table %{public}s, errCode is %{public}d.", + tableName.c_str(), executeRes); + return executeRes; + } + + LOGI(ATM_DOMAIN, ATM_TAG, "Success to add column kernel_effect to permission_definition_table."); + + // check if column has_value exsit + checkSql = "SELECT 1 FROM " + tableName + " WHERE " + TokenFiledConst::FIELD_HAS_VALUE + "=" + std::to_string(0); + + checkRes = rdbStore.ExecuteSql(checkSql); + if (checkRes == NativeRdb::E_OK) { + return NativeRdb::E_OK; // success means there exsit column has_value in table + } + + // alter table add column has_value + executeSql = "alter table " + tableName + " add column " + TokenFiledConst::FIELD_HAS_VALUE + + " integer default " + std::to_string(0); + + executeRes = rdbStore.ExecuteSql(executeSql); + if (executeRes != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column has_value to table %{public}s, errCode is %{public}d.", + tableName.c_str(), executeRes); + return executeRes; + } + + LOGI(ATM_DOMAIN, ATM_TAG, "Success to add column has_value to permission_definition_table."); + + return NativeRdb::E_OK; +} + int32_t AccessTokenOpenCallback::HandleUpdateWithFlag(NativeRdb::RdbStore& rdbStore, uint32_t flag) { int32_t res = NativeRdb::E_OK; @@ -356,6 +516,21 @@ int32_t AccessTokenOpenCallback::HandleUpdateWithFlag(NativeRdb::RdbStore& rdbSt } } + if ((flag & FLAG_HANDLE_FROM_FOUR_TO_FIVE) == FLAG_HANDLE_FROM_FOUR_TO_FIVE) { + res = CreatePermissionExtendValueTable(rdbStore); + if (res != NativeRdb::E_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_extend_bool_table."); + return res; + } + + res = RemoveUnusedTableAndColumn(rdbStore); + if (res != NativeRdb::E_OK) { + return res; + } + + return AddKernelEffectAndHasValueColumn(rdbStore); + } + return res; } @@ -389,6 +564,15 @@ int32_t AccessTokenOpenCallback::UpdateFromVersionOne(NativeRdb::RdbStore& rdbSt } break; + case DATABASE_VERSION_5: + flag = FLAG_HANDLE_FROM_ONE_TO_TWO + FLAG_HANDLE_FROM_TWO_TO_THREE + FLAG_HANDLE_FROM_THREE_TO_FOUR + + FLAG_HANDLE_FROM_FOUR_TO_FIVE; + res = HandleUpdateWithFlag(rdbStore, flag); + if (res != NativeRdb::E_OK) { + return res; + } + break; + default: break; } @@ -418,6 +602,14 @@ int32_t AccessTokenOpenCallback::UpdateFromVersionTwo(NativeRdb::RdbStore& rdbSt } break; + case DATABASE_VERSION_5: + flag = FLAG_HANDLE_FROM_TWO_TO_THREE + FLAG_HANDLE_FROM_THREE_TO_FOUR + FLAG_HANDLE_FROM_FOUR_TO_FIVE; + res = HandleUpdateWithFlag(rdbStore, flag); + if (res != NativeRdb::E_OK) { + return res; + } + break; + default: break; } @@ -439,6 +631,35 @@ int32_t AccessTokenOpenCallback::UpdateFromVersionThree(NativeRdb::RdbStore& rdb } break; + case DATABASE_VERSION_5: + flag = FLAG_HANDLE_FROM_THREE_TO_FOUR + FLAG_HANDLE_FROM_FOUR_TO_FIVE; + res = HandleUpdateWithFlag(rdbStore, flag); + if (res != NativeRdb::E_OK) { + return res; + } + break; + + default: + break; + } + + return res; +} + +int32_t AccessTokenOpenCallback::UpdateFromVersionFour(NativeRdb::RdbStore& rdbStore, int32_t targetVersion) +{ + int32_t res = 0; + uint32_t flag = 0; + + switch (targetVersion) { + case DATABASE_VERSION_5: + flag = FLAG_HANDLE_FROM_FOUR_TO_FIVE; + res = HandleUpdateWithFlag(rdbStore, flag); + if (res != NativeRdb::E_OK) { + return res; + } + break; + default: break; } @@ -475,6 +696,13 @@ int32_t AccessTokenOpenCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int32_ } break; + case DATABASE_VERSION_4: + res = UpdateFromVersionFour(rdbStore, targetVersion); + if (res != 0) { + return res; + } + break; + default: break; } diff --git a/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp b/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp index 7fccb5ec2a0ae71722207044aa3fdda6bfc954d3..d5564544fe68de2bf827bd2045032fa18f535d78 100644 --- a/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp @@ -42,6 +42,8 @@ int DataTranslator::TranslationIntoGenericValues(const PermissionDef& inPermissi outGenericValues.Put(TokenFiledConst::FIELD_DESCRIPTION, inPermissionDef.description); outGenericValues.Put(TokenFiledConst::FIELD_DESCRIPTION_ID, inPermissionDef.descriptionId); outGenericValues.Put(TokenFiledConst::FIELD_AVAILABLE_TYPE, inPermissionDef.availableType); + outGenericValues.Put(TokenFiledConst::FIELD_KERNEL_EFFECT, inPermissionDef.isKernelEffect ? 1 : 0); + outGenericValues.Put(TokenFiledConst::FIELD_HAS_VALUE, inPermissionDef.hasValue ? 1 : 0); return RET_SUCCESS; } @@ -65,6 +67,8 @@ int DataTranslator::TranslationIntoPermissionDef(const GenericValues& inGenericV outPermissionDef.descriptionId = inGenericValues.GetInt(TokenFiledConst::FIELD_DESCRIPTION_ID); int availableType = inGenericValues.GetInt(TokenFiledConst::FIELD_AVAILABLE_TYPE); outPermissionDef.availableType = static_cast(availableType); + outPermissionDef.isKernelEffect = (inGenericValues.GetInt(TokenFiledConst::FIELD_KERNEL_EFFECT) == 1); + outPermissionDef.hasValue = (inGenericValues.GetInt(TokenFiledConst::FIELD_HAS_VALUE) == 1); return RET_SUCCESS; } diff --git a/services/accesstokenmanager/main/cpp/src/database/token_field_const.cpp b/services/accesstokenmanager/main/cpp/src/database/token_field_const.cpp index b27da70fbb61d322b6110df6eb543f8f92f47493..4a09e0314b4c0a19db4646082b915316f5d65a68 100644 --- a/services/accesstokenmanager/main/cpp/src/database/token_field_const.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/token_field_const.cpp @@ -46,6 +46,9 @@ const std::string TokenFiledConst::FIELD_GRANT_IS_GENERAL = "is_general"; const std::string TokenFiledConst::FIELD_GRANT_STATE = "grant_state"; const std::string TokenFiledConst::FIELD_GRANT_FLAG = "grant_flag"; const std::string TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS = "status"; +const std::string TokenFiledConst::FIELD_KERNEL_EFFECT = "kernel_effect"; +const std::string TokenFiledConst::FIELD_HAS_VALUE = "has_value"; +const std::string TokenFiledConst::FIELD_VALUE = "value"; } // namespace AccessToken } // namespace Security } // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_definition_parser.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_definition_parser.cpp index 4b74de0b171034a951c06dfaff19152da1c2d622..f30dccac17e552958949767bb45c92bc0988fd91 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_definition_parser.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_definition_parser.cpp @@ -43,6 +43,8 @@ static const std::string PERMISSION_AVAILABLE_LEVEL = "availableLevel"; static const std::string PERMISSION_AVAILABLE_TYPE = "availableType"; static const std::string PERMISSION_PROVISION_ENABLE = "provisionEnable"; static const std::string PERMISSION_DISTRIBUTED_SCENE_ENABLE = "distributedSceneEnable"; +static const std::string PERMISSION_IS_KERNEL_EFFECT = "isKernelEffect"; +static const std::string PERMISSION_HAS_VALUE = "hasValue"; static const std::string PERMISSION_LABEL = "label"; static const std::string PERMISSION_DESCRIPTION = "description"; static const std::string AVAILABLE_TYPE_NORMAL_HAP = "NORMAL"; @@ -79,7 +81,7 @@ static bool GetPermissionApl(const std::string &apl, AccessToken::ATokenAplEnum& return false; } -static bool GetPermissionAvailableType(const std::string &availableType, AccessToken::ATokenAvailableTypeEnum& typeNum) +static bool GetPermissionAvailableType(const std::string& availableType, AccessToken::ATokenAvailableTypeEnum& typeNum) { if (availableType == AVAILABLE_TYPE_NORMAL_HAP) { typeNum = AccessToken::ATokenAvailableTypeEnum::NORMAL; @@ -110,7 +112,7 @@ static bool GetPermissionAvailableType(const std::string &availableType, AccessT return false; } -static int32_t GetPermissionGrantMode(const std::string &mode) +static int32_t GetPermissionGrantMode(const std::string& mode) { if (mode == PERMISSION_GRANT_MODE_SYSTEM_GRANT) { return AccessToken::GrantMode::SYSTEM_GRANT; @@ -154,6 +156,10 @@ void from_json(const nlohmann::json& j, PermissionDefParseRet& result) if (!JsonParser::GetBoolFromJson(j, PERMISSION_DISTRIBUTED_SCENE_ENABLE, permDef.distributedSceneEnable)) { return; } + + JsonParser::GetBoolFromJson(j, PERMISSION_IS_KERNEL_EFFECT, permDef.isKernelEffect); // if not exsit default false + JsonParser::GetBoolFromJson(j, PERMISSION_HAS_VALUE, permDef.hasValue); // if not exsit default false + permDef.bundleName = "system_ability"; if (permDef.grantMode == AccessToken::GrantMode::SYSTEM_GRANT) { result.permDef = permDef; @@ -190,7 +196,7 @@ int32_t PermissionDefinitionParser::GetPermissionDefList(const nlohmann::json& j } nlohmann::json JsonData = json.at(type).get(); - for (auto it = JsonData.begin(); it != JsonData.end(); it++) { + for (auto it = JsonData.begin(); it != JsonData.end(); ++it) { auto result = it->get(); if (!result.isSuccessful) { LOGE(ATM_DOMAIN, ATM_TAG, "Get permission def failed."); diff --git a/services/accesstokenmanager/test/unittest/permission_definition_parser_test.cpp b/services/accesstokenmanager/test/unittest/permission_definition_parser_test.cpp index 951447117b15a8adba479188833ccd1852d62f4d..a0791c44a11aba6b14c7ec2eeaafe65aa57ffe1b 100644 --- a/services/accesstokenmanager/test/unittest/permission_definition_parser_test.cpp +++ b/services/accesstokenmanager/test/unittest/permission_definition_parser_test.cpp @@ -360,6 +360,60 @@ HWTEST_F(PermissionDefinitionParserTest, FromJson005, TestSize.Level1) EXPECT_EQ(0, permDefList.size()); } +/** + * @tc.name: FromJson006 + * @tc.desc: Invalid param + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PermissionDefinitionParserTest, FromJson006, TestSize.Level1) +{ + PermissionDefinitionParser& instance = PermissionDefinitionParser::GetInstance(); + std::string permsRawData = R"({"systemGrantPermissions":[)"\ + R"({"name":"ohos.permission.PermDefParserTestA","grantMode":"system_grant","availableLevel":"system_basic",)"\ + R"("availableType":"SERVICE","provisionEnable":true,"distributedSceneEnable":false}],)"\ + R"("userGrantPermissions":[]})"; + std::vector permDefList; + instance.ParserPermsRawData(permsRawData, permDefList); + EXPECT_EQ(1, permDefList.size()); + EXPECT_EQ(false, permDefList[0].isKernelEffect); + EXPECT_EQ(false, permDefList[0].hasValue); + permDefList.clear(); + + permsRawData = R"({"systemGrantPermissions":[)"\ + R"({"name":"ohos.permission.PermDefParserTestA","grantMode":"system_grant","availableLevel":"system_basic",)"\ + R"("availableType":"SERVICE","provisionEnable":true,"distributedSceneEnable":false,)"\ + R"("isKernelEffect":true}],)"\ + R"("userGrantPermissions":[]})"; + instance.ParserPermsRawData(permsRawData, permDefList); + EXPECT_EQ(1, permDefList.size()); + EXPECT_EQ(true, permDefList[0].isKernelEffect); + EXPECT_EQ(false, permDefList[0].hasValue); + permDefList.clear(); + + permsRawData = R"({"systemGrantPermissions":[)"\ + R"({"name":"ohos.permission.PermDefParserTestA","grantMode":"system_grant","availableLevel":"system_basic",)"\ + R"("availableType":"SERVICE","provisionEnable":true,"distributedSceneEnable":false,)"\ + R"("hasValue":true}],)"\ + R"("userGrantPermissions":[]})"; + instance.ParserPermsRawData(permsRawData, permDefList); + EXPECT_EQ(1, permDefList.size()); + EXPECT_EQ(false, permDefList[0].isKernelEffect); + EXPECT_EQ(true, permDefList[0].hasValue); + permDefList.clear(); + + permsRawData = R"({"systemGrantPermissions":[)"\ + R"({"name":"ohos.permission.PermDefParserTestA","grantMode":"system_grant","availableLevel":"system_basic",)"\ + R"("availableType":"SERVICE","provisionEnable":true,"distributedSceneEnable":false,)"\ + R"("isKernelEffect":true, "hasValue":true}],)"\ + R"("userGrantPermissions":[]})"; + instance.ParserPermsRawData(permsRawData, permDefList); + EXPECT_EQ(1, permDefList.size()); + EXPECT_EQ(true, permDefList[0].isKernelEffect); + EXPECT_EQ(true, permDefList[0].hasValue); + permDefList.clear(); +} + /** * @tc.name: IsSystemGrantedPermission001 * @tc.desc: Invalid param