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 const int32_t EXTENSION_PERMISSION_ID = 0;
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
30 LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionDefinitionCache"
31 };
32 std::recursive_mutex g_instanceMutex;
33 }
34
GetInstance()35 PermissionDefinitionCache& PermissionDefinitionCache::GetInstance()
36 {
37 static PermissionDefinitionCache* instance = nullptr;
38 if (instance == nullptr) {
39 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
40 if (instance == nullptr) {
41 instance = new PermissionDefinitionCache();
42 }
43 }
44 return *instance;
45 }
46
PermissionDefinitionCache()47 PermissionDefinitionCache::PermissionDefinitionCache()
48 {}
49
~PermissionDefinitionCache()50 PermissionDefinitionCache::~PermissionDefinitionCache()
51 {}
52
Insert(const PermissionDef & info,AccessTokenID tokenId)53 bool PermissionDefinitionCache::Insert(const PermissionDef& info, AccessTokenID tokenId)
54 {
55 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
56 auto it = permissionDefinitionMap_.find(info.permissionName);
57 if (it != permissionDefinitionMap_.end()) {
58 ACCESSTOKEN_LOG_DEBUG(LABEL, "Info for permission: %{public}s has been insert, please check!",
59 info.permissionName.c_str());
60 return false;
61 }
62 permissionDefinitionMap_[info.permissionName].permDef = info;
63 permissionDefinitionMap_[info.permissionName].tokenId = tokenId;
64 if (!hasHapPermissionDefinition_ && (tokenId != EXTENSION_PERMISSION_ID)) {
65 hasHapPermissionDefinition_ = true;
66 }
67 return true;
68 }
69
Update(const PermissionDef & info,AccessTokenID tokenId)70 bool PermissionDefinitionCache::Update(const PermissionDef& info, AccessTokenID tokenId)
71 {
72 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
73 permissionDefinitionMap_[info.permissionName].permDef = info;
74 permissionDefinitionMap_[info.permissionName].tokenId = tokenId;
75 return true;
76 }
77
DeleteByToken(AccessTokenID tokenId)78 void PermissionDefinitionCache::DeleteByToken(AccessTokenID tokenId)
79 {
80 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
81 auto it = permissionDefinitionMap_.begin();
82 while (it != permissionDefinitionMap_.end()) {
83 if (tokenId == it->second.tokenId) {
84 it = permissionDefinitionMap_.erase(it);
85 } else {
86 ++it;
87 }
88 }
89 }
90
FindByPermissionName(const std::string & permissionName,PermissionDef & info)91 int PermissionDefinitionCache::FindByPermissionName(const std::string& permissionName, PermissionDef& info)
92 {
93 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
94 auto it = permissionDefinitionMap_.find(permissionName);
95 if (it == permissionDefinitionMap_.end()) {
96 ACCESSTOKEN_LOG_ERROR(LABEL, "Can not find definition info for permission: %{public}s",
97 permissionName.c_str());
98 return AccessTokenError::ERR_PERMISSION_NOT_EXIST;
99 }
100 info = it->second.permDef;
101 return RET_SUCCESS;
102 }
103
IsSystemGrantedPermission(const std::string & permissionName)104 bool PermissionDefinitionCache::IsSystemGrantedPermission(const std::string& permissionName)
105 {
106 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
107 return IsGrantedModeEqualInner(permissionName, SYSTEM_GRANT);
108 }
109
IsUserGrantedPermission(const std::string & permissionName)110 bool PermissionDefinitionCache::IsUserGrantedPermission(const std::string& permissionName)
111 {
112 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
113 return IsGrantedModeEqualInner(permissionName, USER_GRANT);
114 }
115
IsGrantedModeEqualInner(const std::string & permissionName,int grantMode) const116 bool PermissionDefinitionCache::IsGrantedModeEqualInner(const std::string& permissionName, int grantMode) const
117 {
118 auto it = permissionDefinitionMap_.find(permissionName);
119 if (it == permissionDefinitionMap_.end()) {
120 return false;
121 }
122 return it->second.permDef.grantMode == grantMode;
123 }
124
HasDefinition(const std::string & permissionName)125 bool PermissionDefinitionCache::HasDefinition(const std::string& permissionName)
126 {
127 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
128 auto it = permissionDefinitionMap_.find(permissionName);
129 if (it != permissionDefinitionMap_.end()) {
130 return true;
131 }
132 return false;
133 }
134
HasHapPermissionDefinitionForHap(const std::string & permissionName)135 bool PermissionDefinitionCache::HasHapPermissionDefinitionForHap(const std::string& permissionName)
136 {
137 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
138 auto it = permissionDefinitionMap_.find(permissionName);
139 if ((it != permissionDefinitionMap_.end()) && (it->second.tokenId != EXTENSION_PERMISSION_ID)) {
140 return true;
141 }
142 return false;
143 }
144
IsHapPermissionDefEmpty()145 bool PermissionDefinitionCache::IsHapPermissionDefEmpty()
146 {
147 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
148 return !hasHapPermissionDefinition_;
149 }
150
StorePermissionDef(std::vector<GenericValues> & valueList)151 void PermissionDefinitionCache::StorePermissionDef(std::vector<GenericValues>& valueList)
152 {
153 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
154 auto it = permissionDefinitionMap_.begin();
155 while (it != permissionDefinitionMap_.end()) {
156 GenericValues genericValues;
157 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(it->second.tokenId));
158 DataTranslator::TranslationIntoGenericValues(it->second.permDef, genericValues);
159 valueList.emplace_back(genericValues);
160 ++it;
161 }
162 }
163
StorePermissionDef(AccessTokenID tokenID,std::vector<GenericValues> & valueList)164 void PermissionDefinitionCache::StorePermissionDef(AccessTokenID tokenID, std::vector<GenericValues>& valueList)
165 {
166 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
167 auto it = permissionDefinitionMap_.begin();
168 while (it != permissionDefinitionMap_.end()) {
169 if (tokenID == it->second.tokenId) {
170 GenericValues genericValues;
171 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(it->second.tokenId));
172 DataTranslator::TranslationIntoGenericValues(it->second.permDef, genericValues);
173 valueList.emplace_back(genericValues);
174 }
175 ++it;
176 }
177 }
178
GetDefPermissionsByTokenId(std::vector<PermissionDef> & permList,AccessTokenID tokenId)179 void PermissionDefinitionCache::GetDefPermissionsByTokenId(std::vector<PermissionDef>& permList,
180 AccessTokenID tokenId)
181 {
182 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
183 auto it = permissionDefinitionMap_.begin();
184 while (it != permissionDefinitionMap_.end()) {
185 if (tokenId == it->second.tokenId) {
186 permList.emplace_back(it->second.permDef);
187 }
188 ++it;
189 }
190 }
191
RestorePermDefInfo(std::vector<GenericValues> & permDefRes)192 int32_t PermissionDefinitionCache::RestorePermDefInfo(std::vector<GenericValues>& permDefRes)
193 {
194 for (const GenericValues& defValue : permDefRes) {
195 PermissionDef def;
196 AccessTokenID tokenId = (AccessTokenID)defValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID);
197 int32_t ret = DataTranslator::TranslationIntoPermissionDef(defValue, def);
198 if (ret != RET_SUCCESS) {
199 ACCESSTOKEN_LOG_ERROR(LABEL, "TokenId 0x%{public}x permDef is wrong.", tokenId);
200 return ret;
201 }
202 Insert(def, tokenId);
203 }
204 return RET_SUCCESS;
205 }
206
GetDefPermissionsSize()207 uint32_t PermissionDefinitionCache::GetDefPermissionsSize()
208 {
209 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
210 return static_cast<uint32_t>(permissionDefinitionMap_.size());
211 }
212 } // namespace AccessToken
213 } // namespace Security
214 } // namespace OHOS
215