Commit 958a991e authored by Adrien Béraud's avatar Adrien Béraud

server account manager: authenticate account

Change-Id: I962a9423ca29f6e7d5c59896c326edeb954afe1a
parent b86ecf7a
......@@ -29,6 +29,8 @@
#include <algorithm>
#include <string_view>
using namespace std::literals;
namespace jami {
using Request = dht::http::Request;
......@@ -209,6 +211,24 @@ ServerAccountManager::initAuthentication(PrivateKey key,
});
}
void
ServerAccountManager::onAuthEnded(const Json::Value& json, const dht::http::Response& response, TokenScope expectedScope)
{
if (response.status_code >= 200 && response.status_code < 300) {
auto scopeStr = json["scope"].asString();
auto scope = scopeStr == "DEVICE"sv ? TokenScope::Device
: (scopeStr == "USER"sv ? TokenScope::User
: TokenScope::None);
auto expires_in = json["expires_in"].asLargestUInt();
auto expiration = std::chrono::steady_clock::now() + std::chrono::seconds(expires_in);
JAMI_WARN("[Auth] Got server response: %d %s", response.status_code, response.body.c_str());
setToken(json["access_token"].asString(), scope, expiration);
} else {
authFailed(expectedScope, response.status_code);
}
clearRequest(response.request);
}
void
ServerAccountManager::authenticateDevice()
{
......@@ -217,37 +237,30 @@ ServerAccountManager::authenticateDevice()
}
const std::string url = managerHostname_ + JAMI_PATH_LOGIN;
JAMI_WARN("[Auth] getting a device token: %s", url.c_str());
auto request = std::make_shared<Request>(
*Manager::instance().ioContext(),
url,
Json::Value {Json::objectValue},
[onAsync = onAsync_](Json::Value json, const dht::http::Response& response) {
onAsync([=](AccountManager& accountManager) {
auto& this_ = *static_cast<ServerAccountManager*>(&accountManager);
if (response.status_code >= 200 && response.status_code < 300) {
auto scopeStr = json["scope"].asString();
auto scope = scopeStr == "DEVICE"
? TokenScope::Device
: (scopeStr == "USER" ? TokenScope::User : TokenScope::None);
auto expires_in = json["expires_in"].asLargestUInt();
auto expiration = std::chrono::steady_clock::now()
+ std::chrono::seconds(expires_in);
JAMI_WARN("[Auth] Got server response: %d %s",
response.status_code,
response.body.c_str());
this_.setToken(json["access_token"].asString(), scope, expiration);
} else {
this_.authFailed(TokenScope::Device, response.status_code);
}
this_.clearRequest(response.request);
});
},
logger_);
auto request = std::make_shared<Request>(*Manager::instance().ioContext(), url, Json::Value{Json::objectValue}, [onAsync = onAsync_](Json::Value json, const dht::http::Response& response) {
onAsync([=] (AccountManager& accountManager) {
static_cast<ServerAccountManager*>(&accountManager)->onAuthEnded(json, response, TokenScope::Device);
});
}, logger_);
request->set_identity(info_->identity);
// request->set_certificate_authority(info_->identity.second->issuer->issuer);
sendRequest(request);
}
void
ServerAccountManager::authenticateAccount(const std::string& username, const std::string& password)
{
const std::string url = managerHostname_ + JAMI_PATH_LOGIN;
JAMI_WARN("[Auth] getting a device token: %s", url.c_str());
auto request = std::make_shared<Request>(*Manager::instance().ioContext(), url, Json::Value{Json::objectValue}, [onAsync = onAsync_] (Json::Value json, const dht::http::Response& response){
onAsync([=] (AccountManager& accountManager) {
static_cast<ServerAccountManager*>(&accountManager)->onAuthEnded(json, response, TokenScope::User);
});
}, logger_);
request->set_auth(username, password);
sendRequest(request);
}
void
ServerAccountManager::sendRequest(const std::shared_ptr<dht::http::Request>& request)
{
......@@ -311,7 +324,7 @@ ServerAccountManager::setToken(std::string token,
tokenExpire_ = expiration;
nameDir_.get().setToken(token_);
if (not token_.empty()) {
if (not token_.empty() and scope != TokenScope::None) {
auto& reqQueue = getRequestQueue(scope);
JAMI_DBG("[Auth] Got token with scope %d, handling %zu pending requests",
(int) scope,
......@@ -341,14 +354,17 @@ ServerAccountManager::sendDeviceRequest(const std::shared_ptr<dht::http::Request
}
void
ServerAccountManager::sendAccountRequest(const std::shared_ptr<dht::http::Request>& req)
ServerAccountManager::sendAccountRequest(const std::shared_ptr<dht::http::Request>& req, const std::string& pwd)
{
std::lock_guard<std::mutex> lock(tokenLock_);
if (hasAuthorization(TokenScope::User)) {
setAuthHeaderFields(*req);
sendRequest(req);
} else {
pendingAccountRequests_.emplace(req);
auto& rQueue = getRequestQueue(TokenScope::User);
if (rQueue.empty())
authenticateAccount(info_->username, pwd);
rQueue.emplace(req);
}
}
......@@ -445,35 +461,29 @@ ServerAccountManager::revokeDevice(const std::string& password,
return false;
}
const std::string url = managerHostname_ + PATH_DEVICE + "?deviceId=" + device;
JAMI_WARN("[Revoke] Removing device of %s at %s", info_->username.c_str(), url.c_str());
auto request = std::make_shared<Request>(
*Manager::instance().ioContext(),
url,
[cb, onAsync = onAsync_](Json::Value json, const dht::http::Response& response) {
onAsync([=](AccountManager& accountManager) {
JAMI_DBG("[Revoke] Got request callback with status code=%u", response.status_code);
auto& this_ = *static_cast<ServerAccountManager*>(&accountManager);
if (response.status_code >= 200 && response.status_code < 300) {
try {
JAMI_WARN("[Revoke] Got server response");
if (json["errorDetails"].empty()) {
if (cb)
cb(RevokeDeviceResult::SUCCESS);
this_.syncDevices();
}
} catch (const std::exception& e) {
JAMI_ERR("Error when loading device list: %s", e.what());
JAMI_WARN("[Revoke] Revoking device of %s at %s", info_->username.c_str(), url.c_str());
auto request = std::make_shared<Request>(*Manager::instance().ioContext(), url, [cb, onAsync = onAsync_] (Json::Value json, const dht::http::Response& response){
onAsync([=] (AccountManager& accountManager) {
JAMI_DBG("[Revoke] Got request callback with status code=%u", response.status_code);
auto& this_ = *static_cast<ServerAccountManager*>(&accountManager);
if (response.status_code >= 200 && response.status_code < 300) {
try {
JAMI_WARN("[Revoke] Got server response");
if (json["errorDetails"].empty()) {
if (cb)
cb(RevokeDeviceResult::SUCCESS);
this_.syncDevices();
}
} else if (cb)
cb(RevokeDeviceResult::ERROR_NETWORK);
this_.clearRequest(response.request);
});
},
logger_);
} catch (const std::exception& e) {
JAMI_ERR("Error when loading device list: %s", e.what());
}
} else if (cb)
cb(RevokeDeviceResult::ERROR_NETWORK);
this_.clearRequest(response.request);
});
}, logger_);
request->set_method(restinio::http_method_delete());
request->set_auth(info_->username, password);
JAMI_DBG("[Revoke] Sending revoke device '%s' to JAMS", device.c_str());
sendRequest(request);
sendAccountRequest(request, password);
return false;
}
......
......@@ -108,12 +108,13 @@ private:
void setAuthHeaderFields(dht::http::Request& request) const;
void sendDeviceRequest(const std::shared_ptr<dht::http::Request>& req);
void sendAccountRequest(const std::shared_ptr<dht::http::Request>& req);
void sendAccountRequest(const std::shared_ptr<dht::http::Request>& req, const std::string& password);
void authenticateDevice();
void authenticateAccount();
void authenticateAccount(const std::string& username, const std::string& password);
void authFailed(TokenScope scope, int code);
void authError(TokenScope scope);
void onAuthEnded(const Json::Value& json, const dht::http::Response& response, TokenScope scope);
void setToken(std::string token,
TokenScope scope,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment