summaryrefslogtreecommitdiff
path: root/src/web_service/verify_user_jwt.cpp
diff options
context:
space:
mode:
authorGravatar liamwhite2022-07-25 18:31:45 -0400
committerGravatar GitHub2022-07-25 18:31:45 -0400
commit1e67d2b59f6dfd561768db3fb9a8e0c6a16ec9f2 (patch)
tree999411f1ca76390654d1034c6d0bd2c47c3f101c /src/web_service/verify_user_jwt.cpp
parentMerge pull request #8564 from lat9nq/dinner-fork (diff)
parentnetwork: Address review comments (diff)
downloadyuzu-1e67d2b59f6dfd561768db3fb9a8e0c6a16ec9f2.tar.gz
yuzu-1e67d2b59f6dfd561768db3fb9a8e0c6a16ec9f2.tar.xz
yuzu-1e67d2b59f6dfd561768db3fb9a8e0c6a16ec9f2.zip
Merge pull request #8541 from FearlessTobi/multiplayer-part1
yuzu, network: Add room service and UI configuration
Diffstat (limited to 'src/web_service/verify_user_jwt.cpp')
-rw-r--r--src/web_service/verify_user_jwt.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/web_service/verify_user_jwt.cpp b/src/web_service/verify_user_jwt.cpp
new file mode 100644
index 000000000..3bff46f0a
--- /dev/null
+++ b/src/web_service/verify_user_jwt.cpp
@@ -0,0 +1,67 @@
1// SPDX-FileCopyrightText: Copyright 2018 Citra Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#if defined(__GNUC__) || defined(__clang__)
5#pragma GCC diagnostic push
6#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
7#endif
8#include <jwt/jwt.hpp>
9#if defined(__GNUC__) || defined(__clang__)
10#pragma GCC diagnostic pop
11#endif
12
13#include <system_error>
14#include "common/logging/log.h"
15#include "web_service/verify_user_jwt.h"
16#include "web_service/web_backend.h"
17#include "web_service/web_result.h"
18
19namespace WebService {
20
21static std::string public_key;
22std::string GetPublicKey(const std::string& host) {
23 if (public_key.empty()) {
24 Client client(host, "", ""); // no need for credentials here
25 public_key = client.GetPlain("/jwt/external/key.pem", true).returned_data;
26 if (public_key.empty()) {
27 LOG_ERROR(WebService, "Could not fetch external JWT public key, verification may fail");
28 } else {
29 LOG_INFO(WebService, "Fetched external JWT public key (size={})", public_key.size());
30 }
31 }
32 return public_key;
33}
34
35VerifyUserJWT::VerifyUserJWT(const std::string& host) : pub_key(GetPublicKey(host)) {}
36
37Network::VerifyUser::UserData VerifyUserJWT::LoadUserData(const std::string& verify_uid,
38 const std::string& token) {
39 const std::string audience = fmt::format("external-{}", verify_uid);
40 using namespace jwt::params;
41 std::error_code error;
42 auto decoded =
43 jwt::decode(token, algorithms({"rs256"}), error, secret(pub_key), issuer("yuzu-core"),
44 aud(audience), validate_iat(true), validate_jti(true));
45 if (error) {
46 LOG_INFO(WebService, "Verification failed: category={}, code={}, message={}",
47 error.category().name(), error.value(), error.message());
48 return {};
49 }
50 Network::VerifyUser::UserData user_data{};
51 if (decoded.payload().has_claim("username")) {
52 user_data.username = decoded.payload().get_claim_value<std::string>("username");
53 }
54 if (decoded.payload().has_claim("displayName")) {
55 user_data.display_name = decoded.payload().get_claim_value<std::string>("displayName");
56 }
57 if (decoded.payload().has_claim("avatarUrl")) {
58 user_data.avatar_url = decoded.payload().get_claim_value<std::string>("avatarUrl");
59 }
60 if (decoded.payload().has_claim("roles")) {
61 auto roles = decoded.payload().get_claim_value<std::vector<std::string>>("roles");
62 user_data.moderator = std::find(roles.begin(), roles.end(), "moderator") != roles.end();
63 }
64 return user_data;
65}
66
67} // namespace WebService