Skip to main content

v_common/storage/
async_storage.rs

1use v_authorization_impl_tt2_lmdb::AzContext;
2use v_individual_model::onto::individual::Individual;
3use v_individual_model::onto::parser::parse_raw;
4use v_storage::{Storage, StorageId, StorageResult};
5use v_storage::lmdb_storage::LMDBStorage;
6use crate::v_api::common_type::ResultCode;
7use crate::v_authorization::common::{Access, AuthorizationContext, Trace};
8use futures::lock::Mutex;
9use std::io;
10use std::io::{Error, ErrorKind};
11use v_storage::tt_wrapper::{Client, IteratorType};      
12
13pub const INDIVIDUALS_SPACE_ID: i32 = 512;
14pub const TICKETS_SPACE_ID: i32 = 513;
15
16pub struct AStorage {
17    pub tt: Option<Client>,
18    pub lmdb: Option<Mutex<LMDBStorage>>,
19}
20
21pub async fn check_indv_access_read(
22    mut indv: Individual,
23    uri: &str,
24    user_uri: &str,
25    az: Option<&Mutex<AzContext>>,
26) -> io::Result<(Individual, ResultCode)> {
27    if indv.get_id().is_empty() {
28        return Ok((indv, ResultCode::NotFound));
29    }
30
31    if let Some(a) = az {
32        if a.lock().await.authorize(uri, user_uri, Access::CanRead as u8, false).unwrap_or(0) != Access::CanRead as u8 {
33            return Ok((indv, ResultCode::NotAuthorized));
34        }
35    }
36
37    indv.parse_all();
38    Ok((indv, ResultCode::Ok))
39}
40
41pub async fn check_user_in_group(user_id: &str, group_id: &str, az: Option<&Mutex<AzContext>>) -> io::Result<bool> {
42    if let Some(a) = az {
43        let mut tr = Trace {
44            acl: &mut "".to_string(),
45            is_acl: false,
46            group: &mut String::new(),
47            is_group: true,
48            info: &mut "".to_string(),
49            is_info: false,
50            str_num: 0,
51        };
52        if a.lock().await.authorize_and_trace(user_id, user_id, 0xF, false, &mut tr).is_ok() {
53            for gr in tr.group.split('\n') {
54                if gr == group_id {
55                    return Ok(true);
56                }
57            }
58        } else {
59            return Err(Error::new(ErrorKind::Other, "fail authorize_and_trace"));
60        }
61    }
62
63    Ok(false)
64}
65
66pub async fn get_individual_from_db(uri: &str, user_uri: &str, db: &AStorage, az: Option<&Mutex<AzContext>>) -> io::Result<(Individual, ResultCode)> {
67    get_individual_use_storage_id(StorageId::Individuals, uri, user_uri, db, az).await
68}
69
70pub async fn get_individual_use_storage_id(
71    storage_id: StorageId,
72    uri: &str,
73    user_uri: &str,
74    db: &AStorage,
75    az: Option<&Mutex<AzContext>>,
76) -> io::Result<(Individual, ResultCode)> {
77    if let Some(tt) = &db.tt {
78        let space_id = match storage_id {
79            StorageId::Tickets => TICKETS_SPACE_ID,
80            StorageId::Individuals => INDIVIDUALS_SPACE_ID,
81            StorageId::Az => 514,
82        };
83
84        let response = tt.select(space_id, 0, &(uri,), 0, 100, IteratorType::EQ).await?;
85
86        let mut iraw = Individual::default();
87        iraw.set_raw(&response.data[5..]);
88        if parse_raw(&mut iraw).is_ok() {
89            return check_indv_access_read(iraw, uri, user_uri, az).await;
90        }
91        return Ok((iraw, ResultCode::UnprocessableEntity));
92    }
93    if let Some(lmdb) = &db.lmdb {
94        let mut iraw = Individual::default();
95        let res = lmdb.lock().await.get_individual(storage_id, uri, &mut iraw);
96        match res {
97            StorageResult::Ok(()) => {
98                return check_indv_access_read(iraw, uri, user_uri, az).await;
99            }
100            StorageResult::NotFound => {
101                return Ok((Individual::default(), ResultCode::NotFound));
102            }
103            _ => {
104                return Ok((Individual::default(), ResultCode::UnprocessableEntity));
105            }
106        }
107    }
108
109    Ok((Individual::default(), ResultCode::UnprocessableEntity))
110}