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,AccessTokenID tokenId)59 bool PermissionDefinitionCache::Update(const PermissionDef& info, AccessTokenID tokenId)
60 {
61 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
62 permissionDefinitionMap_[info.permissionName].permDef = info;
63 permissionDefinitionMap_[info.permissionName].tokenId = tokenId;
64 return true;
65 }
66
DeleteByBundleName(const std::string & bundleName)67 void PermissionDefinitionCache::DeleteByBundleName(const std::string& bundleName)
68 {
69 Utils::UniqueWriteGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
70 auto it = permissionDefinitionMap_.begin();
71 while (it != permissionDefinitionMap_.end()) {
72 if (bundleName == it->second.permDef.bundleName) {
73 permissionDefinitionMap_.erase(it++);
74 } else {
75 ++it;
76 }
77 }
78 }
79
FindByPermissionName(const std::string & permissionName,PermissionDef & info)80 int PermissionDefinitionCache::FindByPermissionName(const std::string& permissionName, PermissionDef& info)
81 {
82 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
83 auto it = permissionDefinitionMap_.find(permissionName);
84 if (it == permissionDefinitionMap_.end()) {
85 ACCESSTOKEN_LOG_DEBUG(LABEL, "can not find definition info for permission: %{public}s",
86 permissionName.c_str());
87 return AccessTokenError::ERR_PARAM_INVALID;
88 }
89 info = it->second.permDef;
90 return RET_SUCCESS;
91 }
92
IsSystemGrantedPermission(const std::string & permissionName)93 bool PermissionDefinitionCache::IsSystemGrantedPermission(const std::string& permissionName)
94 {
95 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
96 return IsGrantedModeEqualInner(permissionName, SYSTEM_GRANT);
97 }
98
IsUserGrantedPermission(const std::string & permissionName)99 bool PermissionDefinitionCache::IsUserGrantedPermission(const std::string& permissionName)
100 {
101 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
102 return IsGrantedModeEqualInner(permissionName, USER_GRANT);
103 }
104
IsGrantedModeEqualInner(const std::string & permissionName,int grantMode) const105 bool PermissionDefinitionCache::IsGrantedModeEqualInner(const std::string& permissionName, int grantMode) const
106 {
107 auto it = permissionDefinitionMap_.find(permissionName);
108 if (it == permissionDefinitionMap_.end()) {
109 return false;
110 }
111 return it->second.permDef.grantMode == grantMode;
112 }
113
HasDefinition(const std::string & permissionName)114 bool PermissionDefinitionCache::HasDefinition(const std::string& permissionName)
115 {
116 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
117 return permissionDefinitionMap_.count(permissionName) == 1;
118 }
119
IsPermissionDefEmpty()120 bool PermissionDefinitionCache::IsPermissionDefEmpty()
121 {
122 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
123 return permissionDefinitionMap_.empty();
124 }
125
StorePermissionDef(std::vector<GenericValues> & valueList)126 void PermissionDefinitionCache::StorePermissionDef(std::vector<GenericValues>& valueList)
127 {
128 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
129 auto it = permissionDefinitionMap_.begin();
130 while (it != permissionDefinitionMap_.end()) {
131 GenericValues genericValues;
132 genericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(it->second.tokenId));
133 DataTranslator::TranslationIntoGenericValues(it->second.permDef, genericValues);
134 valueList.emplace_back(genericValues);
135 ++it;
136 }
137 }
138
GetDefPermissionsByTokenId(std::vector<PermissionDef> & permList,AccessTokenID tokenId)139 void PermissionDefinitionCache::GetDefPermissionsByTokenId(std::vector<PermissionDef>& permList,
140 AccessTokenID tokenId)
141 {
142 Utils::UniqueReadGuard<Utils::RWLock> cacheGuard(this->cacheLock_);
143 auto it = permissionDefinitionMap_.begin();
144 while (it != permissionDefinitionMap_.end()) {
145 if (tokenId == it->second.tokenId) {
146 permList.emplace_back(it->second.permDef);
147 }
148 ++it;
149 }
150 }
151
RestorePermDefInfo(std::vector<GenericValues> & permDefRes)152 int32_t PermissionDefinitionCache::RestorePermDefInfo(std::vector<GenericValues>& permDefRes)
153 {
154 for (const GenericValues& defValue : permDefRes) {
155 PermissionDef def;
156 AccessTokenID tokenId = (AccessTokenID)defValue.GetInt(TokenFiledConst::FIELD_TOKEN_ID);
157 int32_t ret = DataTranslator::TranslationIntoPermissionDef(defValue, def);
158 if (ret != RET_SUCCESS) {
159 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x permDef is wrong.", tokenId);
160 return ret;
161 }
162 Insert(def, tokenId);
163 }
164 return RET_SUCCESS;
165 }
166 } // namespace AccessToken
167 } // namespace Security
168 } // namespace OHOS
169