1 /*
2  * Copyright (c) 2023-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 //! This module implements the capability of processing the identity information of the Asset caller.
17 
18 use asset_definition::Value;
19 
20 use crate::{process_info::ProcessInfoDetail, OwnerType, ProcessInfo};
21 
22 /// The identity of calling process.
23 #[derive(Clone)]
24 #[derive(PartialEq, Eq)]
25 pub struct CallingInfo {
26     user_id: i32,
27     owner_type: OwnerType,
28     owner_info: Vec<u8>,
29 }
30 
31 impl CallingInfo {
32     /// Build identity of current process.
new_self() -> Self33     pub fn new_self() -> Self {
34         Self::new(0, OwnerType::Native, "asset_service_8100".as_bytes().to_vec())
35     }
36 
37     /// Build identity of part process info.
new_part_info(user_id: i32) -> Self38     pub fn new_part_info(user_id: i32) -> Self {
39         Self::new(user_id, OwnerType::Native, "asset_service_8100".as_bytes().to_vec())
40     }
41 
42     /// Build identity of the specified owner.
new(user_id: i32, owner_type: OwnerType, owner_info: Vec<u8>) -> Self43     pub fn new(user_id: i32, owner_type: OwnerType, owner_info: Vec<u8>) -> Self {
44         Self { user_id, owner_type, owner_info }
45     }
46 
47     /// Build a instance of CallingInfo.
build(specific_user_id: Option<Value>, process_info: &ProcessInfo) -> Self48     pub fn build(specific_user_id: Option<Value>, process_info: &ProcessInfo) -> Self {
49         let mut owner_info = Vec::new();
50         match &process_info.process_info_detail {
51             ProcessInfoDetail::Hap(hap_info) => {
52                 owner_info.append(&mut hap_info.app_id.clone());
53                 owner_info.append(&mut "_".to_string().as_bytes().to_vec());
54                 owner_info.append(&mut hap_info.app_index.to_string().as_bytes().to_vec());
55             },
56             ProcessInfoDetail::Native(native_info) => {
57                 owner_info.append(&mut process_info.process_name.clone());
58                 owner_info.append(&mut "_".to_string().as_bytes().to_vec());
59                 owner_info.append(&mut native_info.uid.to_string().as_bytes().to_vec());
60             },
61         };
62         let mut user_id = process_info.user_id;
63         if let Some(Value::Number(specific_user_id)) = specific_user_id {
64             user_id = specific_user_id;
65         };
66 
67         CallingInfo { user_id: user_id as i32, owner_type: process_info.owner_type, owner_info }
68     }
69 
70     /// Get owner type of calling.
owner_type(&self) -> u3271     pub fn owner_type(&self) -> u32 {
72         self.owner_type as u32
73     }
74 
75     /// Get owner type enum of calling.
owner_type_enum(&self) -> OwnerType76     pub fn owner_type_enum(&self) -> OwnerType {
77         self.owner_type
78     }
79 
80     /// Get owner info of calling.
owner_info(&self) -> &Vec<u8>81     pub fn owner_info(&self) -> &Vec<u8> {
82         &self.owner_info
83     }
84 
85     /// Get user id of calling.
user_id(&self) -> i3286     pub fn user_id(&self) -> i32 {
87         self.user_id
88     }
89 
90     /// Get appindex.
app_index(&self) -> u3291     pub fn app_index(&self) -> u32 {
92         match self.owner_type_enum() {
93             OwnerType::Hap => {
94                 let owner_info_str = String::from_utf8_lossy(self.owner_info()).to_string();
95                 let owner_info_vec: Vec<_> = owner_info_str.split('_').collect();
96                 match owner_info_vec.last().unwrap().parse::<u32>() {
97                     Ok(num) => num,
98                     Err(_e) => 0,
99                 }
100             },
101             OwnerType::Native=> 0
102         }
103     }
104 }
105 
106 #[cfg(test)]
107 use crate::process_info::{HapInfo, NativeInfo};
108 
109 #[test]
test_build_callig_info_specific_and_hap()110 fn test_build_callig_info_specific_and_hap() {
111     let specific_user_id = 100;
112     let process_name = "test_process".as_bytes().to_vec();
113     let app_id = "test_app_id".as_bytes().to_vec();
114     let app_index = 0;
115     let process_info = ProcessInfo {
116         user_id: 0,
117         owner_type: OwnerType::Hap,
118         process_name,
119         process_info_detail: ProcessInfoDetail::Hap(HapInfo { app_id, app_index }),
120     };
121 
122     let calling_info = CallingInfo::build(Some(Value::Number(specific_user_id)), &process_info);
123     assert_eq!(calling_info.user_id(), specific_user_id as i32);
124 
125     let owner_info = "test_app_id_0".as_bytes().to_vec();
126     assert_eq!(calling_info.owner_info(), &owner_info);
127 }
128 
129 #[test]
test_build_callig_info_hap()130 fn test_build_callig_info_hap() {
131     let process_name = "test_process".as_bytes().to_vec();
132     let app_id = "test_app_id".as_bytes().to_vec();
133     let app_index = 0;
134     let user_id = 0;
135     let process_info = ProcessInfo {
136         user_id,
137         owner_type: OwnerType::Hap,
138         process_name,
139         process_info_detail: ProcessInfoDetail::Hap(HapInfo { app_id, app_index }),
140     };
141 
142     let calling_info = CallingInfo::build(None, &process_info);
143     assert_eq!(calling_info.user_id(), user_id as i32);
144     let owner_info = "test_app_id_0".as_bytes().to_vec();
145     assert_eq!(calling_info.owner_info(), &owner_info);
146 }
147 
148 #[test]
test_build_callig_info_native()149 fn test_build_callig_info_native() {
150     let process_name = "test_process".as_bytes().to_vec();
151     let user_id = 0;
152     let uid = 999;
153     let process_info = ProcessInfo {
154         user_id,
155         owner_type: OwnerType::Native,
156         process_name,
157         process_info_detail: ProcessInfoDetail::Native(NativeInfo { uid }),
158     };
159 
160     let calling_info = CallingInfo::build(None, &process_info);
161     assert_eq!(calling_info.user_id(), user_id as i32);
162     let owner_info = "test_process_999".as_bytes().to_vec();
163     assert_eq!(calling_info.owner_info(), &owner_info);
164 }
165 
166 #[test]
test_build_callig_info_specific_and_native()167 fn test_build_callig_info_specific_and_native() {
168     let specific_user_id = 100;
169     let process_name = "test_process".as_bytes().to_vec();
170     let user_id = 0;
171     let uid = 999;
172     let process_info = ProcessInfo {
173         user_id,
174         owner_type: OwnerType::Native,
175         process_name,
176         process_info_detail: ProcessInfoDetail::Native(NativeInfo { uid }),
177     };
178 
179     let calling_info = CallingInfo::build(Some(Value::Number(specific_user_id)), &process_info);
180 
181     assert_eq!(calling_info.user_id(), specific_user_id as i32);
182     let owner_info = "test_process_999".as_bytes().to_vec();
183     assert_eq!(calling_info.owner_info(), &owner_info);
184 }
185