1use crate::app::App;
2use crate::common::{CyclicEnum, InputFocus, PageSize};
3use crate::ui::iam::{
4 filtered_iam_policies, filtered_iam_roles, filtered_iam_users, filtered_last_accessed,
5 filtered_tags as filtered_iam_tags, filtered_user_tags, GroupTab, RoleTab, UserTab,
6 GROUP_FILTER_CONTROLS, HISTORY_FILTER, POLICY_FILTER_CONTROLS, POLICY_TYPE_DROPDOWN,
7 ROLE_FILTER_CONTROLS, USER_LAST_ACCESSED_FILTER_CONTROLS, USER_SIMPLE_FILTER_CONTROLS,
8};
9
10pub fn apply_filter_reset_users(app: &mut App) {
13 if app.iam_state.current_user.is_some() {
14 app.iam_state.user_tags.reset();
15 app.iam_state.policies.reset();
16 } else {
17 app.iam_state.users.reset();
18 }
19}
20
21pub fn apply_filter_reset_roles(app: &mut App) {
22 if app.iam_state.current_role.is_some() {
23 app.iam_state.tags.reset();
24 app.iam_state.policies.reset();
25 } else {
26 app.iam_state.roles.reset();
27 }
28}
29
30pub fn apply_filter_reset_groups(app: &mut App) {
31 if app.iam_state.current_group.is_some() {
32 app.iam_state.policies.reset();
33 app.iam_state.group_users.reset();
34 } else {
35 app.iam_state.groups.reset();
36 }
37}
38
39pub fn reset_on_service_select_roles(app: &mut App) {
40 app.iam_state.roles.reset();
41}
42
43pub fn reset_on_service_select_users(app: &mut App) {
44 app.iam_state.users.reset();
45}
46
47pub fn reset_on_service_select_groups(app: &mut App) {
48 app.iam_state.groups.reset();
49}
50
51pub fn next_filter_focus_roles(app: &mut App) {
54 if app.iam_state.current_role.is_some() {
55 app.iam_state.policy_input_focus = app
56 .iam_state
57 .policy_input_focus
58 .next(&POLICY_FILTER_CONTROLS);
59 } else {
60 app.iam_state.role_input_focus = app.iam_state.role_input_focus.next(&ROLE_FILTER_CONTROLS);
61 }
62}
63
64pub fn prev_filter_focus_roles(app: &mut App) {
65 if app.iam_state.current_role.is_some() {
66 app.iam_state.policy_input_focus = app
67 .iam_state
68 .policy_input_focus
69 .prev(&POLICY_FILTER_CONTROLS);
70 } else {
71 app.iam_state.role_input_focus = app.iam_state.role_input_focus.prev(&ROLE_FILTER_CONTROLS);
72 }
73}
74
75pub fn next_filter_focus_users(app: &mut App) {
76 if app.iam_state.user_tab == UserTab::Permissions {
77 app.iam_state.policy_input_focus = app
78 .iam_state
79 .policy_input_focus
80 .next(&POLICY_FILTER_CONTROLS);
81 } else if app.iam_state.user_tab == UserTab::LastAccessed {
82 app.iam_state.last_accessed_input_focus = app
83 .iam_state
84 .last_accessed_input_focus
85 .next(&USER_LAST_ACCESSED_FILTER_CONTROLS);
86 } else {
87 app.iam_state.user_input_focus = app
88 .iam_state
89 .user_input_focus
90 .next(&USER_SIMPLE_FILTER_CONTROLS);
91 }
92}
93
94pub fn prev_filter_focus_users(app: &mut App) {
95 if app.iam_state.user_tab == UserTab::Permissions {
96 app.iam_state.policy_input_focus = app
97 .iam_state
98 .policy_input_focus
99 .prev(&POLICY_FILTER_CONTROLS);
100 } else if app.iam_state.user_tab == UserTab::LastAccessed {
101 app.iam_state.last_accessed_input_focus = app
102 .iam_state
103 .last_accessed_input_focus
104 .prev(&USER_LAST_ACCESSED_FILTER_CONTROLS);
105 } else {
106 app.iam_state.user_input_focus = app
107 .iam_state
108 .user_input_focus
109 .prev(&USER_SIMPLE_FILTER_CONTROLS);
110 }
111}
112
113pub fn next_filter_focus_groups(app: &mut App) {
114 app.iam_state.group_input_focus = app.iam_state.group_input_focus.next(&GROUP_FILTER_CONTROLS);
115}
116
117pub fn prev_filter_focus_groups(app: &mut App) {
118 app.iam_state.group_input_focus = app.iam_state.group_input_focus.prev(&GROUP_FILTER_CONTROLS);
119}
120
121pub fn is_pagination_focused_roles(app: &App) -> bool {
122 app.iam_state.current_role.is_none() && app.iam_state.role_input_focus == InputFocus::Pagination
123}
124
125pub fn is_filter_focused_roles(app: &App) -> bool {
126 app.iam_state.current_role.is_none() && app.iam_state.role_input_focus == InputFocus::Filter
127}
128
129pub fn is_filter_focused_policy_view(app: &App) -> bool {
130 app.iam_state.policy_input_focus == InputFocus::Filter
131}
132
133pub fn is_pagination_focused_policy_view(app: &App) -> bool {
134 app.iam_state.policy_input_focus == InputFocus::Pagination
135}
136
137pub fn next_item_users(app: &mut App) {
140 if app.iam_state.current_user.is_some() {
141 if app.iam_state.user_tab == UserTab::Tags {
142 let filtered = filtered_user_tags(app);
143 if !filtered.is_empty() {
144 app.iam_state.user_tags.next_item(filtered.len());
145 }
146 } else {
147 let filtered = filtered_iam_policies(app);
148 if !filtered.is_empty() {
149 app.iam_state.policies.next_item(filtered.len());
150 }
151 }
152 } else {
153 let filtered = filtered_iam_users(app);
154 if !filtered.is_empty() {
155 app.iam_state.users.next_item(filtered.len());
156 }
157 }
158}
159
160pub fn next_item_roles(app: &mut App) {
161 if app.iam_state.current_role.is_some() {
162 match app.iam_state.role_tab {
163 RoleTab::TrustRelationships => {
164 let lines = app.iam_state.trust_policy_document.lines().count();
165 let max_scroll = lines.saturating_sub(1);
166 app.iam_state.trust_policy_scroll =
167 (app.iam_state.trust_policy_scroll + 1).min(max_scroll);
168 }
169 RoleTab::RevokeSessions => {
170 app.iam_state.revoke_sessions_scroll =
171 (app.iam_state.revoke_sessions_scroll + 1).min(19);
172 }
173 RoleTab::Tags => {
174 let filtered = filtered_iam_tags(app);
175 if !filtered.is_empty() {
176 app.iam_state.tags.next_item(filtered.len());
177 }
178 }
179 RoleTab::LastAccessed => {
180 let filtered = filtered_last_accessed(app);
181 if !filtered.is_empty() {
182 app.iam_state
183 .last_accessed_services
184 .next_item(filtered.len());
185 }
186 }
187 _ => {
188 let filtered = filtered_iam_policies(app);
189 if !filtered.is_empty() {
190 app.iam_state.policies.next_item(filtered.len());
191 }
192 }
193 }
194 } else {
195 let filtered = filtered_iam_roles(app);
196 if !filtered.is_empty() {
197 app.iam_state.roles.next_item(filtered.len());
198 }
199 }
200}
201
202pub fn next_item_groups(app: &mut App) {
203 if app.iam_state.current_group.is_some() {
204 match app.iam_state.group_tab {
205 GroupTab::Users => {
206 let filtered: Vec<_> = app
207 .iam_state
208 .group_users
209 .items
210 .iter()
211 .filter(|u| {
212 app.iam_state.group_users.filter.is_empty()
213 || u.user_name
214 .to_lowercase()
215 .contains(&app.iam_state.group_users.filter.to_lowercase())
216 })
217 .collect();
218 if !filtered.is_empty() {
219 app.iam_state.group_users.next_item(filtered.len());
220 }
221 }
222 GroupTab::Permissions => {
223 let filtered = filtered_iam_policies(app);
224 if !filtered.is_empty() {
225 app.iam_state.policies.next_item(filtered.len());
226 }
227 }
228 GroupTab::AccessAdvisor => {
229 let filtered = filtered_last_accessed(app);
230 if !filtered.is_empty() {
231 app.iam_state
232 .last_accessed_services
233 .next_item(filtered.len());
234 }
235 }
236 }
237 } else {
238 let filtered: Vec<_> = app
239 .iam_state
240 .groups
241 .items
242 .iter()
243 .filter(|g| {
244 app.iam_state.groups.filter.is_empty()
245 || g.group_name
246 .to_lowercase()
247 .contains(&app.iam_state.groups.filter.to_lowercase())
248 })
249 .collect();
250 if !filtered.is_empty() {
251 app.iam_state.groups.next_item(filtered.len());
252 }
253 }
254}
255
256pub fn prev_item_users(app: &mut App) {
257 app.iam_state.users.prev_item();
258}
259
260pub fn prev_item_roles(app: &mut App) {
261 if app.iam_state.current_role.is_some() {
262 match app.iam_state.role_tab {
263 RoleTab::TrustRelationships => {
264 app.iam_state.trust_policy_scroll =
265 app.iam_state.trust_policy_scroll.saturating_sub(1);
266 }
267 RoleTab::RevokeSessions => {
268 app.iam_state.revoke_sessions_scroll =
269 app.iam_state.revoke_sessions_scroll.saturating_sub(1);
270 }
271 RoleTab::Tags => app.iam_state.tags.prev_item(),
272 RoleTab::LastAccessed => app.iam_state.last_accessed_services.prev_item(),
273 _ => app.iam_state.policies.prev_item(),
274 }
275 } else {
276 app.iam_state.roles.prev_item();
277 }
278}
279
280pub fn prev_item_groups(app: &mut App) {
281 if app.iam_state.current_group.is_some() {
282 match app.iam_state.group_tab {
283 GroupTab::Users => app.iam_state.group_users.prev_item(),
284 GroupTab::Permissions => app.iam_state.policies.prev_item(),
285 GroupTab::AccessAdvisor => app.iam_state.last_accessed_services.prev_item(),
286 }
287 } else {
288 app.iam_state.groups.prev_item();
289 }
290}
291
292pub fn page_down_filter_input_roles(app: &mut App) {
293 let page_size = app.iam_state.roles.page_size.value();
294 let filtered_count = filtered_iam_roles(app).len();
295 app.iam_state.role_input_focus.handle_page_down(
296 &mut app.iam_state.roles.selected,
297 &mut app.iam_state.roles.scroll_offset,
298 page_size,
299 filtered_count,
300 );
301}
302
303pub fn page_down_filter_input_policy_view(app: &mut App) {
304 let page_size = app.iam_state.policies.page_size.value();
305 let filtered_count = filtered_iam_policies(app).len();
306 app.iam_state.policy_input_focus.handle_page_down(
307 &mut app.iam_state.policies.selected,
308 &mut app.iam_state.policies.scroll_offset,
309 page_size,
310 filtered_count,
311 );
312}
313
314pub fn page_down_normal_users(app: &mut App) {
315 let len = filtered_iam_users(app).len();
316 crate::app::nav_page_down(&mut app.iam_state.users.selected, len, 10);
317}
318
319pub fn page_down_normal_roles(app: &mut App) {
320 if app.iam_state.current_role.is_some() {
321 let filtered = filtered_iam_policies(app);
322 if !filtered.is_empty() {
323 app.iam_state.policies.page_down(filtered.len());
324 }
325 } else {
326 let filtered = filtered_iam_roles(app);
327 app.iam_state.roles.page_down(filtered.len());
328 }
329}
330
331pub fn page_down_normal_groups(app: &mut App) {
332 if app.iam_state.current_group.is_some() {
333 match app.iam_state.group_tab {
334 GroupTab::Users => {
335 let filtered: Vec<_> = app
336 .iam_state
337 .group_users
338 .items
339 .iter()
340 .filter(|u| {
341 app.iam_state.group_users.filter.is_empty()
342 || u.user_name
343 .to_lowercase()
344 .contains(&app.iam_state.group_users.filter.to_lowercase())
345 })
346 .collect();
347 if !filtered.is_empty() {
348 app.iam_state.group_users.page_down(filtered.len());
349 }
350 }
351 GroupTab::Permissions => {
352 let filtered = filtered_iam_policies(app);
353 if !filtered.is_empty() {
354 app.iam_state.policies.page_down(filtered.len());
355 }
356 }
357 GroupTab::AccessAdvisor => {
358 let filtered = filtered_last_accessed(app);
359 if !filtered.is_empty() {
360 app.iam_state
361 .last_accessed_services
362 .page_down(filtered.len());
363 }
364 }
365 }
366 } else {
367 let filtered: Vec<_> = app
368 .iam_state
369 .groups
370 .items
371 .iter()
372 .filter(|g| {
373 app.iam_state.groups.filter.is_empty()
374 || g.group_name
375 .to_lowercase()
376 .contains(&app.iam_state.groups.filter.to_lowercase())
377 })
378 .collect();
379 if !filtered.is_empty() {
380 app.iam_state.groups.page_down(filtered.len());
381 }
382 }
383}
384
385pub fn page_up_filter_input_roles(app: &mut App) {
386 let page_size = app.iam_state.roles.page_size.value();
387 app.iam_state.role_input_focus.handle_page_up(
388 &mut app.iam_state.roles.selected,
389 &mut app.iam_state.roles.scroll_offset,
390 page_size,
391 );
392}
393
394pub fn page_up_filter_input_policy_view(app: &mut App) {
395 let page_size = app.iam_state.policies.page_size.value();
396 app.iam_state.policy_input_focus.handle_page_up(
397 &mut app.iam_state.policies.selected,
398 &mut app.iam_state.policies.scroll_offset,
399 page_size,
400 );
401}
402
403pub fn page_up_normal_users(app: &mut App) {
404 app.iam_state.users.page_up();
405}
406
407pub fn page_up_normal_roles(app: &mut App) {
408 if app.iam_state.current_role.is_some() {
409 app.iam_state.policies.page_up();
410 } else {
411 app.iam_state.roles.page_up();
412 }
413}
414
415pub fn go_to_page_users(app: &mut App, page: usize) {
416 let filtered_count = filtered_iam_users(app).len();
417 app.iam_state.users.goto_page(page, filtered_count);
418}
419
420pub fn go_to_page_roles(app: &mut App, page: usize) {
421 let filtered_count = filtered_iam_roles(app).len();
422 app.iam_state.roles.goto_page(page, filtered_count);
423}
424
425pub fn scroll_up_policy_view(app: &mut App) {
426 app.iam_state.policy_scroll = app.iam_state.policy_scroll.saturating_sub(10);
427}
428
429pub fn scroll_down_policy_view(app: &mut App) {
430 let lines = app.iam_state.policy_document.lines().count();
431 let max_scroll = lines.saturating_sub(1);
432 app.iam_state.policy_scroll = (app.iam_state.policy_scroll + 10).min(max_scroll);
433}
434
435pub fn scroll_up_trust_policy(app: &mut App) {
436 app.iam_state.trust_policy_scroll = app.iam_state.trust_policy_scroll.saturating_sub(10);
437}
438
439pub fn scroll_down_trust_policy(app: &mut App) {
440 let lines = app.iam_state.trust_policy_document.lines().count();
441 let max_scroll = lines.saturating_sub(1);
442 app.iam_state.trust_policy_scroll = (app.iam_state.trust_policy_scroll + 10).min(max_scroll);
443}
444
445pub fn scroll_up_revoke_sessions(app: &mut App) {
446 app.iam_state.revoke_sessions_scroll = app.iam_state.revoke_sessions_scroll.saturating_sub(10);
447}
448
449pub fn scroll_down_revoke_sessions(app: &mut App) {
450 app.iam_state.revoke_sessions_scroll = (app.iam_state.revoke_sessions_scroll + 10).min(19);
451}
452
453pub fn scroll_down_policy_view_one(app: &mut App) {
454 let lines = app.iam_state.policy_document.lines().count();
455 let max_scroll = lines.saturating_sub(1);
456 app.iam_state.policy_scroll = (app.iam_state.policy_scroll + 1).min(max_scroll);
457}
458
459pub fn scroll_up_policy_view_one(app: &mut App) {
460 app.iam_state.policy_scroll = app.iam_state.policy_scroll.saturating_sub(1);
461}
462
463pub fn next_item_filter_input_users(app: &mut App) {
466 if app.iam_state.user_tab == UserTab::Permissions
467 && app.iam_state.policy_input_focus == POLICY_TYPE_DROPDOWN
468 {
469 cycle_policy_type_next(app);
470 } else if app.iam_state.user_tab == UserTab::LastAccessed
471 && app.iam_state.last_accessed_input_focus == HISTORY_FILTER
472 {
473 app.iam_state.last_accessed_history_filter =
474 app.iam_state.last_accessed_history_filter.next();
475 app.iam_state.last_accessed_services.reset();
476 }
477}
478
479pub fn prev_item_filter_input_users(app: &mut App) {
480 if app.iam_state.user_tab == UserTab::Permissions
481 && app.iam_state.policy_input_focus == POLICY_TYPE_DROPDOWN
482 {
483 cycle_policy_type_prev(app);
484 } else if app.iam_state.user_tab == UserTab::LastAccessed
485 && app.iam_state.last_accessed_input_focus == HISTORY_FILTER
486 {
487 app.iam_state.last_accessed_history_filter =
488 app.iam_state.last_accessed_history_filter.prev();
489 app.iam_state.last_accessed_services.reset();
490 }
491}
492
493pub fn next_item_filter_input_roles(app: &mut App) {
494 if app.iam_state.role_tab == RoleTab::Permissions
495 && app.iam_state.policy_input_focus == POLICY_TYPE_DROPDOWN
496 {
497 cycle_policy_type_next(app);
498 }
499}
500
501pub fn prev_item_filter_input_roles(app: &mut App) {
502 if app.iam_state.role_tab == RoleTab::Permissions
503 && app.iam_state.policy_input_focus == POLICY_TYPE_DROPDOWN
504 {
505 cycle_policy_type_prev(app);
506 }
507}
508
509fn cycle_policy_type_next(app: &mut App) {
510 let types = ["All types", "AWS managed", "Customer managed"];
511 let current_idx = types
512 .iter()
513 .position(|&t| t == app.iam_state.policy_type_filter)
514 .unwrap_or(0);
515 app.iam_state.policy_type_filter = types[(current_idx + 1) % types.len()].to_string();
516 app.iam_state.policies.reset();
517}
518
519fn cycle_policy_type_prev(app: &mut App) {
520 let types = ["All types", "AWS managed", "Customer managed"];
521 let current_idx = types
522 .iter()
523 .position(|&t| t == app.iam_state.policy_type_filter)
524 .unwrap_or(0);
525 let prev_idx = if current_idx == 0 {
526 types.len() - 1
527 } else {
528 current_idx - 1
529 };
530 app.iam_state.policy_type_filter = types[prev_idx].to_string();
531 app.iam_state.policies.reset();
532}
533
534pub fn expand_row_users(app: &mut App) {
537 if app.iam_state.current_user.is_some() {
538 if app.iam_state.user_tab == UserTab::Tags {
539 if app.iam_state.user_tags.expanded_item != Some(app.iam_state.user_tags.selected) {
540 app.iam_state.user_tags.expanded_item = Some(app.iam_state.user_tags.selected);
541 }
542 } else if app.iam_state.policies.expanded_item != Some(app.iam_state.policies.selected) {
543 app.iam_state.policies.toggle_expand();
544 }
545 } else if !app.iam_state.users.is_expanded() {
546 app.iam_state.users.toggle_expand();
547 }
548}
549
550pub fn expand_row_roles(app: &mut App) {
551 if app.iam_state.current_role.is_some() {
552 match app.iam_state.role_tab {
553 RoleTab::Tags => {
554 if !app.iam_state.tags.is_expanded() {
555 app.iam_state.tags.expand();
556 }
557 }
558 RoleTab::LastAccessed => {
559 if !app.iam_state.last_accessed_services.is_expanded() {
560 app.iam_state.last_accessed_services.expand();
561 }
562 }
563 _ => {
564 if !app.iam_state.policies.is_expanded() {
565 app.iam_state.policies.expand();
566 }
567 }
568 }
569 } else if !app.iam_state.roles.is_expanded() {
570 app.iam_state.roles.expand();
571 }
572}
573
574pub fn expand_row_groups(app: &mut App) {
575 if app.iam_state.current_group.is_some() {
576 match app.iam_state.group_tab {
577 GroupTab::Users => {
578 if !app.iam_state.group_users.is_expanded() {
579 app.iam_state.group_users.expand();
580 }
581 }
582 GroupTab::Permissions => {
583 if !app.iam_state.policies.is_expanded() {
584 app.iam_state.policies.expand();
585 }
586 }
587 GroupTab::AccessAdvisor => {
588 if !app.iam_state.last_accessed_services.is_expanded() {
589 app.iam_state.last_accessed_services.expand();
590 }
591 }
592 }
593 } else if !app.iam_state.groups.is_expanded() {
594 app.iam_state.groups.expand();
595 }
596}
597
598pub fn prev_pane_users(app: &mut App) {
599 if app.iam_state.users.has_expanded_item() {
600 app.iam_state.users.collapse();
601 }
602}
603
604pub fn prev_pane_roles(app: &mut App) {
605 if app.iam_state.current_role.is_some() {
606 if app.iam_state.role_tab == RoleTab::Tags && app.iam_state.tags.has_expanded_item() {
607 app.iam_state.tags.collapse();
608 } else if app.iam_state.role_tab == RoleTab::LastAccessed
609 && app.iam_state.last_accessed_services.expanded_item.is_some()
610 {
611 app.iam_state.last_accessed_services.collapse();
612 } else if app.iam_state.policies.has_expanded_item() {
613 app.iam_state.policies.collapse();
614 }
615 } else if app.iam_state.roles.has_expanded_item() {
616 app.iam_state.roles.collapse();
617 }
618}
619
620pub fn prev_pane_groups(app: &mut App) {
621 if app.iam_state.current_group.is_some() {
622 if app.iam_state.group_tab == GroupTab::Users
623 && app.iam_state.group_users.has_expanded_item()
624 {
625 app.iam_state.group_users.collapse();
626 } else if app.iam_state.group_tab == GroupTab::Permissions
627 && app.iam_state.policies.has_expanded_item()
628 {
629 app.iam_state.policies.collapse();
630 } else if app.iam_state.group_tab == GroupTab::AccessAdvisor
631 && app.iam_state.last_accessed_services.expanded_item.is_some()
632 {
633 app.iam_state.last_accessed_services.collapse();
634 }
635 } else if app.iam_state.groups.has_expanded_item() {
636 app.iam_state.groups.collapse();
637 }
638}
639
640pub fn collapse_row_users(app: &mut App) {
641 if app.iam_state.current_user.is_some() {
642 match app.iam_state.user_tab {
643 UserTab::Permissions => app.iam_state.policies.collapse(),
644 UserTab::Groups => app.iam_state.user_group_memberships.collapse(),
645 UserTab::Tags => app.iam_state.user_tags.collapse(),
646 _ => {}
647 }
648 } else {
649 app.iam_state.users.collapse();
650 }
651}
652
653pub fn collapse_row_roles(app: &mut App) {
654 if app.iam_state.current_role.is_some() {
655 match app.iam_state.role_tab {
656 RoleTab::Permissions => app.iam_state.policies.collapse(),
657 RoleTab::Tags => app.iam_state.tags.collapse(),
658 _ => {}
659 }
660 } else {
661 app.iam_state.roles.collapse();
662 }
663}
664
665pub fn collapse_row_groups(app: &mut App) {
666 app.iam_state.groups.collapse();
667}
668
669pub fn go_back_users(app: &mut App) {
672 app.iam_state.current_user = None;
673 app.iam_state.policies.items.clear();
674 app.iam_state.policies.reset();
675 app.update_current_tab_breadcrumb();
676}
677
678pub fn go_back_groups(app: &mut App) {
679 app.iam_state.current_group = None;
680 app.update_current_tab_breadcrumb();
681}
682
683pub fn go_back_roles(app: &mut App) {
684 if app.view_mode == crate::app::ViewMode::PolicyView {
685 app.view_mode = crate::app::ViewMode::Detail;
686 app.iam_state.current_policy = None;
687 app.iam_state.policy_document.clear();
688 app.iam_state.policy_scroll = 0;
689 app.update_current_tab_breadcrumb();
690 } else if app.iam_state.current_role.is_some() {
691 app.iam_state.current_role = None;
692 app.iam_state.policies.items.clear();
693 app.iam_state.policies.reset();
694 app.update_current_tab_breadcrumb();
695 }
696}
697
698pub fn next_detail_tab_roles(app: &mut App) {
701 app.iam_state.role_tab = app.iam_state.role_tab.next();
702 if app.iam_state.role_tab == RoleTab::Tags {
703 app.iam_state.tags.loading = true;
704 }
705}
706
707pub fn prev_detail_tab_roles(app: &mut App) {
708 app.iam_state.role_tab = app.iam_state.role_tab.prev();
709}
710
711pub fn next_detail_tab_users(app: &mut App) {
712 app.iam_state.user_tab = app.iam_state.user_tab.next();
713 if app.iam_state.user_tab == UserTab::Tags {
714 app.iam_state.user_tags.loading = true;
715 }
716}
717
718pub fn prev_detail_tab_users(app: &mut App) {
719 app.iam_state.user_tab = app.iam_state.user_tab.prev();
720}
721
722pub fn next_detail_tab_groups(app: &mut App) {
723 app.iam_state.group_tab = app.iam_state.group_tab.next();
724}
725
726pub fn prev_detail_tab_groups(app: &mut App) {
727 app.iam_state.group_tab = app.iam_state.group_tab.prev();
728}
729
730pub fn select_item_users(app: &mut App) {
733 if app.iam_state.current_user.is_some() {
734 if app.iam_state.user_tab == UserTab::Permissions {
735 let filtered = filtered_iam_policies(app);
736 if let Some(policy) = app.iam_state.policies.get_selected(&filtered) {
737 app.iam_state.current_policy = Some(policy.policy_name.clone());
738 app.iam_state.policy_scroll = 0;
739 app.view_mode = crate::app::ViewMode::PolicyView;
740 app.iam_state.policies.loading = true;
741 app.update_current_tab_breadcrumb();
742 }
743 }
744 } else {
745 let filtered = filtered_iam_users(app);
746 if let Some(user) = app.iam_state.users.get_selected(&filtered) {
747 app.iam_state.current_user = Some(user.user_name.clone());
748 app.iam_state.user_tab = UserTab::Permissions;
749 app.iam_state.policies.reset();
750 app.update_current_tab_breadcrumb();
751 }
752 }
753}
754
755pub fn select_item_roles(app: &mut App) {
756 if app.iam_state.current_role.is_some() {
757 if app.iam_state.role_tab == RoleTab::Permissions {
758 let filtered = filtered_iam_policies(app);
759 if let Some(policy) = app.iam_state.policies.get_selected(&filtered) {
760 app.iam_state.current_policy = Some(policy.policy_name.clone());
761 app.iam_state.policy_scroll = 0;
762 app.view_mode = crate::app::ViewMode::PolicyView;
763 app.iam_state.policies.loading = true;
764 app.update_current_tab_breadcrumb();
765 }
766 }
767 } else {
768 let filtered = filtered_iam_roles(app);
769 if let Some(role) = app.iam_state.roles.get_selected(&filtered) {
770 app.iam_state.current_role = Some(role.role_name.clone());
771 app.iam_state.role_tab = RoleTab::Permissions;
772 app.iam_state.policies.reset();
773 app.update_current_tab_breadcrumb();
774 }
775 }
776}
777
778pub fn select_item_groups(app: &mut App) {
779 if app.iam_state.current_group.is_none() {
780 let filtered: Vec<_> = app
781 .iam_state
782 .groups
783 .items
784 .iter()
785 .filter(|g| {
786 app.iam_state.groups.filter.is_empty()
787 || g.group_name
788 .to_lowercase()
789 .contains(&app.iam_state.groups.filter.to_lowercase())
790 })
791 .collect();
792 if let Some(group) = app.iam_state.groups.get_selected(&filtered) {
793 app.iam_state.current_group = Some(group.group_name.clone());
794 app.update_current_tab_breadcrumb();
795 }
796 }
797}
798
799pub fn yank_users(app: &App) {
802 use crate::app::copy_to_clipboard;
803 if app.iam_state.current_user.is_some() {
804 if let Some(user_name) = &app.iam_state.current_user {
805 if let Some(user) = app
806 .iam_state
807 .users
808 .items
809 .iter()
810 .find(|u| u.user_name == *user_name)
811 {
812 copy_to_clipboard(&user.arn);
813 }
814 }
815 } else {
816 let filtered = filtered_iam_users(app);
817 if let Some(user) = app.iam_state.users.get_selected(&filtered) {
818 copy_to_clipboard(&user.arn);
819 }
820 }
821}
822
823pub fn yank_roles(app: &App) {
824 use crate::app::copy_to_clipboard;
825 if app.iam_state.current_role.is_some() {
826 if let Some(role_name) = &app.iam_state.current_role {
827 if let Some(role) = app
828 .iam_state
829 .roles
830 .items
831 .iter()
832 .find(|r| r.role_name == *role_name)
833 {
834 copy_to_clipboard(&role.arn);
835 }
836 }
837 } else {
838 let filtered = filtered_iam_roles(app);
839 if let Some(role) = app.iam_state.roles.get_selected(&filtered) {
840 copy_to_clipboard(&role.arn);
841 }
842 }
843}
844
845pub fn yank_groups(app: &App) {
846 use crate::app::copy_to_clipboard;
847 use crate::iam;
848 if let Some(group_name) = &app.iam_state.current_group {
849 let arn = iam::format_arn(&app.config.account_id, "group", group_name);
850 copy_to_clipboard(&arn);
851 } else {
852 let filtered: Vec<_> = app
853 .iam_state
854 .groups
855 .items
856 .iter()
857 .filter(|g| {
858 app.iam_state.groups.filter.is_empty()
859 || g.group_name
860 .to_lowercase()
861 .contains(&app.iam_state.groups.filter.to_lowercase())
862 })
863 .collect();
864 if let Some(group) = app.iam_state.groups.get_selected(&filtered) {
865 let arn = iam::format_arn(&app.config.account_id, "group", &group.group_name);
866 copy_to_clipboard(&arn);
867 }
868 }
869}
870
871pub fn toggle_column_users(app: &mut App) {
874 use crate::app::{toggle_iam_page_size_only, toggle_iam_preference_static};
875 let idx = app.column_selector_index;
876 if app.iam_state.current_user.is_some() {
877 match app.iam_state.user_tab {
878 UserTab::Permissions => {
879 if idx > 0 && idx <= app.iam_policy_column_ids.len() {
880 if let Some(col) = app.iam_policy_column_ids.get(idx - 1) {
881 if let Some(pos) = app
882 .iam_policy_visible_column_ids
883 .iter()
884 .position(|c| c == col)
885 {
886 app.iam_policy_visible_column_ids.remove(pos);
887 } else {
888 app.iam_policy_visible_column_ids.push(col.clone());
889 }
890 }
891 } else if idx == app.iam_policy_column_ids.len() + 3 {
892 app.iam_state.policies.page_size = PageSize::Ten;
893 } else if idx == app.iam_policy_column_ids.len() + 4 {
894 app.iam_state.policies.page_size = PageSize::TwentyFive;
895 } else if idx == app.iam_policy_column_ids.len() + 5 {
896 app.iam_state.policies.page_size = PageSize::Fifty;
897 }
898 }
899 UserTab::Groups => toggle_iam_page_size_only(
900 idx,
901 5,
902 &mut app.iam_state.user_group_memberships.page_size,
903 ),
904 UserTab::Tags => {
905 toggle_iam_page_size_only(idx, 5, &mut app.iam_state.user_tags.page_size)
906 }
907 UserTab::LastAccessed => toggle_iam_page_size_only(
908 idx,
909 6,
910 &mut app.iam_state.last_accessed_services.page_size,
911 ),
912 _ => {}
913 }
914 } else {
915 toggle_iam_preference_static(
916 idx,
917 &app.iam_user_column_ids.clone(),
918 &mut app.iam_user_visible_column_ids,
919 &mut app.iam_state.users.page_size,
920 );
921 }
922}
923
924pub fn toggle_column_roles(app: &mut App) {
925 use crate::app::{
926 toggle_iam_page_size_only, toggle_iam_preference, toggle_iam_preference_static,
927 };
928 let idx = app.column_selector_index;
929 if app.iam_state.current_role.is_some() {
930 match app.iam_state.role_tab {
931 RoleTab::Permissions => toggle_iam_preference(
932 idx,
933 &app.iam_policy_column_ids.clone(),
934 &mut app.iam_policy_visible_column_ids,
935 &mut app.iam_state.policies.page_size,
936 ),
937 RoleTab::LastAccessed => toggle_iam_page_size_only(
938 idx,
939 6,
940 &mut app.iam_state.last_accessed_services.page_size,
941 ),
942 _ => {}
943 }
944 } else {
945 toggle_iam_preference_static(
946 idx,
947 &app.iam_role_column_ids.clone(),
948 &mut app.iam_role_visible_column_ids,
949 &mut app.iam_state.roles.page_size,
950 );
951 }
952}
953
954pub fn toggle_column_groups(app: &mut App) {
955 use crate::app::toggle_iam_preference;
956 toggle_iam_preference(
957 app.column_selector_index,
958 &app.iam_group_column_ids.clone(),
959 &mut app.iam_group_visible_column_ids,
960 &mut app.iam_state.groups.page_size,
961 );
962}
963
964pub fn next_preferences_users(app: &mut App) {
967 if app.iam_state.current_user.is_some() {
968 match app.iam_state.user_tab {
969 UserTab::Permissions => {
970 let page_size_idx = app.iam_policy_column_ids.len() + 2;
971 if app.column_selector_index < page_size_idx {
972 app.column_selector_index = page_size_idx;
973 } else {
974 app.column_selector_index = 0;
975 }
976 }
977 UserTab::Groups | UserTab::Tags => {
978 if app.column_selector_index < 4 {
979 app.column_selector_index = 4;
980 } else {
981 app.column_selector_index = 0;
982 }
983 }
984 UserTab::LastAccessed => {
985 if app.column_selector_index < 5 {
986 app.column_selector_index = 5;
987 } else {
988 app.column_selector_index = 0;
989 }
990 }
991 _ => {}
992 }
993 } else {
994 let page_size_idx = app.iam_user_column_ids.len() + 2;
995 if app.column_selector_index < page_size_idx {
996 app.column_selector_index = page_size_idx;
997 } else {
998 app.column_selector_index = 0;
999 }
1000 }
1001}
1002
1003pub fn prev_preferences_users(app: &mut App) {
1004 if app.iam_state.current_user.is_some() {
1005 match app.iam_state.user_tab {
1006 UserTab::Permissions => {
1007 let page_size_idx = app.iam_policy_column_ids.len() + 2;
1008 if app.column_selector_index >= page_size_idx {
1009 app.column_selector_index = 0;
1010 } else {
1011 app.column_selector_index = page_size_idx;
1012 }
1013 }
1014 UserTab::Groups | UserTab::Tags => {
1015 if app.column_selector_index >= 4 {
1016 app.column_selector_index = 0;
1017 } else {
1018 app.column_selector_index = 4;
1019 }
1020 }
1021 UserTab::LastAccessed => {
1022 if app.column_selector_index >= 5 {
1023 app.column_selector_index = 0;
1024 } else {
1025 app.column_selector_index = 5;
1026 }
1027 }
1028 _ => {}
1029 }
1030 } else {
1031 let page_size_idx = app.iam_user_column_ids.len() + 2;
1032 if app.column_selector_index >= page_size_idx {
1033 app.column_selector_index = 0;
1034 } else {
1035 app.column_selector_index = page_size_idx;
1036 }
1037 }
1038}
1039
1040pub fn next_preferences_roles(app: &mut App) {
1041 if app.iam_state.current_role.is_some() {
1042 match app.iam_state.role_tab {
1043 RoleTab::Permissions => {
1044 let page_size_idx = app.iam_policy_column_ids.len() + 2;
1045 if app.column_selector_index < page_size_idx {
1046 app.column_selector_index = page_size_idx;
1047 } else {
1048 app.column_selector_index = 0;
1049 }
1050 }
1051 RoleTab::Tags => {
1052 if app.column_selector_index < 4 {
1053 app.column_selector_index = 4;
1054 } else {
1055 app.column_selector_index = 0;
1056 }
1057 }
1058 RoleTab::LastAccessed => {
1059 if app.column_selector_index < 5 {
1060 app.column_selector_index = 5;
1061 } else {
1062 app.column_selector_index = 0;
1063 }
1064 }
1065 _ => {}
1066 }
1067 } else {
1068 let page_size_idx = app.iam_role_column_ids.len() + 2;
1069 if app.column_selector_index < page_size_idx {
1070 app.column_selector_index = page_size_idx;
1071 } else {
1072 app.column_selector_index = 0;
1073 }
1074 }
1075}
1076
1077pub fn prev_preferences_roles(app: &mut App) {
1078 if app.iam_state.current_role.is_some() {
1079 match app.iam_state.role_tab {
1080 RoleTab::Permissions => {
1081 let page_size_idx = app.iam_policy_column_ids.len() + 2;
1082 if app.column_selector_index >= page_size_idx {
1083 app.column_selector_index = 0;
1084 } else {
1085 app.column_selector_index = page_size_idx;
1086 }
1087 }
1088 RoleTab::Tags => {
1089 if app.column_selector_index >= 4 {
1090 app.column_selector_index = 0;
1091 } else {
1092 app.column_selector_index = 4;
1093 }
1094 }
1095 RoleTab::LastAccessed => {
1096 if app.column_selector_index >= 5 {
1097 app.column_selector_index = 0;
1098 } else {
1099 app.column_selector_index = 5;
1100 }
1101 }
1102 _ => {}
1103 }
1104 } else {
1105 let page_size_idx = app.iam_role_column_ids.len() + 2;
1106 if app.column_selector_index >= page_size_idx {
1107 app.column_selector_index = 0;
1108 } else {
1109 app.column_selector_index = page_size_idx;
1110 }
1111 }
1112}
1113
1114pub fn next_preferences_groups(app: &mut App) {
1115 let page_size_idx = app.iam_group_column_ids.len() + 2;
1116 if app.column_selector_index < page_size_idx {
1117 app.column_selector_index = page_size_idx;
1118 } else {
1119 app.column_selector_index = 0;
1120 }
1121}
1122
1123pub fn prev_preferences_groups(app: &mut App) {
1124 let page_size_idx = app.iam_group_column_ids.len() + 2;
1125 if app.column_selector_index >= page_size_idx {
1126 app.column_selector_index = 0;
1127 } else {
1128 app.column_selector_index = page_size_idx;
1129 }
1130}
1131
1132pub fn column_selector_max_users(app: &App) -> usize {
1133 if app.iam_state.current_user.is_some() {
1134 app.iam_policy_column_ids.len() + 5
1135 } else {
1136 app.iam_user_column_ids.len() + 5
1137 }
1138}
1139
1140pub fn column_count_users(app: &App) -> usize {
1141 if app.iam_state.current_user.is_some() {
1142 app.iam_policy_column_ids.len()
1143 } else {
1144 app.iam_user_column_ids.len()
1145 }
1146}
1147
1148pub fn column_selector_max_roles(app: &App) -> usize {
1149 if app.iam_state.current_role.is_some() {
1150 app.iam_policy_column_ids.len() + 5
1151 } else {
1152 app.iam_role_column_ids.len() + 5
1153 }
1154}
1155
1156pub fn column_count_roles(app: &App) -> usize {
1157 if app.iam_state.current_role.is_some() {
1158 app.iam_policy_column_ids.len()
1159 } else {
1160 app.iam_role_column_ids.len()
1161 }
1162}
1163
1164pub fn column_selector_max_groups(app: &App) -> usize {
1165 app.iam_group_column_ids.len() + 5
1166}
1167
1168pub fn column_count_groups(app: &App) -> usize {
1169 app.iam_group_column_ids.len()
1170}
1171
1172pub fn breadcrumb_users() -> Vec<String> {
1175 vec!["IAM".to_string(), "Users".to_string()]
1176}
1177
1178pub fn breadcrumb_roles(app: &App) -> Vec<String> {
1179 let mut parts = vec!["IAM".to_string(), "Roles".to_string()];
1180 if let Some(role_name) = &app.iam_state.current_role {
1181 parts.push(role_name.clone());
1182 if let Some(policy_name) = &app.iam_state.current_policy {
1183 parts.push(policy_name.clone());
1184 }
1185 }
1186 parts
1187}
1188
1189pub fn breadcrumb_groups(app: &App) -> Vec<String> {
1190 let mut parts = vec!["IAM".to_string(), "User Groups".to_string()];
1191 if let Some(group_name) = &app.iam_state.current_group {
1192 parts.push(group_name.clone());
1193 }
1194 parts
1195}
1196
1197pub fn console_url_users(app: &App) -> String {
1198 use crate::iam;
1199 if let Some(user_name) = &app.iam_state.current_user {
1200 let section = match app.iam_state.user_tab {
1201 UserTab::Permissions => "permissions",
1202 UserTab::Groups => "groups",
1203 UserTab::Tags => "tags",
1204 UserTab::SecurityCredentials => "security_credentials",
1205 UserTab::LastAccessed => "access_advisor",
1206 };
1207 iam::console_url_user_detail(&app.config.region, user_name, section)
1208 } else {
1209 iam::console_url_users(&app.config.region)
1210 }
1211}
1212
1213pub fn console_url_roles(app: &App) -> String {
1214 use crate::iam;
1215 if let Some(policy_name) = &app.iam_state.current_policy {
1216 if let Some(role_name) = &app.iam_state.current_role {
1217 return iam::console_url_role_policy(&app.config.region, role_name, policy_name);
1218 }
1219 }
1220 if let Some(role_name) = &app.iam_state.current_role {
1221 let section = match app.iam_state.role_tab {
1222 RoleTab::Permissions => "permissions",
1223 RoleTab::TrustRelationships => "trust_relationships",
1224 RoleTab::Tags => "tags",
1225 RoleTab::LastAccessed => "access_advisor",
1226 RoleTab::RevokeSessions => "revoke_sessions",
1227 };
1228 iam::console_url_role_detail(&app.config.region, role_name, section)
1229 } else {
1230 iam::console_url_roles(&app.config.region)
1231 }
1232}
1233
1234pub fn console_url_groups(app: &App) -> String {
1235 use crate::iam;
1236 iam::console_url_groups(&app.config.region)
1237}