226{
227 BOOST_LOG_TRIVIAL(info) << "thirdparty_login: get_response";
228
230 if (!auth_code.empty()) {
232 if (state.empty()) {
234 }
235 NetworkAgent* agent = wxGetApp().getAgent();
236 if (!agent) {
237 return std::make_shared<ResponseNotFound>();
238 }
239
241 payload["command"] = "user_login";
242 payload["data"]["code"] = auth_code;
243 payload["data"]["state"] = state;
244
245 agent->change_user(payload.dump(), provider);
246 const bool login_ok = agent->is_user_login(provider);
247 if (login_ok) {
248 wxGetApp().request_user_login(1, provider);
249 GUI::wxGetApp().CallAfter([] { wxGetApp().ShowUserLogin(false); });
250 }
251
252 const std::string title = login_ok ?
_u8L(
"Authentication complete") :
_u8L(
"Authentication failed");
253 const std::string message = login_ok
254 ?
_u8L(
"You can return to OrcaSlicer. This window will close automatically.")
255 :
_u8L(
"Something went wrong. Please return to OrcaSlicer and try again.");
256 const std::string html =
257 "<html><head><meta charset=\"utf-8\">"
258 "<style>body{font-family:Arial,sans-serif;background:#f7f7f7;color:#222;margin:32px;}"
259 "a.button{display:inline-block;padding:10px 16px;margin-top:12px;background:#0f8bff;color:#fff;text-decoration:none;border-radius:6px;}"
260 "</style></head><body><div class=\"container\">"
261 "<h2>" + title + "</h2>"
262 "<p>" + message + "</p>"
263 "<script>setTimeout(function(){try{window.close();}catch(e){}},1500);</script>"
264 "</div></body></html>";
265 return std::make_shared<ResponseHtml>(html);
266 }
267
268 if (boost::contains(url, "access_token")) {
269 std::string redirect_url =
url_get_param(url,
"redirect_url");
270 std::string access_token =
url_get_param(url,
"access_token");
271 std::string refresh_token =
url_get_param(url,
"refresh_token");
272 std::string expires_in_str =
url_get_param(url,
"expires_in");
273 std::string refresh_expires_in_str =
url_get_param(url,
"refresh_expires_in");
274 NetworkAgent* agent = wxGetApp().getAgent();
275
276 unsigned int http_code;
277 std::string http_body;
278 int result = agent->get_my_profile(access_token, &http_code, &http_body, provider);
279 if (result == 0) {
280 std::string user_id;
281 std::string user_name;
282 std::string user_account;
283 std::string user_avatar;
284 try {
285 json user_j = json::parse(http_body);
286 if (user_j.contains("uidStr"))
287 user_id = user_j["uidStr"].get<std::string>();
288 if (user_j.contains("name"))
289 user_name = user_j["name"].get<std::string>();
290 if (user_j.contains("avatar"))
291 user_avatar = user_j["avatar"].get<std::string>();
292 if (user_j.contains("account"))
293 user_account = user_j["account"].get<std::string>();
294 } catch (...) {
295 ;
296 }
298 j["data"]["refresh_token"] = refresh_token;
299 j["data"]["token"] = access_token;
300 j["data"]["expires_in"] = expires_in_str;
301 j["data"]["refresh_expires_in"] = refresh_expires_in_str;
302 j["data"]["user"]["uid"] = user_id;
303 j["data"]["user"]["name"] = user_name;
304 j["data"]["user"]["account"] = user_account;
305 j["data"]["user"]["avatar"] = user_avatar;
306 agent->change_user(j.dump(), provider);
307 if (agent->is_user_login(provider)) {
308 wxGetApp().request_user_login(1, provider);
309 }
310 GUI::wxGetApp().CallAfter([] { wxGetApp().ShowUserLogin(false); });
311 std::string location_str = (boost::format("%1%?result=success") % redirect_url).str();
312 return std::make_shared<ResponseRedirect>(location_str);
313 } else {
314 std::string error_str = "get_user_profile_error_" + std::to_string(result);
315 std::string location_str = (boost::format("%1%?result=fail&error=%2%") % redirect_url % error_str).str();
316 return std::make_shared<ResponseRedirect>(location_str);
317 }
318 }
319
320
321
322
323
324
325
326
328 const std::string ticket_redirect_url =
url_get_param(url,
"redirect_url");
329 if (!ticket.empty() && !ticket_redirect_url.empty() &&
331 BOOST_LOG_TRIVIAL(info) << "thirdparty_login: ticket flow";
332 NetworkAgent* agent = wxGetApp().getAgent();
333 if (!agent) {
334 std::string location_str = (boost::format("%1%?result=fail&error=no_agent") % ticket_redirect_url).str();
335 return std::make_shared<ResponseRedirect>(location_str);
336 }
337
338 auto fail_redirect = [&ticket_redirect_url](const std::string& reason) {
339 std::string location_str = (boost::format("%1%?result=fail&error=%2%") % ticket_redirect_url % reason).str();
340 return std::make_shared<ResponseRedirect>(location_str);
341 };
342
343 unsigned int token_http_code = 0;
344 std::string token_body;
345 int token_result = agent->get_my_token(ticket, &token_http_code, &token_body, provider);
346 if (token_result != 0) {
347 BOOST_LOG_TRIVIAL(warning) << "thirdparty_login: get_my_token failed, http_code=" << token_http_code;
348 return fail_redirect("get_my_token_error_" + std::to_string(token_result));
349 }
350
351 std::string access_token;
352 std::string refresh_token;
353 std::string expires_in_str;
354 std::string refresh_expires_in_str;
355 try {
356 json token_j = json::parse(token_body);
357 if (token_j.contains("accessToken"))
358 access_token = token_j["accessToken"].get<std::string>();
359 if (token_j.contains("refreshToken"))
360 refresh_token = token_j["refreshToken"].get<std::string>();
361 if (token_j.contains("expiresIn"))
362 expires_in_str = std::to_string(token_j["expiresIn"].get<double>());
363 if (token_j.contains("refreshExpiresIn"))
364 refresh_expires_in_str = std::to_string(token_j["refreshExpiresIn"].get<double>());
365 } catch (...) {
366 return fail_redirect("token_parse_error");
367 }
368
369 if (access_token.empty()) {
370 return fail_redirect("token_missing");
371 }
372
373 unsigned int profile_http_code = 0;
374 std::string profile_body;
375 int profile_result = agent->get_my_profile(access_token, &profile_http_code, &profile_body, provider);
376 if (profile_result != 0) {
377 BOOST_LOG_TRIVIAL(warning) << "thirdparty_login: get_my_profile failed, http_code=" << profile_http_code;
378 return fail_redirect("get_user_profile_error_" + std::to_string(profile_result));
379 }
380
381 std::string user_id;
382 std::string user_name;
383 std::string user_account;
384 std::string user_avatar;
385 try {
386 json user_j = json::parse(profile_body);
387 if (user_j.contains("uidStr"))
388 user_id = user_j["uidStr"].get<std::string>();
389 if (user_j.contains("name"))
390 user_name = user_j["name"].get<std::string>();
391 if (user_j.contains("avatar"))
392 user_avatar = user_j["avatar"].get<std::string>();
393 if (user_j.contains("account"))
394 user_account = user_j["account"].get<std::string>();
395 } catch (...) {
396 BOOST_LOG_TRIVIAL(warning) << "thirdparty_login: profile JSON parse failed";
397 }
398
400 j["data"]["refresh_token"] = refresh_token;
401 j["data"]["token"] = access_token;
402 j["data"]["expires_in"] = expires_in_str;
403 j["data"]["refresh_expires_in"] = refresh_expires_in_str;
404 j["data"]["user"]["uid"] = user_id;
405 j["data"]["user"]["name"] = user_name;
406 j["data"]["user"]["account"] = user_account;
407 j["data"]["user"]["avatar"] = user_avatar;
408 agent->change_user(j.dump(), provider);
409 if (agent->is_user_login(provider)) {
410 wxGetApp().request_user_login(1, provider);
411 }
412 GUI::wxGetApp().CallAfter([] { wxGetApp().ShowUserLogin(false); });
413 std::string location_str = (boost::format("%1%?result=success") % ticket_redirect_url).str();
414 return std::make_shared<ResponseRedirect>(location_str);
415 }
416
417 return std::make_shared<ResponseNotFound>();
418}
static BBLNetworkPlugin & instance()
Definition BBLNetworkPlugin.cpp:56
func_get_my_token get_get_my_token() const
Definition BBLNetworkPlugin.hpp:395
std::string url_get_param(const std::string &url, const std::string &key)
Definition HttpServer.cpp:35
nlohmann::json json
Definition AssembleList.cpp:42
#define _u8L(s)
Definition I18N.hpp:11