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