add example for db
This commit is contained in:
parent
4cca3e4a7c
commit
811888ba7d
|
@ -62,6 +62,15 @@ namespace bserv::utils {
|
||||||
|
|
||||||
namespace file {
|
namespace file {
|
||||||
|
|
||||||
|
class file_not_found : public std::exception {
|
||||||
|
private:
|
||||||
|
std::string msg_;
|
||||||
|
public:
|
||||||
|
file_not_found(const std::string& filename)
|
||||||
|
: msg_{ std::string{ "'" } + filename + "' does not exist" } {}
|
||||||
|
const char* what() const { return msg_.c_str(); }
|
||||||
|
};
|
||||||
|
|
||||||
std::string read_bin(const std::string& filename);
|
std::string read_bin(const std::string& filename);
|
||||||
|
|
||||||
std::nullopt_t serve(
|
std::nullopt_t serve(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "bserv/utils.hpp"
|
#include "bserv/utils.hpp"
|
||||||
|
#include "bserv/router.hpp"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -238,6 +239,7 @@ namespace bserv::utils {
|
||||||
|
|
||||||
std::string read_bin(const std::string& filename) {
|
std::string read_bin(const std::string& filename) {
|
||||||
std::ifstream fin(filename, std::ios_base::in | std::ios_base::binary);
|
std::ifstream fin(filename, std::ios_base::in | std::ios_base::binary);
|
||||||
|
if (!fin.is_open()) throw file_not_found{ filename };
|
||||||
std::string res;
|
std::string res;
|
||||||
while (true) {
|
while (true) {
|
||||||
char c = (char)fin.get();
|
char c = (char)fin.get();
|
||||||
|
@ -285,7 +287,12 @@ namespace bserv::utils {
|
||||||
response_type& response,
|
response_type& response,
|
||||||
const std::string& filename) {
|
const std::string& filename) {
|
||||||
response.set(bserv::http::field::content_type, mime_type(filename));
|
response.set(bserv::http::field::content_type, mime_type(filename));
|
||||||
response.body() = read_bin(filename);
|
try {
|
||||||
|
response.body() = read_bin(filename);
|
||||||
|
}
|
||||||
|
catch (const file_not_found&) {
|
||||||
|
throw url_not_found_exception{};
|
||||||
|
}
|
||||||
response.prepare_payload();
|
response.prepare_payload();
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{9c6ee570-c51b-46b0-aa25-8aa1752ca68a}</ProjectGuid>
|
||||||
|
<RootNamespace>DB</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="..\bserv-debug-x64.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="db.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="源文件">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="资源文件">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="db.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
|
@ -15,6 +15,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Routing", "Routing.vcxproj"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bserv", "..\bserv\bserv.vcxproj", "{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bserv", "..\bserv\bserv.vcxproj", "{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DB", "DB.vcxproj", "{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296} = {F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
@ -47,6 +52,14 @@ Global
|
||||||
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x64.Build.0 = Release|x64
|
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x64.Build.0 = Release|x64
|
||||||
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x86.ActiveCfg = Release|Win32
|
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x86.Build.0 = Release|Win32
|
{F5C0CF6D-7BF9-40A5-AF2E-8FC36A1D7296}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{9C6EE570-C51B-46B0-AA25-8AA1752CA68A}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
#include <bserv/common.hpp>
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
|
bserv::db_relation_to_object orm_user{
|
||||||
|
bserv::make_db_field<int>("id"),
|
||||||
|
bserv::make_db_field<std::string>("username"),
|
||||||
|
bserv::make_db_field<std::string>("password"),
|
||||||
|
bserv::make_db_field<bool>("is_active"),
|
||||||
|
bserv::make_db_field<bool>("is_superuser"),
|
||||||
|
bserv::make_db_field<std::optional<std::string>>("first_name"),
|
||||||
|
bserv::make_db_field<std::optional<std::string>>("last_name"),
|
||||||
|
bserv::make_db_field<std::optional<std::string>>("email")
|
||||||
|
};
|
||||||
|
std::optional<boost::json::object> get_user(
|
||||||
|
bserv::db_transaction& tx,
|
||||||
|
const boost::json::value& username) {
|
||||||
|
bserv::db_result r = tx.exec(
|
||||||
|
"select * from ex_auth_user where username = ?;", username);
|
||||||
|
lginfo << r.query();
|
||||||
|
return orm_user.convert_to_optional(r);
|
||||||
|
}
|
||||||
|
std::optional<boost::json::value> get_or_empty(
|
||||||
|
boost::json::object& obj,
|
||||||
|
const std::string& key) {
|
||||||
|
if (!obj.contains(key)) return std::nullopt;
|
||||||
|
return obj[key];
|
||||||
|
}
|
||||||
|
boost::json::object greet(
|
||||||
|
std::shared_ptr<bserv::session_type> session_ptr) {
|
||||||
|
bserv::session_type& session = *session_ptr;
|
||||||
|
if (session.count("user")) {
|
||||||
|
boost::json::object& user = session["user"].as_object();
|
||||||
|
boost::json::object obj;
|
||||||
|
// the first way to check non-null (!= nullptr)
|
||||||
|
if (user["first_name"] != nullptr && user["last_name"] != nullptr) {
|
||||||
|
obj["welcome"] = std::string{ user["first_name"].as_string() }
|
||||||
|
+ ' ' + std::string{ user["last_name"].as_string() };
|
||||||
|
}
|
||||||
|
else obj["welcome"] = user["username"];
|
||||||
|
// the second way (!is_null())
|
||||||
|
if (!user["email"].is_null()) {
|
||||||
|
obj["email"] = user["email"];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
else return { {"hello", "world"} };
|
||||||
|
}
|
||||||
|
boost::json::object user_register(
|
||||||
|
bserv::request_type& request,
|
||||||
|
boost::json::object&& params,
|
||||||
|
std::shared_ptr<bserv::db_connection> conn) {
|
||||||
|
if (request.method() != boost::beast::http::verb::post)
|
||||||
|
throw bserv::url_not_found_exception{};
|
||||||
|
if (!params.contains("username")) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "`username` is required"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!params.contains("password")) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "`password` is required"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto username = params["username"];
|
||||||
|
bserv::db_transaction tx{ conn };
|
||||||
|
auto opt_user = get_user(tx, username);
|
||||||
|
if (opt_user) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "`username` existed"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto password = params["password"].as_string();
|
||||||
|
bserv::db_result r = tx.exec(
|
||||||
|
"insert into ex_auth_user "
|
||||||
|
"(username, password, is_active, is_superuser, "
|
||||||
|
"first_name, last_name, email) values "
|
||||||
|
"(?, ?, ?, ?, ?, ?, ?);",
|
||||||
|
username,
|
||||||
|
bserv::utils::security::encode_password(
|
||||||
|
password.c_str()),
|
||||||
|
params.contains("is_active") ? params["is_active"] : true,
|
||||||
|
params.contains("is_superuser") ? params["is_superuser"] : false,
|
||||||
|
get_or_empty(params, "first_name"),
|
||||||
|
get_or_empty(params, "last_name"),
|
||||||
|
get_or_empty(params, "email"));
|
||||||
|
lginfo << r.query();
|
||||||
|
tx.commit(); // commit must be done explicitly
|
||||||
|
return {
|
||||||
|
{"success", true},
|
||||||
|
{"message", "user registered"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
boost::json::object user_login(
|
||||||
|
bserv::request_type& request,
|
||||||
|
boost::json::object&& params,
|
||||||
|
std::shared_ptr<bserv::db_connection> conn,
|
||||||
|
std::shared_ptr<bserv::session_type> session_ptr) {
|
||||||
|
if (request.method() != boost::beast::http::verb::post)
|
||||||
|
throw bserv::url_not_found_exception{};
|
||||||
|
if (!params.contains("username")) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "`username` is required"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!params.contains("password")) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "`password` is required"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto username = params["username"];
|
||||||
|
bserv::db_transaction tx{ conn };
|
||||||
|
auto opt_user = get_user(tx, username);
|
||||||
|
if (!opt_user) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "invalid username/password"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto& user = opt_user.value();
|
||||||
|
if (!user["is_active"].as_bool()) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "invalid username/password"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto password = params["password"].as_string();
|
||||||
|
auto encoded_password = user["password"].as_string();
|
||||||
|
if (!bserv::utils::security::check_password(
|
||||||
|
password.c_str(), encoded_password.c_str())) {
|
||||||
|
return {
|
||||||
|
{"success", false},
|
||||||
|
{"message", "invalid username/password"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
bserv::session_type& session = *session_ptr;
|
||||||
|
session["user"] = user;
|
||||||
|
return {
|
||||||
|
{"success", true},
|
||||||
|
{"message", "login successfully"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
boost::json::object user_logout(
|
||||||
|
std::shared_ptr<bserv::session_type> session_ptr) {
|
||||||
|
bserv::session_type& session = *session_ptr;
|
||||||
|
if (session.count("user"))
|
||||||
|
session.erase("user");
|
||||||
|
return {
|
||||||
|
{"success", true},
|
||||||
|
{"message", "logout successfully"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
int main() {
|
||||||
|
std::string config_content = bserv::utils::file::read_bin("../config.json");
|
||||||
|
boost::json::object config_obj = boost::json::parse(config_content).as_object();
|
||||||
|
bserv::server_config config;
|
||||||
|
config.set_db_conn_str(config_obj["conn-str"].as_string().c_str());
|
||||||
|
bserv::server{ config, {
|
||||||
|
bserv::make_path("/greet", &greet,
|
||||||
|
bserv::placeholders::session),
|
||||||
|
bserv::make_path("/register", &user_register,
|
||||||
|
bserv::placeholders::request,
|
||||||
|
bserv::placeholders::json_params,
|
||||||
|
bserv::placeholders::db_connection_ptr),
|
||||||
|
bserv::make_path("/login", &user_login,
|
||||||
|
bserv::placeholders::request,
|
||||||
|
bserv::placeholders::json_params,
|
||||||
|
bserv::placeholders::db_connection_ptr,
|
||||||
|
bserv::placeholders::session),
|
||||||
|
bserv::make_path("/logout", &user_logout,
|
||||||
|
bserv::placeholders::session)
|
||||||
|
} };
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
DROP TABLE IF EXISTS ex_auth_user;
|
||||||
|
CREATE TABLE ex_auth_user (
|
||||||
|
id serial PRIMARY KEY,
|
||||||
|
username character varying(255) NOT NULL UNIQUE,
|
||||||
|
password character varying(255) NOT NULL,
|
||||||
|
is_active boolean NOT NULL,
|
||||||
|
is_superuser boolean NOT NULL,
|
||||||
|
first_name character varying(255),
|
||||||
|
last_name character varying(255),
|
||||||
|
email character varying(255)
|
||||||
|
);
|
Loading…
Reference in New Issue