added birthdate parser
This commit is contained in:
parent
ddd0e0af13
commit
145310e20e
@ -19,9 +19,12 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler-exchange-httpd.h"
|
||||
#include "taler-exchange-httpd_common_kyc.h"
|
||||
#include "taler_attributes.h"
|
||||
#include "taler_error_codes.h"
|
||||
#include "taler_exchangedb_plugin.h"
|
||||
#include <gnunet/gnunet_common.h>
|
||||
|
||||
struct TEH_KycAmlTrigger
|
||||
{
|
||||
@ -114,7 +117,7 @@ kyc_aml_finished (void *cls,
|
||||
size_t eas;
|
||||
void *ea;
|
||||
const char *birthdate;
|
||||
unsigned int birthday;
|
||||
unsigned int birthday = 0;
|
||||
struct GNUNET_ShortHashCode kyc_prox;
|
||||
struct GNUNET_AsyncScopeSave old_scope;
|
||||
|
||||
@ -125,9 +128,29 @@ kyc_aml_finished (void *cls,
|
||||
&kyc_prox);
|
||||
birthdate = json_string_value (json_object_get (kat->attributes,
|
||||
TALER_ATTRIBUTE_BIRTHDATE));
|
||||
birthday = 0; (void) birthdate; // FIXME-Oec: calculate birthday here...
|
||||
// Convert 'birthdate' to time after 1970, then compute days.
|
||||
// Then compare against max age-restriction, and if before, set to 0.
|
||||
|
||||
if (TEH_age_restriction_enabled)
|
||||
{
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
ret = TALER_parse_coarse_date (birthdate,
|
||||
&TEH_age_restriction_config.mask,
|
||||
&birthday);
|
||||
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
if (NULL != kat->response)
|
||||
MHD_destroy_response (kat->response);
|
||||
kat->http_status = MHD_HTTP_BAD_REQUEST;
|
||||
kat->response = TALER_MHD_make_error (
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
TALER_ATTRIBUTE_BIRTHDATE);
|
||||
|
||||
/* FIXME-Christian: shouldn't we return in the error case? */
|
||||
}
|
||||
}
|
||||
|
||||
TALER_CRYPTO_kyc_attributes_encrypt (&TEH_attribute_key,
|
||||
kat->attributes,
|
||||
&ea,
|
||||
@ -159,6 +182,8 @@ kyc_aml_finished (void *cls,
|
||||
kat->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
|
||||
kat->response = TALER_MHD_make_error (TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"do_insert_kyc_attributes");
|
||||
|
||||
/* FIXME-Christian: shouldn't we return in the error case? */
|
||||
}
|
||||
/* Finally, return result to main handler */
|
||||
kat->cb (kat->cb_cls,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#ifndef TALER_UTIL_H
|
||||
#define TALER_UTIL_H
|
||||
|
||||
#include <gnunet/gnunet_common.h>
|
||||
#define __TALER_UTIL_LIB_H_INSIDE__
|
||||
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
@ -510,6 +511,33 @@ char *strchrnul (const char *s, int c);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Parses a date information into days after 1970-01-01 (or 0)
|
||||
*
|
||||
* The input MUST be of the form
|
||||
*
|
||||
* 1) YYYY-MM-DD, representing a valid date
|
||||
* 2) YYYY-MM-00, representing a valid month in a particular year
|
||||
* 3) YYYY-00-00, representing a valid year.
|
||||
*
|
||||
* In the cases 2) and 3) the out parameter is set to the beginning of the
|
||||
* time, f.e. 1950-00-00 == 1950-01-01 and 1888-03-00 == 1888-03-01
|
||||
*
|
||||
* The output will set to the number of days after 1970-01-01 or 0, if the input
|
||||
* represents a date belonging to the largest allowed age group.
|
||||
*
|
||||
* @param in Input string representation of the date
|
||||
* @param mask Age mask
|
||||
* @param[out] out Where to write the result
|
||||
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_parse_coarse_date (
|
||||
const char *in,
|
||||
const struct TALER_AgeMask *mask,
|
||||
uint32_t *out);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parses a string as a list of age groups.
|
||||
*
|
||||
|
@ -710,4 +710,57 @@ TALER_age_restriction_from_secret (
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_parse_coarse_date (
|
||||
const char *in,
|
||||
const struct TALER_AgeMask *mask,
|
||||
uint32_t *out)
|
||||
{
|
||||
struct tm date = {0};
|
||||
struct tm limit = {0};
|
||||
time_t seconds;
|
||||
|
||||
if (NULL == in)
|
||||
{
|
||||
/* FIXME[oec]: correct behaviour? */
|
||||
*out = 0;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
GNUNET_assert (NULL !=mask);
|
||||
GNUNET_assert (NULL !=out);
|
||||
|
||||
if (NULL == strptime (in, "%Y-%0m-%0d", &date))
|
||||
{
|
||||
if (NULL == strptime (in, "%Y-%0m-00", &date))
|
||||
if (NULL == strptime (in, "%Y-00-00", &date))
|
||||
return GNUNET_SYSERR;
|
||||
|
||||
/* turns out that the day is off by one in the last two cases */
|
||||
date.tm_mday += 1;
|
||||
}
|
||||
|
||||
seconds = mktime (&date);
|
||||
if (-1 == seconds)
|
||||
return GNUNET_SYSERR;
|
||||
|
||||
/* calculate the limit date for the largest age group */
|
||||
localtime_r (&(time_t){time (NULL)}, &limit);
|
||||
limit.tm_year -= TALER_get_lowest_age (mask, 255);
|
||||
GNUNET_assert (-1 != mktime (&limit));
|
||||
|
||||
if ((limit.tm_year < date.tm_year)
|
||||
|| ((limit.tm_year == date.tm_year)
|
||||
&& (limit.tm_mon < date.tm_mon))
|
||||
|| ((limit.tm_year == date.tm_year)
|
||||
&& (limit.tm_mon == date.tm_mon)
|
||||
&& (limit.tm_mday < date.tm_mday)))
|
||||
*out = seconds / 60 / 60 / 24;
|
||||
else
|
||||
*out = 0;
|
||||
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/* end util/age_restriction.c */
|
||||
|
@ -129,6 +129,77 @@ test_groups (void)
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
test_dates (void)
|
||||
{
|
||||
struct TALER_AgeMask mask = {
|
||||
.bits = 1 | 1 << 5 | 1 << 9 | 1 << 13 | 1 << 17 | 1 << 21
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
char *date;
|
||||
uint32_t expected;
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
}
|
||||
test [] = {
|
||||
{.date = "abcd-00-00", .expected = 0, .ret = GNUNET_SYSERR},
|
||||
{.date = "1900-00-01", .expected = 0, .ret = GNUNET_SYSERR},
|
||||
{.date = "19000001", .expected = 0, .ret = GNUNET_SYSERR},
|
||||
{.date = "2001-33-05", .expected = 0, .ret = GNUNET_SYSERR},
|
||||
{.date = "2001-33-35", .expected = 0, .ret = GNUNET_SYSERR},
|
||||
|
||||
{.date = "1900-00-00", .expected = 0, .ret = GNUNET_OK},
|
||||
{.date = "2001-00-00", .expected = 0, .ret = GNUNET_OK},
|
||||
{.date = "2001-03-00", .expected = 0, .ret = GNUNET_OK},
|
||||
{.date = "2001-03-05", .expected = 0, .ret = GNUNET_OK},
|
||||
|
||||
/* These dates should be far enough for the near future so that
|
||||
* the expected values are correct. Will need adjustment in 2044 :) */
|
||||
{.date = "2023-06-26", .expected = 19533, .ret = GNUNET_OK },
|
||||
{.date = "2023-06-01", .expected = 19508, .ret = GNUNET_OK },
|
||||
{.date = "2023-06-00", .expected = 19508, .ret = GNUNET_OK },
|
||||
{.date = "2023-01-01", .expected = 19357, .ret = GNUNET_OK },
|
||||
{.date = "2023-00-00", .expected = 19357, .ret = GNUNET_OK },
|
||||
};
|
||||
|
||||
for (uint8_t t = 0; t < sizeof(test) / sizeof(test[0]); t++)
|
||||
{
|
||||
uint32_t d;
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
ret = TALER_parse_coarse_date (test[t].date,
|
||||
&mask,
|
||||
&d);
|
||||
if (ret != test[t].ret)
|
||||
{
|
||||
printf (
|
||||
"dates[%d] for date `%s` expected parser to return: %d, got: %d\n",
|
||||
t, test[t].date, test[t].ret, ret);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
if (ret == GNUNET_SYSERR)
|
||||
continue;
|
||||
|
||||
if (d != test[t].expected)
|
||||
{
|
||||
printf (
|
||||
"dates[%d] for date `%s` expected value %d, but got %d\n",
|
||||
t, test[t].date, test[t].expected, d);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
printf ("dates[%d] for date `%s` got expected value %d\n",
|
||||
t, test[t].date, d);
|
||||
}
|
||||
|
||||
printf ("done with dates\n");
|
||||
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
test_lowest (void)
|
||||
{
|
||||
@ -308,6 +379,8 @@ main (int argc,
|
||||
GNUNET_break (0);
|
||||
return 3;
|
||||
}
|
||||
if (GNUNET_OK != test_dates ())
|
||||
return 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user