Skip to content

Commit

Permalink
Check model exists on sozo auth (starkware-libs#1644)
Browse files Browse the repository at this point in the history
* feat: check model name and address before granting write access

* Update crates/dojo-world/src/contracts/model.rs

Co-authored-by: glihm <dev@glihm.net>

* Update bin/sozo/src/ops/auth.rs

Co-authored-by: glihm <dev@glihm.net>

---------

Co-authored-by: glihm <dev@glihm.net>
  • Loading branch information
remybar and glihm committed Mar 13, 2024
1 parent a007ca1 commit 5ff37ec
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
38 changes: 26 additions & 12 deletions bin/sozo/src/ops/auth.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use anyhow::{Context, Result};
use dojo_world::contracts::world::WorldContract;
use dojo_world::contracts::WorldContractReader;
use dojo_world::metadata::Environment;
use dojo_world::utils::TransactionWaiter;
use starknet::accounts::Account;
use starknet::core::types::{BlockId, BlockTag};
use starknet::core::utils::parse_cairo_short_string;

use super::get_contract_address;
use crate::commands::auth::{AuthCommand, AuthKind, ResourceType};
Expand All @@ -16,25 +19,36 @@ pub async fn execute(command: AuthCommand, env_metadata: Option<Environment>) ->

let account = account.account(&provider, env_metadata.as_ref()).await?;
let world = WorldContract::new(world_address, &account);
let world_reader = WorldContractReader::new(world_address, &provider)
.with_block(BlockId::Tag(BlockTag::Pending));

let mut calls = Vec::new();

for mc in models_contracts {
let contract = get_contract_address(&world, mc.contract).await?;
calls.push(world.grant_writer_getcall(&mc.model, &contract.into()));
let model_name = parse_cairo_short_string(&mc.model)?;

if world_reader.model_reader(&model_name).await.is_ok() {
let contract = get_contract_address(&world, mc.contract).await?;
calls.push(world.grant_writer_getcall(&mc.model, &contract.into()));
} else {
println!("Unknown model '{}' => IGNORED", model_name);
}
}

let res = account
.execute(calls)
.send()
.await
.with_context(|| "Failed to send transaction")?;
if !calls.is_empty() {
let res = account
.execute(calls)
.send()
.await
.with_context(|| "Failed to send transaction")?;

if transaction.wait {
let receipt = TransactionWaiter::new(res.transaction_hash, &provider).await?;
println!("{}", serde_json::to_string_pretty(&receipt)?);
} else {
println!("Transaction hash: {:#x}", res.transaction_hash);
if transaction.wait {
let receipt =
TransactionWaiter::new(res.transaction_hash, &provider).await?;
println!("{}", serde_json::to_string_pretty(&receipt)?);
} else {
println!("Transaction hash: {:#x}", res.transaction_hash);
}
}
}
AuthKind::Owner { owners_resources } => {
Expand Down
8 changes: 7 additions & 1 deletion crates/dojo-world/src/contracts/model.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use abigen::model::ModelContractReader;
use async_trait::async_trait;
use cainome::cairo_serde::Error as CainomeError;
use cainome::cairo_serde::{ContractAddress, Error as CainomeError};
use dojo_types::packing::{parse_ty, unpack, PackingError, ParseError};
use dojo_types::primitive::PrimitiveError;
use dojo_types::schema::Ty;
Expand Down Expand Up @@ -86,6 +86,12 @@ where
err => err.into(),
})?;

// World Cairo contract won't raise an error in case of unknown/unregistered
// model so raise an error here in case of zero address.
if contract_address == ContractAddress(FieldElement::ZERO) {
return Err(ModelError::ModelNotFound);
}

let model_reader = ModelContractReader::new(contract_address.into(), world.provider());

Ok(Self {
Expand Down

0 comments on commit 5ff37ec

Please sign in to comment.