gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]