From a067756a292c475755ec86d7979ed4396fa4b48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 19 Sep 2014 23:29:20 +0200 Subject: [PATCH] HaikuDepot: Get captcha image in UserLoginWindow --- src/apps/haikudepot/MainWindow.cpp | 2 +- src/apps/haikudepot/UserLoginWindow.cpp | 95 ++++++++++++++++++++++--- src/apps/haikudepot/UserLoginWindow.h | 10 ++- 3 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/apps/haikudepot/MainWindow.cpp b/src/apps/haikudepot/MainWindow.cpp index 8d7c2c6cb0..9192131bdc 100644 --- a/src/apps/haikudepot/MainWindow.cpp +++ b/src/apps/haikudepot/MainWindow.cpp @@ -853,7 +853,7 @@ void MainWindow::_OpenLoginWindow() { UserLoginWindow* window = new UserLoginWindow(this, - BRect(0, 0, 500, 400)); + BRect(0, 0, 500, 400), fModel); window->Show(); } diff --git a/src/apps/haikudepot/UserLoginWindow.cpp b/src/apps/haikudepot/UserLoginWindow.cpp index 75732d4068..b9e06c1f81 100644 --- a/src/apps/haikudepot/UserLoginWindow.cpp +++ b/src/apps/haikudepot/UserLoginWindow.cpp @@ -8,7 +8,10 @@ #include #include +#include + #include +#include #include #include #include @@ -16,6 +19,8 @@ #include #include "BitmapView.h" +#include "Model.h" +#include "WebAppInterface.h" #undef B_TRANSLATION_CONTEXT @@ -24,7 +29,8 @@ enum { MSG_SEND = 'send', - MSG_TAB_SELECTED = 'tbsl' + MSG_TAB_SELECTED = 'tbsl', + MSG_CAPTCHA_OBTAINED = 'cpob', }; @@ -53,13 +59,14 @@ private: }; -UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame) +UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame, Model& model) : BWindow(frame, B_TRANSLATE_SYSTEM_NAME("Log in"), B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS - | B_NOT_RESIZABLE), - fMode(NONE) + | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), + fMode(NONE), + fRequestCaptchaThread(-1) { AddToSubset(parent); @@ -71,8 +78,9 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame) NULL); fRepeatPasswordField = new BTextControl(B_TRANSLATE("Repeat pass phrase:"), "", NULL); - fLanguageCodeField = new BTextControl(B_TRANSLATE("Language code:"), "", - NULL); + fLanguageCodeField = new BTextControl(B_TRANSLATE("Language code:"), + model.PreferredLanguage(), NULL); + fEmailField = new BTextControl(B_TRANSLATE("Email address:"), "", NULL); fCaptchaView = new BitmapView("captcha view"); fCaptchaResultField = new BTextControl("", "", NULL); @@ -94,9 +102,10 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame) .AddTextControl(fNewUsernameField, 0, 0) .AddTextControl(fNewPasswordField, 0, 1) .AddTextControl(fRepeatPasswordField, 0, 2) - .AddTextControl(fLanguageCodeField, 0, 3) - .Add(fCaptchaView, 0, 4) - .Add(fCaptchaResultField, 1, 4) + .AddTextControl(fEmailField, 0, 3) + .AddTextControl(fLanguageCodeField, 0, 4) + .Add(fCaptchaView, 0, 5) + .Add(fCaptchaResultField, 1, 5) .SetInsets(B_USE_DEFAULT_SPACING) ; @@ -129,6 +138,10 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame) UserLoginWindow::~UserLoginWindow() { + BAutolock locker(&fLock); + + if (fRequestCaptchaThread >= 0) + wait_for_thread(fRequestCaptchaThread, NULL); } @@ -167,6 +180,13 @@ UserLoginWindow::MessageReceived(BMessage* message) break; } + case MSG_CAPTCHA_OBTAINED: + if (fCaptchaImage.Get() != NULL) { + fCaptchaView->SetBitmap( + fCaptchaImage->Bitmap(SharedBitmap::SIZE_ANY)); + } + break; + default: BWindow::MessageReceived(message); break; @@ -190,6 +210,8 @@ UserLoginWindow::_SetMode(Mode mode) case CREATE_ACCOUNT: fTabView->Select(1); fSendButton->SetLabel(B_TRANSLATE("Create account")); + if (fCaptchaToken.IsEmpty()) + _RequestCaptcha(); break; default: break; @@ -230,13 +252,66 @@ UserLoginWindow::_CreateAccount() void UserLoginWindow::_RequestCaptcha() { + BAutolock locker(&fLock); + + if (fRequestCaptchaThread >= 0) + return; + + fRequestCaptchaThread = spawn_thread(&_RequestCaptchaThreadEntry, + "Captcha requester", B_NORMAL_PRIORITY, this); + if (fRequestCaptchaThread >= 0) + resume_thread(fRequestCaptchaThread); + } int32 UserLoginWindow::_RequestCaptchaThreadEntry(void* data) { - // TODO: Use WebInterface to + UserLoginWindow* window = reinterpret_cast(data); + window->_RequestCaptchaThread(); return 0; } + +void +UserLoginWindow::_RequestCaptchaThread() +{ + WebAppInterface interface; + BMessage info; + + status_t status = interface.RequestCaptcha(info); + + BAutolock locker(&fLock); + + BMessage result; + if (status == B_OK && info.FindMessage("result", &result) == B_OK) { + result.FindString("token", &fCaptchaToken); + BString imageDataBase64; + if (result.FindString("pngImageDataBase64", &imageDataBase64) == B_OK) { + ssize_t encodedSize = imageDataBase64.Length(); + ssize_t decodedSize = (encodedSize * 3 + 3) / 4; + if (decodedSize > 0) { + char* buffer = new char[decodedSize]; + decodedSize = decode_base64(buffer, imageDataBase64.String(), + encodedSize); + if (decodedSize > 0) { + BMemoryIO memoryIO(buffer, (size_t)decodedSize); + fCaptchaImage.SetTo(new(std::nothrow) SharedBitmap( + memoryIO), true); + BMessenger(this).SendMessage(MSG_CAPTCHA_OBTAINED); + } else { + fprintf(stderr, "Failed to decode captcha: %s\n", + strerror(decodedSize)); + } + delete[] buffer; + } + } + } else { + fprintf(stderr, "Failed to obtain captcha: %s\n", strerror(status)); + } + + fRequestCaptchaThread = -1; +} + + diff --git a/src/apps/haikudepot/UserLoginWindow.h b/src/apps/haikudepot/UserLoginWindow.h index 8886c77fa6..31044a009f 100644 --- a/src/apps/haikudepot/UserLoginWindow.h +++ b/src/apps/haikudepot/UserLoginWindow.h @@ -5,6 +5,7 @@ #ifndef USER_LOGIN_WINDOW_H #define USER_LOGIN_WINDOW_H +#include #include #include "PackageInfo.h" @@ -14,11 +15,13 @@ class BButton; class BTabView; class BTextControl; class BitmapView; +class Model; class UserLoginWindow : public BWindow { public: - UserLoginWindow(BWindow* parent, BRect frame); + UserLoginWindow(BWindow* parent, BRect frame, + Model& model); virtual ~UserLoginWindow(); virtual void MessageReceived(BMessage* message); @@ -36,6 +39,7 @@ private: void _RequestCaptcha(); static int32 _RequestCaptchaThreadEntry(void* data); + void _RequestCaptchaThread(); private: BTabView* fTabView; @@ -46,6 +50,7 @@ private: BTextControl* fNewUsernameField; BTextControl* fNewPasswordField; BTextControl* fRepeatPasswordField; + BTextControl* fEmailField; BTextControl* fLanguageCodeField; BitmapView* fCaptchaView; BTextControl* fCaptchaResultField; @@ -57,6 +62,9 @@ private: BitmapRef fCaptchaImage; Mode fMode; + + BLocker fLock; + thread_id fRequestCaptchaThread; };