registry: Reward collection authorization (#58)

This commit is contained in:
Armani Ferrante 2020-12-09 21:31:39 -08:00 committed by GitHub
parent 855790b722
commit d2d5e287d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 5 deletions

View File

@ -21,6 +21,7 @@ pub fn handler(
let acc_infos = &mut accounts.iter();
let signer_acc_info = next_account_info(acc_infos)?;
let entity_acc_info = next_account_info(acc_infos)?;
let member_acc_info = next_account_info(acc_infos)?;
let registrar_acc_info = next_account_info(acc_infos)?;
@ -46,6 +47,7 @@ pub fn handler(
ref clock,
} = access_control(AccessControlRequest {
program_id,
signer_acc_info,
registrar_acc_info,
entity_acc_info,
member_acc_info,
@ -90,6 +92,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
let AccessControlRequest {
program_id,
cursor,
signer_acc_info,
registrar_acc_info,
entity_acc_info,
member_acc_info,
@ -98,8 +101,10 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
clock_acc_info,
} = req;
// Authorization: none required. This operation is purely beneficial for
// the member account.
// Authorization. Must be either the beneficiary or the node leader.
if !signer_acc_info.is_signer {
return Err(RegistryErrorCode::Unauthorized)?;
}
// Account validation.
let clock = access_control::clock(clock_acc_info)?;
@ -149,6 +154,10 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
if entity.state == EntityState::Inactive {
return Err(RegistryErrorCode::EntityNotActivated)?;
}
// Is the beneficiary or the node leader the signer?
if &entity.leader != signer_acc_info.key && &member.beneficiary != signer_acc_info.key {
return Err(RegistryErrorCode::Unauthorized)?;
}
Ok(AccessControlResponse {
vendor,
@ -253,6 +262,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
struct AccessControlRequest<'a, 'b> {
program_id: &'a Pubkey,
cursor: u32,
signer_acc_info: &'a AccountInfo<'b>,
entity_acc_info: &'a AccountInfo<'b>,
member_acc_info: &'a AccountInfo<'b>,
registrar_acc_info: &'a AccountInfo<'b>,

View File

@ -18,6 +18,7 @@ pub fn handler(
let acc_infos = &mut accounts.iter();
let signer_acc_info = next_account_info(acc_infos)?;
let entity_acc_info = next_account_info(acc_infos)?;
let member_acc_info = next_account_info(acc_infos)?;
let registrar_acc_info = next_account_info(acc_infos)?;
@ -37,6 +38,7 @@ pub fn handler(
ref spts,
} = access_control(AccessControlRequest {
program_id,
signer_acc_info,
registrar_acc_info,
entity_acc_info,
member_acc_info,
@ -74,6 +76,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
let AccessControlRequest {
program_id,
cursor,
signer_acc_info,
registrar_acc_info,
entity_acc_info,
member_acc_info,
@ -82,9 +85,10 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
spt_acc_infos,
} = req;
// Authorization: none required. This operation is purely beneficial for
// the member account, the beneficiary of which must own
// the destination token to which rewards are sent.
// Authorization. Must be either the beneficiary or the node leader.
if !signer_acc_info.is_signer {
return Err(RegistryErrorCode::Unauthorized)?;
}
// Account validation.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
@ -134,6 +138,10 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
if entity.state == EntityState::Inactive {
return Err(RegistryErrorCode::EntityNotActivated)?;
}
// Is the beneficiary or the node leader the signer?
if &entity.leader != signer_acc_info.key && &member.beneficiary != signer_acc_info.key {
return Err(RegistryErrorCode::Unauthorized)?;
}
Ok(AccessControlResponse { vendor, spts })
}
@ -185,6 +193,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
struct AccessControlRequest<'a, 'b> {
program_id: &'a Pubkey,
cursor: u32,
signer_acc_info: &'a AccountInfo<'b>,
entity_acc_info: &'a AccountInfo<'b>,
member_acc_info: &'a AccountInfo<'b>,
registrar_acc_info: &'a AccountInfo<'b>,