Skip to content

Commit

Permalink
Merge pull request hyperledger-archives#1512 from Artemkaaas/feature/…
Browse files Browse the repository at this point in the history
…auth-rule-builder

AUTH_RULE transaction builder
  • Loading branch information
jovfer authored Mar 14, 2019
2 parents 8bb0f1c + 284ea63 commit cc36f3e
Show file tree
Hide file tree
Showing 31 changed files with 1,380 additions and 77 deletions.
4 changes: 2 additions & 2 deletions ci/indy-pool.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ RUN echo "deb https://repo.sovrin.org/deb xenial $indy_stream" >> /etc/apt/sourc

RUN useradd -ms /bin/bash -u $uid indy

ARG indy_plenum_ver=1.6.662
ARG indy_plenum_ver=1.6.705
ARG indy_anoncreds_ver=1.0.32
ARG indy_node_ver=1.6.772
ARG indy_node_ver=1.6.839
ARG python3_indy_crypto_ver=0.4.5
ARG indy_crypto_ver=0.4.5

Expand Down
130 changes: 129 additions & 1 deletion cli/src/commands/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,78 @@ pub mod sign_multi_command {
}
}

pub mod auth_rule_command {
use super::*;

command!(CommandMetadata::build("auth-rule", "Send AUTH_RULE request to change authentication rules for a ledger transaction.")
.add_required_param("txn_type", "Ledger transaction alias or associated value")
.add_required_param("action", "Type of an action. One of: ADD, EDIT")
.add_required_param("field", "Transaction field")
.add_optional_param("old_value", "Old value of field, which can be changed to a new_value (mandatory for EDIT action)")
.add_required_param("new_value", "New value that can be used to fill the field")
.add_required_param("constraint", r#"Set of constraints required for execution of an action
{
constraint_id - type of a constraint. Can be either "ROLE" to specify final constraint or "AND"/"OR" to combine constraints.
role - role of a user which satisfy to constrain.
sig_count - the number of signatures required to execution action.
need_to_be_owner - if user must be an owner of transaction.
metadata - additional parameters of the constraint.
}
can be combined by
{
constraint_id: <"AND" or "OR">
auth_constraints: [<constraint_1>, <constraint_2>]
}
"#)
.add_example(r#"ledger auth-rule txn_type=NYM action=ADD field=role new_value=101 constraint={"sig_count":1,"role":0,"constraint_id":"role","need_to_be_owner":false}"#)
.add_example(r#"ledger auth-rule txn_type=NYM action=EDIT field=role old_value=101 new_value=0 constraint={"sig_count":1,"role":0,"constraint_id":"role","need_to_be_owner":false}"#)
.finalize()
);

fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
trace!("execute >> ctx {:?} params {:?}", ctx, params);

let (pool_handle, pool_name) = ensure_connected_pool(&ctx)?;
let (wallet_handle, wallet_name) = ensure_opened_wallet(&ctx)?;
let submitter_did = ensure_active_did(&ctx)?;

let txn_type = get_str_param("txn_type", params).map_err(error_err!())?;
let action = get_str_param("action", params).map_err(error_err!())?;
let field = get_str_param("field", params).map_err(error_err!())?;
let old_value = get_opt_str_param("old_value", params).map_err(error_err!())?;
let new_value = get_str_param("new_value", params).map_err(error_err!())?;
let constraint = get_str_param("constraint", params).map_err(error_err!())?;

let request = Ledger::build_auth_rule_request(&submitter_did, txn_type, &action.to_uppercase(), field, old_value, new_value, constraint)
.map_err(|err| handle_indy_error(err, None, None, None))?;

let response_json = Ledger::sign_and_submit_request(pool_handle, wallet_handle, &submitter_did, &request)
.map_err(|err| handle_indy_error(err, Some(&submitter_did), Some(&pool_name), Some(&wallet_name)))?;

let mut response: Response<serde_json::Value> = serde_json::from_str::<Response<serde_json::Value>>(&response_json)
.map_err(|err| println_err!("Invalid data has been received: {:?}", err))?;

if let Some(result) = response.result.as_mut() {
result["txn"]["data"]["auth_type"] = get_txn_title(&result["txn"]["data"]["auth_type"]);
result["txn"]["data"]["constraint"] = serde_json::Value::String(::serde_json::to_string_pretty(&result["txn"]["data"]["constraint"]).unwrap());
}

let res = handle_transaction_response(response)
.map(|result| print_transaction_response(result,
"Auth Rule request has been sent to Ledger.",
None,
&mut vec![("auth_type", "Txn Type"),
("auth_action", "Action"),
("field", "Field"),
("old_value", "Old Value"),
("new_value", "New Value"),
("constraint", "Constraint")]))?;

trace!("execute << {:?}", res);
Ok(res)
}
}

pub fn set_request_fees(request: &mut String, wallet_handle: i32, submitter_did: Option<&str>, fees_inputs: &Option<Vec<&str>>, fees_outputs: &Option<Vec<String>>, extra: Option<&str>) -> Result<Option<String>, ()> {
let mut payment_method: Option<String> = None;
if let &Some(ref inputs) = fees_inputs {
Expand Down Expand Up @@ -1413,6 +1485,33 @@ fn get_role_title(role: &serde_json::Value) -> serde_json::Value {
}.to_string())
}

fn get_txn_title(role: &serde_json::Value) -> serde_json::Value {
serde_json::Value::String(match role.as_str() {
Some("0") => "NODE",
Some("1") => "NYM",
Some("3") => "GET_TXN",
Some("100") => "ATTRIB",
Some("101") => "SCHEMA",
Some("104") => "GET_ATTR",
Some("105") => "GET_NYM",
Some("107") => "GET_SCHEMA",
Some("108") => "GET_CRED_DEF",
Some("102") => "CRED_DEF",
Some("109") => "POOL_UPGRADE",
Some("111") => "POOL_CONFIG",
Some("113") => "REVOC_REG_DEF",
Some("114") => "REVOC_REG_ENTRY",
Some("115") => "GET_REVOC_REG_DEF",
Some("116") => "GET_REVOC_REG",
Some("117") => "GET_REVOC_REG_DELTA",
Some("118") => "POOL_RESTART",
Some("119") => "GET_VALIDATOR_INFO",
Some("120") => "AUTH_RULE",
Some(val) => val,
_ => "-"
}.to_string())
}

fn timestamp_to_datetime(_time: i64) -> String {
NaiveDateTime::from_timestamp(_time, 0).to_string()
}
Expand Down Expand Up @@ -1444,7 +1543,7 @@ pub struct ReplyResult<T> {
pub mod tests {
use super::*;
use commands::wallet::tests::{create_and_open_wallet, close_and_delete_wallet, open_wallet, close_wallet};
use commands::pool::tests::{disconnect_and_delete_pool};
use commands::pool::tests::disconnect_and_delete_pool;
use commands::did::tests::{new_did, use_did, SEED_TRUSTEE, DID_TRUSTEE, DID_MY1, VERKEY_MY1, SEED_MY3, DID_MY3, VERKEY_MY3};
#[cfg(feature = "nullpay_plugin")]
use commands::common::tests::{load_null_payment_plugin, NULL_PAYMENT_METHOD};
Expand Down Expand Up @@ -3473,6 +3572,35 @@ pub mod tests {
}
}

mod auth_rule {
use super::*;

const ROLE_CONSTRAINT: &str = r#"{
"sig_count": 1,
"metadata": {},
"role": "0",
"constraint_id": "ROLE",
"need_to_be_owner": false
}"#;

#[test]
pub fn auth_rule_works() {
let ctx = setup_with_wallet_and_pool();
use_trustee(&ctx);
{
let cmd = auth_rule_command::new();
let mut params = CommandParams::new();
params.insert("txn_type", "NYM".to_string());
params.insert("action", "add".to_string());
params.insert("field", "role".to_string());
params.insert("new_value", "101".to_string());
params.insert("constraint", ROLE_CONSTRAINT.to_string());
cmd.execute(&ctx, &params).unwrap();
}
tear_down_with_wallet_and_pool(&ctx);
}
}

fn create_new_did(ctx: &CommandContext) -> (String, String) {
let (wallet_handle, _) = get_opened_wallet(ctx).unwrap();
Did::new(wallet_handle, "{}").unwrap()
Expand Down
15 changes: 13 additions & 2 deletions cli/src/libindy/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,18 @@ impl Ledger {
pub fn indy_build_pool_upgrade_request(submitter_did: &str, name: &str, version: &str, action: &str, sha256: &str, timeout: Option<u32>, schedule: Option<&str>,
justification: Option<&str>, reinstall: bool, force: bool, package: Option<&str>) -> Result<String, IndyError> {
ledger::build_pool_upgrade_request(submitter_did, name, version, action, sha256,
timeout, schedule, justification,
reinstall, force, package).wait()
timeout, schedule, justification,
reinstall, force, package).wait()
}

pub fn build_auth_rule_request(submitter_did: &str,
txn_type: &str,
action: &str,
field: &str,
old_value: Option<&str>,
new_value: &str,
constraint: &str, ) -> Result<String, IndyError> {
ledger::build_auth_rule_request(submitter_did, txn_type, action, field,
old_value, new_value, constraint).wait()
}
}
1 change: 1 addition & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ fn build_executor() -> CommandExecutor {
.add_command(ledger::set_fees_prepare_command::new())
.add_command(ledger::verify_payment_receipt_command::new())
.add_command(ledger::sign_multi_command::new())
.add_command(ledger::auth_rule_command::new())
.finalize_group()
.add_group(payment_address::group::new())
.add_command(payment_address::create_command::new())
Expand Down
6 changes: 6 additions & 0 deletions docs/design/001-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ Send custom transaction with user defined json body and optional signature
ledger custom [txn=]<txn-json-value> [sign=<true|false>]
```

#### AUTH_RULE transaction
Send AUTH_RULE transaction
```
ledger auth-rule txn_type=<txn type> action=<add or edit> field=<txn field> [old_value=<value>] new_value=<new_value> constraint=<{constraint json}>
```

#### GET_PAYMENT_SOURCES transaction
Send GET_PAYMENT_SOURCES transaction
```
Expand Down
46 changes: 46 additions & 0 deletions libindy/include/indy_ledger.h
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,52 @@ extern "C" {
const char* response_metadata)
);

/// Builds a AUTH_RULE request. Request to change authentication rules for a ledger transaction.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// txn_type: ledger transaction alias or associated value.
/// action: type of an action.
/// Can be either "ADD" (to add a new rule) or "EDIT" (to edit an existing one).
/// field: transaction field.
/// old_value: old value of a field, which can be changed to a new_value (mandatory for EDIT action).
/// new_value: new value that can be used to fill the field.
/// constraint: set of constraints required for execution of an action in the following format
/// {
/// constraint_id - <string> type of a constraint.
/// Can be either "ROLE" to specify final constraint or "AND"/"OR" to combine constraints.
/// role - <string> role of a user which satisfy to constrain.
/// sig_count - <u32> the number of signatures required to execution action.
/// need_to_be_owner - <bool> if user must be an owner of transaction.
/// metadata - <object> additional parameters of the constraint.
/// }
/// can be combined by
/// {
/// 'constraint_id': <"AND" or "OR">
/// 'auth_constraints': [<constraint_1>, <constraint_2>]
/// }
///
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
///
/// #Errors
/// Common*
extern indy_error_t indy_build_auth_rule_request(indy_handle_t command_handle,
const char * submitter_did,
const char * txn_type,
const char * action,
const char * field,
const char * old_value,
const char * new_value,
const char * constraint,

void (*cb)(indy_handle_t command_handle_,
indy_error_t err,
const char* request_json)
);

#ifdef __cplusplus
}
#endif
Expand Down
85 changes: 85 additions & 0 deletions libindy/src/api/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1834,3 +1834,88 @@ pub extern fn indy_get_response_metadata(command_handle: CommandHandle,

res
}

/// Builds a AUTH_RULE request. Request to change authentication rules for a ledger transaction.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// txn_type: ledger transaction alias or associated value.
/// action: type of an action.
/// Can be either "ADD" (to add a new rule) or "EDIT" (to edit an existing one).
/// field: transaction field.
/// old_value: old value of a field, which can be changed to a new_value (mandatory for EDIT action).
/// new_value: new value that can be used to fill the field.
/// constraint: set of constraints required for execution of an action in the following format:
/// {
/// constraint_id - <string> type of a constraint.
/// Can be either "ROLE" to specify final constraint or "AND"/"OR" to combine constraints.
/// role - <string> role of a user which satisfy to constrain.
/// sig_count - <u32> the number of signatures required to execution action.
/// need_to_be_owner - <bool> if user must be an owner of transaction.
/// metadata - <object> additional parameters of the constraint.
/// }
/// can be combined by
/// {
/// 'constraint_id': <"AND" or "OR">
/// 'auth_constraints': [<constraint_1>, <constraint_2>]
/// }
///
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
///
/// #Errors
/// Common*
#[no_mangle]
pub extern fn indy_build_auth_rule_request(command_handle: CommandHandle,
submitter_did: *const c_char,
txn_type: *const c_char,
action: *const c_char,
field: *const c_char,
old_value: *const c_char,
new_value: *const c_char,
constraint: *const c_char,
cb: Option<extern fn(command_handle_: CommandHandle,
err: ErrorCode,
request_json: *const c_char)>) -> ErrorCode {
trace!("indy_build_auth_rule_request: >>> submitter_did: {:?}, txn_type: {:?}, action: {:?}, field: {:?}, \
old_value: {:?}, new_value: {:?}, constraint: {:?}",
submitter_did, txn_type, action, field, old_value, new_value, constraint);

check_useful_c_str!(submitter_did, ErrorCode::CommonInvalidParam2);
check_useful_c_str!(txn_type, ErrorCode::CommonInvalidParam3);
check_useful_c_str!(action, ErrorCode::CommonInvalidParam4);
check_useful_c_str!(field, ErrorCode::CommonInvalidParam5);
check_useful_opt_c_str!(old_value, ErrorCode::CommonInvalidParam6);
check_useful_c_str!(new_value, ErrorCode::CommonInvalidParam7);
check_useful_c_str!(constraint, ErrorCode::CommonInvalidParam8);
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam9);

trace!("indy_build_auth_rule_request: entities >>> submitter_did: {:?}, txn_type: {:?}, action: {:?}, field: {:?}, \
old_value: {:?}, new_value: {:?}, constraint: {:?}",
submitter_did, txn_type, action, field, old_value, new_value, constraint);

let result = CommandExecutor::instance()
.send(Command::Ledger(LedgerCommand::BuildAuthRuleRequest(
submitter_did,
txn_type,
action,
field,
old_value,
new_value,
constraint,
Box::new(move |result| {
let (err, request_json) = prepare_result_1!(result, String::new());
trace!("indy_build_auth_rule_request: request_json: {:?}", request_json);
let request_json = ctypes::string_to_cstring(request_json);
cb(command_handle, err, request_json.as_ptr())
})
)));

let res = prepare_result!(result);

trace!("indy_build_auth_rule_request: <<< res: {:?}", res);

res
}
Loading

0 comments on commit cc36f3e

Please sign in to comment.