Add logout button in home screen
[staging/HomeScreen.git] / HomeScreen / src2 / usermanagement.cpp
1 #include "usermanagement.h"
2 #include <QDebug>
3 #include <QtCore/QJsonDocument>
4 #include <QByteArray>
5 UserManagement::UserManagement(QObject *root) : QObject()
6 {
7     home = root->findChild<QObject *>("Home");
8     QObject::connect(home, SIGNAL(disconnect()),
9                          this, SLOT(slot_disconnect()));
10     logo = root->findChild<QObject *>("Logo_colour");
11     shortcutArea = root->findChild<QObject *>("ShortcutArea");
12     statusArea = root->findChild<QObject *>("StatusArea");
13     this->appModel = home->findChild<ApplicationModel *>("ApplicationModel");
14     sequence = 0;
15     isRed = false;
16     connect(&timerRed, SIGNAL(timeout()), this, SLOT(slot_turnOffRed()));
17     timerRed.setSingleShot(true);
18     timerRed.setInterval(3000);
19 #ifdef REAL_SERVER
20     connectWebsockets();
21 #else
22     pSocket = NULL;
23     connect(&timerTest, SIGNAL(timeout()), this, SLOT(slot_timerTest()));
24     timerTest.setSingleShot(false);
25     timerTest.start(5000);
26     launchServer();
27 #endif
28 }
29 void UserManagement::slot_disconnect()
30 {
31     appModel->changeOrder(-1);
32     timerRed.stop();
33     slot_turnOffRed();
34     QMetaObject::invokeMethod(home, "languageChanged");
35     QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, "en"));
36     QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, "en"));
37     QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, false));
38     QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, false), Q_ARG(QVariant, ""));
39     QMetaObject::invokeMethod(home, "changeFlag", Q_ARG(QVariant, "./images/us_flag.png"));
40 }
41
42 void UserManagement::setUser(const User &user)
43 {
44     int hash = qHash(user.name + user.first_name);
45     timerRed.stop();
46     appModel->changeLanguage(user.graphPreferredLanguage);
47     appModel->changeOrder(hash);
48     slot_turnOffRed();
49     QMetaObject::invokeMethod(home, "languageChanged");
50     QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
51     QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
52     QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, !user.graphActions.contains("Exceed 100 Kph")));
53     if(user.ccNumberMasked.isEmpty())
54         QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, false), Q_ARG(QVariant, ""));
55     else
56         QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, true), Q_ARG(QVariant, user.ccNumberMasked));
57     const QString welcome = QString("%1").arg(user.graphPreferredLanguage == "fr" ? "Bonjour " : "Hello") + " ";
58     QMetaObject::invokeMethod(home, "showHello", Q_ARG(QVariant, welcome + user.first_name));
59     QMetaObject::invokeMethod(home, "changeFlag", Q_ARG(QVariant, user.graphPreferredLanguage == "fr" ? "./images/french_flag.png" : "./images/us_flag.png"));
60 }
61 void UserManagement::slot_turnOffRed()
62 {
63     if(!isRed)
64         return;
65     QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Colour-01.png"));
66     isRed = false;
67 }
68
69 void UserManagement::connectWebsockets()
70 {
71 #ifdef REAL_SERVER
72     const QUrl url(REAL_SERVER);
73 #else
74     const QUrl url(QStringLiteral("ws://localhost:1234"));
75 #endif
76     QSslConfiguration config = QSslConfiguration::defaultConfiguration();
77     config.setProtocol(QSsl::SecureProtocols);
78     webSocket.setSslConfiguration(config);
79     connect(&webSocket, &QWebSocket::connected, this, &UserManagement::onConnected);
80     connect(&webSocket, &QWebSocket::disconnected, this, &UserManagement::onClosed);
81     if(!connect(&webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onWebSocketError(QAbstractSocket::SocketError)))) {
82         qWarning() << "Failed to connect to QWebSocket::error";
83     }
84     webSocket.open(QUrl(url));
85 }
86 void UserManagement::onWebSocketError(QAbstractSocket::SocketError)
87 {
88     qWarning()<<"Websocket error:" << webSocket.errorString();
89 }
90
91 void UserManagement::onConnected()
92 {
93     connect(&webSocket, &QWebSocket::textMessageReceived,
94             this, &UserManagement::onTextMessageReceived);
95     QVariantList list;
96     QByteArray json;
97     list << 2 << QString().setNum(++sequence) << "agl-identity-agent/subscribe" << true;
98     listToJson(list, &json);
99     webSocket.sendTextMessage(QString(json));
100     list .clear();
101     list << 2 << QString().setNum(++sequence) << "agl-identity-agent/scan" << true;
102     listToJson(list, &json);
103     webSocket.sendTextMessage(QString(json));
104 }
105 void UserManagement::onTextMessageReceived(QString message)
106 {
107     QVariantList list;
108     const bool ok = jsonToList(message.toUtf8(), &list);
109     if(!ok || list.size() < 3) {
110         qWarning()<<"error 1 decoding json"<<list.size()<<message;
111         return;
112     }
113     QVariantMap map  = list.at(2).toMap();
114     if(list.first().toInt() == 5) {
115         if(!isRed)
116             QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Red-01.png"));
117         isRed = true;
118         timerRed.start();
119         map = map["data"].toMap();
120         if(map["eventName"].toString() == "login") {
121             //qWarning()<<"login received in client";
122             list.clear();
123             list << 2 << QString().setNum(++sequence) << "agl-identity-agent/get" << true;
124             listToJson(list, &data);
125             QTimer::singleShot(300, this, SLOT(slot_sendData()));
126         }
127         return;
128     }
129     if(list.first().toInt() == 3) {
130         if(!map.contains("response")) {
131             return;
132         }
133         map = map["response"].toMap();
134         User user;
135         user.postal_address = map["postal_address"].toString();
136         QStringList temp  = map["loc"].toString().split(",");
137         if(temp.size() == 2) {
138             user.loc.setX(temp.at(0).toDouble());
139             user.loc.setY(temp.at(1).toDouble());
140         }
141         user.graphActions = map["graphActions"].toString().split(",");
142         user.country = map["country"].toString();
143         user.mail = map["mail"].toString();
144         user.city = map["city"].toString();
145         user.graphEmail = map["graphEmail"].toString();
146         user.graphPreferredLanguage = map["graphPreferredLanguage"].toString();
147         user.ccNumberMasked = map["ccNumberMasked"].toString();
148         user.ccExpYear = map["ccExpYear"].toString();
149         user.ccExpMonth = map["ccExpMonth"].toString();
150         user.description = map["description"].toString();
151         user.groups = map["groups"].toStringList();
152         user.last_name = map["last_name"].toString();
153         user.ccNumber = map["ccNumber"].toString();
154         user.house_identifier = map["house_identifier"].toString();
155         user.phone = map["phone"].toString();
156         user.name = map["name"].toString();
157         user.state = map["state"].toString();
158         user.common_name = map["common_name"].toString();
159         user.fax = map["fax"].toString();
160         user.postal_code = map["postal_code"].toString();
161         user.first_name = map["first_name"].toString();
162         user.keytoken = map["keytoken"].toString();
163         setUser(user);
164     }
165 }
166 void UserManagement::slot_sendData()
167 {
168     webSocket.sendTextMessage(QString(data));
169 }
170
171 void UserManagement::onClosed()
172 {
173     qWarning()<<"webSocket closed";
174 }
175 bool UserManagement::listToJson(const QList<QVariant> &list, QByteArray *json) const
176 {
177     QVariant v(list);
178     *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
179     return true;
180 }
181 bool UserManagement::jsonToList(const QByteArray &buf, QList<QVariant> *list) const
182 {
183     if(!list)
184         return false;
185     QJsonParseError err;
186     QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
187     if(err.error != 0) {
188         qWarning() << "Error parsing json data" << err.errorString() << buf;
189         *list = QList<QVariant>();
190         return false;
191     }
192     *list = v.toList();
193     return true;
194 }
195 bool UserManagement::mapToJson( const QVariantMap &map, QByteArray *json) const
196 {
197     if(!json)
198         return false;
199     QVariant v(map);
200     *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
201     return true;
202 }
203 bool UserManagement::jsonToMap(const QByteArray &buf, QVariantMap *map) const
204 {
205     if(!map)
206         return false;
207     QJsonParseError err;
208     QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
209     if(err.error != 0) {
210         qWarning() << "Error parsing json data" << err.errorString() << buf;
211         *map = QVariantMap();
212         return false;
213     }
214     *map = v.toMap();
215     return true;
216 }
217 #ifndef REAL_SERVER
218 void UserManagement::launchServer()
219 {
220       webSocketServer = new QWebSocketServer(QStringLiteral("My Server"),
221                                               QWebSocketServer::NonSecureMode, this);
222       if(webSocketServer->listen(QHostAddress::Any, 1234)) {
223           connect(webSocketServer, &QWebSocketServer::newConnection,
224                   this, &UserManagement::onServerNewConnection);
225           connect(webSocketServer, &QWebSocketServer::closed, this, &UserManagement::onServerClosed);
226           QTimer::singleShot(100, this, SLOT(connectWebsockets()));
227       } else {
228           qWarning()<<"unable to launch webSocket server";
229       }
230 }
231 void UserManagement::onServerNewConnection()
232 {
233     pSocket = webSocketServer->nextPendingConnection();
234     connect(pSocket, &QWebSocket::textMessageReceived, this, &UserManagement::processTextMessage, Qt::UniqueConnection);
235     connect(pSocket, &QWebSocket::binaryMessageReceived, this, &UserManagement::processBinaryMessage, Qt::UniqueConnection);
236     connect(pSocket, &QWebSocket::disconnected, this, &UserManagement::serverSocketDisconnected, Qt::UniqueConnection);
237 }
238 void UserManagement::processTextMessage(QString message)
239 {
240     QString clientDetails_1 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\",\"graphActions\":\"Install App,Update Software,Exceed 100 Kph,Open Trunk,View Online\""
241                               ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
242                               "\"bjensen@example.com\",\"graphPreferredLanguage\":\"en\",\"ccNumberMasked\":\"-111\",\"ccExpYear\""
243                               ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
244                               "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
245                               "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
246                               "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"Barbara\",\"keytoken\":\"a123456\"}";
247     QString clientDetails_2 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\""
248                               ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
249                               "\"bjensen@example.com\",\"graphPreferredLanguage\":\"fr\",\"ccNumberMasked\":\"-222\",\"ccExpYear\""
250                               ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
251                               "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
252                               "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
253                               "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"José\",\"keytoken\":\"a123456\"}";
254     QString clientDetails = clientDetails_1;
255     if(sequence % 2 == 1)
256         clientDetails = clientDetails_2;
257     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
258     //qDebug() << "message received in server:" << message;
259     if (!pClient)
260         return;
261     QVariantList list;
262     if(!jsonToList(message.toUtf8(), &list))
263         return;
264     if(list.size() < 2)
265         return;
266     const int messType = list.at(0).toInt();
267     const QString messId = list.at(1).toString();
268     const QString cmd = list.at(2).toString();
269     list.clear();
270     QString reply;
271     switch(messType) {
272     case 2:
273         if(cmd == "agl-identity-agent/subscribe") {
274             reply = "[3,\"999maitai999\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\",\"uuid\":\"1f2f7678-6f2e-4f54-b7b5-d0d4dcbf2e41\"}}]";
275         } else if (cmd == "agl-identity-agent/get") {
276             reply = "[3,\"999maitai99\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\"},\"response\":....}]";
277             reply = reply.replace("....", clientDetails);
278         } else {
279             qWarning()<<"invalid cmd received:"<<cmd;
280             return;
281         }
282         break;
283     default:
284         qWarning()<<"invalid message type"<<messType;
285         return;
286         break;
287     }
288     reply = reply.replace("999maitai999", messId);
289     pClient->sendTextMessage(reply);
290 }
291 void UserManagement::processBinaryMessage(QByteArray message)
292 {
293     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
294     qDebug() << "Binary Message received ????:" << message;
295     if (pClient) {
296        // pClient->sendBinaryMessage(message);
297     }
298 }
299 void UserManagement::serverSocketDisconnected()
300 {
301     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
302     qDebug() << "socketDisconnected:" << pClient;
303     if (pClient) {
304         pClient->deleteLater();
305     }
306 }
307 void UserManagement::slot_timerTest()
308 {
309     if(!pSocket)
310         return;
311     if(sequence > 3) {
312         timerTest.stop();
313         return;
314     }
315     pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"incoming\",\"accountid\":\"D2:D4:71:0D:B5:F1\",\"nickname\":\"D2:D4:71:0D:B5:F1\"},\"jtype\":\"afb-event\"}]");
316     pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"login\",\"accountid\":\"null\"},\"jtype\":\"afb-event\"}]");
317 }
318 void UserManagement::onServerClosed()
319 {
320     qWarning()<<"websocket server closed";
321 }
322 #endif