-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Remove dependencies on nns governance crate from sns cli an…
…d ic-admin (#1252) Continuing to remove dependencies on nns governance crate to the end of making it have no bazel visibility as a dependency. --------- Co-authored-by: IDX GitHub Automation <infra+github-automation@dfinity.org>
- Loading branch information
1 parent
4cede51
commit 41f6ce3
Showing
34 changed files
with
707 additions
and
668 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
load("@rules_rust//rust:defs.bzl", "rust_library") | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
rust_library( | ||
name = "validation", | ||
srcs = glob(["src/**"]), | ||
crate_name = "ic_nervous_system_common_validation", | ||
version = "0.9.0", | ||
deps = [ | ||
# Keep sorted. | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "ic-nervous-system-common-validation" | ||
version.workspace = true | ||
authors.workspace = true | ||
edition.workspace = true | ||
description.workspace = true | ||
documentation.workspace = true | ||
|
||
[lib] | ||
path = "src/lib.rs" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/// Verifies that the url is within the allowed length, and begins with | ||
/// `http://` or `https://`. In addition, it will return an error in case of a | ||
/// possibly "dangerous" condition, such as the url containing a username or | ||
/// password, or having a port, or not having a domain name. | ||
pub fn validate_proposal_url( | ||
url: &str, | ||
min_length: usize, | ||
max_length: usize, | ||
field_name: &str, | ||
allowed_domains: Option<Vec<&str>>, | ||
) -> Result<(), String> { | ||
// // Check that the URL is a sensible length | ||
if url.len() > max_length { | ||
return Err(format!( | ||
"{field_name} must be less than {max_length} characters long, but it is {} characters long. (Field was set to `{url}`.)", | ||
url.len(), | ||
)); | ||
} | ||
if url.len() < min_length { | ||
return Err(format!( | ||
"{field_name} must be greater or equal to than {min_length} characters long, but it is {} characters long. (Field was set to `{url}`.)", | ||
url.len(), | ||
)); | ||
} | ||
|
||
// | ||
|
||
if !url.starts_with("https://") { | ||
return Err(format!( | ||
"{field_name} must begin with https://. (Field was set to `{url}`.)", | ||
)); | ||
} | ||
|
||
let parts_url: Vec<&str> = url.split("://").collect(); | ||
if parts_url.len() > 2 { | ||
return Err(format!( | ||
"{field_name} contains an invalid sequence of characters" | ||
)); | ||
} | ||
|
||
if parts_url.len() < 2 { | ||
return Err(format!("{field_name} is missing content after protocol.")); | ||
} | ||
|
||
if url.contains('@') { | ||
return Err(format!( | ||
"{field_name} cannot contain authentication information" | ||
)); | ||
} | ||
|
||
let parts_past_protocol = parts_url[1].split_once('/'); | ||
|
||
let (domain, _path) = match parts_past_protocol { | ||
Some((domain, path)) => (domain, Some(path)), | ||
None => (parts_url[1], None), | ||
}; | ||
|
||
match allowed_domains { | ||
Some(allowed) => match allowed.iter().any(|allowed| domain == *allowed) { | ||
true => Ok(()), | ||
false => Err(format!( | ||
"{field_name} was not in the list of allowed domains: {:?}", | ||
allowed | ||
)), | ||
}, | ||
None => Ok(()), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
pub mod bitcoin; | ||
pub mod pb; | ||
pub mod proposal_helpers; | ||
pub mod proposal_submission_helpers; | ||
pub mod proposal_validation; | ||
pub mod subnet_rental; | ||
pub mod test_api; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use crate::pb::v1::Proposal; | ||
|
||
// The limits on NNS proposal title len (in bytes). | ||
const PROPOSAL_TITLE_BYTES_MIN: usize = 5; | ||
const PROPOSAL_TITLE_BYTES_MAX: usize = 256; | ||
// Proposal validation | ||
// 30000 B | ||
const PROPOSAL_SUMMARY_BYTES_MAX: usize = 30000; | ||
// 2048 characters | ||
const PROPOSAL_URL_CHAR_MAX: usize = 2048; | ||
// 10 characters | ||
const PROPOSAL_URL_CHAR_MIN: usize = 10; | ||
|
||
/// Validates the user submitted proposal fields. | ||
pub fn validate_user_submitted_proposal_fields(proposal: &Proposal) -> Result<(), String> { | ||
validate_proposal_title(&proposal.title)?; | ||
validate_proposal_summary(&proposal.summary)?; | ||
validate_proposal_url(&proposal.url)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Returns whether the following requirements are met: | ||
/// 1. proposal must have a title. | ||
/// 2. title len (bytes, not characters) is between min and max. | ||
pub fn validate_proposal_title(title: &Option<String>) -> Result<(), String> { | ||
// Require that proposal has a title. | ||
let len = title.as_ref().ok_or("Proposal lacks a title")?.len(); | ||
|
||
// Require that title is not too short. | ||
if len < PROPOSAL_TITLE_BYTES_MIN { | ||
return Err(format!( | ||
"Proposal title is too short (must be at least {} bytes)", | ||
PROPOSAL_TITLE_BYTES_MIN, | ||
)); | ||
} | ||
|
||
// Require that title is not too long. | ||
if len > PROPOSAL_TITLE_BYTES_MAX { | ||
return Err(format!( | ||
"Proposal title is too long (can be at most {} bytes)", | ||
PROPOSAL_TITLE_BYTES_MAX, | ||
)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Returns whether the following requirements are met: | ||
/// 1. summary len (bytes, not characters) is below the max. | ||
pub fn validate_proposal_summary(summary: &str) -> Result<(), String> { | ||
if summary.len() > PROPOSAL_SUMMARY_BYTES_MAX { | ||
return Err(format!( | ||
"The maximum proposal summary size is {} bytes, this proposal is: {} bytes", | ||
PROPOSAL_SUMMARY_BYTES_MAX, | ||
summary.len(), | ||
)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Returns whether the following requirements are met: | ||
/// 1. If a url is provided, it is between the max and min | ||
/// 2. If a url is specified, it must be from the list of allowed domains. | ||
pub fn validate_proposal_url(url: &str) -> Result<(), String> { | ||
// An empty string will fail validation as it is not a valid url, | ||
// but it's fine for us. | ||
if !url.is_empty() { | ||
ic_nervous_system_common_validation::validate_proposal_url( | ||
url, | ||
PROPOSAL_URL_CHAR_MIN, | ||
PROPOSAL_URL_CHAR_MAX, | ||
"Proposal url", | ||
Some(vec!["forum.dfinity.org"]), | ||
)? | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.