Skip to content

Commit

Permalink
Use external plugin adapter authority to validate
Browse files Browse the repository at this point in the history
  • Loading branch information
danenbm committed Jul 15, 2024
1 parent 8ff399b commit 43e5f4c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 18 deletions.
48 changes: 48 additions & 0 deletions programs/mpl-core/src/plugins/external_plugin_adapters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use strum::EnumCount;

use crate::{
error::MplCoreError,
plugins::lifecycle::{approve, reject},
state::{AssetV1, SolanaAccount},
};

Expand Down Expand Up @@ -198,6 +199,53 @@ impl ExternalPluginAdapter {
}
}

/// Validate the add external plugin adapter lifecycle event.
pub(crate) fn validate_update_external_plugin_adapter(
external_plugin_adapter: &ExternalPluginAdapter,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
let resolved_authorities = ctx
.resolved_authorities
.ok_or(MplCoreError::InvalidAuthority)?;
let base_result = if resolved_authorities.contains(ctx.self_authority) {
solana_program::msg!("Base: Approved");
ValidationResult::Approved
} else {
ValidationResult::Pass
};

let result = match external_plugin_adapter {
ExternalPluginAdapter::LifecycleHook(lifecycle_hook) => {
lifecycle_hook.validate_update_external_plugin_adapter(ctx)
}
ExternalPluginAdapter::Oracle(oracle) => {
oracle.validate_update_external_plugin_adapter(ctx)
}
ExternalPluginAdapter::DataStore(app_data) => {
app_data.validate_update_external_plugin_adapter(ctx)
}
}?;

match (&base_result, &result) {
(ValidationResult::Approved, ValidationResult::Approved) => {
approve!()
}
(ValidationResult::Approved, ValidationResult::Rejected) => {
reject!()
}
(ValidationResult::Rejected, ValidationResult::Approved) => {
reject!()
}
(ValidationResult::Rejected, ValidationResult::Rejected) => {
reject!()
}
(ValidationResult::Pass, _) => Ok(result),
(ValidationResult::ForceApproved, _) => unreachable!(),
(_, ValidationResult::Pass) => Ok(base_result),
(_, ValidationResult::ForceApproved) => unreachable!(),
}
}

/// Load and deserialize a plugin from an offset in the account.
pub fn load(account: &AccountInfo, offset: usize) -> Result<Self, ProgramError> {
let mut bytes: &[u8] = &(*account.data).borrow()[offset..];
Expand Down
35 changes: 29 additions & 6 deletions programs/mpl-core/src/processor/update_external_plugin_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use crate::{
plugins::{
fetch_wrapped_external_plugin_adapter, find_external_plugin_adapter, ExternalPluginAdapter,
ExternalPluginAdapterKey, ExternalPluginAdapterUpdateInfo, Plugin, PluginHeaderV1,
PluginRegistryV1, PluginType,
PluginRegistryV1, PluginType, PluginValidationContext, ValidationResult,
},
state::{AssetV1, CollectionV1, DataBlob, Key, SolanaAccount},
utils::{
load_key, resize_or_reallocate_account, resolve_authority, validate_asset_permissions,
validate_collection_permissions,
fetch_core_data, load_key, resize_or_reallocate_account, resolve_authority,
resolve_pubkey_to_authorities, validate_asset_permissions, validate_collection_permissions,
},
};

Expand Down Expand Up @@ -56,17 +56,40 @@ pub(crate) fn update_external_plugin_adapter<'a>(
return Err(MplCoreError::NotAvailable.into());
}

let (_, plugin) =
let (deserialized_asset, _plugin_header, _plugin_registry) =
fetch_core_data::<AssetV1>(ctx.accounts.asset)?;
let resolved_authorities =
resolve_pubkey_to_authorities(authority, ctx.accounts.collection, &deserialized_asset)?;
let (external_registry_record_authority, external_plugin_adapter) =
fetch_wrapped_external_plugin_adapter::<AssetV1>(ctx.accounts.asset, None, &args.key)?;

let validation_ctx = PluginValidationContext {
accounts,
asset_info: Some(ctx.accounts.asset),
collection_info: ctx.accounts.collection,
self_authority: &external_registry_record_authority,
authority_info: authority,
resolved_authorities: Some(&resolved_authorities),
new_owner: None,
target_plugin: None,
};

if ExternalPluginAdapter::validate_update_external_plugin_adapter(
&external_plugin_adapter,
&validation_ctx,
)? == ValidationResult::Rejected
{
return Err(MplCoreError::InvalidAuthority.into());
}

let (mut asset, plugin_header, plugin_registry) = validate_asset_permissions(
accounts,
authority,
ctx.accounts.asset,
ctx.accounts.collection,
None,
None,
Some(&plugin),
Some(&external_plugin_adapter),
AssetV1::check_update_external_plugin_adapter,
CollectionV1::check_update_external_plugin_adapter,
PluginType::check_update_external_plugin_adapter,
Expand All @@ -82,7 +105,7 @@ pub(crate) fn update_external_plugin_adapter<'a>(

process_update_external_plugin_adapter(
asset,
plugin,
external_plugin_adapter,
args.key,
args.update_info,
plugin_header,
Expand Down
8 changes: 2 additions & 6 deletions programs/mpl-core/src/state/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl AssetV1 {

/// Check permissions for the update external plugin adapter lifecycle event.
pub fn check_update_external_plugin_adapter() -> CheckResult {
CheckResult::CanApprove
CheckResult::None
}

/// Validate the add plugin lifecycle event.
Expand Down Expand Up @@ -332,11 +332,7 @@ impl AssetV1 {
_: Option<&Plugin>,
_plugin: Option<&ExternalPluginAdapter>,
) -> Result<ValidationResult, ProgramError> {
if self.update_authority == UpdateAuthority::Address(*authority_info.key) {
approve!()
} else {
abstain!()
}
abstain!()
}
}

Expand Down
8 changes: 2 additions & 6 deletions programs/mpl-core/src/state/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl CollectionV1 {

/// Check permissions for the update external plugin adapter lifecycle event.
pub fn check_update_external_plugin_adapter() -> CheckResult {
CheckResult::CanApprove
CheckResult::None
}

/// Validate the add plugin lifecycle event.
Expand Down Expand Up @@ -297,11 +297,7 @@ impl CollectionV1 {
_: Option<&Plugin>,
_plugin: Option<&ExternalPluginAdapter>,
) -> Result<ValidationResult, ProgramError> {
if self.update_authority == *authority_info.key {
approve!()
} else {
abstain!()
}
abstain!()
}

/// Increment size of the Collection
Expand Down

0 comments on commit 43e5f4c

Please sign in to comment.