Skip to main content

this_env/env/methods/
resolve.rs

1//this.env/src/env/methods/resolve.rs
2// by suiGn
3// This file contains the implementation of the `resolve_from_request` method for the `Env`
4// struct, which is responsible for determining the environment configuration based on an incoming request.
5// It handles the logic of checking if an environment already exists in the database, and if not,
6// it defaults to an approved state while logging the request details.
7use crate::env::structs::{EnvRequestLog, EnvStatus};
8use crate::middleware::env_request::EnvRequestInfo;
9use crate::middleware::env_request::EnvRequest;
10use crate::env::Env;
11use rusqlite::{params, Connection, Result as SqlResult};
12
13impl Env {
14    fn check_if_blocked(req: &EnvRequest) -> Option<String> {
15        // Ejemplo simple: bloquear por dominio
16        let blocked_domains = vec!["malicious.com", "banned.example"];
17        let domain = match req {
18            EnvRequest::Http(http_req) => http_req.headers.get("domain"),
19            EnvRequest::Ws(ws_req) => ws_req.headers.get("domain"),
20            EnvRequest::Cli(_) => None,
21        };
22
23        if let Some(domain) = domain {
24            if blocked_domains.contains(&domain.as_str()) {
25                return Some(format!("Domain '{}' is blocked", domain));
26            }
27        }
28
29        None
30    }
31
32    pub fn resolve(req: &EnvRequest, conn: &Connection) -> EnvStatus {
33        //log::debug!("this.env resolve: attempting to fetch env from request");
34        // Extract domain and env_type from EnvRequest variants
35        let (domain, _env_type) = match req {
36            EnvRequest::Http(http_req) => {
37                // Assuming domain and env_type are headers or fields in http_req
38                // Replace the following with actual extraction logic
39                let domain = http_req.headers.get("domain").cloned().unwrap_or_default();
40                let env_type = http_req.headers.get("env_type").cloned().unwrap_or_default();
41                (domain, env_type)
42            }
43            EnvRequest::Ws(ws_req) => {
44                // Assuming domain and env_type are fields or headers in ws_req
45                let domain = ws_req.headers.get("domain").cloned().unwrap_or_default();
46                let env_type = ws_req.headers.get("env_type").cloned().unwrap_or_default();
47                (domain, env_type)
48            }
49            EnvRequest::Cli(_cli_req) => {
50                let domain = "localhost".to_string();
51                let env_type = "cli".to_string();
52                (domain, env_type)
53            }
54            // Add other EnvRequest variants here if any
55        };
56
57        // Dummy lookup logic; replace with actual query
58        let env_found = false;
59        if let Some(reason) = Self::check_if_blocked(req) {
60            log::debug!("this.env resolve: request is explicitly blocked");
61            // Convert EnvRequest to EnvRequestLog for logging
62            let mut log_entry: EnvRequestLog = req.clone().into();
63            log_entry.decision = "Blocked".into();
64            log_entry.reason = reason.clone();
65            // Save the log
66            if let Err(e) = Self::save_log_to_sqlite(conn, &log_entry) {
67                log::error!("this.env resolve: failed to save blocked log: {:?}", e);
68            } else {
69                log::debug!("this.env resolve: blocked log saved to SQLite");
70            }
71            let env_info = EnvRequestInfo::from(req);
72            return EnvStatus::Blocked { env_request: env_info, reason };
73        }
74
75        if env_found {
76            log::debug!("this.env resolve: found existing env");
77            // TODO: return fetched env
78            let env_info = EnvRequestInfo::from(req);
79            EnvStatus::Approved { env_request: env_info }
80        } else {
81            log::debug!("this.env resolve: no env found, defaulting to Pending");
82            // Convert EnvRequest to EnvRequestLog for logging
83            let mut log_entry: EnvRequestLog = req.clone().into();
84            log_entry.decision = "PendingApproval".into();
85            log_entry.reason = "No existing env found".into();
86
87            // Save the log
88            if let Err(e) = Self::save_log_to_sqlite(conn, &log_entry) {
89                log::error!("this.env resolve: failed to save log: {:?}", e);
90            } else {
91                log::debug!("this.env resolve: log saved to SQLite");
92            }
93            let env_info = EnvRequestInfo::from(req);
94            EnvStatus::PendingApproval { env_request: env_info, reason: domain }
95        }
96    }
97
98    fn save_log_to_sqlite(conn: &Connection, log: &EnvRequestLog) -> SqlResult<()> {
99        conn.execute(
100            "INSERT INTO env_request_logs (ip, method, path, host, headers, decision, reason, timestamp, domain) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)",
101            params![
102                log.ip.as_deref().unwrap_or("unknown"),
103                log.method,
104                log.path,
105                log.host,
106                log.headers,
107                log.decision,
108                log.reason,
109                log.timestamp,
110                log.domain,
111            ],
112        )?;
113        Ok(())
114    }
115}