Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
treehub_server.cc
1 #include "treehub_server.h"
2 
3 #include <cassert>
4 #include <iostream>
5 
6 #include <boost/algorithm/string.hpp>
7 
8 using std::string;
9 
10 TreehubServer::TreehubServer() {
11  auth_header_.data = const_cast<char*>(auth_header_contents_.c_str());
12  auth_header_.next = &force_header_;
13  force_header_contents_ = "x-ats-ostree-force: true";
14  force_header_.data = const_cast<char*>(force_header_contents_.c_str());
15  force_header_.next = &content_type_header_;
16  content_type_header_.data = const_cast<char*>(content_type_header_contents_.c_str());
17  content_type_header_.next = nullptr;
18 }
19 
20 void TreehubServer::SetToken(const string& token) {
21  assert(auth_header_.next == &force_header_);
22  assert(force_header_.next == &content_type_header_);
23  assert(content_type_header_.next == nullptr);
24 
25  auth_header_contents_ = "Authorization: Bearer " + token;
26  auth_header_.data = const_cast<char*>(auth_header_contents_.c_str());
27  method_ = AuthMethod::kOauth2;
28 }
29 
30 void TreehubServer::SetContentType(const string& content_type) {
31  assert(auth_header_.next == &force_header_);
32  assert(force_header_.next == &content_type_header_);
33  assert(content_type_header_.next == nullptr);
34 
35  content_type_header_contents_ = content_type;
36  content_type_header_.data = const_cast<char*>(content_type_header_contents_.c_str());
37 }
38 
39 void TreehubServer::SetCerts(const std::string& client_p12) {
40  method_ = AuthMethod::kTls;
41  client_p12_path_.PutContents(client_p12);
42 }
43 
44 void TreehubServer::SetAuthBasic(const std::string& username, const std::string& password) {
45  method_ = AuthMethod::kBasic;
46  username_ = username;
47  password_ = password;
48 }
49 
50 // Note that this method creates a reference from curl_handle to this. Keep
51 // this TreehubServer object alive until the curl request has been completed
52 void TreehubServer::InjectIntoCurl(const string& url_suffix, CURL* curl_handle, const bool tufrepo) const {
53  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
54  std::string url = (tufrepo ? repo_url_ : root_url_);
55 
56  if (*url.rbegin() != '/' && *url_suffix.begin() != '/') {
57  url += "/";
58  } else if (*url.rbegin() == '/' && *url_suffix.begin() == '/') {
59  url.erase(url.length() - 1);
60  }
61 
62  boost::trim_if(url, boost::is_any_of(" \t\r\n"));
63 
64  curlEasySetoptWrapper(curl_handle, CURLOPT_URL, (url + url_suffix).c_str());
65 
66  curlEasySetoptWrapper(curl_handle, CURLOPT_HTTPHEADER, &auth_header_);
67  // If we need authentication but don't have an OAuth2 token or TLS
68  // credentials, fall back to legacy username/password.
69  if (method_ == AuthMethod::kBasic) {
70  curlEasySetoptWrapper(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
71  curlEasySetoptWrapper(curl_handle, CURLOPT_USERNAME, username_.c_str());
72  curlEasySetoptWrapper(curl_handle, CURLOPT_PASSWORD, password_.c_str());
73  }
74 
75  if (method_ == AuthMethod::kTls) {
76  curlEasySetoptWrapper(curl_handle, CURLOPT_SSLCERT, client_p12_path_.PathString().c_str());
77  curlEasySetoptWrapper(curl_handle, CURLOPT_SSLCERTTYPE, "P12");
78  curlEasySetoptWrapper(curl_handle, CURLOPT_SSL_VERIFYPEER, 1);
79  curlEasySetoptWrapper(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
80  curlEasySetoptWrapper(curl_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL);
81  }
82 
83  if (!ca_certs_.empty()) {
84  curlEasySetoptWrapper(curl_handle, CURLOPT_CAINFO, ca_certs_.c_str());
85  curlEasySetoptWrapper(curl_handle, CURLOPT_CAPATH, NULL);
86  }
87 }
88 
89 // Set the url of the treehub server, this should be something like
90 // "https://treehub-staging.atsgarage.com/api/v2/"
91 // The trailing slash is optional, and will be appended if required
92 void TreehubServer::root_url(const std::string& _root_url) {
93  root_url_ = _root_url;
94  if (!root_url_.empty() && root_url_[root_url_.size() - 1] != '/') {
95  root_url_.append("/");
96  }
97 }
98 
99 void TreehubServer::repo_url(const std::string& _repo_url) {
100  repo_url_ = _repo_url;
101  if (!repo_url_.empty() && repo_url_[repo_url_.size() - 1] != '/') {
102  repo_url_.append("/");
103  }
104 }
105 
106 // vim: set tabstop=2 shiftwidth=2 expandtab: