16 changed files with 239 additions and 133 deletions
-
3.gitmodules
-
5externals/CMakeLists.txt
-
10src/core/CMakeLists.txt
-
2src/input_common/helpers/udp_protocol.h
-
2src/network/room.h
-
4src/web_service/CMakeLists.txt
-
60src/web_service/verify_user_jwt.cpp
-
25src/web_service/verify_user_jwt.h
-
4src/yuzu/CMakeLists.txt
-
148src/yuzu/configuration/config.cpp
-
2src/yuzu/multiplayer/chat_room.cpp
-
20src/yuzu/multiplayer/direct_connect.cpp
-
45src/yuzu/multiplayer/host_room.cpp
-
18src/yuzu/multiplayer/lobby.cpp
-
2src/yuzu/multiplayer/state.cpp
-
22src/yuzu/uisettings.h
@ -0,0 +1,60 @@ |
|||
// Copyright 2018 Citra Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <system_error>
|
|||
#include <jwt/jwt.hpp>
|
|||
#include "common/logging/log.h"
|
|||
#include "web_service/verify_user_jwt.h"
|
|||
#include "web_service/web_backend.h"
|
|||
#include "web_service/web_result.h"
|
|||
|
|||
namespace WebService { |
|||
|
|||
static std::string public_key; |
|||
std::string GetPublicKey(const std::string& host) { |
|||
if (public_key.empty()) { |
|||
Client client(host, "", ""); // no need for credentials here
|
|||
public_key = client.GetPlain("/jwt/external/key.pem", true).returned_data; |
|||
if (public_key.empty()) { |
|||
LOG_ERROR(WebService, "Could not fetch external JWT public key, verification may fail"); |
|||
} else { |
|||
LOG_INFO(WebService, "Fetched external JWT public key (size={})", public_key.size()); |
|||
} |
|||
} |
|||
return public_key; |
|||
} |
|||
|
|||
VerifyUserJWT::VerifyUserJWT(const std::string& host) : pub_key(GetPublicKey(host)) {} |
|||
|
|||
Network::VerifyUser::UserData VerifyUserJWT::LoadUserData(const std::string& verify_UID, |
|||
const std::string& token) { |
|||
const std::string audience = fmt::format("external-{}", verify_UID); |
|||
using namespace jwt::params; |
|||
std::error_code error; |
|||
auto decoded = |
|||
jwt::decode(token, algorithms({"rs256"}), error, secret(pub_key), issuer("yuzu-core"), |
|||
aud(audience), validate_iat(true), validate_jti(true)); |
|||
if (error) { |
|||
LOG_INFO(WebService, "Verification failed: category={}, code={}, message={}", |
|||
error.category().name(), error.value(), error.message()); |
|||
return {}; |
|||
} |
|||
Network::VerifyUser::UserData user_data{}; |
|||
if (decoded.payload().has_claim("username")) { |
|||
user_data.username = decoded.payload().get_claim_value<std::string>("username"); |
|||
} |
|||
if (decoded.payload().has_claim("displayName")) { |
|||
user_data.display_name = decoded.payload().get_claim_value<std::string>("displayName"); |
|||
} |
|||
if (decoded.payload().has_claim("avatarUrl")) { |
|||
user_data.avatar_url = decoded.payload().get_claim_value<std::string>("avatarUrl"); |
|||
} |
|||
if (decoded.payload().has_claim("roles")) { |
|||
auto roles = decoded.payload().get_claim_value<std::vector<std::string>>("roles"); |
|||
user_data.moderator = std::find(roles.begin(), roles.end(), "moderator") != roles.end(); |
|||
} |
|||
return user_data; |
|||
} |
|||
|
|||
} // namespace WebService
|
|||
@ -0,0 +1,25 @@ |
|||
// Copyright 2018 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <fmt/format.h> |
|||
#include "network/verify_user.h" |
|||
#include "web_service/web_backend.h" |
|||
|
|||
namespace WebService { |
|||
|
|||
class VerifyUserJWT final : public Network::VerifyUser::Backend { |
|||
public: |
|||
VerifyUserJWT(const std::string& host); |
|||
~VerifyUserJWT() = default; |
|||
|
|||
Network::VerifyUser::UserData LoadUserData(const std::string& verify_UID, |
|||
const std::string& token) override; |
|||
|
|||
private: |
|||
std::string pub_key; |
|||
}; |
|||
|
|||
} // namespace WebService |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue