Skip to content

Commit

Permalink
broken code
Browse files Browse the repository at this point in the history
  • Loading branch information
gersbach committed Dec 20, 2024
1 parent d53df63 commit e0f36ed
Showing 1 changed file with 128 additions and 108 deletions.
236 changes: 128 additions & 108 deletions crates/fsrt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{
};

use graphql_parser::{
query::{Mutation, Query},
query::{Document, Mutation, Query, SelectionSet},
schema::ObjectType,
};

Expand All @@ -36,7 +36,7 @@ use forge_analyzer::{
PermissionVuln, SecretChecker,
},
ctx::ModId,
definitions::{Const, DefId, PackageData, Value},
definitions::{self, Const, DefId, PackageData, Value},
interp::Interp,

Check failure on line 40 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

unused import: `self`

Check failure on line 40 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

unused import: `self`
reporter::{Report, Reporter},
};
Expand Down Expand Up @@ -115,115 +115,121 @@ impl fmt::Display for Error {
}
}

fn parse_grapqhql_schema<'a>(
s: &'a str,
schema_doc: &'a [graphql_parser::schema::Definition<'a, String>],
fn parse_grapqhql_schema(
schema_doc: &[graphql_parser::schema::Definition<'_, String>],
query_doc: Vec<graphql_parser::query::Definition<'_, String>>,

Check warning on line 120 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
) -> Vec<String> {
let mut permission_list = vec![];
let mut permission_list= vec![];

if let std::result::Result::Ok(query_doc) = parse_query::<&str>(s) {
// dequeue of (parsed_query_selection: SelectionSet, schema_type_field: Field)
let mut deq = VecDeque::from([]);
// dequeue of (parsed_query_selection: SelectionSet, schema_type_field: Field)
let mut deq: VecDeque<(&SelectionSet<'_, String>, &String)> = VecDeque::from([]);

let fragments: HashMap<&str, &Vec<graphql_parser::query::Selection<'_, &str>>> = query_doc
.definitions
.iter()
.filter_map(|def| match def {
Definition::Fragment(fragment) => {
Some((fragment.name, fragment.selection_set.items.as_ref()))
// lifetime b
let fragments: HashMap<&String, &Vec<graphql_parser::query::Selection<'_, String>>> = query_doc
.iter()

Check failure on line 129 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

`query_doc` does not live long enough

Check failure on line 129 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

`query_doc` does not live long enough
.filter_map(|def| match def {
Definition::Fragment(fragment) => Some((&fragment.name, &fragment.selection_set.items)),
_ => None,
})
.collect();

// lifetime a
query_doc.iter().for_each(|def| match def {
Definition::Operation(OperationDefinition::Mutation(Mutation {

Check failure on line 138 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

`query_doc` does not live long enough

Check failure on line 138 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

lifetime may not live long enough

Check failure on line 138 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

`query_doc` does not live long enough

Check failure on line 138 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

lifetime may not live long enough
selection_set, ..
}))
| Definition::Operation(OperationDefinition::Query(Query { selection_set, .. })) => deq
.extend(selection_set.items.iter().filter_map(|item| {
let definition =

Check failure on line 143 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

lifetime may not live long enough

Check failure on line 143 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

lifetime may not live long enough
if let Definition::Operation(OperationDefinition::Mutation(_)) = def {
"Mutation"
} else if let Definition::Operation(OperationDefinition::Query(_)) = def {
"Query"
} else {
"Unkown"
};

Check warning on line 151 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
if let Selection::Field(Field { name, .. }) = &item {
if let Some(QueryPermissionsAndNextSelection { selection_set, name_field, .. }) = test(schema_doc, name, definition, item) {
return Some((selection_set, name_field));

Check failure on line 154 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

lifetime may not live long enough

Check failure on line 154 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

lifetime may not live long enough
}
}
_ => None,
})
.collect();

query_doc.definitions.iter().for_each(|def| match def {
Definition::Operation(OperationDefinition::Mutation(Mutation {
selection_set,
..
}))
| Definition::Operation(OperationDefinition::Query(Query { selection_set, .. })) => deq
.extend(selection_set.items.iter().filter_map(|item| {
let definition =
if let Definition::Operation(OperationDefinition::Mutation(_)) = def {
"Mutation"
} else if let Definition::Operation(OperationDefinition::Query(_)) = def {
"Query"
} else {
"Unkown"
};
None
})),
_ => {}
});

while let Some((query_set, schema_field)) = deq.pop_front() {
deq.extend(
query_set
.items
.iter()
.filter_map(|item| {

Check warning on line 168 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
if let Selection::Field(Field { name, .. }) = &item {
let field_type = get_type_or_typex_with_name(schema_doc, definition)
.find(|field| field.name == *name);
if let Selection::Field(field) = item {
if let Some(field_type) = field_type {
if let Type::NamedType(name) = &&field_type.field_type {
return Some((field.selection_set.clone(), name));
if let Some(QueryPermissionsAndNextSelection { permissions, selection_set, name_field }) =
test(schema_doc, name, &schema_field, item)
{
permission_list.extend(permissions);
return Some(vec![(selection_set, name_field)]);
}
} else if let Selection::FragmentSpread(fragment_spread) = item {
// check to see if the fragment spread resolves as fragmemnt
if let Some(set) = fragments.get(&fragment_spread.fragment_name) {
let mut selections = vec![];
for selection in set.iter() {

Check warning on line 180 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
if let Selection::Field(Field { name, .. }) = selection {
if let Some(QueryPermissionsAndNextSelection { permissions, selection_set, name_field }) =
test(schema_doc, name, &schema_field, selection)
{
permission_list.extend(permissions);
selections.push((selection_set, name_field));
}
}
}

return Some(selections);
}
}

None
})),
_ => {}
});
})
.flatten(),
)
}

while !deq.is_empty() {
let (query_set, schema_field) = deq.pop_front().unwrap();
deq.extend(
query_set
.items
.iter()
.filter_map(|item| {
if let Selection::Field(Field { name, .. }) = &item {
let field_type = get_type_or_typex_with_name(schema_doc, schema_field)
.find(|field| field.name == *name);

if let Selection::Field(field) = item {
if let Some(field_type) = field_type {
if let Type::NamedType(name) = &&field_type.field_type {
permission_list.extend(get_field_directives(field_type));
return Some(vec![(field.selection_set.clone(), name)]);
}
}
}
} else if let Selection::FragmentSpread(fragment_spread) = item {
// check to see if the fragment spread resolves as fragmemnt
if let Some(set) = fragments.get(&fragment_spread.fragment_name) {
let mut selections = vec![];
for selection in set.iter() {
if let Selection::Field(Field { name, .. }) = selection {
let field_type =
get_type_or_typex_with_name(schema_doc, schema_field)
.find(|field| field.name == *name);

if let Selection::Field(field) = selection {
if let Some(field_type) = field_type {
if let Type::NamedType(name) =
&&field_type.field_type
{
permission_list
.extend(get_field_directives(field_type));
selections
.push((field.selection_set.clone(), name));
}
}
}
}
}
vec![]
}

return Some(selections);
}
}
struct QueryPermissionsAndNextSelection<'a> {
permissions: Vec<&'a String>,
selection_set: &'a SelectionSet<'a, String>,
name_field: &'a String,
}

None
})
.flatten(),
)
fn test<'a>(
definitions: &'a [graphql_parser::schema::Definition<'a, String>],
name: &'a str,
schema_field: &'a str,
selection: &'a Selection<'a, String>,
) -> Option<QueryPermissionsAndNextSelection<'a>> {
let field_type =
get_type_or_typex_with_name(definitions, schema_field).find(|field| field.name == *name);

if let Selection::Field(field) = selection {
if let Some(field_type) = field_type {

Check warning on line 220 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
if let Type::NamedType(name) = &field_type.field_type {
return Some(
QueryPermissionsAndNextSelection {
permissions: get_field_directives(field_type),
selection_set: &field.selection_set,
name_field: name
}
);
}
}
}

permission_list
None
}

fn get_type_or_typex_with_name<'a>(
Expand All @@ -232,24 +238,25 @@ fn get_type_or_typex_with_name<'a>(
) -> impl Iterator<Item = &'a graphql_parser::schema::Field<'a, String>> {
definitions
.iter()
.filter_map(move |def| match def {
.flat_map(move |def| match def {
graphql_parser::schema::Definition::TypeDefinition(TypeDefinition::Object(
ObjectType { name, fields, .. },
))
| graphql_parser::schema::Definition::TypeExtension(TypeExtension::Object(
ObjectTypeExtension { name, fields, .. },
)) => {
if name == search_name {
return Some(fields);
return &fields[..];
}
None
&[]
}
_ => None,
_ => &[],
})
.flatten()
}

fn get_field_directives(field: &graphql_parser::schema::Field<'_, String>) -> Vec<String> {
fn get_field_directives<'a>(
field: &'a graphql_parser::schema::Field<'_, String>,
) -> Vec<&'a String> {
let mut perm_vec = vec![];
field.directives.iter().for_each(|directive| {
if directive.name.as_str() == "scopes" {
Expand All @@ -258,7 +265,7 @@ fn get_field_directives(field: &graphql_parser::schema::Field<'_, String>) -> Ve
if let query::Value::List(val) = &arg.1 {
val.iter().for_each(|val| {
if let query::Value::Enum(en) = val {
perm_vec.push(en.clone());
perm_vec.push(en);
}
});
}
Expand All @@ -271,21 +278,34 @@ fn get_field_directives(field: &graphql_parser::schema::Field<'_, String>) -> Ve

fn check_graphql_and_perms<'a>(

Check warning on line 279 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
val: &'a Value,
path: &'a graphql_parser::schema::Document<'a, String>,
) -> Vec<String> {
path: &'a [graphql_parser::schema::Definition<'a, std::string::String>], // pass in the definitions here :)
) -> Vec<&'a String> {
let mut operations = vec![];

match val {
Value::Const(Const::Literal(s)) => {

Check warning on line 286 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
operations.extend(parse_grapqhql_schema(s, &path.definitions));
if let std::result::Result::Ok(Document { definitions, .. }) = parse_query::<String>(s) {
operations.extend(parse_grapqhql_schema(
&path,
definitions,
));
}

}
Value::Phi(vals) => vals.iter().for_each(|val| match val {
Const::Literal(s) => {
operations.extend(parse_grapqhql_schema(s, &path.definitions));
if let std::result::Result::Ok(Document { definitions, .. }) = parse_query::<String>(s) {
operations.extend(parse_grapqhql_schema(

Check warning on line 298 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

Diff in /home/runner/work/FSRT/FSRT/crates/fsrt/src/main.rs
&path,
definitions,
));

}
}
}),
_ => {}
}

// TODO : Build out permission resolver here

operations
Expand Down Expand Up @@ -564,21 +584,21 @@ pub(crate) fn scan_directory<'a>(
.value_manager
.varid_to_value_with_proj
.values()
.flat_map(|val| check_graphql_and_perms(val, &doc))
.flat_map(|val| check_graphql_and_perms(val, &doc.definitions))
.collect();

let graphql_perms_varid: Vec<String> = definition_analysis_interp
.value_manager
.varid_to_value
.values()
.flat_map(|val| check_graphql_and_perms(val, &doc))
.flat_map(|val| check_graphql_and_perms(val, &doc.definitions))
.collect();

let graphql_perms_defid: Vec<String> = definition_analysis_interp
.value_manager
.defid_to_value
.values()

Check failure on line 600 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Linux Tester

a value of type `Vec<std::string::String>` cannot be built from an iterator over elements of type `&std::string::String`

Check failure on line 600 in crates/fsrt/src/main.rs

View workflow job for this annotation

GitHub Actions / Clippy

a value of type `std::vec::Vec<std::string::String>` cannot be built from an iterator over elements of type `&std::string::String`
.flat_map(|val| check_graphql_and_perms(val, &doc))
.flat_map(|val| check_graphql_and_perms(val, &doc.definitions))
.collect();

used_graphql_perms.extend_from_slice(&graphql_perms_defid);
Expand Down

0 comments on commit e0f36ed

Please sign in to comment.