123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #include "AuthListener.hpp"
- #include <OBSApp.hpp>
- #include <qt-wrappers.hpp>
- #include <QRegularExpression>
- #include <QTcpServer>
- #include <QTcpSocket>
- #include "moc_AuthListener.cpp"
- #define LOGO_URL "https://obsproject.com/assets/images/new_icon_small-r.png"
- static const QString serverResponseHeader = QStringLiteral("HTTP/1.0 200 OK\n"
- "Connection: close\n"
- "Content-Type: text/html; charset=UTF-8\n"
- "Server: OBS Studio\n"
- "\n"
- "<html><head><title>OBS Studio"
- "</title></head>");
- static const QString responseTemplate = "<center>"
- "<img src=\"" LOGO_URL
- "\" alt=\"OBS\" class=\"center\" height=\"60\" width=\"60\">"
- "</center>"
- "<center><p style=\"font-family:verdana; font-size:13pt\">%1</p></center>";
- AuthListener::AuthListener(QObject *parent) : QObject(parent)
- {
- server = new QTcpServer(this);
- connect(server, &QTcpServer::newConnection, this, &AuthListener::NewConnection);
- if (!server->listen(QHostAddress::LocalHost, 0)) {
- blog(LOG_DEBUG, "Server could not start");
- emit fail();
- } else {
- blog(LOG_DEBUG, "Server started at port %d", server->serverPort());
- }
- }
- quint16 AuthListener::GetPort()
- {
- return server ? server->serverPort() : 0;
- }
- void AuthListener::SetState(QString state)
- {
- this->state = state;
- }
- void AuthListener::NewConnection()
- {
- QTcpSocket *socket = server->nextPendingConnection();
- if (socket) {
- connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
- connect(socket, &QTcpSocket::readyRead, socket, [&, socket]() {
- QByteArray buffer;
- while (socket->bytesAvailable() > 0) {
- buffer.append(socket->readAll());
- }
- socket->write(QT_TO_UTF8(serverResponseHeader));
- QString redirect = QString::fromLatin1(buffer);
- blog(LOG_DEBUG, "redirect: %s", QT_TO_UTF8(redirect));
- QRegularExpression re_state("(&|\\?)state=(?<state>[^&]+)");
- QRegularExpression re_code("(&|\\?)code=(?<code>[^&]+)");
- QRegularExpressionMatch match = re_state.match(redirect);
- QString code;
- if (match.hasMatch()) {
- if (state == match.captured("state")) {
- match = re_code.match(redirect);
- if (!match.hasMatch())
- blog(LOG_DEBUG, "no 'code' "
- "in server "
- "redirect");
- code = match.captured("code");
- } else {
- blog(LOG_WARNING, "state mismatch "
- "while handling "
- "redirect");
- }
- } else {
- blog(LOG_DEBUG, "no 'state' in "
- "server redirect");
- }
- if (code.isEmpty()) {
- auto data = responseTemplate.arg(QTStr("YouTube.Auth.NoCode"));
- socket->write(QT_TO_UTF8(data));
- emit fail();
- } else {
- auto data = responseTemplate.arg(QTStr("YouTube.Auth.Ok"));
- socket->write(QT_TO_UTF8(data));
- emit ok(code);
- }
- socket->flush();
- socket->close();
- });
- } else {
- emit fail();
- }
- }
|