Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Add validation for workers names in wrangler init and wrangler generate #686

Merged
merged 5 commits into from
Sep 24, 2019
Merged
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: 5 additions & 2 deletions src/commands/generate.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
use crate::settings::target::{Manifest, Site, TargetType};
use crate::{commands, install};
use std::path::PathBuf;
use std::process::Command;

use crate::commands::validate_worker_name;
use crate::settings::target::{Manifest, Site, TargetType};
use crate::terminal::{emoji, message};
use crate::{commands, install};

pub fn generate(
name: &str,
template: &str,
target_type: Option<TargetType>,
site: bool,
) -> Result<(), failure::Error> {
validate_worker_name(name)?;

let target_type = target_type.unwrap_or_else(|| get_target_type(template));
run_generate(name, template, &target_type)?;
let config_path = PathBuf::from("./").join(&name);
Expand Down
6 changes: 5 additions & 1 deletion src/commands/init.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::path::{Path, PathBuf};

use crate::commands;
use crate::commands::validate_worker_name;
use crate::settings::target::{Manifest, Site, TargetType};
use crate::terminal::message;
use std::path::{Path, PathBuf};

pub fn init(
name: Option<&str>,
Expand All @@ -13,6 +15,8 @@ pub fn init(
}
let dirname = get_current_dirname()?;
let name = name.unwrap_or_else(|| &dirname);
validate_worker_name(name)?;

let target_type = target_type.unwrap_or_default();
let config_path = PathBuf::from("./");
let initialized_site = if site { Some(Site::default()) } else { None };
Expand Down
21 changes: 11 additions & 10 deletions src/commands/kv/namespace/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::commands::kv;
use crate::settings::global_user::GlobalUser;
use crate::settings::target::Target;
use crate::terminal::message;
use regex::Regex;

pub fn create(
target: &Target,
Expand All @@ -17,11 +18,7 @@ pub fn create(

let client = kv::api_client(user)?;

if !validate_binding(binding) {
failure::bail!(
"A binding can only have alphanumeric and _ characters, and cannot begin with a number"
);
}
validate_binding(binding)?;

let title = format!("{}-{}", target.name, binding);
let msg = format!("Creating namespace with title \"{}\"", title);
Expand Down Expand Up @@ -74,10 +71,14 @@ pub fn create(
Ok(())
}

fn validate_binding(binding: &str) -> bool {
use regex::Regex;
fn validate_binding(binding: &str) -> Result<(), failure::Error> {
let re = Regex::new(r"^[a-zA-Z_][a-zA-Z0-9_]*$").unwrap();
re.is_match(binding)
if !re.is_match(binding) {
failure::bail!(
"A binding can only have alphanumeric and _ characters, and cannot begin with a number"
)
}
Ok(())
}

#[cfg(test)]
Expand All @@ -88,15 +89,15 @@ mod tests {
fn it_can_detect_invalid_binding() {
let invalid_bindings = vec!["hi there", "1234"];
for binding in invalid_bindings {
assert!(!validate_binding(binding));
assert!(validate_binding(binding).is_err());
}
}

#[test]
fn it_can_detect_valid_binding() {
let valid_bindings = vec!["ONE", "TWO_TWO", "__private_variable", "rud3_var"];
for binding in valid_bindings {
assert!(validate_binding(binding));
assert!(validate_binding(binding).is_ok());
}
}
}
31 changes: 31 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub use init::init;
pub use publish::preview::preview;
pub use publish::preview::HTTPMethod;
pub use publish::publish;
use regex::Regex;
pub use subdomain::subdomain;
pub use whoami::whoami;

Expand All @@ -38,3 +39,33 @@ pub fn run(mut command: Command, command_name: &str) -> Result<(), failure::Erro
)
}
}

// Ensures that Worker name is valid.
pub fn validate_worker_name(name: &str) -> Result<(), failure::Error> {
let re = Regex::new(r"^[a-z0-9_][a-z0-9-_]*$").unwrap();
if !re.is_match(&name) {
failure::bail!("Worker name \"{}\" invalid. Ensure that you only use lowercase letters, dashes, underscores, and numbers.", name)
}
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_can_detect_invalid_worker_name() {
let invalid_names = vec!["mySite", "nicky.fun"];
for name in invalid_names {
assert!(validate_worker_name(name).is_err());
}
}

#[test]
fn it_can_detect_valid_worker_name() {
let valid_names = vec!["my-blog", "blog123", "bloggyity_blog"];
for name in valid_names {
assert!(validate_worker_name(name).is_ok());
}
}
}
6 changes: 4 additions & 2 deletions src/commands/publish/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::path::Path;
use crate::commands;
use crate::commands::kv;
use crate::commands::subdomain::Subdomain;
use crate::commands::validate_worker_name;
use crate::http;
use crate::settings::global_user::GlobalUser;

Expand All @@ -25,7 +26,8 @@ use crate::terminal::{emoji, message};
pub fn publish(user: &GlobalUser, target: &mut Target) -> Result<(), failure::Error> {
log::info!("workers_dev = {}", target.workers_dev);

validate_target(target)?;
validate_target_required_fields_present(target)?;
validate_worker_name(&target.name)?;

if let Some(site_config) = &target.site {
let site_namespace = kv::namespace::site(target, user)?;
Expand Down Expand Up @@ -129,7 +131,7 @@ fn publish_to_subdomain(target: &Target, user: &GlobalUser) -> Result<String, fa
Ok(format!("https://{}.{}.workers.dev", target.name, subdomain))
}

fn validate_target(target: &Target) -> Result<(), failure::Error> {
fn validate_target_required_fields_present(target: &Target) -> Result<(), failure::Error> {
let mut missing_fields = Vec::new();

if target.account_id.is_empty() {
Expand Down