• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 //! This module is used to provide common capabilities for the Asset operations.
17 
18 mod argument_check;
19 mod permission_check;
20 
21 pub(crate) use argument_check::{check_required_tags, check_tag_validity, check_value_validity, MAX_LABEL_SIZE};
22 pub(crate) use permission_check::check_system_permission;
23 
24 use asset_common::CallingInfo;
25 use asset_crypto_manager::secret_key::SecretKey;
26 use asset_db_operator::types::{column, DbMap, DB_DATA_VERSION, DB_DATA_VERSION_V1};
27 use asset_definition::{
28     log_throw_error, Accessibility, AssetMap, AuthType, ErrCode, Extension, OperationType, Result, Tag, Value,
29 };
30 use asset_log::{loge, logi};
31 use asset_plugin::asset_plugin::AssetPlugin;
32 use asset_sdk::plugin_interface::{EventType, ExtDbMap, PARAM_NAME_BUNDLE_NAME, PARAM_NAME_USER_ID};
33 
34 const TAG_COLUMN_TABLE: [(Tag, &str); 20] = [
35     (Tag::Secret, column::SECRET),
36     (Tag::Alias, column::ALIAS),
37     (Tag::Accessibility, column::ACCESSIBILITY),
38     (Tag::AuthType, column::AUTH_TYPE),
39     (Tag::SyncType, column::SYNC_TYPE),
40     (Tag::UpdateTime, column::UPDATE_TIME),
41     (Tag::IsPersistent, column::IS_PERSISTENT),
42     (Tag::RequirePasswordSet, column::REQUIRE_PASSWORD_SET),
43     (Tag::DataLabelCritical1, column::CRITICAL1),
44     (Tag::DataLabelCritical2, column::CRITICAL2),
45     (Tag::DataLabelCritical3, column::CRITICAL3),
46     (Tag::DataLabelCritical4, column::CRITICAL4),
47     (Tag::DataLabelNormal1, column::NORMAL1),
48     (Tag::DataLabelNormal2, column::NORMAL2),
49     (Tag::DataLabelNormal3, column::NORMAL3),
50     (Tag::DataLabelNormal4, column::NORMAL4),
51     (Tag::DataLabelNormalLocal1, column::NORMAL_LOCAL1),
52     (Tag::DataLabelNormalLocal2, column::NORMAL_LOCAL2),
53     (Tag::DataLabelNormalLocal3, column::NORMAL_LOCAL3),
54     (Tag::DataLabelNormalLocal4, column::NORMAL_LOCAL4),
55 ];
56 
57 const AAD_ATTR: [&str; 14] = [
58     column::ALIAS,
59     column::OWNER,
60     column::OWNER_TYPE,
61     column::GROUP_ID,
62     column::SYNC_TYPE,
63     column::ACCESSIBILITY,
64     column::REQUIRE_PASSWORD_SET,
65     column::AUTH_TYPE,
66     column::IS_PERSISTENT,
67     column::VERSION,
68     column::CRITICAL1,
69     column::CRITICAL2,
70     column::CRITICAL3,
71     column::CRITICAL4,
72 ];
73 
74 pub(crate) const CRITICAL_LABEL_ATTRS: [Tag; 4] =
75     [Tag::DataLabelCritical1, Tag::DataLabelCritical2, Tag::DataLabelCritical3, Tag::DataLabelCritical4];
76 
77 pub(crate) const NORMAL_LABEL_ATTRS: [Tag; 4] =
78     [Tag::DataLabelNormal1, Tag::DataLabelNormal2, Tag::DataLabelNormal3, Tag::DataLabelNormal4];
79 
80 pub(crate) const NORMAL_LOCAL_LABEL_ATTRS: [Tag; 4] =
81     [Tag::DataLabelNormalLocal1, Tag::DataLabelNormalLocal2, Tag::DataLabelNormalLocal3, Tag::DataLabelNormalLocal4];
82 
83 pub(crate) const ACCESS_CONTROL_ATTRS: [Tag; 7] = [
84     Tag::Alias,
85     Tag::Accessibility,
86     Tag::AuthType,
87     Tag::IsPersistent,
88     Tag::SyncType,
89     Tag::RequirePasswordSet,
90     Tag::UserId,
91 ];
92 
93 pub(crate) const ASSET_SYNC_ATTRS: [Tag; 1] = [Tag::OperationType];
94 
get_cloumn_name(tag: Tag) -> Option<&'static str>95 pub(crate) fn get_cloumn_name(tag: Tag) -> Option<&'static str> {
96     for (table_tag, table_column) in TAG_COLUMN_TABLE {
97         if table_tag == tag {
98             return Some(table_column);
99         }
100     }
101     None
102 }
103 
into_db_map(attrs: &AssetMap) -> DbMap104 pub(crate) fn into_db_map(attrs: &AssetMap) -> DbMap {
105     let mut db_data = DbMap::new();
106     for (attr_tag, attr_value) in attrs.iter() {
107         for (table_tag, table_column) in TAG_COLUMN_TABLE {
108             if *attr_tag == table_tag {
109                 db_data.insert(table_column, attr_value.clone());
110                 break;
111             }
112         }
113     }
114     db_data
115 }
116 
into_asset_map(db_data: &DbMap) -> AssetMap117 pub(crate) fn into_asset_map(db_data: &DbMap) -> AssetMap {
118     let mut map = AssetMap::new();
119     for (column, data) in db_data.iter() {
120         for (table_tag, table_column) in TAG_COLUMN_TABLE {
121             if (*column).eq(table_column) {
122                 map.insert(table_tag, data.clone());
123                 break;
124             }
125         }
126     }
127     map
128 }
129 
add_owner_info(calling_info: &CallingInfo, db_data: &mut DbMap)130 pub(crate) fn add_owner_info(calling_info: &CallingInfo, db_data: &mut DbMap) {
131     db_data.insert(column::OWNER, Value::Bytes(calling_info.owner_info().clone()));
132     db_data.insert(column::OWNER_TYPE, Value::Number(calling_info.owner_type()));
133 }
134 
build_secret_key(calling: &CallingInfo, attrs: &DbMap) -> Result<SecretKey>135 pub(crate) fn build_secret_key(calling: &CallingInfo, attrs: &DbMap) -> Result<SecretKey> {
136     let auth_type = attrs.get_enum_attr::<AuthType>(&column::AUTH_TYPE)?;
137     let access_type = attrs.get_enum_attr::<Accessibility>(&column::ACCESSIBILITY)?;
138     let require_password_set = attrs.get_bool_attr(&column::REQUIRE_PASSWORD_SET)?;
139     SecretKey::new(calling, auth_type, access_type, require_password_set)
140 }
141 
build_aad_v1(attrs: &DbMap) -> Vec<u8>142 fn build_aad_v1(attrs: &DbMap) -> Vec<u8> {
143     let mut aad = Vec::new();
144     for column in &AAD_ATTR {
145         match attrs.get(column) {
146             Some(Value::Bytes(bytes)) => aad.extend(bytes),
147             Some(Value::Number(num)) => aad.extend(num.to_le_bytes()),
148             Some(Value::Bool(num)) => aad.push(*num as u8),
149             None => continue,
150         }
151     }
152     aad
153 }
154 
to_hex(bytes: &Vec<u8>) -> Result<Vec<u8>>155 fn to_hex(bytes: &Vec<u8>) -> Result<Vec<u8>> {
156     let bytes_len = bytes.len();
157     if bytes_len > MAX_LABEL_SIZE {
158         return log_throw_error!(ErrCode::DataCorrupted, "The data in DB has been tampered with.");
159     }
160 
161     let scale_capacity = 2;
162     let mut hex_vec = Vec::with_capacity(bytes_len * scale_capacity);
163     for byte in bytes.iter() {
164         hex_vec.extend(format!("{:02x}", byte).as_bytes());
165     }
166     Ok(hex_vec)
167 }
168 
build_aad_v2(attrs: &DbMap) -> Result<Vec<u8>>169 fn build_aad_v2(attrs: &DbMap) -> Result<Vec<u8>> {
170     let mut aad = Vec::new();
171     for column in &AAD_ATTR {
172         aad.extend(format!("{}:", column).as_bytes());
173         match attrs.get(column) {
174             Some(Value::Bytes(bytes)) => aad.extend(to_hex(bytes)?),
175             Some(Value::Number(num)) => aad.extend(num.to_le_bytes()),
176             Some(Value::Bool(num)) => aad.push(*num as u8),
177             None => (),
178         }
179         aad.push(b'_');
180     }
181     Ok(aad)
182 }
183 
build_aad(attrs: &DbMap) -> Result<Vec<u8>>184 pub(crate) fn build_aad(attrs: &DbMap) -> Result<Vec<u8>> {
185     let version = attrs.get_num_attr(&column::VERSION)?;
186     if version == DB_DATA_VERSION_V1 {
187         Ok(build_aad_v1(attrs))
188     } else {
189         build_aad_v2(attrs)
190     }
191 }
192 
need_upgrade(db_date: &DbMap) -> Result<bool>193 pub(crate) fn need_upgrade(db_date: &DbMap) -> Result<bool> {
194     let version = db_date.get_num_attr(&column::VERSION)?;
195     Ok(version != DB_DATA_VERSION)
196 }
197 
inform_asset_ext(calling_info: &CallingInfo, input: &AssetMap)198 pub(crate) fn inform_asset_ext(calling_info: &CallingInfo, input: &AssetMap) {
199     if let Some(Value::Number(operation_type)) = input.get(&Tag::OperationType) {
200         match operation_type {
201             x if *x == OperationType::NeedSync as u32 => {
202                 if let Ok(load) = AssetPlugin::get_instance().load_plugin() {
203                     let owner_info_str = String::from_utf8_lossy(calling_info.owner_info()).to_string();
204                     let owner_info_vec: Vec<_> = owner_info_str.split('_').collect();
205                     let caller_name = owner_info_vec[0];
206                     let mut params = ExtDbMap::new();
207                     params.insert(PARAM_NAME_USER_ID, Value::Number(calling_info.user_id() as u32));
208                     params.insert(PARAM_NAME_BUNDLE_NAME, Value::Bytes(caller_name.as_bytes().to_vec()));
209                     match load.process_event(EventType::Sync, &params) {
210                         Ok(()) => logi!("process sync ext event success."),
211                         Err(code) => loge!("process sync ext event failed, code: {}", code),
212                     }
213                 }
214             },
215             x if *x == OperationType::NeedLogout as u32 => {
216                 if let Ok(load) = AssetPlugin::get_instance().load_plugin() {
217                     let owner_info_str = String::from_utf8_lossy(calling_info.owner_info()).to_string();
218                     let owner_info_vec: Vec<_> = owner_info_str.split('_').collect();
219                     let caller_name = owner_info_vec[0];
220                     let mut params = ExtDbMap::new();
221                     params.insert(PARAM_NAME_USER_ID, Value::Number(calling_info.user_id() as u32));
222                     params.insert(PARAM_NAME_BUNDLE_NAME, Value::Bytes(caller_name.as_bytes().to_vec()));
223                     match load.process_event(EventType::CleanCloudFlag, &params) {
224                         Ok(()) => logi!("process clean cloud flag ext event success."),
225                         Err(code) => loge!("process clean cloud flag ext event failed, code: {}", code),
226                     }
227                 }
228             },
229             x if *x == OperationType::NeedDeleteCloudData as u32 => {
230                 if let Ok(load) = AssetPlugin::get_instance().load_plugin() {
231                     let mut params = ExtDbMap::new();
232                     params.insert(PARAM_NAME_USER_ID, Value::Number(calling_info.user_id() as u32));
233                     params.insert(PARAM_NAME_BUNDLE_NAME, Value::Bytes(calling_info.owner_info().clone()));
234                     match load.process_event(EventType::DeleteCloudData, &params) {
235                         Ok(()) => logi!("process delete cloud data ext event success."),
236                         Err(code) => loge!("process delete cloud data ext event failed, code: {}", code),
237                     }
238                 }
239             },
240             _ => {},
241         }
242     }
243 }
244