[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: implement #6749: i18n of author
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: implement #6749: i18n of authorization plugins |
Date: |
Mon, 05 Apr 2021 20:51:47 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository anastasis.
The following commit(s) were added to refs/heads/master by this push:
new 94f3cfc implement #6749: i18n of authorization plugins
94f3cfc is described below
commit 94f3cfc5d58d423b574734f100f4cb7db22f334d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Apr 5 20:51:45 2021 +0200
implement #6749: i18n of authorization plugins
---
src/authorization/Makefile.am | 13 ++++
.../anastasis_authorization_plugin_email.c | 89 ++++++++++++++++++++--
.../anastasis_authorization_plugin_file.c | 7 +-
.../anastasis_authorization_plugin_post.c | 89 +++++++++++++++++++---
.../anastasis_authorization_plugin_sms.c | 80 ++++++++++++++++++-
.../authorization-email-messages.json | 10 +++
src/authorization/authorization-post-messages.json | 7 ++
src/authorization/authorization-sms-messages.json | 6 ++
8 files changed, 280 insertions(+), 21 deletions(-)
diff --git a/src/authorization/Makefile.am b/src/authorization/Makefile.am
index bce6db3..dffecbb 100644
--- a/src/authorization/Makefile.am
+++ b/src/authorization/Makefile.am
@@ -3,6 +3,15 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include
pkgcfgdir = $(prefix)/share/anastasis/config.d/
plugindir = $(libdir)/anastasis
+pkgdatadir= $(prefix)/share/anastasis/
+
+pkgdata_DATA = \
+ authorization-email-messages.json \
+ authorization-post-messages.json \
+ authorization-sms-messages.json
+
+EXTRA_DIST = $(pkgdata_DATA)
+
if USE_COVERAGE
AM_CFLAGS = --coverage -O0
@@ -32,6 +41,7 @@ libanastasis_plugin_authorization_file_la_LIBADD = \
libanastasis_plugin_authorization_file_la_LDFLAGS = \
$(ANASTASIS_PLUGIN_LDFLAGS) \
-ljansson \
+ -ltalerjson \
-ltalerutil \
-lgnunetutil \
$(XLIB)
@@ -43,6 +53,7 @@ libanastasis_plugin_authorization_email_la_LIBADD = \
libanastasis_plugin_authorization_email_la_LDFLAGS = \
$(ANASTASIS_PLUGIN_LDFLAGS) \
-ljansson \
+ -ltalerjson \
-ltalerutil \
-lgnunetutil \
$(XLIB)
@@ -54,6 +65,7 @@ libanastasis_plugin_authorization_post_la_LIBADD = \
libanastasis_plugin_authorization_post_la_LDFLAGS = \
$(ANASTASIS_PLUGIN_LDFLAGS) \
-ljansson \
+ -ltalerjson \
-ltalerutil \
-lgnunetutil \
$(XLIB)
@@ -65,6 +77,7 @@ libanastasis_plugin_authorization_sms_la_LIBADD = \
libanastasis_plugin_authorization_sms_la_LDFLAGS = \
$(ANASTASIS_PLUGIN_LDFLAGS) \
-ljansson \
+ -ltalerjson \
-ltalerutil \
-lgnunetutil \
$(XLIB)
diff --git a/src/authorization/anastasis_authorization_plugin_email.c
b/src/authorization/anastasis_authorization_plugin_email.c
index f5fdf26..46c8eb2 100644
--- a/src/authorization/anastasis_authorization_plugin_email.c
+++ b/src/authorization/anastasis_authorization_plugin_email.c
@@ -1,6 +1,6 @@
/*
This file is part of Anastasis
- Copyright (C) 2019 Taler Systems SA
+ Copyright (C) 2019-2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under
the
terms of the GNU Lesser General Public License as published by the Free
Software
@@ -21,6 +21,7 @@
#include "platform.h"
#include "anastasis_authorization_plugin.h"
#include <taler/taler_mhd_lib.h>
+#include <taler/taler_json_lib.h>
#include <regex.h>
#include "anastasis_util_lib.h"
@@ -42,6 +43,11 @@ struct Email_Context
*/
regex_t regex;
+ /**
+ * Messages of the plugin, read from a resource file.
+ */
+ json_t *messages;
+
};
@@ -115,10 +121,52 @@ struct ANASTASIS_AUTHORIZATION_State
*/
enum GNUNET_OS_ProcessStatusType pst;
-
};
+/**
+ * Obtain internationalized message @a msg_id from @a ctx using
+ * language preferences of @a conn.
+ *
+ * @param messages JSON object to lookup message from
+ * @param conn connection to lookup message for
+ * @param msg_id unique message ID
+ * @return NULL if message was not found
+ */
+static const char *
+get_message (const json_t *messages,
+ struct MHD_Connection *conn,
+ const char *msg_id)
+{
+ const char *accept_lang;
+
+ accept_lang = MHD_lookup_connection_value (conn,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if (NULL == accept_lang)
+ accept_lang = "en_US";
+ {
+ const char *ret;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_i18n_string (msg_id,
+ accept_lang,
+ &ret),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (messages,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ return ret;
+ }
+}
+
+
/**
* Validate @a data is a well-formed input into the challenge method,
* i.e. @a data is a well-formed phone number for sending an SMS, or
@@ -302,9 +350,10 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as,
tpk = GNUNET_STRINGS_data_to_string_alloc (
&as->truth_uuid,
sizeof (as->truth_uuid));
- /* FIXME #6749: i18n based on language preferences of the client */
GNUNET_asprintf (&as->msg,
- "Subject: Anastasis recovery code: A-%llu\n\nThis is
for challenge %s.\n",
+ get_message (as->ctx->messages,
+ connection,
+ "body"),
(unsigned long long) as->code,
tpk);
GNUNET_free (tpk);
@@ -404,9 +453,10 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as,
size_t reply_len;
char *reply;
- /* FIXME #6749: i18n based on language preferences of the client */
reply_len = GNUNET_asprintf (&reply,
- "Recovery TAN send to email %.*s@DOMAIN",
+ get_message (as->ctx->messages,
+ connection,
+ "instructions"),
(unsigned int) len,
as->email);
resp = MHD_create_response_from_buffer (reply_len,
@@ -471,6 +521,30 @@ libanastasis_plugin_authorization_email_init (void *cls)
struct Email_Context *ctx;
ctx = GNUNET_new (struct Email_Context);
+ {
+ char *fn;
+ json_error_t err;
+
+ GNUNET_asprintf (&fn,
+ "%sauthorization-email-messages.json",
+ GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR));
+ ctx->messages = json_load_file (fn,
+ JSON_REJECT_DUPLICATES,
+ &err);
+ if (NULL == ctx->messages)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load messages from `%s': %s at %d:%d\n",
+ fn,
+ err.text,
+ err.line,
+ err.column);
+ GNUNET_free (fn);
+ GNUNET_free (ctx);
+ return NULL;
+ }
+ GNUNET_free (fn);
+ }
{
int regex_result;
const char *regexp = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}";
@@ -481,6 +555,7 @@ libanastasis_plugin_authorization_email_init (void *cls)
if (0 < regex_result)
{
GNUNET_break (0);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
return NULL;
}
@@ -506,6 +581,7 @@ libanastasis_plugin_authorization_email_init (void *cls)
"authorization-email",
"COMMAND");
regfree (&ctx->regex);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
@@ -528,6 +604,7 @@ libanastasis_plugin_authorization_email_done (void *cls)
GNUNET_free (ctx->auth_command);
regfree (&ctx->regex);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
diff --git a/src/authorization/anastasis_authorization_plugin_file.c
b/src/authorization/anastasis_authorization_plugin_file.c
index 0c88719..210ade7 100644
--- a/src/authorization/anastasis_authorization_plugin_file.c
+++ b/src/authorization/anastasis_authorization_plugin_file.c
@@ -170,7 +170,7 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as,
"open",
as->filename);
resp = TALER_MHD_make_error (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "Failed to open file");
+ "open");
mres = MHD_queue_response (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
resp);
@@ -190,7 +190,7 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as,
GNUNET_break (0 == fclose (f));
resp = TALER_MHD_make_error (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "Failed to write to file");
+ "write");
mres = MHD_queue_response (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
resp);
@@ -222,9 +222,8 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as,
size_t response_size;
char *response;
- /* FIXME #6749: i18n based on 'lang' (language preferences of the
client!) */
response_size = GNUNET_asprintf (&response,
- "Challenge written to file");
+ _ ("Challenge written to file"));
resp = MHD_create_response_from_buffer (response_size,
response,
MHD_RESPMEM_MUST_COPY);
diff --git a/src/authorization/anastasis_authorization_plugin_post.c
b/src/authorization/anastasis_authorization_plugin_post.c
index 5ff2892..c77ac03 100644
--- a/src/authorization/anastasis_authorization_plugin_post.c
+++ b/src/authorization/anastasis_authorization_plugin_post.c
@@ -21,6 +21,7 @@
#include "platform.h"
#include "anastasis_authorization_plugin.h"
#include <taler/taler_mhd_lib.h>
+#include <taler/taler_json_lib.h>
#include <jansson.h>
#include "anastasis_util_lib.h"
@@ -37,6 +38,10 @@ struct PostContext
*/
char *auth_command;
+ /**
+ * Messages of the plugin, read from a resource file.
+ */
+ json_t *messages;
};
@@ -114,6 +119,49 @@ struct ANASTASIS_AUTHORIZATION_State
};
+/**
+ * Obtain internationalized message @a msg_id from @a ctx using
+ * language preferences of @a conn.
+ *
+ * @param messages JSON object to lookup message from
+ * @param conn connection to lookup message for
+ * @param msg_id unique message ID
+ * @return NULL if message was not found
+ */
+static const char *
+get_message (const json_t *messages,
+ struct MHD_Connection *conn,
+ const char *msg_id)
+{
+ const char *accept_lang;
+
+ accept_lang = MHD_lookup_connection_value (conn,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if (NULL == accept_lang)
+ accept_lang = "en_US";
+ {
+ const char *ret;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_i18n_string (msg_id,
+ accept_lang,
+ &ret),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (messages,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ return ret;
+ }
+}
+
+
/**
* Validate @a data is a well-formed input into the challenge method,
* i.e. @a data is a well-formed phone number for sending an SMS, or
@@ -374,14 +422,10 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as,
tpk = GNUNET_STRINGS_data_to_string_alloc (
&as->truth_uuid,
sizeof (as->truth_uuid));
- /* FIXME #6749: i18n based on language preferences of the client */
GNUNET_asprintf (&as->msg,
- "Dear Customer\n\n"
- "The Anastasis recovery code you need to\n"
- "recover your data is A-%llu.\n"
- "This is for challenge %s.\n\n"
- "Best regards\n\n"
- "Your Anastasis provider",
+ get_message (as->ctx->messages,
+ connection,
+ "body"),
(unsigned long long) as->code,
tpk);
GNUNET_free (tpk);
@@ -469,9 +513,10 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as,
size_t reply_len;
char *reply;
- /* FIXME #6749: i18n based on language preferences of the client */
reply_len = GNUNET_asprintf (&reply,
- "Recovery message zip code %s",
+ get_message (as->ctx->messages,
+ connection,
+ "instructions"),
zip);
resp = MHD_create_response_from_buffer (reply_len,
reply,
@@ -531,6 +576,30 @@ libanastasis_plugin_authorization_post_init (void *cls)
struct PostContext *ctx;
ctx = GNUNET_new (struct PostContext);
+ {
+ char *fn;
+ json_error_t err;
+
+ GNUNET_asprintf (&fn,
+ "%sauthorization-post-messages.json",
+ GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR));
+ ctx->messages = json_load_file (fn,
+ JSON_REJECT_DUPLICATES,
+ &err);
+ if (NULL == ctx->messages)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load messages from `%s': %s at %d:%d\n",
+ fn,
+ err.text,
+ err.line,
+ err.column);
+ GNUNET_free (fn);
+ GNUNET_free (ctx);
+ return NULL;
+ }
+ GNUNET_free (fn);
+ }
plugin = GNUNET_new (struct ANASTASIS_AuthorizationPlugin);
plugin->code_validity_period = GNUNET_TIME_UNIT_MONTHS;
plugin->code_rotation_period = GNUNET_TIME_UNIT_WEEKS;
@@ -552,6 +621,7 @@ libanastasis_plugin_authorization_post_init (void *cls)
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"authorization-post",
"COMMAND");
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
@@ -573,6 +643,7 @@ libanastasis_plugin_authorization_post_done (void *cls)
struct PostContext *ctx = plugin->cls;
GNUNET_free (ctx->auth_command);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
diff --git a/src/authorization/anastasis_authorization_plugin_sms.c
b/src/authorization/anastasis_authorization_plugin_sms.c
index 45bafe9..7b37b7b 100644
--- a/src/authorization/anastasis_authorization_plugin_sms.c
+++ b/src/authorization/anastasis_authorization_plugin_sms.c
@@ -21,6 +21,7 @@
#include "platform.h"
#include "anastasis_authorization_plugin.h"
#include <taler/taler_mhd_lib.h>
+#include <taler/taler_json_lib.h>
#include <regex.h>
#include "anastasis_util_lib.h"
@@ -42,6 +43,10 @@ struct SMS_Context
*/
regex_t regex;
+ /**
+ * Messages of the plugin, read from a resource file.
+ */
+ json_t *messages;
};
@@ -118,6 +123,49 @@ struct ANASTASIS_AUTHORIZATION_State
};
+/**
+ * Obtain internationalized message @a msg_id from @a ctx using
+ * language preferences of @a conn.
+ *
+ * @param messages JSON object to lookup message from
+ * @param conn connection to lookup message for
+ * @param msg_id unique message ID
+ * @return NULL if message was not found
+ */
+static const char *
+get_message (const json_t *messages,
+ struct MHD_Connection *conn,
+ const char *msg_id)
+{
+ const char *accept_lang;
+
+ accept_lang = MHD_lookup_connection_value (conn,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if (NULL == accept_lang)
+ accept_lang = "en_US";
+ {
+ const char *ret;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_i18n_string (msg_id,
+ accept_lang,
+ &ret),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (messages,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ return ret;
+ }
+}
+
+
/**
* Validate @a data is a well-formed input into the challenge method,
* i.e. @a data is a well-formed phone number for sending an SMS, or
@@ -398,9 +446,10 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as,
size_t reply_len;
char *reply;
- /* FIXME #6749: i18n based on language preferences of the client */
reply_len = GNUNET_asprintf (&reply,
- "Recovery TAN send to phone number ending
with %s",
+ get_message (as->ctx->messages,
+ connection,
+ "instructions"),
end);
resp = MHD_create_response_from_buffer (reply_len,
reply,
@@ -464,6 +513,30 @@ libanastasis_plugin_authorization_sms_init (void *cls)
struct SMS_Context *ctx;
ctx = GNUNET_new (struct SMS_Context);
+ {
+ char *fn;
+ json_error_t err;
+
+ GNUNET_asprintf (&fn,
+ "%sauthorization-sms-messages.json",
+ GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR));
+ ctx->messages = json_load_file (fn,
+ JSON_REJECT_DUPLICATES,
+ &err);
+ if (NULL == ctx->messages)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load messages from `%s': %s at %d:%d\n",
+ fn,
+ err.text,
+ err.line,
+ err.column);
+ GNUNET_free (fn);
+ GNUNET_free (ctx);
+ return NULL;
+ }
+ GNUNET_free (fn);
+ }
{
int regex_result;
const char *regexp = "^\\+?[0-9]+$";
@@ -474,6 +547,7 @@ libanastasis_plugin_authorization_sms_init (void *cls)
if (0 != regex_result)
{
GNUNET_break (0);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
return NULL;
}
@@ -498,6 +572,7 @@ libanastasis_plugin_authorization_sms_init (void *cls)
"authorization-sms",
"COMMAND");
regfree (&ctx->regex);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
@@ -520,6 +595,7 @@ libanastasis_plugin_authorization_email_done (void *cls)
GNUNET_free (ctx->auth_command);
regfree (&ctx->regex);
+ json_decref (ctx->messages);
GNUNET_free (ctx);
GNUNET_free (plugin);
return NULL;
diff --git a/src/authorization/authorization-email-messages.json
b/src/authorization/authorization-email-messages.json
new file mode 100644
index 0000000..bdcd6db
--- /dev/null
+++ b/src/authorization/authorization-email-messages.json
@@ -0,0 +1,10 @@
+{
+ "instructions" : "Recovery TAN send to email %.*s@DOMAIN",
+ "instructions_i18n" : {
+ "de_DE" : "Ein Authorisierungscode wurde an %.*s@DOMAIN geschickt"
+ }
+ "body" : "Subject: Anastasis recovery code: A-%llu\n\nThis is for
challenge %s.\n",
+ "body_i18n" : {
+ "de_DE" : "Subject: Anastasis Autorisierungscode: A-%llu\n\nDies ist
der Code für den Vorgang %s.\n"
+ }
+}
diff --git a/src/authorization/authorization-post-messages.json
b/src/authorization/authorization-post-messages.json
new file mode 100644
index 0000000..8152c27
--- /dev/null
+++ b/src/authorization/authorization-post-messages.json
@@ -0,0 +1,7 @@
+{
+ "instructions" : "Recovery message send to an address with ZIP code %s",
+ "instructions_i18n" : {
+ "de_DE" : "Ein Authorisierungscode wurde an eine Addresse mit der
Postleitzahl %s geschickt"
+ }
+ "body" : "Dear Customer\n\nThe Anastasis recovery code you need
to\nrecover your data is A-%llu.\nThis is for challenge %s.\n\nBest
regards\n\nYour Anastasis provider"
+}
diff --git a/src/authorization/authorization-sms-messages.json
b/src/authorization/authorization-sms-messages.json
new file mode 100644
index 0000000..cb45ed8
--- /dev/null
+++ b/src/authorization/authorization-sms-messages.json
@@ -0,0 +1,6 @@
+{
+ "instructions" : "Recovery TAN send to phone number ending with %s",
+ "instructions_i18n" : {
+ "de_DE" : "Ein Authorisierungscode wurde an die Telefonnummer mit der
Endung %s geschickt"
+ }
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: implement #6749: i18n of authorization plugins,
gnunet <=