summaryrefslogtreecommitdiff
path: root/protocols/VKontakte/src/vk_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/VKontakte/src/vk_thread.cpp')
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp98
1 files changed, 97 insertions, 1 deletions
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index 71ee02c2a3..23ef63165a 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -27,19 +27,115 @@ void CVkProto::ShutdownSession()
OnLoggedOut();
}
+void CVkProto::ConnectionFailed(int iReason)
+{
+ delSetting("AccessToken");
+
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, iReason);
+
+ ShutdownSession();
+}
+
+void CVkProto::OnLoggedIn()
+{
+ m_bOnline = true;
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, m_iDesiredStatus);
+ m_iStatus = m_iDesiredStatus;
+
+ RequestMyInfo();
+}
+
void CVkProto::OnLoggedOut()
{
m_hWorkerThread = 0;
+ m_bOnline = false;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
+extern CMStringA loginCookie;
+
+static char VK_TOKEN_BEG[] = "access_token=";
+
void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply)
{
+ if (reply->resultCode == 302) { // manual redirect
+ LPCSTR pszLocation = findHeader(reply, "Location");
+ if (pszLocation) {
+ if ( !_strnicmp(pszLocation, VK_REDIRECT_URL, sizeof(VK_REDIRECT_URL)-1)) {
+ m_szAccessToken = NULL;
+ LPCSTR p = strstr(pszLocation, VK_TOKEN_BEG);
+ if (p) {
+ p += sizeof(VK_TOKEN_BEG)-1;
+ for (LPCSTR q = p+1; *q; q++) {
+ if (*q == '&' || *q == '=' || *q == '\"') {
+ m_szAccessToken = mir_strndup(p, q-p);
+ break;
+ }
+ }
+ if (m_szAccessToken == NULL)
+ m_szAccessToken = mir_strdup(p);
+ setString("AccessToken", m_szAccessToken);
+ }
+ else delSetting("AccessToken");
+
+ OnLoggedIn();
+ }
+ else {
+ AsyncHttpRequest *pReq = new AsyncHttpRequest();
+ pReq->requestType = REQUEST_GET;
+ pReq->flags = NLHRF_PERSISTENT | NLHRF_HTTP11 | NLHRF_REMOVEHOST | NLHRF_SMARTREMOVEHOST;
+ pReq->m_pFunc = &CVkProto::OnOAuthAuthorize;
+ pReq->AddHeader("Referer", m_prevUrl);
+ pReq->Redirect(reply);
+ if (pReq->szUrl) {
+ if ( strstr(pReq->szUrl, "login.vk.com"))
+ pReq->AddHeader("Cookie", loginCookie);
+ m_prevUrl = pReq->szUrl;
+ }
+ PushAsyncHttpRequest(pReq);
+ }
+ }
+ else ConnectionFailed(LOGINERR_NOSERVER);
+ return;
+ }
+
+ if (reply->resultCode != 200) { // something went wrong
+LBL_NoForm:
+ ConnectionFailed(LOGINERR_NOSERVER);
+ return;
+ }
+
+ if ( strstr(reply->pData, ptrA( mir_utf8encodecp("неверный логин или пароль", 1251)))) {
+ ConnectionFailed(LOGINERR_WRONGPASSWORD);
+ return;
+ }
+
+ // Application requests access to user's account
+ if ( !strstr(reply->pData, "form method=\"post\""))
+ goto LBL_NoForm;
+
+ CMStringA szAction;
+ CMStringA szBody = AutoFillForm(reply->pData, szAction);
+ if (szAction.IsEmpty() || szBody.IsEmpty())
+ goto LBL_NoForm;
+
+ AsyncHttpRequest *pReq = new AsyncHttpRequest();
+ pReq->requestType = REQUEST_POST;
+ pReq->flags = NLHRF_PERSISTENT | NLHRF_HTTP11 | NLHRF_REMOVEHOST | NLHRF_SMARTREMOVEHOST;
+ pReq->pData = mir_strdup(szBody);
+ pReq->dataLength = szBody.GetLength();
+ pReq->szUrl = mir_strdup(szAction); m_prevUrl = pReq->szUrl;
+ pReq->m_pFunc = &CVkProto::OnOAuthAuthorize;
+ pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ pReq->Redirect(reply);
+ PushAsyncHttpRequest(pReq);
}
void CVkProto::RequestMyInfo()
{
}
-