HaikuDepot: Implemented logging into haiku-depot-server
UserLoginWindow: * Focus nickname text field on tab switches * Implement testing the login info, the web-app replies with a token, if valid. It could be used for Token Bearer authorization of requests, but this is not used yet. Instead the username and password are set on the Model. Also after creating a new account successfully. Model: * Use a member instance of WebAppInterface. Set the preferred language and the login-info only once.
This commit is contained in:
parent
f511367b33
commit
28075ee427
@ -21,8 +21,6 @@
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include "WebAppInterface.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Model"
|
||||
@ -338,6 +336,7 @@ Model::Model()
|
||||
language.CopyInto(fPreferredLanguage, 0, 2);
|
||||
}
|
||||
}
|
||||
fWebAppInterface.SetPreferredLanguage(fPreferredLanguage);
|
||||
}
|
||||
|
||||
|
||||
@ -516,8 +515,6 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags)
|
||||
|
||||
if ((flags & POPULATE_USER_RATINGS) != 0) {
|
||||
// Retrieve info from web-app
|
||||
WebAppInterface interface;
|
||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
||||
BMessage info;
|
||||
|
||||
BString packageName;
|
||||
@ -528,7 +525,7 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags)
|
||||
architecture = package->Architecture();
|
||||
}
|
||||
|
||||
status_t status = interface.RetrieveUserRatings(packageName,
|
||||
status_t status = fWebAppInterface.RetrieveUserRatings(packageName,
|
||||
architecture, 0, 50, info);
|
||||
if (status == B_OK) {
|
||||
// Parse message
|
||||
@ -641,6 +638,17 @@ Model::StopPopulatingAllPackages()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::SetAuthorization(const BString& username, const BString& password)
|
||||
{
|
||||
BAutolock locker(&fLock);
|
||||
fWebAppInterface.SetAuthorization(username, password);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private
|
||||
|
||||
|
||||
int32
|
||||
Model::_PopulateAllPackagesEntry(void* cookie)
|
||||
{
|
||||
@ -727,8 +735,6 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
|
||||
return;
|
||||
|
||||
// Retrieve info from web-app
|
||||
WebAppInterface interface;
|
||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
||||
BMessage info;
|
||||
|
||||
StringList packageNames;
|
||||
@ -739,7 +745,7 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
|
||||
packageArchitectures.Add(package->Architecture());
|
||||
}
|
||||
|
||||
status_t status = interface.RetrieveBulkPackageInfo(packageNames,
|
||||
status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames,
|
||||
packageArchitectures, info);
|
||||
if (status == B_OK) {
|
||||
// Parse message
|
||||
@ -818,11 +824,9 @@ Model::_PopulatePackageInfo(const PackageInfoRef& package, bool fromCacheOnly)
|
||||
return;
|
||||
|
||||
// Retrieve info from web-app
|
||||
WebAppInterface interface;
|
||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
||||
BMessage info;
|
||||
|
||||
status_t status = interface.RetrievePackageInfo(package->Title(),
|
||||
status_t status = fWebAppInterface.RetrievePackageInfo(package->Title(),
|
||||
package->Architecture(), info);
|
||||
if (status == B_OK) {
|
||||
// Parse message
|
||||
@ -995,10 +999,10 @@ Model::_PopulatePackageIcon(const PackageInfoRef& package, bool fromCacheOnly)
|
||||
return;
|
||||
|
||||
// Retrieve icon from web-app
|
||||
WebAppInterface interface;
|
||||
BMallocIO buffer;
|
||||
|
||||
status_t status = interface.RetrievePackageIcon(package->Title(), &buffer);
|
||||
status_t status = fWebAppInterface.RetrievePackageIcon(package->Title(),
|
||||
&buffer);
|
||||
if (status == B_OK) {
|
||||
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
||||
BAutolock locker(&fLock);
|
||||
@ -1053,12 +1057,11 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
|
||||
return;
|
||||
|
||||
// Retrieve screenshot from web-app
|
||||
WebAppInterface interface;
|
||||
BMallocIO buffer;
|
||||
|
||||
int32 scaledHeight = scaledWidth * info.Height() / info.Width();
|
||||
|
||||
status_t status = interface.RetrieveScreenshot(info.Code(),
|
||||
status_t status = fWebAppInterface.RetrieveScreenshot(info.Code(),
|
||||
scaledWidth, scaledHeight, &buffer);
|
||||
if (status == B_OK) {
|
||||
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <Locker.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
#include "WebAppInterface.h"
|
||||
|
||||
|
||||
class BMessage;
|
||||
|
||||
@ -105,6 +107,9 @@ public:
|
||||
const BString& PreferredLanguage() const
|
||||
{ return fPreferredLanguage; }
|
||||
|
||||
void SetAuthorization(const BString& username,
|
||||
const BString& password);
|
||||
|
||||
private:
|
||||
static int32 _PopulateAllPackagesEntry(void* cookie);
|
||||
void _PopulateAllPackagesThread(bool fromCacheOnly);
|
||||
@ -168,6 +173,8 @@ private:
|
||||
thread_id fPopulateAllPackagesThread;
|
||||
volatile bool fStopPopulatingAllPackages;
|
||||
BString fPreferredLanguage;
|
||||
|
||||
WebAppInterface fWebAppInterface;
|
||||
};
|
||||
|
||||
|
||||
|
@ -209,12 +209,14 @@ UserLoginWindow::_SetMode(Mode mode)
|
||||
case LOGIN:
|
||||
fTabView->Select((int32)0);
|
||||
fSendButton->SetLabel(B_TRANSLATE("Log in"));
|
||||
fUsernameField->MakeFocus();
|
||||
break;
|
||||
case CREATE_ACCOUNT:
|
||||
fTabView->Select(1);
|
||||
fSendButton->SetLabel(B_TRANSLATE("Create account"));
|
||||
if (fCaptchaToken.IsEmpty())
|
||||
_RequestCaptcha();
|
||||
fNewUsernameField->MakeFocus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -225,15 +227,15 @@ UserLoginWindow::_SetMode(Mode mode)
|
||||
void
|
||||
UserLoginWindow::_Login()
|
||||
{
|
||||
// TODO: Implement...
|
||||
BAlert* alert = new BAlert(B_TRANSLATE("Not implemented"),
|
||||
B_TRANSLATE("Sorry, while the web application would already support "
|
||||
"logging in, HaikuDepot was not yet updated to use "
|
||||
"this functionality."),
|
||||
B_TRANSLATE("Bummer"));
|
||||
alert->Go(NULL);
|
||||
BAutolock locker(&fLock);
|
||||
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
if (fWorkerThread >= 0)
|
||||
return;
|
||||
|
||||
thread_id thread = spawn_thread(&_AuthenticateThreadEntry,
|
||||
"Authenticator", B_NORMAL_PRIORITY, this);
|
||||
if (thread >= 0)
|
||||
_SetWorkerThread(thread);
|
||||
}
|
||||
|
||||
|
||||
@ -303,6 +305,79 @@ UserLoginWindow::_SetWorkerThread(thread_id thread)
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
UserLoginWindow::_AuthenticateThreadEntry(void* data)
|
||||
{
|
||||
UserLoginWindow* window = reinterpret_cast<UserLoginWindow*>(data);
|
||||
window->_AuthenticateThread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UserLoginWindow::_AuthenticateThread()
|
||||
{
|
||||
if (!Lock())
|
||||
return;
|
||||
|
||||
BString nickName(fUsernameField->Text());
|
||||
BString passwordClear(fPasswordField->Text());
|
||||
|
||||
Unlock();
|
||||
|
||||
WebAppInterface interface;
|
||||
BMessage info;
|
||||
|
||||
status_t status = interface.AuthenticateUser(
|
||||
nickName, passwordClear, info);
|
||||
|
||||
BString error = B_TRANSLATE("Authentication failed. "
|
||||
"Connection to the service failed.");
|
||||
|
||||
BMessage result;
|
||||
if (status == B_OK && info.FindMessage("result", &result) == B_OK) {
|
||||
BString token;
|
||||
if (result.FindString("token", &token) == B_OK && !token.IsEmpty()) {
|
||||
// We don't care for or store the token for now. The web-service
|
||||
// supports two methods of authorizing requests. One is via
|
||||
// Basic Authentication in the HTTP header, the other is via
|
||||
// Token Bearer. Since the connection is encrypted, it is hopefully
|
||||
// ok to send the password with each request instead of implementing
|
||||
// the Token Bearer. See section 5.1.2 in the haiku-depot-web
|
||||
// documentation.
|
||||
error = "";
|
||||
fModel.SetAuthorization(nickName, passwordClear);
|
||||
} else {
|
||||
error = B_TRANSLATE("Authentication failed. The user does "
|
||||
"not exist or the wrong password was supplied.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!error.IsEmpty()) {
|
||||
BAlert* alert = new(std::nothrow) BAlert(
|
||||
B_TRANSLATE("Authentication failed"),
|
||||
error,
|
||||
B_TRANSLATE("Close"));
|
||||
|
||||
if (alert != NULL)
|
||||
alert->Go();
|
||||
|
||||
_SetWorkerThread(-1);
|
||||
} else {
|
||||
_SetWorkerThread(-1);
|
||||
BMessenger(this).SendMessage(B_QUIT_REQUESTED);
|
||||
|
||||
BAlert* alert = new(std::nothrow) BAlert(
|
||||
B_TRANSLATE("Success"),
|
||||
B_TRANSLATE("The authentication was successful."),
|
||||
B_TRANSLATE("Close"));
|
||||
|
||||
if (alert != NULL)
|
||||
alert->Go();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
UserLoginWindow::_RequestCaptchaThreadEntry(void* data)
|
||||
{
|
||||
@ -433,6 +508,8 @@ UserLoginWindow::_CreateAccountThread()
|
||||
fCaptchaToken = "";
|
||||
_RequestCaptcha();
|
||||
} else {
|
||||
fModel.SetAuthorization(nickName, passwordClear);
|
||||
|
||||
_SetWorkerThread(-1);
|
||||
BMessenger(this).SendMessage(B_QUIT_REQUESTED);
|
||||
|
||||
|
@ -40,6 +40,9 @@ private:
|
||||
|
||||
void _SetWorkerThread(thread_id thread);
|
||||
|
||||
static int32 _AuthenticateThreadEntry(void* data);
|
||||
void _AuthenticateThread();
|
||||
|
||||
static int32 _RequestCaptchaThreadEntry(void* data);
|
||||
void _RequestCaptchaThread();
|
||||
|
||||
|
@ -238,11 +238,34 @@ WebAppInterface::WebAppInterface()
|
||||
}
|
||||
|
||||
|
||||
WebAppInterface::WebAppInterface(const WebAppInterface& other)
|
||||
:
|
||||
fUsername(other.fUsername),
|
||||
fPassword(other.fPassword),
|
||||
fLanguage(other.fLanguage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WebAppInterface::~WebAppInterface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WebAppInterface&
|
||||
WebAppInterface::operator=(const WebAppInterface& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
fUsername = other.fUsername;
|
||||
fPassword = other.fPassword;
|
||||
fLanguage = other.fLanguage;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebAppInterface::SetAuthorization(const BString& username,
|
||||
const BString& password)
|
||||
@ -452,6 +475,26 @@ WebAppInterface::CreateUser(const BString& nickName,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WebAppInterface::AuthenticateUser(const BString& nickName,
|
||||
const BString& passwordClear, BMessage& message)
|
||||
{
|
||||
BString jsonString = JsonBuilder()
|
||||
.AddValue("jsonrpc", "2.0")
|
||||
.AddValue("id", ++fRequestIndex)
|
||||
.AddValue("method", "authenticateUser")
|
||||
.AddArray("params")
|
||||
.AddObject()
|
||||
.AddValue("nickname", nickName)
|
||||
.AddValue("passwordClear", passwordClear)
|
||||
.EndObject()
|
||||
.EndArray()
|
||||
.End();
|
||||
|
||||
return _SendJsonRequest("user", jsonString, message);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private
|
||||
|
||||
|
||||
|
@ -21,8 +21,11 @@ typedef List<BString, false> StringList;
|
||||
class WebAppInterface {
|
||||
public:
|
||||
WebAppInterface();
|
||||
WebAppInterface(const WebAppInterface& other);
|
||||
virtual ~WebAppInterface();
|
||||
|
||||
WebAppInterface& operator=(const WebAppInterface& other);
|
||||
|
||||
void SetAuthorization(const BString& username,
|
||||
const BString& password);
|
||||
void SetPreferredLanguage(const BString& language);
|
||||
@ -63,6 +66,10 @@ public:
|
||||
const BString& languageCode,
|
||||
BMessage& message);
|
||||
|
||||
status_t AuthenticateUser(const BString& nickName,
|
||||
const BString& passwordClear,
|
||||
BMessage& message);
|
||||
|
||||
private:
|
||||
status_t _SendJsonRequest(const char* domain,
|
||||
BString jsonString, BMessage& reply) const;
|
||||
@ -71,7 +78,6 @@ private:
|
||||
BString fUsername;
|
||||
BString fPassword;
|
||||
BString fLanguage;
|
||||
BString fArchitecture;
|
||||
static int fRequestIndex;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user