mirror of
https://github.com/Expand-sys/CCash
synced 2026-03-22 20:47:10 +11:00
✨ base64
This commit is contained in:
parent
e7f7f0f698
commit
c9da3eab04
9 changed files with 92 additions and 154 deletions
|
|
@ -20,9 +20,9 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||||
src/admin_filter.cpp
|
src/admin_filter.cpp
|
||||||
src/bank_api.cpp
|
src/bank_api.cpp
|
||||||
src/bank.cpp
|
src/bank.cpp
|
||||||
src/base64.c #temp
|
|
||||||
src/change_flag.cpp
|
src/change_flag.cpp
|
||||||
src/log.cpp
|
src/log.cpp
|
||||||
|
src/substr_view.cpp
|
||||||
src/transaction.cpp
|
src/transaction.cpp
|
||||||
src/user_filter.cpp
|
src/user_filter.cpp
|
||||||
src/user.cpp
|
src/user.cpp
|
||||||
|
|
@ -32,8 +32,12 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC third_party)
|
target_include_directories(${PROJECT_NAME} PUBLIC third_party)
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC third_party/drogon/lib/inc)
|
target_include_directories(${PROJECT_NAME} PUBLIC third_party/drogon/lib/inc)
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC third_party/base64/include)
|
||||||
|
|
||||||
add_subdirectory(third_party/drogon)
|
add_subdirectory(third_party/drogon)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
|
target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT} )
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT} )
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||||
|
|
||||||
|
# AVX2_CFLAGS=-mavx2 SSSE3_CFLAGS=-mssse3 SSE41_CFLAGS=-msse4.1 SSE42_CFLAGS=-msse4.2 AVX_CFLAGS=-mavx make lib/libbase64.o
|
||||||
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/third_party/base64/lib/libbase64.o)
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <drogon/HttpFilter.h>
|
#include <drogon/HttpFilter.h>
|
||||||
|
#include <libbase64.h>
|
||||||
|
#include "substr_view.h"
|
||||||
#include "bank.h"
|
#include "bank.h"
|
||||||
|
|
||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
|
|
|
||||||
16
include/substr_view.h
Normal file
16
include/substr_view.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class substr_view
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const char *begin;
|
||||||
|
size_t end;
|
||||||
|
|
||||||
|
public:
|
||||||
|
substr_view(std::string_view str, size_t begin_init = 0, size_t end_init = 0) noexcept;
|
||||||
|
bool operator==(const std::string &str) const noexcept;
|
||||||
|
const char *data() const noexcept;
|
||||||
|
std::string_view str_view() const noexcept;
|
||||||
|
};
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <drogon/HttpFilter.h>
|
#include <drogon/HttpFilter.h>
|
||||||
|
#include <libbase64.h>
|
||||||
|
#include "substr_view.h"
|
||||||
#include "bank.h"
|
#include "bank.h"
|
||||||
|
|
||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
struct xxHashStringGen
|
struct xxHashStringGen
|
||||||
{
|
{
|
||||||
XXH64_hash_t operator()(const std::string &str) const noexcept;
|
XXH64_hash_t operator()(const std::string_view &str) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,71 +1,5 @@
|
||||||
#include "admin_filter.h"
|
#include "admin_filter.h"
|
||||||
|
|
||||||
static char DecodeChar2(const char ch)
|
|
||||||
{
|
|
||||||
if (ch >= 'A' && ch <= 'Z')
|
|
||||||
{
|
|
||||||
return ch - 'A';
|
|
||||||
}
|
|
||||||
if (ch >= 'a' && ch <= 'z')
|
|
||||||
{
|
|
||||||
return ch - 'a' + 26;
|
|
||||||
}
|
|
||||||
if (ch >= '0' && ch <= '9')
|
|
||||||
{
|
|
||||||
return ch - '0' + 52;
|
|
||||||
}
|
|
||||||
return 63 - (ch == '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
char *DecodeBase642(const char *string)
|
|
||||||
{
|
|
||||||
char *output;
|
|
||||||
size_t length = strlen(string);
|
|
||||||
if (!(output = (char *)malloc(1 + (length >> 2) * 3 - (string[length - 1] == '=') - (string[length - 2] == '='))))
|
|
||||||
{
|
|
||||||
return (char *)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t index = 0;
|
|
||||||
uint32_t storage = 0;
|
|
||||||
while (string[4])
|
|
||||||
{
|
|
||||||
storage |= DecodeChar2(*string++) << 18;
|
|
||||||
storage |= DecodeChar2(*string++) << 12;
|
|
||||||
storage |= DecodeChar2(*string++) << 6;
|
|
||||||
storage |= DecodeChar2(*string++);
|
|
||||||
|
|
||||||
output[index++] = storage >> 16;
|
|
||||||
output[index++] = (char)(storage >> 8);
|
|
||||||
output[index++] = (char)storage;
|
|
||||||
|
|
||||||
storage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage |= DecodeChar2(*string++) << 18;
|
|
||||||
storage |= DecodeChar2(*string++) << 12;
|
|
||||||
output[index++] = storage >> 16;
|
|
||||||
|
|
||||||
if (*string == '=')
|
|
||||||
{
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
storage |= DecodeChar2(*string++) << 6;
|
|
||||||
output[index++] = (char)(storage >> 8);
|
|
||||||
|
|
||||||
if (*string == '=')
|
|
||||||
{
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
storage |= DecodeChar2(*string);
|
|
||||||
output[index++] = (char)storage;
|
|
||||||
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdminFilter::AdminFilter(Bank &b) : bank(b) {}
|
AdminFilter::AdminFilter(Bank &b) : bank(b) {}
|
||||||
|
|
||||||
void AdminFilter::doFilter(const HttpRequestPtr &req,
|
void AdminFilter::doFilter(const HttpRequestPtr &req,
|
||||||
|
|
@ -75,15 +9,22 @@ void AdminFilter::doFilter(const HttpRequestPtr &req,
|
||||||
const std::string &auth_header = req->getHeader("Authorization");
|
const std::string &auth_header = req->getHeader("Authorization");
|
||||||
if (auth_header.size() > 6)
|
if (auth_header.size() > 6)
|
||||||
{
|
{
|
||||||
if (auth_header.substr(0, 6) == "Basic ")
|
if (substr_view(auth_header, 0, 6) == "Basic ")
|
||||||
{
|
{
|
||||||
std::stringstream ss(DecodeBase642(auth_header.substr(6).c_str()));
|
//only one alloc for this entire thing!
|
||||||
std::string username, password;
|
char base64_result[((auth_header.size() - 6) * 3) / 4];
|
||||||
std::getline(ss, username, ':');
|
size_t new_sz;
|
||||||
std::getline(ss, password);
|
base64_decode(substr_view(auth_header, 6).data(), auth_header.size() - 6, base64_result, &new_sz, 0);
|
||||||
if (bank.AdminVerifyPass(password)) //is admin
|
|
||||||
|
std::size_t res = std::string_view(base64_result, new_sz).find(':');
|
||||||
|
if (res != std::string::npos)
|
||||||
{
|
{
|
||||||
if (bank.VerifyPassword(username, password)) //is valid pair
|
std::string_view username = substr_view(base64_result, 0, res).str_view();
|
||||||
|
std::string_view password = substr_view(base64_result, res + 1, new_sz).str_view();
|
||||||
|
if (bank.AdminVerifyAccount(username))
|
||||||
|
{
|
||||||
|
//another alloc
|
||||||
|
if (bank.VerifyPassword(username, password))
|
||||||
{
|
{
|
||||||
fccb();
|
fccb();
|
||||||
return;
|
return;
|
||||||
|
|
@ -91,6 +32,7 @@ void AdminFilter::doFilter(const HttpRequestPtr &req,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto resp = HttpResponse::newHttpJsonResponse("Invalid Credentials");
|
auto resp = HttpResponse::newHttpJsonResponse("Invalid Credentials");
|
||||||
resp->setStatusCode(k401Unauthorized);
|
resp->setStatusCode(k401Unauthorized);
|
||||||
fcb(resp);
|
fcb(resp);
|
||||||
|
|
|
||||||
31
src/substr_view.cpp
Normal file
31
src/substr_view.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "substr_view.h"
|
||||||
|
|
||||||
|
substr_view::substr_view(std::string_view str, size_t begin_init, size_t end_init) noexcept
|
||||||
|
{
|
||||||
|
begin = str.begin() + begin_init;
|
||||||
|
if (!end_init)
|
||||||
|
{
|
||||||
|
end = str.size() - begin_init;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = end_init - begin_init;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool substr_view::operator==(const std::string &str) const noexcept
|
||||||
|
{
|
||||||
|
if (str.size() != end)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < end; ++i)
|
||||||
|
{
|
||||||
|
if (*(begin + end) == str[i])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char *substr_view::data() const noexcept { return begin; }
|
||||||
|
std::string_view substr_view::str_view() const noexcept { return std::string_view(data(), end); }
|
||||||
|
|
@ -1,71 +1,5 @@
|
||||||
#include "user_filter.h"
|
#include "user_filter.h"
|
||||||
|
|
||||||
static char DecodeChar(const char ch)
|
|
||||||
{
|
|
||||||
if (ch >= 'A' && ch <= 'Z')
|
|
||||||
{
|
|
||||||
return ch - 'A';
|
|
||||||
}
|
|
||||||
if (ch >= 'a' && ch <= 'z')
|
|
||||||
{
|
|
||||||
return ch - 'a' + 26;
|
|
||||||
}
|
|
||||||
if (ch >= '0' && ch <= '9')
|
|
||||||
{
|
|
||||||
return ch - '0' + 52;
|
|
||||||
}
|
|
||||||
return 63 - (ch == '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
char *DecodeBase64(const char *string)
|
|
||||||
{
|
|
||||||
char *output;
|
|
||||||
size_t length = strlen(string);
|
|
||||||
if (!(output = (char *)malloc(1 + (length >> 2) * 3 - (string[length - 1] == '=') - (string[length - 2] == '='))))
|
|
||||||
{
|
|
||||||
return (char *)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t index = 0;
|
|
||||||
uint32_t storage = 0;
|
|
||||||
while (string[4])
|
|
||||||
{
|
|
||||||
storage |= DecodeChar(*string++) << 18;
|
|
||||||
storage |= DecodeChar(*string++) << 12;
|
|
||||||
storage |= DecodeChar(*string++) << 6;
|
|
||||||
storage |= DecodeChar(*string++);
|
|
||||||
|
|
||||||
output[index++] = storage >> 16;
|
|
||||||
output[index++] = (char)(storage >> 8);
|
|
||||||
output[index++] = (char)storage;
|
|
||||||
|
|
||||||
storage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage |= DecodeChar(*string++) << 18;
|
|
||||||
storage |= DecodeChar(*string++) << 12;
|
|
||||||
output[index++] = storage >> 16;
|
|
||||||
|
|
||||||
if (*string == '=')
|
|
||||||
{
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
storage |= DecodeChar(*string++) << 6;
|
|
||||||
output[index++] = (char)(storage >> 8);
|
|
||||||
|
|
||||||
if (*string == '=')
|
|
||||||
{
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
storage |= DecodeChar(*string);
|
|
||||||
output[index++] = (char)storage;
|
|
||||||
|
|
||||||
output[index] = '\0';
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserFilter::UserFilter(Bank &b) : bank(b) {}
|
UserFilter::UserFilter(Bank &b) : bank(b) {}
|
||||||
|
|
||||||
void UserFilter::doFilter(const HttpRequestPtr &req,
|
void UserFilter::doFilter(const HttpRequestPtr &req,
|
||||||
|
|
@ -75,20 +9,27 @@ void UserFilter::doFilter(const HttpRequestPtr &req,
|
||||||
const std::string &auth_header = req->getHeader("Authorization");
|
const std::string &auth_header = req->getHeader("Authorization");
|
||||||
if (auth_header.size() > 6)
|
if (auth_header.size() > 6)
|
||||||
{
|
{
|
||||||
if (auth_header.substr(0, 6) == "Basic ")
|
if (substr_view(auth_header, 0, 6) == "Basic ")
|
||||||
{
|
{
|
||||||
std::stringstream ss(DecodeBase64(auth_header.substr(6).c_str()));
|
//only one alloc for this entire thing!
|
||||||
std::string username, password;
|
char base64_result[((auth_header.size() - 6) * 3) / 4];
|
||||||
std::getline(ss, username, ':');
|
size_t new_sz;
|
||||||
std::getline(ss, password);
|
base64_decode(substr_view(auth_header, 6).data(), auth_header.size() - 6, base64_result, &new_sz, 0);
|
||||||
|
|
||||||
|
std::size_t res = std::string_view(base64_result, new_sz).find(':');
|
||||||
|
if (res != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string_view username = substr_view(base64_result, 0, res).str_view();
|
||||||
|
std::string_view password = substr_view(base64_result, res + 1, new_sz).str_view();
|
||||||
|
//another alloc
|
||||||
if (bank.VerifyPassword(username, password))
|
if (bank.VerifyPassword(username, password))
|
||||||
{
|
{
|
||||||
req->setBody(username);
|
|
||||||
fccb();
|
fccb();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto resp = HttpResponse::newHttpJsonResponse("Invalid Credentials");
|
auto resp = HttpResponse::newHttpJsonResponse("Invalid Credentials");
|
||||||
resp->setStatusCode(k401Unauthorized);
|
resp->setStatusCode(k401Unauthorized);
|
||||||
fcb(resp);
|
fcb(resp);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "xxhash_str.h"
|
#include "xxhash_str.h"
|
||||||
|
|
||||||
XXH64_hash_t xxHashStringGen::operator()(const std::string &str) const noexcept
|
XXH64_hash_t xxHashStringGen::operator()(const std::string_view &str) const noexcept
|
||||||
{
|
{
|
||||||
return XXH3_64bits(str.data(), str.size());
|
return XXH3_64bits(str.data(), str.size());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue