From f48b5c7b70168a4b62a79bd1a6a3842dc7420c84 Mon Sep 17 00:00:00 2001
From: Armin <armin.felder@osalliance.com>
Date: Mon, 25 Dec 2017 22:14:00 +0100
Subject: [PATCH] apple push

---
 CMakeLists.txt                |  3 +-
 README.md                     |  6 ++--
 handlers/ApplePushHandler.cpp | 26 +++++++++++++++-
 handlers/ApplePushHandler.h   |  2 ++
 main.cpp                      |  2 ++
 models/ApplePushModel.cpp     | 57 +++++++++++++++++++++++++++++++++++
 models/ApplePushModel.h       | 16 ++++++++++
 models/PusherCpp              |  1 +
 8 files changed, 109 insertions(+), 4 deletions(-)
 create mode 160000 models/PusherCpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e7d5bb..6b0ba76 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,8 @@ project(RocketChatMobilePushGateway)
 set(CMAKE_CXX_STANDARD 14)
 
 include_directories(/usr/local/include/r3/)
-set(SOURCE_FILES main.cpp HandlerFactory.cpp handlers/NorFoundHandler.cpp utils.cpp utils.h handlers/ApplePushHandler.cpp handlers/ApplePushHandler.h handlers/GooglePushHandler.cpp handlers/GooglePushHandler.h models/GooglePushModel.cpp models/GooglePushModel.h models/ApplePushModel.cpp models/ApplePushModel.h)
+set(SOURCE_FILES main.cpp HandlerFactory.cpp handlers/NorFoundHandler.cpp utils.cpp utils.h handlers/ApplePushHandler.cpp handlers/ApplePushHandler.h handlers/GooglePushHandler.cpp handlers/GooglePushHandler.h models/GooglePushModel.cpp models/GooglePushModel.h models/ApplePushModel.cpp models/ApplePushModel.h
+         models/PusherCpp/Pusher.cpp models/PusherCpp/Pusher.h)
 add_executable(rocketChatMobilePushGateway ${SOURCE_FILES} utils.cpp utils.h models/GooglePushModel.cpp models/GooglePushModel.h)
 
 target_link_libraries(rocketChatMobilePushGateway -lwangle -lfolly -lz -lssl -lcrypto -levent -lgflags -lglog  -L/usr/lib64 -lpthread -pthread -lfolly -lglog -ldouble-conversion -lboost_system -lboost_thread -lproxygenhttpserver -ljsoncpp -lcurl)
diff --git a/README.md b/README.md
index 7cb1527..7377371 100644
--- a/README.md
+++ b/README.md
@@ -6,12 +6,14 @@
 - install libjsoncpp-dev, libcurlpp0-dev, cmake
 - cmake 
 - make
-- place the credentials in the servers directory:
+- place the credentials in the servers "credentials" directory:
     - FCM -> google/serverKey.txt
-    - APNS -> 
+    - APNS -> apple/cred.pem
     
 ### Docker
 - pass port 11000
 - mount your credentials folder into the container with -v /certs:/yourCertsFolder
+    - yourCertsFolder/google/serverKey.txt
+    - yourCertsFolder/apple/cred.pem
 
 e.g. docker run -t gateway -v /certs:/yourCertsFolder -p 0.0.0.0:80:11000
\ No newline at end of file
diff --git a/handlers/ApplePushHandler.cpp b/handlers/ApplePushHandler.cpp
index 491ef13..1145709 100644
--- a/handlers/ApplePushHandler.cpp
+++ b/handlers/ApplePushHandler.cpp
@@ -19,13 +19,18 @@
  ********************************************************************************************************************/
 
 #include "ApplePushHandler.h"
+#include "../models/ApplePushModel.h"
 
 void ApplePushHandler::onRequest(std::unique_ptr<HTTPMessage> headers) noexcept {
 
 }
 
 void ApplePushHandler::onBody(std::unique_ptr<folly::IOBuf> body) noexcept {
-
+    if(mBody){
+        (*mBody).appendChain(std::move(body));
+    } else{
+        mBody = std::move(body);
+    }
 }
 
 void ApplePushHandler::onUpgrade(proxygen::UpgradeProtocol prot) noexcept {
@@ -33,7 +38,26 @@ void ApplePushHandler::onUpgrade(proxygen::UpgradeProtocol prot) noexcept {
 }
 
 void ApplePushHandler::onEOM() noexcept {
+    if (mBody) {
+        try {
+            std::string body(reinterpret_cast<const char *>((*mBody).data()));
+            ApplePushModel applePushModel(body);
+            std::string response;
+            if (applePushModel.sendMessage()) {
+                ResponseBuilder(downstream_).status(200, "OK").body("").sendWithEOM();
+
+            } else {
+                ResponseBuilder(downstream_).status(500, "FAILURE").body("failed to send push mesage").sendWithEOM();
+
+            }
 
+        } catch (Exception &e) {
+            std::cout << "exception " << e.what() << std::endl;
+            ResponseBuilder(downstream_).status(500, "FAILURE").body("failed to send push mesage").sendWithEOM();
+        }
+    } else {
+        ResponseBuilder(downstream_).status(400, "BAD REQUEST").body("failed to send push message").sendWithEOM();
+    }
 }
 
 void ApplePushHandler::requestComplete() noexcept {
diff --git a/handlers/ApplePushHandler.h b/handlers/ApplePushHandler.h
index 0c1cf25..512f460 100644
--- a/handlers/ApplePushHandler.h
+++ b/handlers/ApplePushHandler.h
@@ -43,6 +43,8 @@ public:
 
     void onError(ProxygenError err) noexcept override;
 
+private:
+    std::unique_ptr<folly::IOBuf> mBody;
 };
 
 
diff --git a/main.cpp b/main.cpp
index 484182c..e83bbf6 100644
--- a/main.cpp
+++ b/main.cpp
@@ -51,6 +51,8 @@ int main(int argc, char* argv[]) {
 
     GooglePushModel::loadApiKey();
 
+
+
     std::vector<HTTPServer::IPConfig> IPs = {
             {
                     SocketAddress(FLAGS_ip, FLAGS_http_port, true), Protocol::HTTP
diff --git a/models/ApplePushModel.cpp b/models/ApplePushModel.cpp
index e118f03..73bf89d 100644
--- a/models/ApplePushModel.cpp
+++ b/models/ApplePushModel.cpp
@@ -18,4 +18,61 @@
  *                                                                                                                  *
  ********************************************************************************************************************/
 
+#include <jsoncpp/json/json.h>
+#include <iostream>
+#include <curl/curl.h>
+#include <fstream>
+#include <openssl/ssl.h>
 #include "ApplePushModel.h"
+
+
+ApplePushModel::ApplePushModel(const std::string &pJson):mPusher("credentials/apple/cred.pem") {
+    Json::Reader reader;
+    Json::Value obj;
+    reader.parse(pJson, obj);
+    std::cout<<obj["token"].asString()<<std::endl;
+    if(obj.isMember("token") && obj.isMember("options")){
+        std::string token = obj["token"].asString();
+        Json::Value options = obj["options"];
+        if(options.isMember("from")&&options.isMember("badge")&&options.isMember("title")&&options.isMember("text")){
+            std::cout<<"valid json"<<std::endl;
+            mTitle = std::move(options["title"].asString());
+            mText = std::move(options["text"].asString());
+            mFrom = std::move(options["from"].asString());
+            mDeviceToken = std::move(obj["token"].asString());
+            mBadge = options["badge"].asInt();
+        }
+    }
+}
+
+bool ApplePushModel::sendMessage() {
+
+    Json::FastWriter fast;
+
+    std::vector<std::string> tokens;
+    tokens.push_back(mDeviceToken);
+
+    PusherContent content;
+
+    Json::Value obj;
+    Json::Value msg;
+    msg["title"] = mTitle;
+    msg["body"] = mText;
+
+    std::string data = fast.write(msg);
+
+
+    content.badge = mBadge;
+    content.content = mTitle;
+    content.userData = "\"ejson\":"+data;
+
+
+    mPusher.isSandBox = true;
+    mPusher.pushNotification(content, tokens);
+
+    //TODO: shoud be fixed
+
+    std::string url{"https://gateway.sandbox.push.apple.com:2195"};
+
+    return false;
+}
diff --git a/models/ApplePushModel.h b/models/ApplePushModel.h
index 92c5797..686f1a4 100644
--- a/models/ApplePushModel.h
+++ b/models/ApplePushModel.h
@@ -21,9 +21,25 @@
 #ifndef ROCKETCHATMOBILEPUSHGATEWAY_APPLEPUSHMODEL_H
 #define ROCKETCHATMOBILEPUSHGATEWAY_APPLEPUSHMODEL_H
 
+#include <curl/curl.h>
+#include "PusherCpp/Pusher.h"
+
 
 class ApplePushModel {
 
+public:
+    ApplePushModel(const std::string &pJson);
+
+    bool sendMessage();
+
+private:
+    Pusher mPusher;
+
+    std::string mTitle;
+    std::string mText;
+    std::string mDeviceToken;
+    std::string mFrom;
+    int mBadge{0};
 };
 
 
diff --git a/models/PusherCpp b/models/PusherCpp
new file mode 160000
index 0000000..5072100
--- /dev/null
+++ b/models/PusherCpp
@@ -0,0 +1 @@
+Subproject commit 5072100114573dd2d01d8ac7a95ef5121c1c95bb
-- 
GitLab