• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #define MLOG_TAG "DbPermissionHandler"
17 
18 #include "db_permission_handler.h"
19 
20 #include <cstdlib>
21 
22 #include "media_app_uri_permission_column.h"
23 #include "media_file_uri.h"
24 #include "media_file_utils.h"
25 #include "medialibrary_bundle_manager.h"
26 #include "medialibrary_rdbstore.h"
27 #include "rdb_utils.h"
28 #include "medialibrary_uripermission_operations.h"
29 #include "permission_utils.h"
30 #include "medialibrary_type_const.h"
31 #include "medialibrary_data_manager.h"
32 #include "media_column.h"
33 
34 using namespace std;
35 using namespace OHOS::RdbDataShareAdapter;
36 
37 namespace OHOS::Media {
38 
39 static string UFM_PHOTO_PREFIX = "datashare:///media/userfilemgr_photo_operation";
40 static string UFM_AUDIO_PREFIX = "datashare:///media/userfilemgr_audio_operation";
41 static string PATH_PHOTO_PREFIX = "datashare:///media/phaccess_photo_operation";
42 
ParseFileIdFromPredicates(const DataShare::DataSharePredicates & predicates,string & fileId)43 static bool ParseFileIdFromPredicates(const DataShare::DataSharePredicates &predicates, string &fileId)
44 {
45     // parse fileId from operationList
46     constexpr int32_t FIELD_IDX = 0;
47     constexpr int32_t VALUE_IDX = 1;
48     constexpr int32_t OPERATION_SIZE = 2;
49     auto operationItems = predicates.GetOperationList();
50     for (DataShare::OperationItem item : operationItems) {
51         if (item.singleParams.size() < OPERATION_SIZE) {
52             continue;
53         }
54         if (!MediaLibraryDataManagerUtils::IsNumber(static_cast<string>(item.GetSingle(VALUE_IDX)))) {
55             continue;
56         }
57         if (static_cast<string>(item.GetSingle(FIELD_IDX)) == MediaColumn::MEDIA_ID) {
58             fileId = static_cast<string>(item.GetSingle(VALUE_IDX));
59             return true;
60         }
61     }
62 
63     // parse fileId from whereClause
64     const string &clause = predicates.GetWhereClause();
65     const vector<string> &values = predicates.GetWhereArgs();
66     size_t pos = clause.find(MediaColumn::MEDIA_ID);
67     if (pos == string::npos) {
68         MEDIA_ERR_LOG("whereClause not include fileId");
69         return false;
70     }
71     size_t argIndex = 0;
72     constexpr char placeholder = '?';
73     for (size_t i = 0; i < pos; ++i) {
74         if (clause[i] == placeholder) {
75             ++argIndex;
76         }
77     }
78 
79     CHECK_AND_RETURN_RET_LOG(argIndex < values.size(), false, "argIndex should less than values size");
80     fileId = values[argIndex];
81     CHECK_AND_RETURN_RET_LOG(MediaLibraryDataManagerUtils::IsNumber(fileId), false,
82         "whereArgs fileId=%{public}s is not num", fileId.c_str());
83     return true;
84 }
85 
ParseInfoFromCmd(MediaLibraryCommand & cmd,string & fileId,int32_t & uriType)86 static bool ParseInfoFromCmd(MediaLibraryCommand &cmd, string &fileId, int32_t &uriType)
87 {
88     if (MediaFileUtils::StartsWith(cmd.GetUri().ToString(), PhotoColumn::PHOTO_URI_PREFIX)) {
89         uriType = static_cast<int32_t>(TableType::TYPE_PHOTOS);
90         fileId = MediaFileUtils::GetIdFromUri(cmd.GetUri().ToString());
91         return true;
92     }
93     if (MediaFileUtils::StartsWith(cmd.GetUri().ToString(), AudioColumn::AUDIO_URI_PREFIX)) {
94         uriType = static_cast<int32_t>(TableType::TYPE_AUDIOS);
95         fileId = MediaFileUtils::GetIdFromUri(cmd.GetUri().ToString());
96         return true;
97     }
98 
99     if (cmd.IsDataSharePredNull()) {
100         MEDIA_DEBUG_LOG("DataSharePred is nullptr");
101         return false;
102     }
103     bool isPhotoType = MediaFileUtils::StartsWith(cmd.GetUri().ToString(), UFM_PHOTO_PREFIX)
104         || MediaFileUtils::StartsWith(cmd.GetUri().ToString(), PATH_PHOTO_PREFIX);
105     if (isPhotoType) {
106         uriType = static_cast<int32_t>(TableType::TYPE_PHOTOS);
107         return ParseFileIdFromPredicates(cmd.GetDataSharePred(), fileId);
108     }
109     if (MediaFileUtils::StartsWith(cmd.GetUri().ToString(), UFM_AUDIO_PREFIX)) {
110         uriType = static_cast<int32_t>(TableType::TYPE_AUDIOS);
111         return ParseFileIdFromPredicates(cmd.GetDataSharePred(), fileId);
112     }
113     MEDIA_ERR_LOG("parse fileId and uriType from cmd fail");
114     return false;
115 }
116 
ExecuteCheckPermission(MediaLibraryCommand & cmd,PermParam & permParam)117 int32_t DbPermissionHandler::ExecuteCheckPermission(MediaLibraryCommand &cmd, PermParam &permParam)
118 {
119     MEDIA_DEBUG_LOG("DbPermissionHandler enter");
120     bool isWrite = permParam.isWrite;
121     string appId = GetClientAppId();
122     uint32_t tokenId = PermissionUtils::GetTokenId();
123     string fileId = "";
124     int32_t uriType = 0;
125     if (!ParseInfoFromCmd(cmd, fileId, uriType)) {
126         return E_INVALID_URI;
127     }
128     MEDIA_DEBUG_LOG("isWrite=%{public}d,appId=%{public}s,tokenId=%{public}u,fileId=%{public}s,uriType=%{public}d",
129         isWrite, appId.c_str(), tokenId, fileId.c_str(), uriType);
130     bool cond = ((appId.empty() && !tokenId) || fileId.empty());
131     CHECK_AND_RETURN_RET_LOG(!cond, E_INVALID_FILEID, "invalid input");
132 
133     DataShare::DataSharePredicates predicates;
134     predicates.EqualTo(AppUriPermissionColumn::FILE_ID, fileId);
135     predicates.EqualTo(AppUriPermissionColumn::URI_TYPE, uriType);
136     predicates.And()->BeginWrap()->EqualTo(AppUriPermissionColumn::APP_ID, appId)
137         ->Or()->EqualTo(AppUriPermissionColumn::TARGET_TOKENID, to_string(tokenId))->EndWrap();
138     if (isWrite) {
139         predicates.In(FIELD_PERMISSION_TYPE, AppUriPermissionColumn::PERMISSION_TYPES_WRITE_STR);
140     } else {
141         predicates.In(FIELD_PERMISSION_TYPE, AppUriPermissionColumn::PERMISSION_TYPES_READ_STR);
142     }
143     vector<string> columns;
144     auto queryResultSet =
145         MediaLibraryRdbStore::QueryWithFilter(RdbUtils::ToPredicates(predicates, TABLE_PERMISSION), columns);
146     CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, E_PERMISSION_DENIED, "queryResultSet is nullptr");
147     int count = 0;
148     auto ret = queryResultSet->GetRowCount(count);
149     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK && count > 0, E_PERMISSION_DENIED, "db is no permission record");
150     return E_SUCCESS;
151 }
152 
153 } // namespace name