begin API change to allow AML officers to trigger KYC process
This commit is contained in:
parent
437e6ec86a
commit
afe3f70d33
@ -50,6 +50,7 @@ TEH_handler_post_aml_decision (
|
||||
uint32_t new_state32;
|
||||
enum TALER_AmlDecisionState new_state;
|
||||
struct TALER_AmlOfficerSignatureP officer_sig;
|
||||
json_t *kyc_requirements = NULL;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("officer_sig",
|
||||
&officer_sig),
|
||||
@ -64,6 +65,10 @@ TEH_handler_post_aml_decision (
|
||||
&decision_time),
|
||||
GNUNET_JSON_spec_uint32 ("new_state",
|
||||
&new_state32),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_json ("kyc_requirements",
|
||||
&kyc_requirements),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -89,6 +94,7 @@ TEH_handler_post_aml_decision (
|
||||
&new_threshold,
|
||||
&h_payto,
|
||||
new_state,
|
||||
kyc_requirements,
|
||||
officer_pub,
|
||||
&officer_sig))
|
||||
{
|
||||
@ -99,6 +105,8 @@ TEH_handler_post_aml_decision (
|
||||
TALER_EC_EXCHANGE_AML_DECISION_ADD_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
|
||||
// FIXME: check kyc_requirements is well-formed!
|
||||
{
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct GNUNET_TIME_Timestamp last_date;
|
||||
@ -112,6 +120,7 @@ TEH_handler_post_aml_decision (
|
||||
new_state,
|
||||
decision_time,
|
||||
justification,
|
||||
kyc_requirements,
|
||||
officer_pub,
|
||||
&officer_sig,
|
||||
&invalid_officer,
|
||||
@ -127,6 +136,11 @@ TEH_handler_post_aml_decision (
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"add aml_decision");
|
||||
}
|
||||
if (NULL != kyc_requirements)
|
||||
{
|
||||
// FIXME: act on these!
|
||||
}
|
||||
|
||||
if (invalid_officer)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
|
@ -32,6 +32,7 @@ BEGIN
|
||||
',new_status INT4 NOT NULL DEFAULT(0)'
|
||||
',decision_time INT8 NOT NULL DEFAULT(0)'
|
||||
',justification VARCHAR NOT NULL'
|
||||
',kyc_requirements VARCHAR'
|
||||
',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
|
||||
',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
|
||||
') %s ;'
|
||||
@ -80,6 +81,12 @@ BEGIN
|
||||
,table_name
|
||||
,partition_suffix
|
||||
);
|
||||
PERFORM comment_partitioned_column(
|
||||
'Additional KYC requirements imposed by the AML staff member. Serialized JSON array of strings.'
|
||||
,'kyc_requirements'
|
||||
,table_name
|
||||
,partition_suffix
|
||||
);
|
||||
PERFORM comment_partitioned_column(
|
||||
'Signature key of the staff member affirming the AML decision; of type AML_DECISION'
|
||||
,'decider_sig'
|
||||
@ -114,7 +121,6 @@ BEGIN
|
||||
);
|
||||
END $$;
|
||||
|
||||
-- FIXME: also have INSERT on AML decisions to update AML status!
|
||||
|
||||
INSERT INTO exchange_tables
|
||||
(name
|
||||
|
@ -24,6 +24,7 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision(
|
||||
IN in_decider_pub BYTEA,
|
||||
IN in_decider_sig BYTEA,
|
||||
IN in_notify_s VARCHAR,
|
||||
IN in_kyc_requirements VARCHAR,
|
||||
OUT out_invalid_officer BOOLEAN,
|
||||
OUT out_last_date INT8)
|
||||
LANGUAGE plpgsql
|
||||
@ -84,6 +85,7 @@ INSERT INTO exchange.aml_history
|
||||
,new_status
|
||||
,decision_time
|
||||
,justification
|
||||
,kyc_requirements
|
||||
,decider_pub
|
||||
,decider_sig
|
||||
) VALUES
|
||||
@ -93,6 +95,7 @@ INSERT INTO exchange.aml_history
|
||||
,in_new_status
|
||||
,in_decision_time
|
||||
,in_justification
|
||||
,in_kyc_requirements
|
||||
,in_decider_pub
|
||||
,in_decider_sig);
|
||||
|
||||
@ -116,5 +119,5 @@ END IF;
|
||||
END $$;
|
||||
|
||||
|
||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR)
|
||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR)
|
||||
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
|
||||
|
@ -35,6 +35,7 @@ TEH_PG_insert_aml_decision (
|
||||
enum TALER_AmlDecisionState new_status,
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
@ -48,6 +49,9 @@ TEH_PG_insert_aml_decision (
|
||||
.h_payto = *h_payto
|
||||
};
|
||||
char *notify_s = GNUNET_PG_get_event_notify_channel (&rep.header);
|
||||
char *kyc_s = (NULL != kyc_requirements)
|
||||
? json_dumps (kyc_requirements, JSON_COMPACT)
|
||||
: NULL;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (h_payto),
|
||||
TALER_PQ_query_param_amount (new_threshold),
|
||||
@ -57,6 +61,9 @@ TEH_PG_insert_aml_decision (
|
||||
GNUNET_PQ_query_param_auto_from_type (decider_pub),
|
||||
GNUNET_PQ_query_param_auto_from_type (decider_sig),
|
||||
GNUNET_PQ_query_param_string (notify_s),
|
||||
NULL != kyc_requirements
|
||||
? GNUNET_PQ_query_param_string (kyc_s)
|
||||
: GNUNET_PQ_query_param_null (),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
@ -74,11 +81,13 @@ TEH_PG_insert_aml_decision (
|
||||
" out_invalid_officer"
|
||||
",out_last_date"
|
||||
" FROM exchange_do_insert_aml_decision"
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9);");
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
|
||||
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
||||
"do_insert_aml_decision",
|
||||
params,
|
||||
rs);
|
||||
GNUNET_free (notify_s);
|
||||
if (NULL != kyc_s)
|
||||
free (kyc_s);
|
||||
return qs;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
* @param new_status AML decision status
|
||||
* @param decision_time when was the decision made
|
||||
* @param justification human-readable text justifying the decision
|
||||
* @param kyc_requirements JSON array with KYC requirements
|
||||
* @param decider_pub public key of the staff member
|
||||
* @param decider_sig signature of the staff member
|
||||
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
|
||||
@ -51,6 +52,7 @@ TEH_PG_insert_aml_decision (
|
||||
enum TALER_AmlDecisionState new_status,
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
|
@ -2406,6 +2406,8 @@ TALER_officer_aml_query_verify (
|
||||
* @param h_payto payto URI hash of the account the
|
||||
* decision is about
|
||||
* @param new_state updated AML state
|
||||
* @param kyc_requirements additional KYC requirements to
|
||||
* impose, can be NULL
|
||||
* @param officer_priv private key of AML officer
|
||||
* @param[out] officer_sig where to write the signature
|
||||
*/
|
||||
@ -2416,6 +2418,7 @@ TALER_officer_aml_decision_sign (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
|
||||
struct TALER_AmlOfficerSignatureP *officer_sig);
|
||||
|
||||
@ -2430,6 +2433,8 @@ TALER_officer_aml_decision_sign (
|
||||
* @param h_payto payto URI hash of the account the
|
||||
* decision is about
|
||||
* @param new_state updated AML state
|
||||
* @param kyc_requirements additional KYC requirements to
|
||||
* impose, can be NULL
|
||||
* @param officer_pub public key of AML officer
|
||||
* @param officer_sig signature to verify
|
||||
* @return #GNUNET_OK if the signature is valid
|
||||
@ -2441,6 +2446,7 @@ TALER_officer_aml_decision_verify (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *officer_sig);
|
||||
|
||||
|
@ -4608,6 +4608,7 @@ typedef void
|
||||
* @param h_payto payto URI hash of the account the
|
||||
* decision is about
|
||||
* @param new_state updated AML state
|
||||
* @param kyc_requirements JSON array of KYC requirements being imposed, NULL for none
|
||||
* @param officer_priv private key of the deciding AML officer
|
||||
* @param cb function to call with the exchange's result
|
||||
* @param cb_cls closure for @a cb
|
||||
@ -4622,6 +4623,7 @@ TALER_EXCHANGE_add_aml_decision (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
|
||||
TALER_EXCHANGE_AddAmlDecisionCallback cb,
|
||||
void *cb_cls);
|
||||
|
@ -6704,6 +6704,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
enum TALER_AmlDecisionState new_status,
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
|
@ -2741,6 +2741,7 @@ TALER_TESTING_cmd_set_officer (
|
||||
* @param new_threshold new threshold to set
|
||||
* @param justification justification given for the decision
|
||||
* @param new_state new AML state for the account
|
||||
* @param kyc_requirement KYC requirement to impose
|
||||
* @param expected_response expected HTTP return status
|
||||
* @return the command
|
||||
*/
|
||||
@ -2752,6 +2753,7 @@ TALER_TESTING_cmd_take_aml_decision (
|
||||
const char *new_threshold,
|
||||
const char *justification,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const char *kyc_requirement,
|
||||
unsigned int expected_response);
|
||||
|
||||
|
||||
|
@ -132,6 +132,7 @@ TALER_EXCHANGE_add_aml_decision (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
|
||||
TALER_EXCHANGE_AddAmlDecisionCallback cb,
|
||||
void *cb_cls)
|
||||
@ -149,6 +150,7 @@ TALER_EXCHANGE_add_aml_decision (
|
||||
new_threshold,
|
||||
h_payto,
|
||||
new_state,
|
||||
kyc_requirements,
|
||||
officer_priv,
|
||||
&officer_sig);
|
||||
wh = GNUNET_new (struct TALER_EXCHANGE_AddAmlDecision);
|
||||
@ -190,6 +192,9 @@ TALER_EXCHANGE_add_aml_decision (
|
||||
h_payto),
|
||||
GNUNET_JSON_pack_uint64 ("new_state",
|
||||
(uint32_t) new_state),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_array_incref ("kyc_requirements",
|
||||
(json_t *) kyc_requirements)),
|
||||
TALER_JSON_pack_amount ("new_threshold",
|
||||
new_threshold),
|
||||
GNUNET_JSON_pack_timestamp ("decision_time",
|
||||
|
@ -448,6 +448,7 @@ run (void *cls,
|
||||
"EUR:10000",
|
||||
"party time",
|
||||
TALER_AML_NORMAL,
|
||||
NULL,
|
||||
MHD_HTTP_FORBIDDEN),
|
||||
/* Check that no decision was taken, but that we are allowed
|
||||
to read this information */
|
||||
@ -468,6 +469,7 @@ run (void *cls,
|
||||
"EUR:10000",
|
||||
"party time",
|
||||
TALER_AML_NORMAL,
|
||||
NULL,
|
||||
MHD_HTTP_NO_CONTENT),
|
||||
TALER_TESTING_cmd_check_aml_decisions ("check-decisions-one-normal",
|
||||
"create-aml-officer-1",
|
||||
@ -489,6 +491,7 @@ run (void *cls,
|
||||
"EUR:1000",
|
||||
"party over",
|
||||
TALER_AML_FROZEN,
|
||||
NULL,
|
||||
MHD_HTTP_NO_CONTENT),
|
||||
TALER_TESTING_cmd_check_aml_decisions ("check-decisions-one-frozen",
|
||||
"create-aml-officer-1",
|
||||
|
@ -72,6 +72,11 @@ struct AmlDecisionState
|
||||
*/
|
||||
const char *justification;
|
||||
|
||||
/**
|
||||
* KYC requirement to add.
|
||||
*/
|
||||
const char *kyc_requirement;
|
||||
|
||||
/**
|
||||
* Threshold transaction amount.
|
||||
*/
|
||||
@ -133,6 +138,7 @@ take_aml_decision_run (void *cls,
|
||||
const struct TALER_PaytoHashP *h_payto;
|
||||
const struct TALER_AmlOfficerPrivateKeyP *officer_priv;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
json_t *kyc_requirements = NULL;
|
||||
|
||||
(void) cmd;
|
||||
now = GNUNET_TIME_timestamp_get ();
|
||||
@ -160,6 +166,15 @@ take_aml_decision_run (void *cls,
|
||||
TALER_TESTING_get_trait_officer_priv (ref,
|
||||
&officer_priv));
|
||||
ds->h_payto = *h_payto;
|
||||
if (NULL != ds->kyc_requirement)
|
||||
{
|
||||
kyc_requirements = json_array ();
|
||||
GNUNET_assert (NULL != kyc_requirements);
|
||||
GNUNET_assert (0 ==
|
||||
json_array_append (kyc_requirements,
|
||||
json_string (ds->kyc_requirement)));
|
||||
}
|
||||
|
||||
ds->dh = TALER_EXCHANGE_add_aml_decision (
|
||||
is->ctx,
|
||||
is->exchange_url,
|
||||
@ -168,9 +183,11 @@ take_aml_decision_run (void *cls,
|
||||
&ds->new_threshold,
|
||||
h_payto,
|
||||
ds->new_state,
|
||||
kyc_requirements,
|
||||
officer_priv,
|
||||
&take_aml_decision_cb,
|
||||
ds);
|
||||
json_decref (kyc_requirements);
|
||||
if (NULL == ds->dh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -246,6 +263,7 @@ TALER_TESTING_cmd_take_aml_decision (
|
||||
const char *new_threshold,
|
||||
const char *justification,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const char *kyc_requirement,
|
||||
unsigned int expected_response)
|
||||
{
|
||||
struct AmlDecisionState *ds;
|
||||
@ -253,6 +271,7 @@ TALER_TESTING_cmd_take_aml_decision (
|
||||
ds = GNUNET_new (struct AmlDecisionState);
|
||||
ds->officer_ref_cmd = ref_officer;
|
||||
ds->account_ref_cmd = ref_operation;
|
||||
ds->kyc_requirement = kyc_requirement;
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (new_threshold,
|
||||
&ds->new_threshold))
|
||||
|
@ -56,6 +56,12 @@ struct TALER_AmlDecisionPS
|
||||
*/
|
||||
struct TALER_PaytoHashP h_payto GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* Hash over JSON array with KYC requirements that were imposed. All zeros
|
||||
* for none.
|
||||
*/
|
||||
struct GNUNET_HashCode h_kyc_requirements;
|
||||
|
||||
/**
|
||||
* What is the new AML status?
|
||||
*/
|
||||
@ -72,6 +78,7 @@ TALER_officer_aml_decision_sign (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
|
||||
struct TALER_AmlOfficerSignatureP *officer_sig)
|
||||
{
|
||||
@ -87,6 +94,9 @@ TALER_officer_aml_decision_sign (
|
||||
&ad.h_justification);
|
||||
TALER_amount_hton (&ad.new_threshold,
|
||||
new_threshold);
|
||||
if (NULL != kyc_requirements)
|
||||
TALER_json_hash (kyc_requirements,
|
||||
&ad.h_kyc_requirements);
|
||||
GNUNET_CRYPTO_eddsa_sign (&officer_priv->eddsa_priv,
|
||||
&ad,
|
||||
&officer_sig->eddsa_signature);
|
||||
@ -100,6 +110,7 @@ TALER_officer_aml_decision_verify (
|
||||
const struct TALER_Amount *new_threshold,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
enum TALER_AmlDecisionState new_state,
|
||||
const json_t *kyc_requirements,
|
||||
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *officer_sig)
|
||||
{
|
||||
@ -115,6 +126,9 @@ TALER_officer_aml_decision_verify (
|
||||
&ad.h_justification);
|
||||
TALER_amount_hton (&ad.new_threshold,
|
||||
new_threshold);
|
||||
if (NULL != kyc_requirements)
|
||||
TALER_json_hash (kyc_requirements,
|
||||
&ad.h_kyc_requirements);
|
||||
return GNUNET_CRYPTO_eddsa_verify (
|
||||
TALER_SIGNATURE_AML_DECISION,
|
||||
&ad,
|
||||
|
Loading…
Reference in New Issue
Block a user