Skip to content

Commit

Permalink
Allow filtering targets
Browse files Browse the repository at this point in the history
  • Loading branch information
kpcyrd committed Nov 10, 2018
1 parent 049a276 commit e40f19e
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ pub mod select_cmd;
pub mod mod_cmd;
pub mod noscope_cmd;
pub mod scope_cmd;
pub mod target_cmd;
pub mod quickstart_cmd;
19 changes: 10 additions & 9 deletions src/cmd/run_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use errors::*;

use db::Database;
use db::{Database, Filter};
use sn0int_common::metadata::Source;
use serde::Serialize;
use serde_json;
Expand All @@ -21,10 +21,9 @@ fn prepare_arg<T: Serialize + Model>(x: T) -> Result<(serde_json::Value, Option<
Ok((arg, Some(pretty)))
}

fn prepare_args<T: Scopable + Serialize + Model>(db: &Database) -> Result<Vec<(serde_json::Value, Option<String>)>> {
db.list::<T>()?
fn prepare_args<T: Scopable + Serialize + Model>(db: &Database, filter: &Filter) -> Result<Vec<(serde_json::Value, Option<String>)>> {
db.filter::<T>(filter)?
.into_iter()
.filter(|x| x.scoped())
.map(prepare_arg)
.collect()
}
Expand All @@ -34,12 +33,14 @@ pub fn execute(rl: &mut Readline) -> Result<()> {
.map(|m| m.to_owned())
.ok_or_else(|| format_err!("No module selected"))?;

let filter = rl.scoped_targets();

let args = match module.source() {
Some(Source::Domains) => prepare_args::<Domain>(rl.db()),
Some(Source::Subdomains) => prepare_args::<Subdomain>(rl.db()),
Some(Source::IpAddrs) => prepare_args::<IpAddr>(rl.db()),
Some(Source::Urls) => prepare_args::<Url>(rl.db()),
Some(Source::Emails) => prepare_args::<Email>(rl.db()),
Some(Source::Domains) => prepare_args::<Domain>(rl.db(), &filter),
Some(Source::Subdomains) => prepare_args::<Subdomain>(rl.db(), &filter),
Some(Source::IpAddrs) => prepare_args::<IpAddr>(rl.db(), &filter),
Some(Source::Urls) => prepare_args::<Url>(rl.db(), &filter),
Some(Source::Emails) => prepare_args::<Email>(rl.db(), &filter),
None => Ok(vec![(serde_json::Value::Null, None)]),
};

Expand Down
51 changes: 51 additions & 0 deletions src/cmd/target_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use errors::*;

use db;
use shell::Readline;
use sn0int_common::metadata::Source;
use structopt::StructOpt;
use models::*;


#[derive(Debug, StructOpt)]
pub struct Args {
// TODO: target -p # print current filter
// TODO: target -c # clear filter

filter: Vec<String>,
}

pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
let args = Args::from_iter_safe(args)?;

let source = rl.module()
.ok_or_else(|| format_err!("No module selected"))
.map(|x| x.source().clone())?;

if args.filter.is_empty() {
match source {
Some(Source::Domains) => select::<Domain>(rl)?,
Some(Source::Subdomains) => select::<Subdomain>(rl)?,
Some(Source::IpAddrs) => select::<IpAddr>(rl)?,
Some(Source::Urls) => select::<Url>(rl)?,
Some(Source::Emails) => select::<Email>(rl)?,
None => bail!("Module doesn't have sources"),
}
} else {
debug!("Setting filter to {:?}", args.filter);
let filter = db::Filter::parse_optional(&args.filter)?;
rl.set_target(Some(filter));
}

Ok(())
}

fn select<T: Model + Detailed>(rl: &mut Readline) -> Result<()> {
let filter = rl.scoped_targets();

for obj in rl.db().filter::<T>(&filter)? {
println!("{}", obj.detailed(rl.db())?);
}

Ok(())
}
5 changes: 5 additions & 0 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ impl Filter {
&self.query
}

pub fn and_scoped(&self) -> Filter {
let query = format!("({}) AND unscoped=0", self.query);
Filter::new(query)
}

pub fn sql(&self) -> SqlLiteral<Bool> {
sql::<Bool>(&self.query)
}
Expand Down
24 changes: 23 additions & 1 deletion src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use complete::CmdCompleter;
use config::Config;
use colored::Colorize;
use ctrlc;
use db::Database;
use db::{self, Database};
use engine::{Engine, Module};
use geoip::{GeoIP, AsnDB, Maxmind};
use rustyline::error::ReadlineError;
Expand Down Expand Up @@ -34,6 +34,7 @@ pub enum Command {
Set,
Select,
SwitchDb,
Target,
Update,
Use,
Quickstart,
Expand All @@ -54,6 +55,7 @@ impl Command {
Command::Set => "set",
Command::Select => "select",
Command::SwitchDb => "switch_db",
Command::Target => "target",
Command::Update => "update",
Command::Use => "use",
Command::Quickstart => "quickstart",
Expand All @@ -74,6 +76,7 @@ impl Command {
Command::Set.as_str(),
Command::Select.as_str(),
Command::SwitchDb.as_str(),
Command::Target.as_str(),
Command::Update.as_str(),
Command::Use.as_str(),
Command::Quickstart.as_str(),
Expand All @@ -99,6 +102,7 @@ impl FromStr for Command {
"set" => Ok(Command::Set),
"select" => Ok(Command::Select),
"switch_db" => Ok(Command::SwitchDb),
"target" => Ok(Command::Target),
"update" => Ok(Command::Update),
"use" => Ok(Command::Use),
"quickstart" => Ok(Command::Quickstart),
Expand Down Expand Up @@ -151,12 +155,29 @@ impl Readline {

pub fn set_module(&mut self, module: Module) {
self.prompt.module = Some(module);
// TODO: possibly refactor
self.prompt.target = None;
}

pub fn module(&self) -> Option<&Module> {
self.prompt.module.as_ref()
}

pub fn set_target(&mut self, target: Option<db::Filter>) {
self.prompt.target = target;
}

pub fn target(&self) -> &Option<db::Filter> {
&self.prompt.target
}

pub fn scoped_targets(&self) -> db::Filter {
match &self.prompt.target {
Some(filter) => filter.and_scoped(),
_ => db::Filter::new("unscoped=0"),
}
}

pub fn db(&self) -> &Database {
&self.db
}
Expand Down Expand Up @@ -310,6 +331,7 @@ pub fn run_once(rl: &mut Readline) -> Result<bool> {
Some((Command::Set, _args)) => println!("set"),
Some((Command::Select, args)) => select_cmd::run(rl, &args)?,
Some((Command::SwitchDb, args)) => switch_db_cmd::run(rl, &args)?,
Some((Command::Target, args)) => target_cmd::run(rl, &args)?,
Some((Command::Update, _args)) => {
// TODO
// worker::spawn("Updating public suffix list");
Expand Down
4 changes: 4 additions & 0 deletions src/term.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use db;
use engine::Module;
use rand::prelude::*;
use std::fmt;
Expand Down Expand Up @@ -129,13 +130,16 @@ pub fn error(line: &str) {
pub struct Prompt {
pub workspace: String,
pub module: Option<Module>,
// TODO: wrapper type that holds module+options
pub target: Option<db::Filter>,
}

impl Prompt {
pub fn new(workspace: String) -> Prompt {
Prompt {
workspace,
module: None,
target: None,
}
}
}
Expand Down

0 comments on commit e40f19e

Please sign in to comment.