Parse condition clauses from DDL parts. Recognizes: - `WHEN BETWEEN ' ' AND ' ' ON WEEKDAYS` - `REQUIRE MFA` - `REQUIRE IP IN (' ', ...)` - `REQUIRE STEP_UP ` - `REQUIRE DEVICE_TRUST`
(parts: &[&str])
| 149 | /// - `REQUIRE STEP_UP <seconds>` |
| 150 | /// - `REQUIRE DEVICE_TRUST` |
| 151 | pub fn parse_conditions(parts: &[&str]) -> Vec<GrantCondition> { |
| 152 | let mut conditions = Vec::new(); |
| 153 | let mut i = 0; |
| 154 | |
| 155 | while i < parts.len() { |
| 156 | let upper = parts[i].to_uppercase(); |
| 157 | |
| 158 | if upper == "WHEN" && i + 4 < parts.len() && parts[i + 1].to_uppercase() == "BETWEEN" { |
| 159 | let start = parts[i + 2].trim_matches('\''); |
| 160 | let end = parts[i + 4].trim_matches('\''); |
| 161 | let start_hour = parse_hour(start); |
| 162 | let end_hour = parse_hour(end); |
| 163 | |
| 164 | // Check for ON WEEKDAYS. |
| 165 | let days = if i + 6 < parts.len() && parts[i + 5].to_uppercase() == "ON" { |
| 166 | let day_str = parts[i + 6].to_uppercase(); |
| 167 | match day_str.as_str() { |
| 168 | "WEEKDAYS" => vec![1, 2, 3, 4, 5], |
| 169 | "WEEKENDS" => vec![0, 6], |
| 170 | "ALL" => vec![], |
| 171 | _ => vec![], |
| 172 | } |
| 173 | } else { |
| 174 | vec![] |
| 175 | }; |
| 176 | |
| 177 | conditions.push(GrantCondition::Temporal { |
| 178 | start_hour, |
| 179 | end_hour, |
| 180 | days, |
| 181 | }); |
| 182 | i += 7; |
| 183 | continue; |
| 184 | } |
| 185 | |
| 186 | if upper == "REQUIRE" && i + 1 < parts.len() { |
| 187 | let req = parts[i + 1].to_uppercase(); |
| 188 | match req.as_str() { |
| 189 | "MFA" => { |
| 190 | conditions.push(GrantCondition::RequireMfa); |
| 191 | i += 2; |
| 192 | } |
| 193 | "IP" => { |
| 194 | // REQUIRE IP IN ('cidr1', 'cidr2') |
| 195 | let cidrs: Vec<String> = parts[i + 3..] |
| 196 | .iter() |
| 197 | .take_while(|p| !p.starts_with(')')) |
| 198 | .map(|s| { |
| 199 | s.trim_matches('\'') |
| 200 | .trim_matches('(') |
| 201 | .trim_matches(')') |
| 202 | .trim_end_matches(',') |
| 203 | .to_string() |
| 204 | }) |
| 205 | .filter(|s| !s.is_empty() && s.to_uppercase() != "IN") |
| 206 | .collect(); |
| 207 | conditions.push(GrantCondition::RequireIp { |
| 208 | allowed_cidrs: cidrs, |