auth-listener.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <auth-listener.hpp>
  2. #include <QRegularExpression>
  3. #include <QRegularExpressionMatch>
  4. #include <QString>
  5. #include <QtNetwork/QTcpSocket>
  6. #include "obs-app.hpp"
  7. #include "qt-wrappers.hpp"
  8. #define LOGO_URL "https://obsproject.com/assets/images/new_icon_small-r.png"
  9. static const QString serverResponseHeader =
  10. QStringLiteral("HTTP/1.0 200 OK\n"
  11. "Connection: close\n"
  12. "Content-Type: text/html; charset=UTF-8\n"
  13. "Server: OBS Studio\n"
  14. "\n"
  15. "<html><head><title>OBS Studio"
  16. "</title></head>");
  17. static const QString responseTemplate =
  18. "<center>"
  19. "<img src=\"" LOGO_URL
  20. "\" alt=\"OBS\" class=\"center\" height=\"60\" width=\"60\">"
  21. "</center>"
  22. "<center><p style=\"font-family:verdana; font-size:13pt\">%1</p></center>";
  23. AuthListener::AuthListener(QObject *parent) : QObject(parent)
  24. {
  25. server = new QTcpServer(this);
  26. connect(server, &QTcpServer::newConnection, this,
  27. &AuthListener::NewConnection);
  28. if (!server->listen(QHostAddress::LocalHost, 0)) {
  29. blog(LOG_DEBUG, "Server could not start");
  30. emit fail();
  31. } else {
  32. blog(LOG_DEBUG, "Server started at port %d",
  33. server->serverPort());
  34. }
  35. }
  36. quint16 AuthListener::GetPort()
  37. {
  38. return server ? server->serverPort() : 0;
  39. }
  40. void AuthListener::NewConnection()
  41. {
  42. QTcpSocket *socket = server->nextPendingConnection();
  43. if (socket) {
  44. connect(socket, &QTcpSocket::disconnected, socket,
  45. &QTcpSocket::deleteLater);
  46. connect(socket, &QTcpSocket::readyRead, socket, [&, socket]() {
  47. QByteArray buffer;
  48. while (socket->bytesAvailable() > 0) {
  49. buffer.append(socket->readAll());
  50. }
  51. socket->write(QT_TO_UTF8(serverResponseHeader));
  52. QString redirect = QString::fromLatin1(buffer);
  53. blog(LOG_DEBUG, "redirect: %s", QT_TO_UTF8(redirect));
  54. QRegularExpression re("(&|\\?)code=(?<code>[^&]+)");
  55. QRegularExpressionMatch match = re.match(redirect);
  56. if (!match.hasMatch())
  57. blog(LOG_DEBUG, "no 'code' in server redirect");
  58. QString code = match.captured("code");
  59. if (code.isEmpty()) {
  60. auto data = QTStr("YouTube.Auth.NoCode");
  61. socket->write(QT_TO_UTF8(data));
  62. emit fail();
  63. } else {
  64. auto data = responseTemplate.arg(
  65. QTStr("YouTube.Auth.Ok"));
  66. socket->write(QT_TO_UTF8(data));
  67. emit ok(code);
  68. }
  69. socket->flush();
  70. socket->close();
  71. });
  72. } else {
  73. emit fail();
  74. }
  75. }