1 | /*␊ |
2 | Copyright 2021 Grégory Soutadé␊ |
3 | ␊ |
4 | This file is part of libgourou.␊ |
5 | ␊ |
6 | libgourou is free software: you can redistribute it and/or modify␊ |
7 | it under the terms of the GNU Lesser General Public License as published by␊ |
8 | the Free Software Foundation, either version 3 of the License, or␊ |
9 | (at your option) any later version.␊ |
10 | ␊ |
11 | libgourou is distributed in the hope that it will be useful,␊ |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of␊ |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the␊ |
14 | GNU Lesser General Public License for more details.␊ |
15 | ␊ |
16 | You should have received a copy of the GNU Lesser General Public License␊ |
17 | along with libgourou. If not, see <http://www.gnu.org/licenses/>.␊ |
18 | */␊ |
19 | ␊ |
20 | #include <cctype>␊ |
21 | #include <fulfillment_item.h>␊ |
22 | #include <libgourou_common.h>␊ |
23 | #include "user.h"␊ |
24 | ␊ |
25 | namespace gourou␊ |
26 | {␊ |
27 | FulfillmentItem::FulfillmentItem(pugi::xml_document& doc, User* user)␊ |
28 | ␉: fulfillDoc(), loanToken(0)␊ |
29 | {␊ |
30 | ␉fulfillDoc.reset(doc); /* We must keep a copy */␊ |
31 | ␉metadatas = fulfillDoc.select_node("//metadata").node();␊ |
32 | ␉␊ |
33 | ␉if (!metadatas)␊ |
34 | ␉ EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No metadata tag in document");␊ |
35 | ␉␊ |
36 | ␉pugi::xml_node node = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/src").node();␊ |
37 | ␉downloadURL = node.first_child().value();␊ |
38 | ␊ |
39 | ␉if (downloadURL == "")␊ |
40 | ␉ EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No download URL in document");␊ |
41 | ␉␊ |
42 | ␉node = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/resource").node();␊ |
43 | ␉resource = node.first_child().value();␊ |
44 | ␊ |
45 | ␉if (resource == "")␊ |
46 | ␉ EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No resource in document");␊ |
47 | ␊ |
48 | ␉pugi::xml_node licenseToken = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/licenseToken").node();␊ |
49 | ␊ |
50 | ␉if (!licenseToken)␊ |
51 | ␉ EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "Any license token in document");␊ |
52 | ␉␊ |
53 | ␉buildRights(licenseToken, user);␊ |
54 | ␊ |
55 | ␉node = doc.select_node("/envelope/fulfillmentResult/returnable").node();␊ |
56 | ␉try␊ |
57 | ␉{␊ |
58 | ␉ if (node && node.first_child().value() == std::string("true"))␊ |
59 | ␉␉loanToken = new LoanToken(doc);␊ |
60 | ␉}␊ |
61 | ␉catch(std::exception& e)␊ |
62 | ␉{␊ |
63 | ␉ GOUROU_LOG(ERROR, "Book is returnable, but contains invalid loan token");␊ |
64 | ␉ GOUROU_LOG(ERROR, e.what());␊ |
65 | ␉}␊ |
66 | }␊ |
67 | ␊ |
68 | FulfillmentItem::~FulfillmentItem()␊ |
69 | {␊ |
70 | ␉if (loanToken) delete loanToken;␊ |
71 | }␊ |
72 | ␊ |
73 | void FulfillmentItem::buildRights(const pugi::xml_node& licenseToken, User* user)␊ |
74 | {␊ |
75 | ␉pugi::xml_node decl = rights.append_child(pugi::node_declaration);␊ |
76 | ␉decl.append_attribute("version") = "1.0";␊ |
77 | ␉␊ |
78 | ␉pugi::xml_node root = rights.append_child("adept:rights");␊ |
79 | ␉root.append_attribute("xmlns:adept") = ADOBE_ADEPT_NS;␊ |
80 | ␉␊ |
81 | ␉pugi::xml_node newLicenseToken = root.append_copy(licenseToken);␊ |
82 | ␉if (!newLicenseToken.attribute("xmlns"))␊ |
83 | ␉ newLicenseToken.append_attribute("xmlns") = ADOBE_ADEPT_NS;␊ |
84 | ␊ |
85 | ␉pugi::xml_node licenseServiceInfo = root.append_child("adept:licenseServiceInfo");␊ |
86 | ␉pugi::xml_node licenseURL = licenseToken.select_node("licenseURL").node();␊ |
87 | ␉licenseURL.set_name("adept:licenseURL");␊ |
88 | ␉licenseServiceInfo.append_copy(licenseURL);␊ |
89 | ␉pugi::xml_node certificate = licenseServiceInfo.append_child("adept:certificate");␊ |
90 | ␉std::string certificateValue = user->getLicenseServiceCertificate(licenseURL.first_child().value());␊ |
91 | ␉certificate.append_child(pugi::node_pcdata).set_value(certificateValue.c_str());␊ |
92 | }␊ |
93 | ␊ |
94 | std::string FulfillmentItem::getMetadata(std::string name)␊ |
95 | {␊ |
96 | ␉// https://stackoverflow.com/questions/313970/how-to-convert-an-instance-of-stdstring-to-lower-case␊ |
97 | ␉#if __STDC_VERSION__ >= 201112L␊ |
98 | ␉std::transform(name.begin(), name.end(), name.begin(),␊ |
99 | ␉␉ [](unsigned char c){ return std::tolower(c); });␊ |
100 | ␉#else␊ |
101 | ␉std::transform(name.begin(), name.end(), name.begin(), tolower);␊ |
102 | ␉#endif␊ |
103 | ␉name = std::string("dc:") + name;␊ |
104 | ␉pugi::xpath_node path = metadatas.select_node(name.c_str());␊ |
105 | ␊ |
106 | ␉if (!path)␊ |
107 | ␉ return "";␊ |
108 | ␊ |
109 | ␉return path.node().first_child().value();␊ |
110 | }␊ |
111 | ␊ |
112 | std::string FulfillmentItem::getRights()␊ |
113 | {␊ |
114 | ␉StringXMLWriter xmlWriter;␊ |
115 | ␉rights.save(xmlWriter, " ");␊ |
116 | ␉return xmlWriter.getResult();␊ |
117 | }␊ |
118 | ␊ |
119 | std::string FulfillmentItem::getDownloadURL()␊ |
120 | {␊ |
121 | ␉return downloadURL;␊ |
122 | }␊ |
123 | ␊ |
124 | std::string FulfillmentItem::getResource()␊ |
125 | {␊ |
126 | ␉return resource;␊ |
127 | }␊ |
128 | ␊ |
129 | LoanToken* FulfillmentItem::getLoanToken()␊ |
130 | {␊ |
131 | ␉return loanToken;␊ |
132 | }␊ |
133 | }␊ |