[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