Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ pub fn build_cli(doc: &RestDescription) -> Command {
.action(clap::ArgAction::SetTrue)
.global(true),
)
.arg(
clap::Arg::new("draft-only")
.long("draft-only")
.help("Draft-only mode: strictly intercept and block any users.messages.send or users.drafts.send requests")
.action(clap::ArgAction::SetTrue)
.global(true),
)
.arg(
clap::Arg::new("format")
.long("format")
Expand Down
6 changes: 6 additions & 0 deletions src/helpers/gmail/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,12 @@ pub(super) async fn send_raw_email(
thread_id: Option<&str>,
existing_token: Option<&str>,
) -> Result<(), GwsError> {
if matches.get_flag("draft-only") {
return Err(GwsError::Validation(
"Draft-only mode is enabled. Sending emails is blocked.".to_string(),
));
}

let body = build_raw_send_body(raw_message, thread_id);
let body_str = body.to_string();

Expand Down
11 changes: 11 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,17 @@ async fn run() -> Result<(), GwsError> {

let dry_run = matched_args.get_flag("dry-run");

let draft_only = matches.get_flag("draft-only") || matched_args.get_flag("draft-only");
if draft_only {
if let Some(ref id) = method.id {
if id == "gmail.users.messages.send" || id == "gmail.users.drafts.send" {
return Err(GwsError::Validation(
"Draft-only mode is enabled. Sending emails is blocked.".to_string(),
));
}
}
}
Comment on lines +222 to +231
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This block implements the core logic for --draft-only mode, but it can be made more robust and maintainable.

  1. Redundant Flag Check: The draft-only flag is global, so checking matched_args.get_flag("draft-only") is sufficient. The current logic is inconsistent with how the dry-run flag is handled just above.

  2. Hardcoded Strings: The method IDs (gmail.users.messages.send, gmail.users.drafts.send) and the error message are hardcoded. For a critical safety feature, these should be defined as constants to prevent typos and improve maintainability.

  3. Duplicated Logic: The error message string is duplicated in src/helpers/gmail/mod.rs:584. Defining it as a constant would solve this.

I recommend creating shared constants for the method IDs and the error message, and simplifying the flag check. For example, you could define them in src/helpers/gmail/mod.rs and use them here.

Suggested change
let draft_only = matches.get_flag("draft-only") || matched_args.get_flag("draft-only");
if draft_only {
if let Some(ref id) = method.id {
if id == "gmail.users.messages.send" || id == "gmail.users.drafts.send" {
return Err(GwsError::Validation(
"Draft-only mode is enabled. Sending emails is blocked.".to_string(),
));
}
}
}
let draft_only = matched_args.get_flag("draft-only");
if draft_only {
if let Some(ref id) = method.id {
// It's recommended to define these strings as constants
// in a shared module (e.g. `src/helpers/gmail/mod.rs`)
// to avoid typos and duplication.
if id == "gmail.users.messages.send" || id == "gmail.users.drafts.send" {
return Err(GwsError::Validation(
"Draft-only mode is enabled. Sending emails is blocked.".to_string(),
));
}
}
}


// Build pagination config from flags
let pagination = parse_pagination_config(matched_args);

Expand Down
Loading