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