• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "medialibrary_uripermission_operations.h"
17 
18 #include "common_func.h"
19 #include "ipc_skeleton.h"
20 #include "medialibrary_errno.h"
21 #include "medialibrary_object_utils.h"
22 #include "media_file_utils.h"
23 #include "media_log.h"
24 #include "permission_utils.h"
25 #include "result_set_utils.h"
26 
27 using namespace std;
28 using namespace OHOS::NativeRdb;
29 using namespace OHOS::DataShare;
30 
31 namespace OHOS {
32 namespace Media {
33 
CheckMode(string & mode)34 static bool CheckMode(string& mode)
35 {
36     transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
37     if (MEDIA_OPEN_MODES.find(mode) == MEDIA_OPEN_MODES.end()) {
38         MEDIA_ERR_LOG("mode format is error: %{public}s", mode.c_str());
39         return false;
40     }
41     string tempMode;
42     if (mode.find(MEDIA_FILEMODE_READONLY) != string::npos) {
43         tempMode += MEDIA_FILEMODE_READONLY;
44     }
45     if (mode.find(MEDIA_FILEMODE_WRITEONLY) != string::npos) {
46         tempMode += MEDIA_FILEMODE_WRITEONLY;
47     }
48     mode = tempMode;
49     return true;
50 }
51 
HandleUriPermOperations(MediaLibraryCommand & cmd)52 int32_t UriPermissionOperations::HandleUriPermOperations(MediaLibraryCommand &cmd)
53 {
54     string bundleName;
55     bool isSystemApp = false;
56     PermissionUtils::GetClientBundle(IPCSkeleton::GetCallingUid(), bundleName, isSystemApp);
57     if (!isSystemApp) {
58         MEDIA_ERR_LOG("the caller is not system app");
59         return E_PERMISSION_DENIED;
60     }
61 
62     int32_t errCode = E_FAIL;
63     switch (cmd.GetOprnType()) {
64         case OperationType::INSERT_PERMISSION:
65             errCode = HandleUriPermInsert(cmd);
66             break;
67         default:
68             MEDIA_ERR_LOG("unknown operation type %{public}d", cmd.GetOprnType());
69             break;
70     }
71     return errCode;
72 }
73 
GetUriPermissionMode(const string & fileId,const string & bundleName,string & mode)74 int32_t UriPermissionOperations::GetUriPermissionMode(const string &fileId, const string &bundleName, string &mode)
75 {
76     MediaLibraryCommand cmd(Uri(MEDIALIBRARY_BUNDLEPERM_URI), OperationType::QUERY);
77     cmd.GetAbsRdbPredicates()->EqualTo(PERMISSION_FILE_ID, fileId);
78     cmd.GetAbsRdbPredicates()->And()->EqualTo(PERMISSION_BUNDLE_NAME, bundleName);
79     auto queryResult = MediaLibraryObjectUtils::QueryWithCondition(cmd, {}, "");
80     CHECK_AND_RETURN_RET_LOG(queryResult != nullptr, E_HAS_DB_ERROR, "Failed to obtain value from database");
81     int count = -1;
82     CHECK_AND_RETURN_RET_LOG(queryResult->GetRowCount(count) == NativeRdb::E_OK, E_HAS_DB_ERROR,
83         "Failed to get query result row count");
84     if (count <= 0) {
85         return E_PERMISSION_DENIED;
86     }
87     CHECK_AND_RETURN_RET_LOG(queryResult->GoToFirstRow() == NativeRdb::E_OK, E_HAS_DB_ERROR,
88         "Failed to go to first row");
89     mode = GetStringVal(PERMISSION_MODE, queryResult);
90     return E_SUCCESS;
91 }
92 
CheckUriPermValues(ValuesBucket & valuesBucket,int32_t & fileId,string & bundleName,string & inputMode)93 int32_t CheckUriPermValues(ValuesBucket &valuesBucket, int32_t &fileId, string &bundleName, string &inputMode)
94 {
95     ValueObject valueObject;
96     if (valuesBucket.GetObject(PERMISSION_FILE_ID, valueObject)) {
97         valueObject.GetInt(fileId);
98     } else {
99         MEDIA_ERR_LOG("ValueBucket does not have PERMISSION_FILE_ID");
100         return E_INVALID_VALUES;
101     }
102 
103     if (valuesBucket.GetObject(PERMISSION_BUNDLE_NAME, valueObject)) {
104         valueObject.GetString(bundleName);
105     } else {
106         MEDIA_ERR_LOG("ValueBucket does not have PERMISSION_BUNDLE_NAME");
107         return E_INVALID_VALUES;
108     }
109 
110     if (valuesBucket.GetObject(PERMISSION_MODE, valueObject)) {
111         valueObject.GetString(inputMode);
112     } else {
113         MEDIA_ERR_LOG("ValueBucket does not have PERMISSION_MODE");
114         return E_INVALID_VALUES;
115     }
116     if (!CheckMode(inputMode)) {
117         return E_INVALID_MODE;
118     }
119     valuesBucket.Delete(PERMISSION_MODE);
120     valuesBucket.PutString(PERMISSION_MODE, inputMode);
121     return E_SUCCESS;
122 }
123 
HandleUriPermInsert(MediaLibraryCommand & cmd)124 int32_t UriPermissionOperations::HandleUriPermInsert(MediaLibraryCommand &cmd)
125 {
126     int32_t fileId;
127     string bundleName;
128     string inputMode;
129     ValuesBucket &valuesBucket = cmd.GetValueBucket();
130     auto ret = CheckUriPermValues(valuesBucket, fileId, bundleName, inputMode);
131     CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
132 
133     string permissionMode;
134     ret = GetUriPermissionMode(to_string(fileId), bundleName, permissionMode);
135     if ((ret != E_SUCCESS) && (ret != E_PERMISSION_DENIED)) {
136         return ret;
137     }
138 
139     auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
140     CHECK_AND_RETURN_RET_LOG(uniStore != nullptr, E_HAS_DB_ERROR, "uniStore is nullptr!");
141 
142     if (ret == E_PERMISSION_DENIED) {
143         int64_t outRowId = -1;
144         return uniStore->Insert(cmd, outRowId);
145     }
146     if (permissionMode.find(inputMode) != string::npos) {
147         return E_SUCCESS;
148     }
149     ValuesBucket updateValues;
150     updateValues.PutString(PERMISSION_MODE, MEDIA_FILEMODE_READWRITE);
151     MediaLibraryCommand updateCmd(Uri(MEDIALIBRARY_BUNDLEPERM_URI), updateValues);
152     updateCmd.GetAbsRdbPredicates()->EqualTo(PERMISSION_FILE_ID, to_string(fileId))->And()->
153         EqualTo(PERMISSION_BUNDLE_NAME, bundleName);
154     int32_t updatedRows = -1;
155     return uniStore->Update(updateCmd, updatedRows);
156 }
157 
CheckUriPermission(const std::string & fileUri,std::string mode)158 int32_t UriPermissionOperations::CheckUriPermission(const std::string &fileUri, std::string mode)
159 {
160     if (!CheckMode(mode)) {
161         return E_INVALID_MODE;
162     }
163     string bundleName;
164     bool isSystemApp = false;
165     PermissionUtils::GetClientBundle(IPCSkeleton::GetCallingUid(), bundleName, isSystemApp);
166     string fileId = MediaLibraryDataManagerUtils::GetIdFromUri(fileUri);
167     string permissionMode;
168     int32_t ret = GetUriPermissionMode(fileId, bundleName, permissionMode);
169     CHECK_AND_RETURN_RET(ret == E_SUCCESS, ret);
170     return (permissionMode.find(mode) != string::npos) ? E_SUCCESS : E_PERMISSION_DENIED;
171 }
172 }   // Media
173 }   // OHOS