1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "permission_definition_cache.h"
17
18 #include "access_token.h"
19 #include "access_token_error.h"
20 #include "accesstoken_log.h"
21 #include "generic_values.h"
22 #include "token_field_const.h"
23
24 namespace OHOS {
25 namespace Security {
26 namespace AccessToken {
27 namespace {
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
29 LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionDefinitionCache"
30 };
31 }
32
GetInstance()33 PermissionDefinitionCache& PermissionDefinitionCache::GetInstance()
34 {
35 static PermissionDefinitionCache instance;
36 return instance;
37 }
38
PermissionDefinitionCache()39 PermissionDefinitionCache::PermissionDefinitionCache()
40 {}
41
~PermissionDefinitionCache()42 PermissionDefinitionCache::~PermissionDefinitionCache()
43 {}
44
Insert(const PermissionDef & info,AccessTokenID tokenId)45 bool PermissionDefinitionCache::Insert(const PermissionDef& info, AccessTokenID tokenId)
46 {
47 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
48 auto it = permissionDefinitionMap_.find(info.permissionName);
49 if (it != permissionDefinitionMap_.end()) {
50 ACCESSTOKEN_LOG_WARN(LABEL, "info for permission: %{public}s has been insert, please check!",
51 info.permissionName.c_str());
52 return false;
53 }
54 permissionDefinitionMap_[info.permissionName].permDef = info;
55 permissionDefinitionMap_[info.permissionName].tokenId = tokenId;
56 return true;
57 }
58
Update(const PermissionDef & info)59 bool PermissionDefinitionCache::Update(const PermissionDef& info)
60 {
61 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
62 permissionDefinitionMap_[info.permissionName].permDef = info;
63 return true;
64 }
65
DeleteByBundleName(const std::string & bundleName)66 void PermissionDefinitionCache::DeleteByBundleName(const std::string& bundleName)
67 {
68 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
69 auto it = permissionDefinitionMap_.begin();
70 while (it != permissionDefinitionMap_.end()) {
71 if (bundleName == it->second.permDef.bundleName) {
72 permissionDefinitionMap_.erase(it++);
73 } else {
74 ++it;
75 }
76 }
77 }
78
FindByPermissionName(const std::string & permissionName,PermissionDef & info)79 int PermissionDefinitionCache::FindByPermissionName(const std::string& permissionName, PermissionDef& info)
80 {
81 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
82 auto it = permissionDefinitionMap_.find(permissionName);
83 if (it == permissionDefinitionMap_.end()) {
84 ACCESSTOKEN_LOG_DEBUG(LABEL, "can not find definition info for permission: %{public}s",
85 permissionName.c_str());
86 return AccessTokenError::ERR_PARAM_INVALID;
87 }
88 info = it->second.permDef;
89 return RET_SUCCESS;
90 }
91
IsSystemGrantedPermission(const std::string & permissionName)92 bool PermissionDefinitionCache::IsSystemGrantedPermission(const std::string& permissionName)
93 {
94 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
95 return IsGrantedModeEqualInner(permissionName, SYSTEM_GRANT);
96 }
97
IsUserGrantedPermission(const std::string & permissionName)98 bool PermissionDefinitionCache::IsUserGrantedPermission(const std::string& permissionName)
99 {
100 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
101 return IsGrantedModeEqualInner(permissionName, USER_GRANT);
102 }
103
IsGrantedModeEqualInner(const std::string & permissionName,int grantMode) const104 bool PermissionDefinitionCache::IsGrantedModeEqualInner(const std::string& permissionName, int grantMode) const
105 {
106 auto it = permissionDefinitionMap_.find(permissionName);
107 if (it == permissionDefinitionMap_.end()) {
108 return false;
109 }
110 return it->second.permDef.grantMode == grantMode;
111 }
112
HasDefinition(const std::string & permissionName)113 bool PermissionDefinitionCache::HasDefinition(const std::string& permissionName)
114 {
115 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
116 return permissionDefinitionMap_.count(permissionName) == 1;
117 }
118
IsPermissionDefEmpty()119 bool PermissionDefinitionCache::IsPermissionDefEmpty()
120 {
121 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
122 return permissionDefinitionMap_.empty();
123 }
124
StorePermissionDef(std::vector<GenericValues> & valueList)125 void PermissionDefinitionCache::StorePermissionDef(std::vector<GenericValues>& valueList)
126 {
127 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
128 auto it = permissionDefinitionMap_.begin();
129 while (it != permissionDefinitionMap_.end()) {
130 GenericValues genericValues;
131 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(it->second.tokenId));
132 DataTranslator::TranslationIntoGenericValues(it->second.permDef, genericValues);
133 valueList.emplace_back(genericValues);
134 ++it;
135 }
136 }
137
GetDefPermissionsByTokenId(std::vector<PermissionDef> & permList,AccessTokenID tokenId)138 void PermissionDefinitionCache::GetDefPermissionsByTokenId(std::vector<PermissionDef>& permList,
139 AccessTokenID tokenId)
140 {
141 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
142 auto it = permissionDefinitionMap_.begin();
143 while (it != permissionDefinitionMap_.end()) {
144 if (tokenId == it->second.tokenId) {
145 permList.emplace_back(it->second.permDef);
146 }
147 ++it;
148 }
149 }
150
RestorePermDefInfo(std::vector<GenericValues> & permDefRes)151 int32_t PermissionDefinitionCache::RestorePermDefInfo(std::vector<GenericValues>& permDefRes)
152 {
153 for (const GenericValues& defValue : permDefRes) {
154 PermissionDef def;
155 AccessTokenID tokenId = (AccessTokenID)defValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID);
156 int32_t ret = DataTranslator::TranslationIntoPermissionDef(defValue, def);
157 if (ret != RET_SUCCESS) {
158 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x permDef is wrong.", tokenId);
159 return ret;
160 }
161 Insert(def, tokenId);
162 }
163 return RET_SUCCESS;
164 }
165 } // namespace AccessToken
166 } // namespace Security
167 } // namespace OHOS
168