Skip to content

Commit 0a91ad5

Browse files
greetd: use glaze for json handling
1 parent 87000be commit 0a91ad5

File tree

8 files changed

+172
-404
lines changed

8 files changed

+172
-404
lines changed

CMakeLists.txt

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ find_package(Threads REQUIRED)
7272
find_package(PkgConfig REQUIRED)
7373
find_package(OpenGL REQUIRED COMPONENTS EGL GLES3)
7474
find_package(hyprwayland-scanner 0.4.4 REQUIRED)
75+
find_package(glaze REQUIRED)
7576
pkg_check_modules(
7677
deps
7778
REQUIRED
@@ -96,7 +97,7 @@ pkg_check_modules(
9697
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
9798
add_executable(hyprlock ${SRCFILES})
9899
target_link_libraries(hyprlock PRIVATE pam rt Threads::Threads PkgConfig::deps
99-
OpenGL::EGL OpenGL::GLES3)
100+
OpenGL::EGL OpenGL::GLES3 glaze::glaze)
100101

101102
# protocols
102103
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
@@ -131,7 +132,7 @@ function(protocolWayland)
131132
endfunction()
132133

133134
make_directory(${CMAKE_SOURCE_DIR}/protocols) # we don't ship any custom ones so
134-
# the dir won't be there
135+
# the dir won't be there
135136

136137
protocolwayland()
137138

@@ -153,15 +154,3 @@ install(
153154
FILES ${CMAKE_SOURCE_DIR}/assets/example.conf
154155
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/hypr
155156
RENAME hyprlock.conf)
156-
157-
# Tests
158-
#
159-
include(CTest)
160-
add_custom_target(tests)
161-
162-
add_executable(test_notjson "tests/notjson.cpp")
163-
target_link_libraries(test_notjson PRIVATE PkgConfig::deps)
164-
add_test(
165-
NAME "notjson"
166-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
167-
COMMAND test_notjson "notjson")

nix/default.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
lib,
33
stdenv,
44
cmake,
5-
pkg-config,
65
cairo,
76
file,
7+
glaze,
8+
pkg-config,
89
libdrm,
910
libGL,
1011
libjpeg,
@@ -40,6 +41,7 @@ stdenv.mkDerivation {
4041

4142
buildInputs = [
4243
cairo
44+
glaze
4345
file
4446
libdrm
4547
libGL

src/auth/GreetdLogin.cpp

Lines changed: 74 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,13 @@
11
#include "GreetdLogin.hpp"
22
#include "../config/ConfigManager.hpp"
33
#include "../core/hyprlock.hpp"
4-
#include "../helpers/NotJson.hpp"
54
#include "../helpers/Log.hpp"
65

76
#include <hyprutils/string/VarList.hpp>
87
#include <hyprutils/os/Process.hpp>
98
#include <sys/socket.h>
109
#include <sys/un.h>
1110

12-
static constexpr eGreetdAuthMessageType messageTypeFromString(const std::string_view& type) {
13-
if (type == "visible")
14-
return GREETD_AUTH_VISIBLE;
15-
if (type == "secret")
16-
return GREETD_AUTH_SECRET;
17-
if (type == "info")
18-
return GREETD_AUTH_INFO;
19-
if (type == "error")
20-
return GREETD_AUTH_ERROR;
21-
return GREETD_AUTH_ERROR;
22-
}
23-
24-
static constexpr eGreetdErrorMessageType errorTypeFromString(const std::string_view& type) {
25-
if (type == "auth_error")
26-
return GREETD_ERROR_AUTH;
27-
if (type == "error")
28-
return GREETD_ERROR;
29-
return GREETD_ERROR;
30-
}
31-
3211
static constexpr std::string getErrorString(eRequestError error) {
3312
switch (error) {
3413
case GREETD_REQUEST_ERROR_SEND: return "Failed to send payload to greetd";
@@ -127,20 +106,26 @@ static std::string readFromSock(int fd) {
127106
return msg;
128107
}
129108

130-
static bool sendGreetdRequest(int fd, const NNotJson::SObject& request) {
109+
static bool sendGreetdRequest(int fd, const VGreetdRequest& request) {
131110
if (fd < 0) {
132111
Debug::log(ERR, "[GreetdLogin] Invalid socket fd");
133112
return false;
134113
}
135114

136-
const auto PAYLOAD = NNotJson::serialize(request);
115+
const auto GLZRESULT = glz::write_json(request);
137116

138-
if (!request.values.contains("response"))
139-
Debug::log(TRACE, "[GreetdLogin] Request: {}", PAYLOAD);
140-
else
117+
if (!GLZRESULT.has_value()) {
118+
const auto GLZERRORSTR = glz::format_error(GLZRESULT.error());
119+
Debug::log(ERR, "[GreetdLogin] Failed to serialize request: {}", GLZERRORSTR);
120+
return false;
121+
}
122+
123+
if (std::holds_alternative<SGreetdPostAuthMessageResponse>(request))
141124
Debug::log(TRACE, "[GreetdLogin] Request: REDACTED");
125+
else
126+
Debug::log(TRACE, "[GreetdLogin] Request: {}", GLZRESULT.value());
142127

143-
if (sendToSock(fd, PAYLOAD) < 0) {
128+
if (sendToSock(fd, GLZRESULT.value()) < 0) {
144129
Debug::log(ERR, "[GreetdLogin] Failed to send payload to greetd");
145130
return false;
146131
}
@@ -170,7 +155,7 @@ void CGreetdLogin::init() {
170155
});
171156
}
172157

173-
std::expected<NNotJson::SObject, eRequestError> CGreetdLogin::request(const NNotJson::SObject& req) {
158+
std::expected<VGreetdResponse, eRequestError> CGreetdLogin::request(const VGreetdRequest& req) {
174159
if (!sendGreetdRequest(m_socketFD, req)) {
175160
m_ok = false;
176161
return std::unexpected(GREETD_REQUEST_ERROR_SEND);
@@ -185,69 +170,55 @@ std::expected<NNotJson::SObject, eRequestError> CGreetdLogin::request(const NNot
185170

186171
Debug::log(TRACE, "[GreetdLogin] Response: {}", RESPONSESTR);
187172

188-
const auto [RESULTOBJ, ERROR] = NNotJson::parse(RESPONSESTR);
189-
if (ERROR.status != NNotJson::SError::NOT_JSON_OK) {
190-
Debug::log(ERR, "[GreetdLogin] Failed to parse response from greetd: {}", ERROR.message);
191-
m_ok = false;
192-
return std::unexpected(GREETD_REQUEST_ERROR_PARSE);
193-
}
194-
195-
if (!RESULTOBJ.values.contains("type")) {
196-
Debug::log(ERR, "[GreetdLogin] Invalid greetd response");
173+
const auto GLZRESULT = glz::read_json<VGreetdResponse>(RESPONSESTR);
174+
if (!GLZRESULT.has_value()) {
175+
const auto GLZERRORSTR = glz::format_error(GLZRESULT.error(), RESPONSESTR);
176+
Debug::log(ERR, "[GreetdLogin] Failed to parse response from greetd: {}", GLZERRORSTR);
197177
m_ok = false;
198178
return std::unexpected(GREETD_REQUEST_ERROR_PARSE);
199179
}
200180

201-
return RESULTOBJ;
181+
return GLZRESULT.value();
202182
}
203183

204-
inline static const std::string& getStringValue(NNotJson::SObject& obj, const std::string& key) {
205-
try {
206-
return std::get<std::string>(obj.values[key]);
207-
} catch (std::bad_variant_access const& ex) { RASSERT(false, "Key \"{}\" does not contain a string", key); }
208-
};
209-
210-
void CGreetdLogin::handleResponse(const std::string& request, NNotJson::SObject& response) {
211-
const auto RESPONSETYPE = getStringValue(response, "type");
212-
213-
if (RESPONSETYPE == "error") {
214-
const auto ERRORTYPE = getStringValue(response, "error_type");
215-
m_state.errorType = errorTypeFromString(ERRORTYPE);
216-
m_state.error = getStringValue(response, "description");
217-
Debug::log(ERR, "[GreetdLogin] Request failed: {} - {}", ERRORTYPE, m_state.error);
184+
void CGreetdLogin::handleResponse(const VGreetdRequest& request, const VGreetdResponse& response) {
185+
if (std::holds_alternative<SGreetdErrorResponse>(response)) {
186+
const auto ERRORRESPONSE = std::get<SGreetdErrorResponse>(response);
187+
m_state.errorType = ERRORRESPONSE.error_type;
188+
m_state.error = ERRORRESPONSE.description;
189+
Debug::log(ERR, "[GreetdLogin] Request failed: {} - {}", (int)m_state.errorType, m_state.error);
218190
// Don't post a fail if this is a response to "cancel_session"
219-
if (!m_state.error.empty() && request != "cancel_session")
191+
if (!m_state.error.empty() && !std::holds_alternative<SGreetdCancelSession>(request))
220192
g_pAuth->enqueueFail(m_state.error, AUTH_IMPL_GREETD);
221193

222194
// We don't have to cancel if "create_session" failed
223-
if (request != "create_session")
195+
if (!std::holds_alternative<SGreetdCreateSession>(request))
224196
cancelSession();
225-
} else if (RESPONSETYPE == "auth_message") {
226-
const auto AUTHMESSAGETYPE = getStringValue(response, "auth_message_type");
227-
m_state.authMessageType = messageTypeFromString(AUTHMESSAGETYPE);
228-
m_state.message = getStringValue(response, "auth_message");
229-
Debug::log(LOG, "[GreetdLogin] Auth message: {} - {}", AUTHMESSAGETYPE, m_state.message);
197+
} else if (std::holds_alternative<SGreetdAuthMessageResponse>(response)) {
198+
const auto AUTHMESSAGERESPONSE = std::get<SGreetdAuthMessageResponse>(response);
199+
m_state.authMessageType = AUTHMESSAGERESPONSE.auth_message_type;
200+
m_state.message = AUTHMESSAGERESPONSE.auth_message;
201+
Debug::log(LOG, "[GreetdLogin] Auth message: {} - {}", (int)m_state.authMessageType, m_state.message);
230202
if (m_state.authMessageType == GREETD_AUTH_ERROR && !m_state.message.empty())
231203
g_pAuth->enqueueFail(m_state.message, AUTH_IMPL_GREETD);
232204

233-
} else if (RESPONSETYPE == "success") {
234-
if (request == "create_session" || request == "post_auth_message_response")
205+
} else if (std::holds_alternative<SGreetdSuccessResponse>(response)) {
206+
if (std::holds_alternative<SGreetdCreateSession>(request) || std::holds_alternative<SGreetdPostAuthMessageResponse>(request))
235207
startSessionAfterSuccess();
236208
} else
237-
Debug::log(ERR, "Unknown response type \"{}\"", RESPONSETYPE);
209+
Debug::log(ERR, "Unknown response from greetd");
238210
}
239211

240212
void CGreetdLogin::startSessionAfterSuccess() {
241213
const auto SELECTEDSESSION = g_pHyprlock->getSelectedGreetdLoginSession();
242214
Hyprutils::String::CVarList args(SELECTEDSESSION.exec, 0, ' ');
243215

244-
NNotJson::SObject startSession{.values = {
245-
{"type", "start_session"},
246-
}};
247-
startSession.values["cmd"] = std::vector<std::string>{args.begin(), args.end()};
216+
SGreetdStartSession startSession;
217+
startSession.cmd = std::vector<std::string>{args.begin(), args.end()};
248218

219+
const auto REQUEST = VGreetdRequest{startSession};
249220
// TODO: Is there a response for this? Should we check it?
250-
if (!sendGreetdRequest(m_socketFD, startSession))
221+
if (!sendGreetdRequest(m_socketFD, REQUEST))
251222
m_ok = false;
252223
else {
253224
if (g_pHyprlock->m_sCurrentDesktop == "Hyprland")
@@ -258,18 +229,17 @@ void CGreetdLogin::startSessionAfterSuccess() {
258229
}
259230

260231
void CGreetdLogin::cancelSession() {
261-
NNotJson::SObject cancelSession{
262-
.values =
263-
{
264-
{"type", "cancel_session"},
265-
},
266-
};
267-
268-
auto RESPONSEOPT = request(cancelSession);
269-
if (!RESPONSEOPT.has_value())
232+
SGreetdCancelSession cancelSession;
233+
234+
const auto REQUEST = VGreetdRequest{cancelSession};
235+
const auto RESPONSE = request(REQUEST);
236+
237+
if (!RESPONSE.has_value()) {
238+
Debug::log(ERR, "Failed to cancel session: {}", getErrorString(RESPONSE.error()));
270239
return;
240+
}
271241

272-
handleResponse("cancel_session", RESPONSEOPT.value());
242+
handleResponse(REQUEST, RESPONSE.value());
273243

274244
m_state.authMessageType = GREETD_INITIAL;
275245
m_state.errorType = GREETD_OK;
@@ -279,23 +249,20 @@ void CGreetdLogin::createSession() {
279249
if (m_state.authMessageType != GREETD_INITIAL && m_state.errorType != GREETD_ERROR_AUTH)
280250
Debug::log(WARN, "[GreetdLogin] Trying to create a session, but last one still active?");
281251

282-
NNotJson::SObject createSession = {
283-
.values =
284-
{
285-
{"type", "create_session"},
286-
{"username", m_loginUserName},
287-
},
288-
};
252+
Debug::log(LOG, "Creating session for user {}", m_loginUserName);
253+
254+
SGreetdCreateSession createSession;
255+
createSession.username = m_loginUserName;
289256

290-
Debug::log(INFO, "Creating session for user {}", m_loginUserName);
257+
const auto REQUEST = VGreetdRequest{createSession};
258+
const auto RESPONSE = request(REQUEST);
291259

292-
auto RESPONSEOPT = request(createSession);
293-
if (!RESPONSEOPT.has_value()) {
294-
Debug::log(ERR, "Failed to create session: {}", getErrorString(RESPONSEOPT.error()));
260+
if (!RESPONSE.has_value()) {
261+
Debug::log(ERR, "Failed to create session: {}", getErrorString(RESPONSE.error()));
295262
return;
296263
}
297264

298-
handleResponse("create_session", RESPONSEOPT.value());
265+
handleResponse(REQUEST, RESPONSE.value());
299266
}
300267

301268
void CGreetdLogin::processInput() {
@@ -309,42 +276,37 @@ void CGreetdLogin::processInput() {
309276

310277
while (m_ok && (m_state.authMessageType == GREETD_AUTH_INFO || m_state.authMessageType == GREETD_AUTH_ERROR)) {
311278
// Empty reply
312-
NNotJson::SObject postAuthMessageResponse{
313-
.values =
314-
{
315-
{"type", "post_auth_message_response"},
316-
{"response", ""},
317-
},
318-
};
319-
auto RESPONSEOPT = request(postAuthMessageResponse);
320-
if (!RESPONSEOPT.has_value()) {
321-
Debug::log(ERR, "Failed to create session: {}", getErrorString(RESPONSEOPT.error()));
279+
SGreetdPostAuthMessageResponse postAuthMessageResponse;
280+
281+
const auto REQUEST = VGreetdRequest{postAuthMessageResponse};
282+
const auto RESPONSE = request(REQUEST);
283+
284+
if (!RESPONSE.has_value()) {
285+
Debug::log(ERR, "Failed to create session: {}", getErrorString(RESPONSE.error()));
322286
return;
323287
}
324288

325-
handleResponse("post_auth_message_response", RESPONSEOPT.value());
289+
handleResponse(REQUEST, RESPONSE.value());
326290
}
327291

328292
if (m_state.errorType != GREETD_OK) {
293+
// TODO: this error message is not good
329294
Debug::log(LOG, "Empty response to a info message failed!");
330295
return;
331296
}
332297

333-
NNotJson::SObject postAuthMessageResponse{
334-
.values =
335-
{
336-
{"type", "post_auth_message_response"},
337-
{"response", m_state.input},
338-
},
339-
};
340-
341-
auto RESPONSEOPT = request(postAuthMessageResponse);
342-
if (!RESPONSEOPT.has_value()) {
343-
Debug::log(ERR, "Failed to send auth response: {}", getErrorString(RESPONSEOPT.error()));
298+
SGreetdPostAuthMessageResponse postAuthMessageResponse;
299+
postAuthMessageResponse.response = m_state.input;
300+
301+
const auto REQUEST = VGreetdRequest{postAuthMessageResponse};
302+
const auto RESPONSE = request(REQUEST);
303+
304+
if (!RESPONSE.has_value()) {
305+
Debug::log(ERR, "Failed to send auth response: {}", getErrorString(RESPONSE.error()));
344306
return;
345307
}
346308

347-
handleResponse("post_auth_message_response", RESPONSEOPT.value());
309+
handleResponse(REQUEST, RESPONSE.value());
348310
};
349311

350312
void CGreetdLogin::waitForInput() {

0 commit comments

Comments
 (0)