gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 01/03: anastasis-core: fix upload fee computation, p


From: gnunet
Subject: [taler-wallet-core] 01/03: anastasis-core: fix upload fee computation, prepare for payments
Date: Thu, 04 Nov 2021 20:20:15 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 11e8060ab156e5033c7dd5cd607648d584540883
Author: Florian Dold <florian@dold.me>
AuthorDate: Thu Nov 4 20:02:04 2021 +0100

    anastasis-core: fix upload fee computation, prepare for payments
---
 packages/anastasis-core/src/index.ts         | 127 +++++++++++++--------------
 packages/anastasis-core/src/reducer-types.ts |  36 ++++++++
 2 files changed, 98 insertions(+), 65 deletions(-)

diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index 2ed69b55..0bab510d 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -51,21 +51,17 @@ import {
   codecForActionArgsUpdateExpiration,
   ContinentInfo,
   CountryInfo,
-  MethodSpec,
-  Policy,
-  PolicyProvider,
   RecoveryInformation,
   RecoveryInternalData,
   RecoveryStates,
   ReducerState,
   ReducerStateBackup,
-  ReducerStateBackupUserAttributesCollecting,
   ReducerStateError,
   ReducerStateRecovery,
   SuccessDetails,
-  UserAttributeSpec,
   codecForActionArgsChangeVersion,
   ActionArgsChangeVersion,
+  TruthMetaData,
 } from "./reducer-types.js";
 import fetchPonyfill from "fetch-ponyfill";
 import {
@@ -302,35 +298,6 @@ async function backupEnterUserAttributes(
   return newState;
 }
 
-/**
- * Truth data as stored in the reducer.
- */
-interface TruthMetaData {
-  uuid: string;
-
-  key_share: string;
-
-  policy_index: number;
-
-  pol_method_index: number;
-
-  /**
-   * Nonce used for encrypting the truth.
-   */
-  nonce: string;
-
-  /**
-   * Key that the truth (i.e. secret question answer, email address, mobile 
number, ...)
-   * is encrypted with when stored at the provider.
-   */
-  truth_key: string;
-
-  /**
-   * Truth-specific salt.
-   */
-  truth_salt: string;
-}
-
 async function getTruthValue(
   authMethod: AuthMethod,
   truthUuid: string,
@@ -512,6 +479,8 @@ async function uploadSecret(
 
   const successDetails: SuccessDetails = {};
 
+  const policyPayUris: string[] = [];
+
   for (const prov of state.policy_providers!) {
     const uid = uidMap[prov.provider_url];
     const acctKeypair = accountKeypairDerive(uid);
@@ -536,26 +505,46 @@ async function uploadSecret(
         body: decodeCrock(encRecoveryDoc),
       },
     );
-    if (resp.status !== 204) {
-      return {
-        code: TalerErrorCode.ANASTASIS_REDUCER_NETWORK_FAILED,
-        hint: `could not upload policy (http status ${resp.status})`,
+    if (resp.status === HttpStatusCode.Accepted) {
+      let policyVersion = 0;
+      let policyExpiration: Timestamp = { t_ms: 0 };
+      try {
+        policyVersion = Number(resp.headers.get("Anastasis-Version") ?? "0");
+      } catch (e) {}
+      try {
+        policyExpiration = {
+          t_ms:
+            1000 *
+            Number(resp.headers.get("Anastasis-Policy-Expiration") ?? "0"),
+        };
+      } catch (e) {}
+      successDetails[prov.provider_url] = {
+        policy_version: policyVersion,
+        policy_expiration: policyExpiration,
       };
     }
-    let policyVersion = 0;
-    let policyExpiration: Timestamp = { t_ms: 0 };
-    try {
-      policyVersion = Number(resp.headers.get("Anastasis-Version") ?? "0");
-    } catch (e) {}
-    try {
-      policyExpiration = {
-        t_ms:
-          1000 * Number(resp.headers.get("Anastasis-Policy-Expiration") ?? 
"0"),
-      };
-    } catch (e) {}
-    successDetails[prov.provider_url] = {
-      policy_version: policyVersion,
-      policy_expiration: policyExpiration,
+    if (resp.status === HttpStatusCode.PaymentRequired) {
+      const talerPayUri = resp.headers.get("Taler");
+      if (!talerPayUri) {
+        return {
+          code: TalerErrorCode.ANASTASIS_REDUCER_BACKEND_FAILURE,
+          hint: `payment requested, but no taler://pay URI given`,
+        };
+      }
+      policyPayUris.push(talerPayUri);
+      continue;
+    }
+    return {
+      code: TalerErrorCode.ANASTASIS_REDUCER_NETWORK_FAILED,
+      hint: `could not upload policy (http status ${resp.status})`,
+    };
+  }
+
+  if (policyPayUris.length > 0) {
+    return {
+      ...state,
+      backup_state: BackupStates.PoliciesPaying,
+      payments: policyPayUris,
     };
   }
 
@@ -1048,7 +1037,6 @@ async function updateUploadFees(
   }
   logger.info("updating upload fees");
   const feePerCurrency: Record<string, AmountJson> = {};
-  const coveredProviders = new Set<string>();
   const addFee = (x: AmountLike) => {
     x = Amounts.jsonifyAmount(x);
     feePerCurrency[x.currency] = Amounts.add(
@@ -1058,24 +1046,31 @@ async function updateUploadFees(
   };
   const years = Duration.toIntegerYears(Duration.getRemaining(expiration));
   logger.info(`computing fees for ${years} years`);
+  // For now, we compute fees for *all* available providers.
+  for (const provUrl in state.authentication_providers ?? {}) {
+    const prov = state.authentication_providers![provUrl];
+    if ("annual_fee" in prov) {
+      const annualFee = Amounts.mult(prov.annual_fee, years).amount;
+      logger.info(`adding annual fee ${Amounts.stringify(annualFee)}`);
+      addFee(annualFee);
+    }
+  }
+  const coveredProvTruth = new Set<string>();
   for (const x of state.policies ?? []) {
     for (const m of x.methods) {
       const prov = state.authentication_providers![
         m.provider
       ] as AuthenticationProviderStatusOk;
       const authMethod = 
state.authentication_methods![m.authentication_method];
-      if (!coveredProviders.has(m.provider)) {
-        const annualFee = Amounts.mult(prov.annual_fee, years).amount;
-        logger.info(`adding annual fee ${Amounts.stringify(annualFee)}`);
-        addFee(annualFee);
-        coveredProviders.add(m.provider);
-      }
-      for (const pm of prov.methods) {
-        if (pm.type === authMethod.type) {
-          addFee(pm.usage_fee);
-          break;
-        }
+      const key = `${m.authentication_method}@${m.provider}`;
+      if (coveredProvTruth.has(key)) {
+        continue;
       }
+      logger.info(
+        `adding cost for auth method ${authMethod.challenge} / 
"${authMethod.instructions}" at ${m.provider}`,
+      );
+      coveredProvTruth.add(key);
+      addFee(prov.truth_upload_fee);
     }
   }
   return {
@@ -1252,7 +1247,9 @@ const recoveryTransitions: Record<
     ...transition("solve_challenge", codecForAny(), solveChallenge),
   },
   [RecoveryStates.ChallengePaying]: {},
-  [RecoveryStates.RecoveryFinished]: {},
+  [RecoveryStates.RecoveryFinished]: {
+    ...transitionRecoveryJump("back", RecoveryStates.ChallengeSelecting),
+  },
 };
 
 export async function reduceAction(
diff --git a/packages/anastasis-core/src/reducer-types.ts 
b/packages/anastasis-core/src/reducer-types.ts
index 08e61cef..318e00f8 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -67,6 +67,13 @@ export interface ReducerStateBackup {
   secret_name?: string;
   policies?: Policy[];
 
+  /**
+   * Map from truth key (`${methodIndex}/${providerUrl}`) to
+   * the truth metadata.
+   */
+  truth_metadata?: Record<string, TruthMetaData>;
+  recovery_document?: RecoveryDocument;
+
   /**
    * Policy providers are providers that we checked to be functional
    * and that are actually used in policies.
@@ -198,6 +205,35 @@ export interface ReducerStateRecovery {
   authentication_providers?: { [url: string]: AuthenticationProviderStatus };
 }
 
+/**
+ * Truth data as stored in the reducer.
+ */
+export interface TruthMetaData {
+  uuid: string;
+
+  key_share: string;
+
+  policy_index: number;
+
+  pol_method_index: number;
+
+  /**
+   * Nonce used for encrypting the truth.
+   */
+  nonce: string;
+
+  /**
+   * Key that the truth (i.e. secret question answer, email address, mobile 
number, ...)
+   * is encrypted with when stored at the provider.
+   */
+  truth_key: string;
+
+  /**
+   * Truth-specific salt.
+   */
+  truth_salt: string;
+}
+
 export interface ReducerStateError {
   backup_state?: undefined;
   recovery_state?: undefined;

-- 
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]