Decentralised Art Server
High-performance C++ backend that exposes HTML interface and a secure REST API for managing Performative Transactions entities
 
Loading...
Searching...
No Matches
auth.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <random>
4#include <string>
5#include <expected>
6#include <format>
7#include <regex>
8#include <optional>
9
10#include "native.h"
11#include <asio.hpp>
12#include <asio/experimental/awaitable_operators.hpp>
13using namespace asio::experimental::awaitable_operators;
14
15#include <absl/container/flat_hash_map.h>
16#include <spdlog/spdlog.h>
17#include <secp256k1.h>
18#include <secp256k1_recovery.h>
19#include <jwt-cpp/jwt.h>
20
21// Undefine the conflicting macro
22#ifdef interface
23 #undef interface
24#endif
25#include <evmc/evmc.hpp>
26#ifndef interface
27 #define interface __STRUCT__
28#endif
29
30#include "utils.hpp"
31#include "keccak256.hpp"
32#include "http.hpp"
33
34namespace dcn::parse
35{
36 std::string parseNonceFromMessage(const std::string & msg);
37
38 // access token
39
40 // from header
41 template<http::Header HeaderType>
42 std::optional<std::string> parseAccessTokenFrom(const std::string & header_str);
43
44 template<>
45 std::optional<std::string> parseAccessTokenFrom<http::Header::Cookie>(const std::string& header_str);
46
47 template<>
48 std::optional<std::string> parseAccessTokenFrom<http::Header::Authorization>(const std::string& header_str);
49
50 // to header
51 template<http::Header HeaderType>
52 std::string parseAccessTokenTo(const std::string & token_str);
53
54 template<>
55 std::string parseAccessTokenTo<http::Header::SetCookie>(const std::string & token_str);
56
57 template<>
58 std::string parseAccessTokenTo<http::Header::Authorization>(const std::string & token_str);
59
60 // refresh token
61
62 // from header
63 template<http::Header HeaderType>
64 std::optional<std::string> parseRefreshTokenFrom(const std::string & header_str);
65
66 template<>
67 std::optional<std::string> parseRefreshTokenFrom<http::Header::Cookie>(const std::string & header_str);
68
69 template<>
70 std::optional<std::string> parseRefreshTokenFrom<http::Header::XRefreshToken>(const std::string & header_str);
71
72 // to header
73 template<http::Header HeaderType>
74 std::string parseRefreshTokenTo(const std::string & token_str);
75
76 template<>
77 std::string parseRefreshTokenTo<http::Header::SetCookie>(const std::string & token_str);
78
79 template<>
80 std::string parseRefreshTokenTo<http::Header::XRefreshToken>(const std::string & token_str);
81}
82
83namespace dcn
84{
85 enum class AuthenticationError : std::uint8_t
86 {
87 Unknown = 0,
95 };
96
98 {
99 public:
100 AuthManager() = delete;
101 AuthManager(asio::io_context & io_context);
102
103 AuthManager(const AuthManager&) = delete;
105
106 ~AuthManager() = default;
107
108 asio::awaitable<std::string> generateNonce(const evmc::address & address);
109
110 asio::awaitable<bool> verifyNonce(const evmc::address & address, const std::string & nonce);
111
112 asio::awaitable<bool> verifySignature(const evmc::address & address, const std::string& signature, const std::string& message);
113
114 asio::awaitable<std::string> generateAccessToken(const evmc::address & address);
115
116 asio::awaitable<std::expected<evmc::address, AuthenticationError>> verifyAccessToken(std::string token) const;
117
118 asio::awaitable<bool> compareAccessToken(const evmc::address & address, std::string token) const;
119
120 asio::awaitable<std::string> generateRefreshToken(const evmc::address & address);
121
122 asio::awaitable<std::expected<evmc::address, AuthenticationError>> verifyRefreshToken(std::string token) const;
123
124 private:
125 asio::strand<asio::io_context::executor_type> _strand;
126
127 const std::string _SECRET; // !!! TODO !!! use secure secret in production
128
129 std::mt19937 _rng;
130 std::uniform_int_distribution<int> _dist;
131 absl::flat_hash_map<evmc::address, std::string> _nonces;
132
133 absl::flat_hash_map<evmc::address, std::string> _refresh_tokens;
134 absl::flat_hash_map<evmc::address, std::string> _access_tokens;
135 };
136}
137
138template <>
139struct std::formatter<dcn::AuthenticationError> : std::formatter<std::string> {
140 auto format(const dcn::AuthenticationError & err, format_context& ctx) const {
141 switch(err)
142 {
143 case dcn::AuthenticationError::MissingCookie : return formatter<string>::format("MissingCookie", ctx);
144 case dcn::AuthenticationError::InvalidCookie : return formatter<string>::format("InvalidCookie", ctx);
145 case dcn::AuthenticationError::MissingToken : return formatter<string>::format("MissingToken", ctx);
146 case dcn::AuthenticationError::InvalidToken : return formatter<string>::format("InvalidToken", ctx);
147 case dcn::AuthenticationError::InvalidSignature : return formatter<string>::format("InvalidSignature", ctx);
148 case dcn::AuthenticationError::InvalidNonce : return formatter<string>::format("InvalidNonce", ctx);
149 case dcn::AuthenticationError::InvalidAddress : return formatter<string>::format("InvalidAddress", ctx);
150
151 default: return formatter<string>::format("Unknown", ctx);
152 }
153 return formatter<string>::format("", ctx);
154 }
155};
Definition auth.hpp:98
asio::awaitable< std::string > generateNonce(const evmc::address &address)
Definition auth.cpp:140
asio::awaitable< bool > verifyNonce(const evmc::address &address, const std::string &nonce)
Definition auth.cpp:150
AuthManager()=delete
asio::awaitable< std::string > generateAccessToken(const evmc::address &address)
Definition auth.cpp:211
asio::awaitable< bool > verifySignature(const evmc::address &address, const std::string &signature, const std::string &message)
Definition auth.cpp:169
asio::awaitable< bool > compareAccessToken(const evmc::address &address, std::string token) const
Definition auth.cpp:271
~AuthManager()=default
AuthManager & operator=(const AuthManager &)=delete
asio::awaitable< std::expected< evmc::address, AuthenticationError > > verifyAccessToken(std::string token) const
Definition auth.cpp:228
asio::awaitable< std::string > generateRefreshToken(const evmc::address &address)
Definition auth.cpp:288
AuthManager(const AuthManager &)=delete
asio::awaitable< std::expected< evmc::address, AuthenticationError > > verifyRefreshToken(std::string token) const
Definition auth.cpp:305
Definition auth.hpp:35
std::optional< std::string > parseAccessTokenFrom< http::Header::Authorization >(const std::string &header_str)
Definition auth.cpp:51
std::optional< std::string > parseRefreshTokenFrom< http::Header::XRefreshToken >(const std::string &header_str)
Definition auth.cpp:99
std::string parseAccessTokenTo< http::Header::SetCookie >(const std::string &token_str)
Definition auth.cpp:68
std::optional< std::string > parseRefreshTokenFrom< http::Header::Cookie >(const std::string &header_str)
Definition auth.cpp:83
std::string parseAccessTokenTo< http::Header::Authorization >(const std::string &token_str)
Definition auth.cpp:74
std::string parseNonceFromMessage(const std::string &msg)
Definition auth.cpp:17
std::string parseRefreshTokenTo(const std::string &token_str)
std::string parseRefreshTokenTo< http::Header::XRefreshToken >(const std::string &token_str)
Definition auth.cpp:123
std::string parseRefreshTokenTo< http::Header::SetCookie >(const std::string &token_str)
Definition auth.cpp:117
std::optional< std::string > parseRefreshTokenFrom(const std::string &header_str)
std::optional< std::string > parseAccessTokenFrom(const std::string &header_str)
std::optional< std::string > parseAccessTokenFrom< http::Header::Cookie >(const std::string &header_str)
Definition auth.cpp:35
std::string parseAccessTokenTo(const std::string &token_str)
Definition decentralised_art.hpp:30
AuthenticationError
Definition auth.hpp:86
auto format(const dcn::AuthenticationError &err, format_context &ctx) const
Definition auth.hpp:140