Cryptolens Client API for C++
basic_Cryptolens.hpp
1 #pragma once
2 
3 #include <cstring>
4 #include <string>
5 #include <sstream>
6 
7 #include "imports/std/optional"
8 
9 #include "ActivateError.hpp"
10 #include "api.hpp"
11 #include "basic_Error.hpp"
12 #include "LicenseKey.hpp"
13 #include "LicenseKeyChecker.hpp"
14 #include "LicenseKeyInformation.hpp"
15 #include "RawLicenseKey.hpp"
16 #include "ResponseParser_ArduinoJson5.hpp"
17 
18 namespace cryptolens_io {
19 
20 namespace v20190401 {
21 
22 namespace internal {
23 
24 template<typename ResponseParser, typename SignatureVerifier>
25 optional<RawLicenseKey>
26 handle_activate
27  ( basic_Error & e
28  , ResponseParser const& response_parser
29  , SignatureVerifier const& signature_verifier
30  , std::string const& response
31  );
32 
33 int
34 activate_parse_server_error_message(char const* server_response);
35 
37 public:
39  ( LicenseKeyInformation const& license_key_information
40  , int product_id
41  , std::string const& key
42  , std::string const& machine_code
43  , int fields_to_return
44  , bool floating
45  )
46  : license_key_information_(&license_key_information)
47  , product_id_(product_id), key_(&key), machine_code_(&machine_code)
48  , fields_to_return_(fields_to_return), floating_(floating)
49  {}
50 
52  get_license_key_information() const {
53  return *license_key_information_;
54  }
55 
56  int
57  get_product_id() const
58  {
59  return product_id_;
60  }
61 
62  std::string const&
63  get_key() const
64  {
65  return *key_;
66  }
67 
68  std::string const&
69  get_machine_code() const
70  {
71  return *machine_code_;
72  }
73 
74  int
75  get_fields_to_return() const
76  {
77  return fields_to_return_;
78  }
79 
80  bool
81  get_floating() const
82  {
83  return floating_;
84  }
85 
86 private:
87  LicenseKeyInformation const* license_key_information_;
88  int product_id_;
89  std::string const* key_;
90  std::string const* machine_code_;
91  int fields_to_return_;
92  bool floating_;
93 };
94 
95 } // namespace internal
96 
97 template<typename SignatureVerifier>
98 optional<RawLicenseKey>
99 handle_activate_raw
100  ( basic_Error & e
101  , SignatureVerifier const& signature_verifier
102  , std::string const& response
103  )
104 {
105  if (e) { return nullopt; }
106 
107  ResponseParser_ArduinoJson5 response_parser(e);
108  if (e) { return nullopt; }
109 
110  auto x = internal::handle_activate(e, response_parser, signature_verifier, response);
111  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_HANDLE_ACTIVATE_RAW); }
112  return x;
113 }
114 
115 template<typename SignatureVerifier>
117 handle_activate_raw_exn
118  ( api::experimental_v1 experimental
119  , SignatureVerifier const& signature_verifier
120  , std::string const& response
121  )
122 {
123  basic_Error e;
124  optional<RawLicenseKey> raw_license_key =
125  handle_activate(e, signature_verifier, response);
126 
127  if (raw_license_key && !e) { return *raw_license_key; }
128 
129  throw ActivateError::from_server_response(NULL);
130 }
131 
132 template<typename SignatureVerifier>
133 optional<LicenseKey>
134 handle_activate
135  ( basic_Error & e
136  , SignatureVerifier const& signature_verifier
137  , std::string const& response
138  )
139 {
140  if (e) { return nullopt; }
141 
142  ResponseParser_ArduinoJson5 response_parser(e);
143  if (e) { return nullopt; }
144 
145  optional<RawLicenseKey> x = internal::handle_activate(e, response_parser, signature_verifier, response);
146  optional<LicenseKeyInformation> y = response_parser.make_license_key_information(e, x);
147  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_HANDLE_ACTIVATE); }
148 
149  return LicenseKey(std::move(*y), std::move(*x));
150 }
151 
163 template<typename Configuration>
165 {
166 public:
167 #ifndef CRYPTOLENS_20190701_ALLOW_IMPLICIT_CONSTRUCTORS
168  explicit
169 #endif
171  : response_parser(e), request_handler(e), signature_verifier(e), machine_code_computer(e)
172  , activate_validator(e)
173  { }
174 
175  optional<LicenseKey>
176  activate
177  ( basic_Error & e
178  , std::string token
179  , int product_id
180  , std::string key
181  , int fields_to_return = 0
182  );
183 
184  optional<RawLicenseKey>
185  activate_raw
186  ( basic_Error & e
187  , std::string token
188  , int product_id
189  , std::string key
190  , int fields_to_return = 0
191  );
192 
193  optional<LicenseKey>
194  activate_floating
195  ( basic_Error & e
196  , std::string token
197  , int product_id
198  , std::string key
199  , long floating_time_interval
200  , int fields_to_return = 0
201  );
202 
204  activate_raw_exn
205  ( api::experimental_v1 experimental
206  , std::string token
207  , int product_id
208  , std::string key
209  , int fields_to_return = 0
210  );
211 
212  std::string
213  create_trial_key
214  ( basic_Error & e
215  , std::string token
216  , int product_id
217  );
218 
219  std::string
220  last_message
221  ( basic_Error & e
222  , std::string token
223  , std::string channel
224  , int since_unix_timestamp
225  );
226 
227  optional<LicenseKey>
228  make_license_key(basic_Error & e, std::string const& s);
229 
230  typename Configuration::ResponseParser response_parser;
231  typename Configuration::RequestHandler request_handler;
232  typename Configuration::SignatureVerifier signature_verifier;
233  typename Configuration::MachineCodeComputer machine_code_computer;
234  typename Configuration::template ActivateValidator<internal::ActivateEnvironment> activate_validator;
235 
236 private:
237  optional<RawLicenseKey>
238  activate_
239  ( basic_Error & e
240  , std::string token
241  , int product_id
242  , std::string key
243  , std::string machine_code
244  , int fields_to_return = 0
245  );
246 
247  optional<RawLicenseKey>
248  activate_floating_
249  ( basic_Error & e
250  , std::string token
251  , int product_id
252  , std::string key
253  , std::string machine_code
254  , long floating_time_interval
255  , int fields_to_return = 0
256  );
257 
258  std::string
259  create_trial_key_
260  ( basic_Error & e
261  , std::string token
262  , int product_id
263  );
264 
265  std::string
266  last_message_
267  ( basic_Error & e
268  , std::string token
269  , std::string channel
270  , int since_unix_timestamp
271  );
272 };
273 
286 template<typename Configuration>
287 optional<LicenseKey>
290  , std::string token
291  , int product_id
292  , std::string key
293  , int fields_to_return
294  )
295 {
296  if (e) { return nullopt; }
297 
298  std::string machine_code = machine_code_computer.get_machine_code(e);
299 
300  optional<RawLicenseKey> x = this->activate_
301  ( e
302  , std::move(token)
303  , product_id
304  , key // NOTE: Copy is performed here
305  , machine_code // NOTE: Copy is performed here
306  , fields_to_return
307  );
308  optional<LicenseKeyInformation> y = response_parser.make_license_key_information(e, x);
309  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE); return nullopt; }
310 
311  typename internal::ActivateEnvironment env(*y, product_id, key, machine_code, fields_to_return, false);
312  activate_validator.validate(e, env);
313  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE); return nullopt; }
314 
315  return LicenseKey(std::move(*y), std::move(*x));
316 }
317 
330 template<typename Configuration>
331 optional<RawLicenseKey>
334  , std::string token
335  , int product_id
336  , std::string key
337  , int fields_to_return
338  )
339 {
340  if (e) { return nullopt; }
341 
342  std::string machine_code = machine_code_computer.get_machine_code(e);
343 
344  auto x = this->activate_( e
345  , std::move(token)
346  , std::move(product_id)
347  , std::move(key)
348  , std::move(machine_code)
349  , fields_to_return
350  );
351  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE_RAW); }
352  return x;
353 }
354 
377 template<typename Configuration>
378 optional<LicenseKey>
381  , std::string token
382  , int product_id
383  , std::string key
384  , long floating_time_interval
385  , int fields_to_return
386  )
387 {
388  if (e) { return nullopt; }
389 
390  std::string machine_code = machine_code_computer.get_machine_code(e);
391 
392  optional<RawLicenseKey> x = this->activate_floating_
393  ( e
394  , std::move(token)
395  , std::move(product_id)
396  , key // NOTE: Copy is performed here
397  , machine_code // NOTE: Copy is performed here
398  , floating_time_interval
399  , fields_to_return
400  );
401  optional<LicenseKeyInformation> y = response_parser.make_license_key_information(e, x);
402  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE_FLOATING); return nullopt; }
403 
404  typename internal::ActivateEnvironment env(*y, product_id, key, machine_code, fields_to_return, true);
405  activate_validator.validate(e, env);
406  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE_FLOATING); return nullopt; }
407 
408  return LicenseKey(std::move(*y), std::move(*x));
409 }
410 
411 template<typename Configuration>
412 std::string
414  ( basic_Error & e
415  , std::string token
416  , int product_id
417  )
418 {
419  if (e) { return ""; }
420 
421  std::string key = create_trial_key_(e, token, product_id);
422  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_CREATE_TRIAL_KEY); return ""; }
423  return key;
424 }
425 
426 template<typename Configuration>
427 optional<RawLicenseKey>
429  ( basic_Error & e
430  , std::string token
431  , int product_id
432  , std::string key
433  , std::string machine_code
434  , int fields_to_return
435  )
436 {
437  if (e) { return nullopt; }
438 
439  auto request = request_handler.post_request(e, "app.cryptolens.io", "/api/key/Activate");
440 
441  std::ostringstream product_id_; product_id_ << product_id;
442  std::ostringstream fields_to_return_; fields_to_return_ << fields_to_return;
443 
444  std::string response =
445  request.add_argument(e, "token" , token.c_str())
446  .add_argument(e, "ProductId" , product_id_.str().c_str())
447  .add_argument(e, "Key" , key.c_str())
448  .add_argument(e, "Sign" , "true")
449  .add_argument(e, "MachineCode" , machine_code.c_str())
450  .add_argument(e, "FieldsToReturn", fields_to_return_.str().c_str())
451  .add_argument(e, "SignMethod" , "1")
452  .add_argument(e, "v" , "1")
453  .make(e);
454 
455  return handle_activate_raw(e, this->signature_verifier, response);
456 }
457 
458 template<typename Configuration>
459 optional<RawLicenseKey>
461  ( basic_Error & e
462  , std::string token
463  , int product_id
464  , std::string key
465  , std::string machine_code
466  , long floating_time_interval
467  , int fields_to_return
468  )
469 {
470  if (e) { return nullopt; }
471 
472  auto request = request_handler.post_request(e, "app.cryptolens.io", "/api/key/Activate");
473 
474  std::ostringstream product_id_; product_id_ << product_id;
475  std::ostringstream fields_to_return_; fields_to_return_ << fields_to_return;
476  std::ostringstream floating_time_interval_; floating_time_interval_ << floating_time_interval;
477 
478  std::string response =
479  request.add_argument(e, "token" , token.c_str())
480  .add_argument(e, "ProductId" , product_id_.str().c_str())
481  .add_argument(e, "Key" , key.c_str())
482  .add_argument(e, "Sign" , "true")
483  .add_argument(e, "MachineCode" , machine_code.c_str())
484  .add_argument(e, "FieldsToReturn" , fields_to_return_.str().c_str())
485  .add_argument(e, "SignMethod" , "1")
486  .add_argument(e, "v" , "1")
487  .add_argument(e, "FloatingTimeInterval", floating_time_interval_.str().c_str())
488  .make(e);
489 
490  return handle_activate_raw(e, this->signature_verifier, response);
491 }
492 
506 template<typename Configuration>
509  ( api::experimental_v1 experimental
510  , std::string token
511  , int product_id
512  , std::string key
513  , int fields_to_return
514  )
515 {
516  basic_Error e;
517 
518  std::string machine_code = machine_code_computer.get_machine_code(e);
519 
520  optional<RawLicenseKey> raw_license_key =
521  activate_raw( e, std::move(token), std::move(product_id), std::move(key)
522  , std::move(machine_code), fields_to_return);
523 
524  if (!e) { return *raw_license_key; }
525  throw ActivateError::from_server_response(NULL);
526 }
527 
528 template<typename Configuration>
529 std::string
531  ( basic_Error & e
532  , std::string token
533  , std::string channel
534  , int since_unix_timestamp
535  )
536 {
537  if (e) { return ""; }
538 
539  std::string message = last_message_(e, token, channel, since_unix_timestamp);
540  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_LAST_MESSAGE); return ""; }
541  return message;
542 }
543 
544 template<typename Configuration>
545 std::string
547  ( basic_Error & e
548  , std::string token
549  , int product_id
550  )
551 {
552  if (e) { return ""; }
553 
554  std::string machine_code = machine_code_computer.get_machine_code(e);
555 
556  auto request = request_handler.post_request(e, "app.cryptolens.io", "/api/Key/CreateTrialKey");
557 
558  std::ostringstream product_id_; product_id_ << product_id;
559 
560  std::string response =
561  request.add_argument(e, "token" , token.c_str())
562  .add_argument(e, "ProductId" , product_id_.str().c_str())
563  .add_argument(e, "MachineCode", machine_code.c_str())
564  .make(e);
565 
566  if (e) { return ""; }
567 
568  return response_parser.parse_create_trial_key_response(e, response);
569 }
570 
571 template<typename Configuration>
572 std::string
574  ( basic_Error & e
575  , std::string token
576  , std::string channel
577  , int since_unix_timestamp
578  )
579 {
580  if (e) { return ""; }
581 
582  auto request = request_handler.post_request(e, "app.cryptolens.io", "/api/message/GetMessages");
583 
584  std::ostringstream stm; stm << since_unix_timestamp;
585 
586  std::string response =
587  request.add_argument(e, "token" , token.c_str())
588  .add_argument(e, "Channel", channel.c_str())
589  .add_argument(e, "Time" , stm.str().c_str())
590  .make(e);
591 
592  if (e) { return ""; }
593 
594  return response_parser.parse_last_message_response(e, response);
595 }
596 
597 template<typename Configuration>
598 optional<LicenseKey>
600 {
601  if (e) { return nullopt; }
602 
603  optional<RawLicenseKey> raw_license_key;
604 
605  raw_license_key =
606  ::cryptolens_io::v20190401::internal::handle_activate(e, this->response_parser, this->signature_verifier, s);
607 
608  if (e) {
609  e.reset(api::main());
610 
611  size_t k = s.find('-');
612  if (k == std::string::npos) { e.set(api::main(), errors::Subsystem::Main, errors::Main::UNKNOWN_SERVER_REPLY); return nullopt; }
613 
614  std::string version = s.substr(0, k);
615  std::string rem = s.substr(k+1, std::string::npos);
616  // NOTE: s.substr(s.size(), _) returns empty string, thus the previous line does never throw
617 
618  k = rem.find('-');
619  if (k == std::string::npos) { e.set(api::main(), errors::Subsystem::Main, errors::Main::UNKNOWN_SERVER_REPLY); return nullopt; }
620 
621  std::string license = rem.substr(0, k);
622  std::string signature = rem.substr(k+1, std::string::npos); // k+1 is fine, see comment above
623 
624  raw_license_key =
625  RawLicenseKey::make
626  ( e
627  , signature_verifier
628  , license
629  , signature
630  );
631  }
632 
633  optional<LicenseKeyInformation> license_key_information = response_parser.make_license_key_information(e, raw_license_key);
634  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_MAKE_LICENSE_KEY); return nullopt; }
635  return LicenseKey(std::move(*license_key_information), std::move(*raw_license_key));
636 }
637 
638 namespace internal {
639 
640 template<typename ResponseParser, typename SignatureVerifier>
641 optional<RawLicenseKey>
642 handle_activate
643  ( basic_Error & e
644  , ResponseParser const& response_parser
645  , SignatureVerifier const& signature_verifier
646  , std::string const& response
647  )
648 {
649  if (e) { return nullopt; }
650 
651  optional<std::pair<std::string, std::string>> x = response_parser.parse_activate_response(e, response);
652  if (e) { return nullopt; }
653 
654  return RawLicenseKey::make
655  ( e
656  , signature_verifier
657  , x->first
658  , x->second
659  );
660 }
661 
662 } // namespace internal
663 
664 } // namespace v20190401
665 
666 namespace latest {
667 
668 template<typename Configuration>
670 
671 } // namespace latest
672 
673 } // namespace cryptolens_io
virtual void reset(api::main api)
Definition: basic_Error.hpp:119
Definition: basic_Cryptolens.hpp:164
RawLicenseKey activate_raw_exn(api::experimental_v1 experimental, std::string token, int product_id, std::string key, int fields_to_return=0)
Definition: basic_Cryptolens.hpp:509
Definition: ActivateError.hpp:5
Definition: RawLicenseKey.hpp:24
Definition: basic_Error.hpp:90
optional< LicenseKey > activate(basic_Error &e, std::string token, int product_id, std::string key, int fields_to_return=0)
Definition: basic_Cryptolens.hpp:289
optional< RawLicenseKey > activate_raw(basic_Error &e, std::string token, int product_id, std::string key, int fields_to_return=0)
Definition: basic_Cryptolens.hpp:333
optional< LicenseKey > activate_floating(basic_Error &e, std::string token, int product_id, std::string key, long floating_time_interval, int fields_to_return=0)
Definition: basic_Cryptolens.hpp:380
Definition: ResponseParser_ArduinoJson5.hpp:15
Definition: LicenseKey.hpp:34
Definition: LicenseKeyInformation.hpp:34