summaryrefslogtreecommitdiff
path: root/protocols/SkypeWeb/src/skype_login.cpp
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-04-07 21:50:05 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-04-07 21:50:05 +0000
commit90a05404a6ded56141c0230f663686439f8fa146 (patch)
tree6531783fbbedc04db025526243342823ed9ccd65 /protocols/SkypeWeb/src/skype_login.cpp
parentde593c8e4ae504a8d159cc272740846ef9c20ca6 (diff)
SkypeWeb:
- added ability to getting contacts statuses - partly reworked login flow git-svn-id: http://svn.miranda-ng.org/main/trunk@12665 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/SkypeWeb/src/skype_login.cpp')
-rw-r--r--protocols/SkypeWeb/src/skype_login.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp
new file mode 100644
index 0000000000..ea5a949af0
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_login.cpp
@@ -0,0 +1,188 @@
+#include "common.h"
+
+int CSkypeProto::OnModulesLoaded(WPARAM, LPARAM)
+{
+ return 0;
+}
+
+void CSkypeProto::OnLoginFirst(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+
+ const std::string content = response->pData;
+
+ regex = "<input type=\"hidden\" name=\"pie\" id=\"pie\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string pie = match[1];
+
+ regex = "<input type=\"hidden\" name=\"etm\" id=\"etm\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string etm = match[1];
+
+ ptrA skypename(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_ID))));
+ ptrA password(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_PASSWORD))));
+
+ PushRequest(new LoginRequest(skypename, password, pie.c_str(), etm.c_str()), &CSkypeProto::OnLoginSecond);
+}
+
+void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+
+ std::string content = response->pData;
+
+ regex = "<input type=\"hidden\" name=\"skypetoken\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string token = match[1];
+ setString("TokenSecret", token.c_str());
+
+ regex = "<input type=\"hidden\" name=\"expires_in\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string expiresIn = match[1];
+ int seconds = atoi(expiresIn.c_str());
+ setDword("TokenExpiresIn", time(NULL) + seconds);
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ regex = "^(.+?)=(.+?);";
+ content = response->headers[i].szValue;
+
+ if (std::regex_search(content, match, regex))
+ cookies[match[1]] = match[2];
+ }
+
+ ptrA server(getStringA("Server"));
+ PushRequest(new CreateEndpointRequest(token.c_str()), &CSkypeProto::OnEndpointCreated);
+
+ PushRequest(new GetProfileRequest(token.c_str()), &CSkypeProto::LoadProfile);
+ PushRequest(new GetContactListRequest(token.c_str()), &CSkypeProto::LoadContactList);
+}
+
+void CSkypeProto::OnEndpointCreated(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ return;
+
+ std::regex regex;
+ std::smatch match;
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (!mir_strcmpi(response->headers[i].szName, "Set-RegistrationToken"))
+ {
+ CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal;
+ int iStart = 0;
+ while (true)
+ {
+ CMStringA szToken = szValue.Tokenize(";", iStart).Trim();
+ if (iStart == -1)
+ break;
+ int iStart2 = 0;
+ szCookieName = szToken.Tokenize("=", iStart2);
+ szCookieVal = szToken.Mid(iStart2);
+ setString(szCookieName, szCookieVal);
+ }
+ }
+ else if (!mir_strcmpi(response->headers[i].szName, "Location"))
+ {
+ CMStringA szValue = response->headers[i].szValue, szCookieName, szCookieVal;
+ setString("Server", ptrA(GetServerFromUrl(szValue)));
+ }
+
+ }
+
+ ptrA server(getStringA("Server"));
+
+ if (response->resultCode != 201)
+ {
+ ptrA token(getStringA("Token"));
+ PushRequest(new CreateEndpointRequest(token), &CSkypeProto::OnEndpointCreated);
+ return;
+ }
+
+ ptrA regToken(getStringA("registrationToken"));
+
+
+ PushRequest(new CreateSubscriptionsRequest(regToken), &CSkypeProto::OnSubscriptionsCreated);
+}
+
+void CSkypeProto::OnSubscriptionsCreated(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ return;
+
+ ptrA regToken(getStringA("registrationToken"));
+ ptrA skypename(getStringA(SKYPE_SETTINGS_ID));
+ //ptrA endpoint(getStringA("endpointId"));
+ //PushRequest(new SendCapabilitiesRequest(regToken, endpoint));
+ //PushRequest(new SetStatusRequest(regToken, MirandaToSkypeStatus(m_iDesiredStatus)), &CSkypeProto::OnStatusChanged);
+ PushRequest(new GetContactStatusRequest(regToken, skypename), &CSkypeProto::OnStatusChanged);
+
+ LIST<char> skypenames(1);
+ for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
+ skypenames.insert(getStringA(hContact, SKYPE_SETTINGS_ID));
+ PushRequest(new CreateContactsRequest(regToken, skypenames));
+ for (int i = 0; i < skypenames.getCount(); i++)
+ mir_free(skypenames[i]);
+ skypenames.destroy();
+
+ m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, 0, NULL);
+}
+
+void CSkypeProto::OnStatusChanged(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ return;
+
+ JSONROOT root(response->pData);
+
+ if (root == NULL)
+ return;
+
+ JSONNODE *status_json = json_get(root, "status");
+ ptrT status(json_as_string(status_json));
+ int iNewStatus = SkypeToMirandaStatus(_T2A(status));
+
+ if (iNewStatus == ID_STATUS_OFFLINE)
+ SetStatus(ID_STATUS_OFFLINE);
+
+ m_iStatus = m_iDesiredStatus = iNewStatus;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus);
+} \ No newline at end of file