more towards actually allowing AML decisions to trigger KYC
This commit is contained in:
parent
86e0f2c70d
commit
aa5e7d2ad5
@ -103,6 +103,85 @@ make_aml_decision (void *cls,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct GNUNET_TIME_Timestamp last_date;
|
||||
bool invalid_officer;
|
||||
uint64_t requirement_row = 0;
|
||||
|
||||
if ( (NULL != dc->kyc_requirements) &&
|
||||
(0 != json_array_size (dc->kyc_requirements)) )
|
||||
{
|
||||
char *res = NULL;
|
||||
size_t idx;
|
||||
json_t *req;
|
||||
bool satisfied;
|
||||
|
||||
json_array_foreach (dc->kyc_requirements, idx, req)
|
||||
{
|
||||
const char *r = json_string_value (req);
|
||||
|
||||
if (NULL == res)
|
||||
{
|
||||
res = GNUNET_strdup (r);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
GNUNET_asprintf (&tmp,
|
||||
"%s %s",
|
||||
res,
|
||||
r);
|
||||
GNUNET_free (res);
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
json_t *kyc_details = NULL;
|
||||
|
||||
qs = TALER_KYCLOGIC_check_satisfied (
|
||||
&res,
|
||||
&dc->h_payto,
|
||||
&kyc_details,
|
||||
TEH_plugin->select_satisfied_kyc_processes,
|
||||
TEH_plugin->cls,
|
||||
&satisfied);
|
||||
json_decref (kyc_details);
|
||||
}
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||
"select_satisfied_kyc_processes");
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
if (! satisfied)
|
||||
{
|
||||
qs = TEH_plugin->insert_kyc_requirement_for_account (
|
||||
TEH_plugin->cls,
|
||||
res,
|
||||
&dc->h_payto,
|
||||
&requirement_row);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"insert_kyc_requirement_for_account");
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
}
|
||||
GNUNET_free (res);
|
||||
}
|
||||
|
||||
qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
|
||||
&dc->h_payto,
|
||||
@ -111,6 +190,7 @@ make_aml_decision (void *cls,
|
||||
dc->decision_time,
|
||||
dc->justification,
|
||||
dc->kyc_requirements,
|
||||
requirement_row,
|
||||
dc->officer_pub,
|
||||
&dc->officer_sig,
|
||||
&invalid_officer,
|
||||
@ -151,11 +231,6 @@ make_aml_decision (void *cls,
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
if (NULL != dc->kyc_requirements)
|
||||
{
|
||||
// FIXME: act on these!
|
||||
}
|
||||
|
||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ batch_withdraw_transaction (void *cls,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
bool balance_ok = false;
|
||||
bool found = false;
|
||||
const char *kyc_required;
|
||||
char *kyc_required;
|
||||
struct TALER_PaytoHashP reserve_h_payto;
|
||||
|
||||
wc->now = GNUNET_TIME_timestamp_get ();
|
||||
@ -349,11 +349,22 @@ batch_withdraw_transaction (void *cls,
|
||||
{
|
||||
/* insert KYC requirement into DB! */
|
||||
wc->kyc.ok = false;
|
||||
return TEH_plugin->insert_kyc_requirement_for_account (
|
||||
qs = TEH_plugin->insert_kyc_requirement_for_account (
|
||||
TEH_plugin->cls,
|
||||
kyc_required,
|
||||
&wc->h_payto,
|
||||
&wc->kyc.requirement_row);
|
||||
GNUNET_free (kyc_required);
|
||||
if (qs < 0)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"insert_kyc_requirement_for_account");
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
wc->kyc.ok = true;
|
||||
qs = TEH_plugin->do_batch_withdraw (TEH_plugin->cls,
|
||||
|
@ -332,7 +332,7 @@ kyc_check (void *cls,
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
qs = TALER_KYCLOGIC_check_satisfied (
|
||||
requirements,
|
||||
&requirements,
|
||||
&h_payto,
|
||||
&kyp->kyc_details,
|
||||
TEH_plugin->select_satisfied_kyc_processes,
|
||||
@ -389,6 +389,17 @@ kyc_check (void *cls,
|
||||
NULL,
|
||||
NULL,
|
||||
&kyp->process_row);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"insert_kyc_requirement_process");
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Initiating KYC check with logic %s\n",
|
||||
kyp->ih_logic->name);
|
||||
|
@ -237,7 +237,7 @@ TEH_handler_kyc_wallet (
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
GNUNET_free (kyc.required);
|
||||
GNUNET_free (krc.required);
|
||||
return TEH_RESPONSE_reply_kyc_required (rc->connection,
|
||||
&krc.h_payto,
|
||||
&krc.kyc);
|
||||
|
@ -33,6 +33,7 @@ BEGIN
|
||||
',decision_time INT8 NOT NULL DEFAULT(0)'
|
||||
',justification VARCHAR NOT NULL'
|
||||
',kyc_requirements VARCHAR'
|
||||
',kyc_req_row INT8 NOT NULL DEFAULT(0)'
|
||||
',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
|
||||
',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
|
||||
') %s ;'
|
||||
@ -87,6 +88,12 @@ BEGIN
|
||||
,table_name
|
||||
,partition_suffix
|
||||
);
|
||||
PERFORM comment_partitioned_column(
|
||||
'Row in the KYC table for this KYC requirement, 0 for none.'
|
||||
,'kyc_req_row'
|
||||
,table_name
|
||||
,partition_suffix
|
||||
);
|
||||
PERFORM comment_partitioned_column(
|
||||
'Signature key of the staff member affirming the AML decision; of type AML_DECISION'
|
||||
,'decider_sig'
|
||||
|
@ -25,6 +25,7 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision(
|
||||
IN in_decider_sig BYTEA,
|
||||
IN in_notify_s VARCHAR,
|
||||
IN in_kyc_requirements VARCHAR,
|
||||
IN in_requirement_row INT8,
|
||||
OUT out_invalid_officer BOOLEAN,
|
||||
OUT out_last_date INT8)
|
||||
LANGUAGE plpgsql
|
||||
@ -86,6 +87,7 @@ INSERT INTO exchange.aml_history
|
||||
,decision_time
|
||||
,justification
|
||||
,kyc_requirements
|
||||
,kyc_req_row
|
||||
,decider_pub
|
||||
,decider_sig
|
||||
) VALUES
|
||||
@ -96,6 +98,7 @@ INSERT INTO exchange.aml_history
|
||||
,in_decision_time
|
||||
,in_justification
|
||||
,in_kyc_requirements
|
||||
,in_requirement_row
|
||||
,in_decider_pub
|
||||
,in_decider_sig);
|
||||
|
||||
@ -119,5 +122,5 @@ END IF;
|
||||
END $$;
|
||||
|
||||
|
||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR)
|
||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR, INT8)
|
||||
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
|
||||
|
@ -36,6 +36,7 @@ TEH_PG_insert_aml_decision (
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
uint64_t requirements_row,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
@ -64,6 +65,7 @@ TEH_PG_insert_aml_decision (
|
||||
NULL != kyc_requirements
|
||||
? GNUNET_PQ_query_param_string (kyc_s)
|
||||
: GNUNET_PQ_query_param_null (),
|
||||
GNUNET_PQ_query_param_uint64 (&requirements_row),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
@ -81,7 +83,7 @@ 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, $10);");
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
|
||||
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
||||
"do_insert_aml_decision",
|
||||
params,
|
||||
|
@ -37,6 +37,7 @@
|
||||
* @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 requirements_row row in the KYC table for this process, 0 for none
|
||||
* @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
|
||||
@ -53,6 +54,7 @@ TEH_PG_insert_aml_decision (
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
uint64_t requirements_row,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
|
@ -6689,6 +6689,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @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 specific KYC requiremnts being imposed
|
||||
* @param requirements_row row in the KYC table for this process, 0 for none
|
||||
* @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
|
||||
@ -6705,6 +6707,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
struct GNUNET_TIME_Timestamp decision_time,
|
||||
const char *justification,
|
||||
const json_t *kyc_requirements,
|
||||
uint64_t requirements_row,
|
||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||
bool *invalid_officer,
|
||||
|
@ -232,7 +232,8 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
|
||||
* Check if the @a requirements are now satsified for
|
||||
* @a h_payto account.
|
||||
*
|
||||
* @param requirements space-spearated list of requirements
|
||||
* @param[in,out] requirements space-spearated list of requirements,
|
||||
* already satisfied requirements are removed from the list
|
||||
* @param h_payto hash over the account
|
||||
* @param[out] kyc_details if satisfied, set to what kind of
|
||||
* KYC information was collected
|
||||
@ -242,7 +243,7 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
|
||||
* @return transaction status (from @a ki)
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
||||
TALER_KYCLOGIC_check_satisfied (char **requirements,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
json_t **kyc_details,
|
||||
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
||||
|
@ -1228,7 +1228,7 @@ TALER_KYCLOGIC_kyc_get_details (
|
||||
|
||||
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
||||
TALER_KYCLOGIC_check_satisfied (char **requirements,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
json_t **kyc_details,
|
||||
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
||||
@ -1244,13 +1244,14 @@ TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
||||
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
||||
}
|
||||
{
|
||||
char *req = GNUNET_strdup (requirements);
|
||||
char *req = *requirements;
|
||||
|
||||
for (const char *tok = strtok (req, " ");
|
||||
NULL != tok;
|
||||
tok = strtok (NULL, " "))
|
||||
needed[needed_cnt++] = add_check (tok);
|
||||
GNUNET_free (req);
|
||||
*requirements = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
@ -1286,6 +1287,32 @@ TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
||||
}
|
||||
}
|
||||
*satisfied = (0 == needed_cnt);
|
||||
|
||||
{
|
||||
char *res = NULL;
|
||||
|
||||
for (unsigned int i = 0; i<needed_cnt; i++)
|
||||
{
|
||||
const struct TALER_KYCLOGIC_KycCheck *need = needed[i];
|
||||
|
||||
if (NULL == res)
|
||||
{
|
||||
res = GNUNET_strdup (need->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
GNUNET_asprintf (&tmp,
|
||||
"%s %s",
|
||||
res,
|
||||
need->name);
|
||||
GNUNET_free (res);
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
*requirements = res;
|
||||
}
|
||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user