summaryrefslogtreecommitdiff
path: root/src/backend-lib/merchant_api_contract.c
blob: 239e29fbfca6affe90f18b61869cc7a3cb5ee88f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
  This file is part of TALER
  (C) 2014 Christian Grothoff (and other contributing authors)

  TALER is free software; you can redistribute it and/or modify it under the
  terms of the GNU General Public License as published by the Free Software
  Foundation; either version 3, or (at your option) any later version.

  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along with
  TALER; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
*/

/**
 * @file merchant/merchant_db.c
 * @brief DB work related to contract management
 * @author Marcello Stanisci
 */

#include "platform.h"
#include <jansson.h>
#include <taler/taler_signatures.h>
#include <gnunet/gnunet_util_lib.h>
#include "merchant.h"
#include "merchant_db.h"
#include "taler_merchant_contract_lib.h"

/**
 * Take the global wire details and return a JSON containing them,
 * compliantly with the Taler's API.
 * @param wire the merchant's wire details
 * @param salt the nounce for hashing the wire details with
 * @param edate when the beneficiary wants this transfer to take place
 * @return JSON representation of the wire details, NULL upon errors
 */

json_t *
MERCHANT_get_wire_json (const struct MERCHANT_WIREFORMAT_Sepa *wire,
                        uint64_t salt)

{
  
  json_t *root;
  json_t *j_salt;

  j_nounce = json_integer (salt);

  if (NULL == (root = json_pack ("{s:s, s:s, s:s, s:s, s:I}",
                                 "type", "SEPA",
		                 "IBAN", wire->iban,
		                 "name", wire->name,
		                 "bic", wire->bic,
		                 "r", json_integer_value (j_salt))))
    return NULL;

  return root;
}



/**
* Take from the frontend the (partly) generated contract and fill
* the missing values in it; for example, the SEPA details.
* Moreover, it stores the contract in the DB.
* @param j_contract parsed contract, originated by the frontend. It will be
* hold the new values.
* @param db_conn the handle to the local DB
* @param contract where to store the (subset of the) contract to be (still) signed
* @param timestamp contract's timestamp (shall be generated by the merchant)
* @param expiry the time when the contract will expire
* @param edate when the merchant wants to receive the wire transfer corresponding
* to this deal (this value is also a field inside the 'wire' JSON format)
* @param refund deadline until which the merchant can return the paid amount
* @param nounce the nounce used to hash the wire details
* @param a will be pointed to the (allocated) stringified 0-terminated contract
* @return GNUNET_OK on success, GNUNET_NO if attempting to double insert the
* same contract, GNUNET_SYSERR in case of other (mostly DB related) errors.
*/

/**
* TODO: inspect reference counting and, accordingly, free those json_t*(s)
* still allocated */

uint32_t
MERCHANT_handle_contract (json_t *j_contract,
                          PGconn *db_conn,
			  struct Contract *contract,
			  struct GNUNET_TIME_Absolute timestamp,
			  struct GNUNET_TIME_Absolute expiry,
			  struct GNUNET_TIME_Absolute edate,
			  struct GNUNET_TIME_Absolute refund,
			  char **a,
			  uint64_t nounce)
{
  json_t *j_amount;
  json_int_t j_product_id;
  json_int_t j_trans_id;
  char *contract_str;

  struct TALER_Amount amount;



  /* Extracting values useful for DB work. Only gettable from the JSON
  since they are generated by the frontend */
  if (-1 == json_unpack (j_contract, "{s:o, s:I, s:{s:I}}",
                         "amount", &j_amount,
			 "trans_id", &j_trans_id,
			 "details", "product_id",
			 &j_product_id))
  {
    printf ("no unpacking\n");
    return GNUNET_SYSERR;
  }

  TALER_json_to_amount (j_amount, &amount);
  contract_str = json_dumps (j_contract, JSON_COMPACT | JSON_PRESERVE_ORDER);
  *a = contract_str;
  GNUNET_CRYPTO_hash (contract_str, strlen (contract_str) + 1,
                      &contract->h_contract_details);
  contract->purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT);
  contract->purpose.size = htonl (sizeof (struct Contract));

  // DB mgmt
  return MERCHANT_DB_contract_create (db_conn,
                                      timestamp,
                                      expiry,
	                              edate,
				      refund,
                                      &amount,
                                      &contract->h_contract_details,
 				      (uint64_t) j_trans_id, // safe?
                                      contract_str,
                                      nounce,
                                      (uint64_t) j_product_id);
}