[vlmc-devel] [PATCH 5/7] Added ICloudStorage implementation.

Paweł Wegner pawel.wegner95 at gmail.com
Mon May 9 15:51:36 CEST 2016


---
 src/ICloudStorage.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ICloudStorage.h   |  61 ++++++++++++++++++++++-
 test/main.cpp         |   1 -
 3 files changed, 190 insertions(+), 2 deletions(-)

diff --git a/src/ICloudStorage.cpp b/src/ICloudStorage.cpp
index 23ed7bd..d720ba6 100644
--- a/src/ICloudStorage.cpp
+++ b/src/ICloudStorage.cpp
@@ -25,6 +25,136 @@
 
 namespace cloudstorage {
 
+namespace {
+
+struct HttpServerData {
+  std::string code_;
+  std::string code_parameter_name_;
+  std::string error_parameter_name_;
+  uint16_t port_;
+  enum { Awaiting, Accepted, Denied } state_;
+};
+
+std::string sendHttpRequestFromJavaScript(const std::string& request) {
+  return "<script>\n"
+         "  var request = new XMLHttpRequest();\n"
+         "  request.open(\"GET\", \"" +
+         request +
+         "\", false);\n"
+         "  request.send(null);\n"
+         "</script>\n";
+}
+
+int httpRequestCallback(void* cls, MHD_Connection* connection,
+                        const char* /*url*/, const char* /*method*/,
+                        const char* /*version*/, const char* /*upload_data*/,
+                        size_t* /*upload_data_size*/, void** /*ptr*/) {
+  HttpServerData* data = static_cast<HttpServerData*>(cls);
+  std::string page;
+
+  const char* code = MHD_lookup_connection_value(
+      connection, MHD_GET_ARGUMENT_KIND, data->code_parameter_name_.c_str());
+  if (code) {
+    data->code_ = code;
+    page = "<body>Success.</body>" +
+           sendHttpRequestFromJavaScript("http://localhost:" +
+                                         std::to_string(data->port_) +
+                                         "/?accepted=true");
+  }
+
+  const char* error = MHD_lookup_connection_value(
+      connection, MHD_GET_ARGUMENT_KIND, data->error_parameter_name_.c_str());
+  if (error) {
+    page = "<body>Error occurred.</body>" +
+           sendHttpRequestFromJavaScript("http://localhost:" +
+                                         std::to_string(data->port_) +
+                                         "/?accepted=false");
+  }
+
+  const char* accepted = MHD_lookup_connection_value(
+      connection, MHD_GET_ARGUMENT_KIND, "accepted");
+  if (accepted) {
+    if (std::string(accepted) == "true") {
+      data->state_ = HttpServerData::Accepted;
+    } else
+      data->state_ = HttpServerData::Denied;
+  }
+
+  MHD_Response* response = MHD_create_response_from_buffer(
+      page.length(), (void*)page.c_str(), MHD_RESPMEM_MUST_COPY);
+  int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+  MHD_destroy_response(response);
+
+  return ret;
+}
+}  // namespace
+
 ICloudStorage::ICloudStorage() {}
 
+ICloudStorage::~ICloudStorage() {}
+
+const std::string& ICloudStorage::authorization_code() const {
+  return authorization_code_;
+}
+
+void ICloudStorage::set_authorization_code(const std::string& code) {
+  authorization_code_ = code;
+}
+
+const std::string& ICloudStorage::client_id() const { return client_id_; }
+
+void ICloudStorage::set_client_id(const std::string& client_id) {
+  client_id_ = client_id;
+}
+
+const std::string& ICloudStorage::redirect_uri() const { return redirect_uri_; }
+
+void ICloudStorage::set_redirect_uri(const std::string& redirect_uri) {
+  redirect_uri_ = redirect_uri;
+}
+
+ICloudStorage::Token* ICloudStorage::access_token() const {
+  return access_token_.get();
+}
+
+void ICloudStorage::set_access_token(
+    std::unique_ptr<ICloudStorage::Token> token) {
+  access_token_ = std::move(token);
+}
+
+void ICloudStorage::addParameter(std::string& url, const std::string& parameter,
+                                 const std::string& value) {
+  url += parameter + "=" + value + "&";
+}
+
+bool ICloudStorage::awaitAuthorizationCode(uint16_t http_server_port,
+                                           std::string code_parameter_name,
+                                           std::string error_parameter_name) {
+  HttpServerData data = {"", code_parameter_name, error_parameter_name,
+                         http_server_port, HttpServerData::Awaiting};
+  MHD_Daemon* http_server =
+      MHD_start_daemon(0, http_server_port, NULL, NULL, &httpRequestCallback,
+                       &data, MHD_OPTION_END);
+  fd_set rs, ws, es;
+  MHD_socket max;
+  while (data.state_ == HttpServerData::Awaiting) {
+    FD_ZERO(&rs);
+    FD_ZERO(&ws);
+    FD_ZERO(&es);
+    MHD_get_fdset(http_server, &rs, &ws, &es, &max);
+    select(max + 1, &rs, &ws, &es, NULL);
+    MHD_run(http_server);
+  }
+
+  MHD_stop_daemon(http_server);
+
+  if (data.state_ == HttpServerData::Accepted)
+    set_authorization_code(data.code_);
+  return data.state_ == HttpServerData::Accepted;
+}
+
+ICloudStorage::Token::Token(const std::string& token, int expires_in,
+                            const std::string& refresh_token)
+    : token_(token), refresh_token_(refresh_token), expires_in_(expires_in) {}
+
 };  //  namespace cloudstorage
diff --git a/src/ICloudStorage.h b/src/ICloudStorage.h
index 3de904c..90a5421 100644
--- a/src/ICloudStorage.h
+++ b/src/ICloudStorage.h
@@ -24,14 +24,73 @@
 #ifndef ICLOUDSTORAGE_H
 #define ICLOUDSTORAGE_H
 
+#include <microhttpd.h>
+#include <memory>
+#include <string>
+#include <vector>
+
 namespace cloudstorage {
 
 class ICloudStorage {
  public:
+  struct File {
+    std::string filename_;
+    bool is_directory_;
+  };
+
+  class Token {
+   public:
+    Token(const std::string& token, int expires_in,
+          const std::string& refresh_token);
+    virtual ~Token() = default;
+
+    inline const std::string& token() const { return token_; }
+    inline int expires_in() const { return expires_in_; }
+    inline const std::string& refresh_token() const { return refresh_token_; }
+
+    inline void set_expires_in(int v) { expires_in_ = v; }
+
+   private:
+    std::string token_;
+    std::string refresh_token_;
+    int expires_in_;
+  };
+
   ICloudStorage();
-  virtual ~ICloudStorage() = default;
+  virtual ~ICloudStorage();
+
+  const std::string& authorization_code() const;
+  void set_authorization_code(const std::string&);
+
+  const std::string& client_id() const;
+  void set_client_id(const std::string&);
+
+  const std::string& redirect_uri() const;
+  void set_redirect_uri(const std::string&);
+
+  Token* access_token() const;
+  void set_access_token(std::unique_ptr<Token>);
+
+  bool awaitAuthorizationCode(uint16_t http_server_port,
+                              std::string code_parameter_name = "code",
+                              std::string error_parameter_name = "error");
+
+  virtual std::string authorizeLibraryUrl() const = 0;
+  virtual std::vector<File> listDirectory(const std::string& path) const = 0;
+
+  virtual std::unique_ptr<Token> requestAccessToken() const = 0;
+  virtual std::unique_ptr<Token> refreshToken() const = 0;
+
+  virtual bool validateToken(Token*) const = 0;
+
+  static void addParameter(std::string& url, const std::string& parameter,
+                           const std::string& value);
 
  private:
+  std::string authorization_code_;
+  std::string client_id_;
+  std::string redirect_uri_;
+  std::unique_ptr<Token> access_token_;
 };
 
 }  //  namespace cloudstorage
diff --git a/test/main.cpp b/test/main.cpp
index e75b175..accdc73 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -1,6 +1,5 @@
 #include <ICloudStorage.h>
 
 int main() {
-  cloudstorage::ICloudStorage obj;
   return 0;
 }
-- 
2.7.4



More information about the Vlmc-devel mailing list