Use shared ContractSet object when verifing user during registration
Server will not start if blockchain configuration is invalid.
This commit is contained in:
parent
6b06d6d18e
commit
b618c5b31f
4 changed files with 22 additions and 29 deletions
|
@ -16,10 +16,9 @@ use super::sync::{
|
||||||
};
|
};
|
||||||
use super::utils::parse_address;
|
use super::utils::parse_address;
|
||||||
|
|
||||||
pub const ADAPTER: &str = "IAdapter";
|
const ADAPTER: &str = "IAdapter";
|
||||||
pub const SUBSCRIPTION: &str = "ISubscription";
|
const SUBSCRIPTION: &str = "ISubscription";
|
||||||
pub const ERC20: &str = "IERC20";
|
const ERC721: &str = "IERC721Metadata";
|
||||||
pub const ERC721: &str = "IERC721Metadata";
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum ArtifactError {
|
pub enum ArtifactError {
|
||||||
|
@ -33,7 +32,7 @@ pub enum ArtifactError {
|
||||||
KeyError,
|
KeyError,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_abi(
|
fn load_abi(
|
||||||
contract_dir: &Path,
|
contract_dir: &Path,
|
||||||
contract_name: &str,
|
contract_name: &str,
|
||||||
) -> Result<Vec<u8>, ArtifactError> {
|
) -> Result<Vec<u8>, ArtifactError> {
|
||||||
|
@ -47,14 +46,13 @@ pub fn load_abi(
|
||||||
Ok(contract_abi)
|
Ok(contract_abi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ContractSet {
|
pub struct ContractSet {
|
||||||
pub web3: Web3<Http>,
|
pub web3: Web3<Http>,
|
||||||
// Last synced block
|
// Last synced block
|
||||||
pub current_block: u64,
|
pub current_block: u64,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub adapter: Contract<Http>,
|
pub adapter: Contract<Http>,
|
||||||
|
|
||||||
pub collectible: Contract<Http>,
|
pub collectible: Contract<Http>,
|
||||||
pub subscription: Contract<Http>,
|
pub subscription: Contract<Http>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,15 @@
|
||||||
use web3::contract::{Contract, Options};
|
use web3::contract::Options;
|
||||||
|
|
||||||
use crate::config::BlockchainConfig;
|
use super::contracts::ContractSet;
|
||||||
use super::api::connect;
|
|
||||||
use super::contracts::{ADAPTER, load_abi};
|
|
||||||
use super::errors::EthereumError;
|
use super::errors::EthereumError;
|
||||||
use super::utils::parse_address;
|
use super::utils::parse_address;
|
||||||
|
|
||||||
pub async fn is_allowed_user(
|
pub async fn is_allowed_user(
|
||||||
config: &BlockchainConfig,
|
contract_set: &ContractSet,
|
||||||
user_address: &str,
|
user_address: &str,
|
||||||
) -> Result<bool, EthereumError> {
|
) -> Result<bool, EthereumError> {
|
||||||
let web3 = connect(&config.api_url)?;
|
|
||||||
let adapter_abi = load_abi(&config.contract_dir, ADAPTER)?;
|
|
||||||
let adapter_address = parse_address(&config.contract_address)?;
|
|
||||||
let adapter = Contract::from_json(
|
|
||||||
web3.eth(),
|
|
||||||
adapter_address,
|
|
||||||
&adapter_abi,
|
|
||||||
)?;
|
|
||||||
let user_address = parse_address(user_address)?;
|
let user_address = parse_address(user_address)?;
|
||||||
let result: bool = adapter.query(
|
let result: bool = contract_set.adapter.query(
|
||||||
"isAllowedUser", (user_address,),
|
"isAllowedUser", (user_address,),
|
||||||
None, Options::default(), None,
|
None, Options::default(), None,
|
||||||
).await?;
|
).await?;
|
||||||
|
|
|
@ -51,16 +51,15 @@ async fn main() -> std::io::Result<()> {
|
||||||
config.environment,
|
config.environment,
|
||||||
);
|
);
|
||||||
|
|
||||||
let maybe_contract_set = if let Some(blockchain_config) = &config.blockchain {
|
let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain {
|
||||||
// Create blockchain interface
|
// Create blockchain interface
|
||||||
get_contracts(blockchain_config, &config.storage_dir).await
|
get_contracts(blockchain_config, &config.storage_dir).await
|
||||||
.map_err(|err| log::error!("{}", err))
|
.map(Some).unwrap()
|
||||||
.ok()
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
scheduler::run(config.clone(), maybe_contract_set, db_pool.clone());
|
scheduler::run(config.clone(), maybe_blockchain.clone(), db_pool.clone());
|
||||||
log::info!("scheduler started");
|
log::info!("scheduler started");
|
||||||
|
|
||||||
let http_socket_addr = format!(
|
let http_socket_addr = format!(
|
||||||
|
@ -117,6 +116,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
.app_data(web::JsonConfig::default().limit(MAX_UPLOAD_SIZE))
|
.app_data(web::JsonConfig::default().limit(MAX_UPLOAD_SIZE))
|
||||||
.app_data(web::Data::new(config.clone()))
|
.app_data(web::Data::new(config.clone()))
|
||||||
.app_data(web::Data::new(db_pool.clone()))
|
.app_data(web::Data::new(db_pool.clone()))
|
||||||
|
.app_data(web::Data::new(maybe_blockchain.clone()))
|
||||||
.app_data(web::Data::clone(&inbox_mutex))
|
.app_data(web::Data::clone(&inbox_mutex))
|
||||||
.service(actix_files::Files::new(
|
.service(actix_files::Files::new(
|
||||||
"/media",
|
"/media",
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::activitypub::deliverer::deliver_activity;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||||
|
use crate::ethereum::contracts::ContractSet;
|
||||||
use crate::ethereum::eip4361::verify_eip4361_signature;
|
use crate::ethereum::eip4361::verify_eip4361_signature;
|
||||||
use crate::ethereum::gate::is_allowed_user;
|
use crate::ethereum::gate::is_allowed_user;
|
||||||
use crate::ethereum::identity::{
|
use crate::ethereum::identity::{
|
||||||
|
@ -68,6 +69,7 @@ use super::types::{
|
||||||
pub async fn create_account(
|
pub async fn create_account(
|
||||||
config: web::Data<Config>,
|
config: web::Data<Config>,
|
||||||
db_pool: web::Data<Pool>,
|
db_pool: web::Data<Pool>,
|
||||||
|
maybe_blockchain: web::Data<Option<ContractSet>>,
|
||||||
account_data: web::Json<AccountCreateData>,
|
account_data: web::Json<AccountCreateData>,
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||||
|
@ -103,16 +105,19 @@ pub async fn create_account(
|
||||||
};
|
};
|
||||||
assert!(password_hash.is_some() || wallet_address.is_some());
|
assert!(password_hash.is_some() || wallet_address.is_some());
|
||||||
|
|
||||||
if let Some(blockchain_config) = config.blockchain.as_ref() {
|
if let Some(contract_set) = maybe_blockchain.as_ref() {
|
||||||
// Wallet address is required if blockchain integration is enabled
|
// Wallet address is required if blockchain integration is enabled
|
||||||
let wallet_address = wallet_address.as_ref()
|
let wallet_address = wallet_address.as_ref()
|
||||||
.ok_or(ValidationError("wallet address is required"))?;
|
.ok_or(ValidationError("wallet address is required"))?;
|
||||||
let is_allowed = is_allowed_user(blockchain_config, wallet_address).await
|
let is_allowed = is_allowed_user(contract_set, wallet_address).await
|
||||||
.map_err(|_| HttpError::InternalError)?;
|
.map_err(|_| HttpError::InternalError)?;
|
||||||
if !is_allowed {
|
if !is_allowed {
|
||||||
return Err(ValidationError("not allowed to sign up").into());
|
return Err(ValidationError("not allowed to sign up").into());
|
||||||
}
|
};
|
||||||
}
|
} else {
|
||||||
|
assert!(config.blockchain.is_none());
|
||||||
|
};
|
||||||
|
|
||||||
// Generate RSA private key for actor
|
// Generate RSA private key for actor
|
||||||
let private_key = match web::block(generate_private_key).await {
|
let private_key = match web::block(generate_private_key).await {
|
||||||
Ok(Ok(private_key)) => private_key,
|
Ok(Ok(private_key)) => private_key,
|
||||||
|
|
Loading…
Reference in a new issue