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 <Message.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
#include "WebAppInterface.h"
|
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
#undef B_TRANSLATION_CONTEXT
|
||||||
#define B_TRANSLATION_CONTEXT "Model"
|
#define B_TRANSLATION_CONTEXT "Model"
|
||||||
@ -338,6 +336,7 @@ Model::Model()
|
|||||||
language.CopyInto(fPreferredLanguage, 0, 2);
|
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) {
|
if ((flags & POPULATE_USER_RATINGS) != 0) {
|
||||||
// Retrieve info from web-app
|
// Retrieve info from web-app
|
||||||
WebAppInterface interface;
|
|
||||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
|
||||||
BMessage info;
|
BMessage info;
|
||||||
|
|
||||||
BString packageName;
|
BString packageName;
|
||||||
@ -528,7 +525,7 @@ Model::PopulatePackage(const PackageInfoRef& package, uint32 flags)
|
|||||||
architecture = package->Architecture();
|
architecture = package->Architecture();
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t status = interface.RetrieveUserRatings(packageName,
|
status_t status = fWebAppInterface.RetrieveUserRatings(packageName,
|
||||||
architecture, 0, 50, info);
|
architecture, 0, 50, info);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// Parse message
|
// 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
|
int32
|
||||||
Model::_PopulateAllPackagesEntry(void* cookie)
|
Model::_PopulateAllPackagesEntry(void* cookie)
|
||||||
{
|
{
|
||||||
@ -727,8 +735,6 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Retrieve info from web-app
|
// Retrieve info from web-app
|
||||||
WebAppInterface interface;
|
|
||||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
|
||||||
BMessage info;
|
BMessage info;
|
||||||
|
|
||||||
StringList packageNames;
|
StringList packageNames;
|
||||||
@ -739,7 +745,7 @@ Model::_PopulatePackageInfos(PackageList& packages, bool fromCacheOnly,
|
|||||||
packageArchitectures.Add(package->Architecture());
|
packageArchitectures.Add(package->Architecture());
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t status = interface.RetrieveBulkPackageInfo(packageNames,
|
status_t status = fWebAppInterface.RetrieveBulkPackageInfo(packageNames,
|
||||||
packageArchitectures, info);
|
packageArchitectures, info);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// Parse message
|
// Parse message
|
||||||
@ -818,11 +824,9 @@ Model::_PopulatePackageInfo(const PackageInfoRef& package, bool fromCacheOnly)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Retrieve info from web-app
|
// Retrieve info from web-app
|
||||||
WebAppInterface interface;
|
|
||||||
interface.SetPreferredLanguage(fPreferredLanguage);
|
|
||||||
BMessage info;
|
BMessage info;
|
||||||
|
|
||||||
status_t status = interface.RetrievePackageInfo(package->Title(),
|
status_t status = fWebAppInterface.RetrievePackageInfo(package->Title(),
|
||||||
package->Architecture(), info);
|
package->Architecture(), info);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// Parse message
|
// Parse message
|
||||||
@ -995,10 +999,10 @@ Model::_PopulatePackageIcon(const PackageInfoRef& package, bool fromCacheOnly)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Retrieve icon from web-app
|
// Retrieve icon from web-app
|
||||||
WebAppInterface interface;
|
|
||||||
BMallocIO buffer;
|
BMallocIO buffer;
|
||||||
|
|
||||||
status_t status = interface.RetrievePackageIcon(package->Title(), &buffer);
|
status_t status = fWebAppInterface.RetrievePackageIcon(package->Title(),
|
||||||
|
&buffer);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
||||||
BAutolock locker(&fLock);
|
BAutolock locker(&fLock);
|
||||||
@ -1053,12 +1057,11 @@ Model::_PopulatePackageScreenshot(const PackageInfoRef& package,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Retrieve screenshot from web-app
|
// Retrieve screenshot from web-app
|
||||||
WebAppInterface interface;
|
|
||||||
BMallocIO buffer;
|
BMallocIO buffer;
|
||||||
|
|
||||||
int32 scaledHeight = scaledWidth * info.Height() / info.Width();
|
int32 scaledHeight = scaledWidth * info.Height() / info.Width();
|
||||||
|
|
||||||
status_t status = interface.RetrieveScreenshot(info.Code(),
|
status_t status = fWebAppInterface.RetrieveScreenshot(info.Code(),
|
||||||
scaledWidth, scaledHeight, &buffer);
|
scaledWidth, scaledHeight, &buffer);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
|
|
||||||
#include "PackageInfo.h"
|
#include "PackageInfo.h"
|
||||||
|
#include "WebAppInterface.h"
|
||||||
|
|
||||||
|
|
||||||
class BMessage;
|
class BMessage;
|
||||||
|
|
||||||
@ -105,6 +107,9 @@ public:
|
|||||||
const BString& PreferredLanguage() const
|
const BString& PreferredLanguage() const
|
||||||
{ return fPreferredLanguage; }
|
{ return fPreferredLanguage; }
|
||||||
|
|
||||||
|
void SetAuthorization(const BString& username,
|
||||||
|
const BString& password);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int32 _PopulateAllPackagesEntry(void* cookie);
|
static int32 _PopulateAllPackagesEntry(void* cookie);
|
||||||
void _PopulateAllPackagesThread(bool fromCacheOnly);
|
void _PopulateAllPackagesThread(bool fromCacheOnly);
|
||||||
@ -168,6 +173,8 @@ private:
|
|||||||
thread_id fPopulateAllPackagesThread;
|
thread_id fPopulateAllPackagesThread;
|
||||||
volatile bool fStopPopulatingAllPackages;
|
volatile bool fStopPopulatingAllPackages;
|
||||||
BString fPreferredLanguage;
|
BString fPreferredLanguage;
|
||||||
|
|
||||||
|
WebAppInterface fWebAppInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,12 +209,14 @@ UserLoginWindow::_SetMode(Mode mode)
|
|||||||
case LOGIN:
|
case LOGIN:
|
||||||
fTabView->Select((int32)0);
|
fTabView->Select((int32)0);
|
||||||
fSendButton->SetLabel(B_TRANSLATE("Log in"));
|
fSendButton->SetLabel(B_TRANSLATE("Log in"));
|
||||||
|
fUsernameField->MakeFocus();
|
||||||
break;
|
break;
|
||||||
case CREATE_ACCOUNT:
|
case CREATE_ACCOUNT:
|
||||||
fTabView->Select(1);
|
fTabView->Select(1);
|
||||||
fSendButton->SetLabel(B_TRANSLATE("Create account"));
|
fSendButton->SetLabel(B_TRANSLATE("Create account"));
|
||||||
if (fCaptchaToken.IsEmpty())
|
if (fCaptchaToken.IsEmpty())
|
||||||
_RequestCaptcha();
|
_RequestCaptcha();
|
||||||
|
fNewUsernameField->MakeFocus();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -225,15 +227,15 @@ UserLoginWindow::_SetMode(Mode mode)
|
|||||||
void
|
void
|
||||||
UserLoginWindow::_Login()
|
UserLoginWindow::_Login()
|
||||||
{
|
{
|
||||||
// TODO: Implement...
|
BAutolock locker(&fLock);
|
||||||
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);
|
|
||||||
|
|
||||||
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
|
int32
|
||||||
UserLoginWindow::_RequestCaptchaThreadEntry(void* data)
|
UserLoginWindow::_RequestCaptchaThreadEntry(void* data)
|
||||||
{
|
{
|
||||||
@ -433,6 +508,8 @@ UserLoginWindow::_CreateAccountThread()
|
|||||||
fCaptchaToken = "";
|
fCaptchaToken = "";
|
||||||
_RequestCaptcha();
|
_RequestCaptcha();
|
||||||
} else {
|
} else {
|
||||||
|
fModel.SetAuthorization(nickName, passwordClear);
|
||||||
|
|
||||||
_SetWorkerThread(-1);
|
_SetWorkerThread(-1);
|
||||||
BMessenger(this).SendMessage(B_QUIT_REQUESTED);
|
BMessenger(this).SendMessage(B_QUIT_REQUESTED);
|
||||||
|
|
||||||
|
@ -40,6 +40,9 @@ private:
|
|||||||
|
|
||||||
void _SetWorkerThread(thread_id thread);
|
void _SetWorkerThread(thread_id thread);
|
||||||
|
|
||||||
|
static int32 _AuthenticateThreadEntry(void* data);
|
||||||
|
void _AuthenticateThread();
|
||||||
|
|
||||||
static int32 _RequestCaptchaThreadEntry(void* data);
|
static int32 _RequestCaptchaThreadEntry(void* data);
|
||||||
void _RequestCaptchaThread();
|
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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebAppInterface&
|
||||||
|
WebAppInterface::operator=(const WebAppInterface& other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
fUsername = other.fUsername;
|
||||||
|
fPassword = other.fPassword;
|
||||||
|
fLanguage = other.fLanguage;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WebAppInterface::SetAuthorization(const BString& username,
|
WebAppInterface::SetAuthorization(const BString& username,
|
||||||
const BString& password)
|
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
|
// #pragma mark - private
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,8 +21,11 @@ typedef List<BString, false> StringList;
|
|||||||
class WebAppInterface {
|
class WebAppInterface {
|
||||||
public:
|
public:
|
||||||
WebAppInterface();
|
WebAppInterface();
|
||||||
|
WebAppInterface(const WebAppInterface& other);
|
||||||
virtual ~WebAppInterface();
|
virtual ~WebAppInterface();
|
||||||
|
|
||||||
|
WebAppInterface& operator=(const WebAppInterface& other);
|
||||||
|
|
||||||
void SetAuthorization(const BString& username,
|
void SetAuthorization(const BString& username,
|
||||||
const BString& password);
|
const BString& password);
|
||||||
void SetPreferredLanguage(const BString& language);
|
void SetPreferredLanguage(const BString& language);
|
||||||
@ -63,6 +66,10 @@ public:
|
|||||||
const BString& languageCode,
|
const BString& languageCode,
|
||||||
BMessage& message);
|
BMessage& message);
|
||||||
|
|
||||||
|
status_t AuthenticateUser(const BString& nickName,
|
||||||
|
const BString& passwordClear,
|
||||||
|
BMessage& message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SendJsonRequest(const char* domain,
|
status_t _SendJsonRequest(const char* domain,
|
||||||
BString jsonString, BMessage& reply) const;
|
BString jsonString, BMessage& reply) const;
|
||||||
@ -71,7 +78,6 @@ private:
|
|||||||
BString fUsername;
|
BString fUsername;
|
||||||
BString fPassword;
|
BString fPassword;
|
||||||
BString fLanguage;
|
BString fLanguage;
|
||||||
BString fArchitecture;
|
|
||||||
static int fRequestIndex;
|
static int fRequestIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user