main
Brett 2023-08-16 01:24:22 -04:00
parent b6e4c3dd22
commit 9160d6a330
7 changed files with 169 additions and 43 deletions

View File

@ -10,6 +10,9 @@ set(CROW_FEATURES compression)
find_package(Crow)
find_package(CURL)
find_package(OpenSSL)
message("SSL ${OPENSSL_INCLUDE_DIR}")
if (NOT CURL_FOUND)
message("libcurl is required!")
@ -28,6 +31,7 @@ add_executable(crowsite ${source_files})
target_link_libraries(crowsite BLT)
target_link_libraries(crowsite Crow::Crow)
target_link_libraries(crowsite ${CURL_LIBRARIES})
target_link_libraries(crowsite OpenSSL::SSL OpenSSL::Crypto)
target_compile_options(crowsite PRIVATE -Wall -Wextra -Wpedantic)
if (${ENABLE_ADDRSAN} MATCHES ON)

View File

@ -27,13 +27,20 @@ namespace cs
request();
static const std::string& getResponse(const std::string& domain);
static std::string getResponseAndClear(const std::string& domain);
static void clearResponse(const std::string& domain);
void setContentHeaderJson();
void setContentHeaderXForm();
void setContentHeader(const std::string& header);
void setAuthHeader(const std::string& header);
void get(const std::string& domain, const std::string& data = "");
void post(const std::string& domain, const std::string& data = "");
long status();
~request();
};

View File

@ -6,9 +6,31 @@
#define CROWSITE_JELLYFIN_H
#include <string_view>
#include <string>
namespace cs::jellyfin
{
enum class auth_response {
AUTHORIZED,
USERNAME,
ERROR
};
struct client_data {
struct {
std::string name;
std::string serverId;
std::string Id;
std::string primaryImageTag;
bool hasPassword;
bool hasConfiguredPassword;
bool hasConfiguredEasyPassword;
bool enableAutoLogin;
std::string lastLoginDate;
std::string lastActivityDate;
} user;
std::string accessToken;
};
void setToken(std::string_view token);
@ -18,6 +40,7 @@ namespace cs::jellyfin
std::string getUserData();
bool hasUser(std::string_view username);
auth_response authenticateUser(std::string_view username, std::string_view password);
}

@ -1 +1 @@
Subproject commit a3f67571460d23fe819a3a3a572344e7030fba4a
Subproject commit 1e8f431f9eb06582083efde6489b59380f3e19ac

View File

@ -58,8 +58,6 @@ namespace cs
void request::setAuthHeader(const std::string& header)
{
curl_slist_free_all(headers);
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, ("Authorization: " + header).c_str());
curl_easy_setopt(handler, CURLOPT_HTTPHEADER, headers);
@ -97,4 +95,38 @@ namespace cs
{
return responses[domain];
}
void request::clearResponse(const std::string& domain)
{
responses.erase(domain);
}
std::string request::getResponseAndClear(const std::string& domain)
{
std::string res = getResponse(domain);
clearResponse(domain);
return res;
}
void request::setContentHeaderJson()
{
setContentHeader("application/json");
}
void request::setContentHeaderXForm()
{
setContentHeader("application/x-www-form-urlencoded");
}
void request::setContentHeader(const std::string& header)
{
headers = curl_slist_append(headers, ("Content-Type: " + header).c_str());
}
long request::status()
{
long code = 0;
curl_easy_getinfo(handler, CURLINFO_RESPONSE_CODE, &code);
return code;
}
}

View File

@ -6,50 +6,106 @@
#include <crow/json.h>
#include <blt/std/hashmap.h>
#include <blt/std/logging.h>
#include <string>
struct
namespace cs::jellyfin
{
struct
{
std::string token;
HASHMAP<std::string, std::string> user_ids;
} GLOBALS;
HASHMAP<std::string, client_data> logged_in_users;
} GLOBALS;
void cs::jellyfin::setToken(std::string_view token)
{
void setToken(std::string_view token)
{
GLOBALS.token = token;
}
}
void cs::jellyfin::processUserData()
{
void processUserData()
{
auto data = getUserData();
auto json = crow::json::load(data);
for (const auto& user : json){
for (const auto& user : json)
{
auto username = user["Name"].s();
auto userid = user["Id"].s();
//BLT_TRACE("Processing %s = %s", username.operator std::string().c_str(), userid.operator std::string().c_str());
GLOBALS.user_ids[username] = userid;
}
}
}
std::string cs::jellyfin::getUserData()
{
std::string getUserData()
{
#define url "https://media.tpgc.me/Users"
cs::request request;
request.setContentHeaderJson();
request.setAuthHeader(generateAuthHeader());
request.get(url);
return cs::request::getResponse(url);
}
}
std::string cs::jellyfin::generateAuthHeader()
{
std::string generateAuthHeader()
{
return "MediaBrowser Client=Crowsite, Device=YourMom, Token=" + GLOBALS.token;
}
}
bool cs::jellyfin::hasUser(std::string_view username)
{
bool hasUser(std::string_view username)
{
return GLOBALS.user_ids.find(std::string(username)) != GLOBALS.user_ids.end();
}
auth_response authenticateUser(std::string_view username, std::string_view password)
{
if (!hasUser(username))
processUserData();
if (!hasUser(username))
{
BLT_ERROR("User not found!");
return auth_response::USERNAME;
}
auto l_url = "https://media.tpgc.me/Users/AuthenticateByName";
cs::request post;
post.setContentHeaderJson();
post.setAuthHeader(generateAuthHeader());
crow::json::wvalue json;
json["Username"] = std::string(username);
json["Pw"] = std::string(password);
post.post(l_url, json.dump());
auto response = cs::request::getResponseAndClear(l_url);
if (post.status() == 200)
{
crow::json::rvalue read = crow::json::load(response);
const auto& users = read["User"];
client_data data;
data.accessToken = read["AccessToken"].s();
auto& user = data.user;
user.name = users["Name"].s();
user.serverId = users["ServerId"].s();
user.Id = users["Id"].s();
user.primaryImageTag = users["PrimaryImageTag"].s();
user.hasPassword = users["HasPassword"].b();
user.hasConfiguredPassword = users["HasConfiguredPassword"].b();
user.hasConfiguredEasyPassword = users["HasConfiguredEasyPassword"].b();
user.enableAutoLogin = users["EnableAutoLogin"].b();
user.lastLoginDate = users["LastLoginDate"].s();
user.lastActivityDate = users["LastActivityDate"].s();
GLOBALS.logged_in_users[std::string(username)] = data;
return auth_response::AUTHORIZED;
}
return auth_response::ERROR;
}
}

View File

@ -48,10 +48,14 @@ int main(int argc, const char** argv)
blt::arg_parse parser;
parser.addArgument(blt::arg_builder("token").build());
parser.addArgument(blt::arg_builder("user").build());
parser.addArgument(blt::arg_builder("pass").build());
auto args = parser.parse_args(argc, argv);
cs::jellyfin::setToken(blt::arg_parse::get<std::string>(args["token"]));
cs::jellyfin::processUserData();
cs::jellyfin::authenticateUser(blt::arg_parse::get<std::string>(args["user"]), blt::arg_parse::get<std::string>(args["pass"]));
// blt::string::StringBuffer buffer;
// std::stringstream stream;
// std::string normalString;