initial commit
This commit is contained in:
commit
973ce95d89
BIN
.cache/clangd/index/main.cpp.6EEB3AD128225F1C.idx
Normal file
BIN
.cache/clangd/index/main.cpp.6EEB3AD128225F1C.idx
Normal file
Binary file not shown.
53
bin/main.cpp
Normal file
53
bin/main.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "jwt-cpp/jwt.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using sec = std::chrono::seconds;
|
||||||
|
using min = std::chrono::minutes;
|
||||||
|
|
||||||
|
auto main() -> int
|
||||||
|
{
|
||||||
|
jwt::claim from_raw_json;
|
||||||
|
std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"};
|
||||||
|
iss >> from_raw_json;
|
||||||
|
|
||||||
|
jwt::claim::set_t list { "once", "twice" };
|
||||||
|
std::vector<int64_t> big_numbers { 727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL };
|
||||||
|
|
||||||
|
const auto time = jwt::date::clock::now();
|
||||||
|
|
||||||
|
const auto token = jwt::create()
|
||||||
|
.set_type("JWT")
|
||||||
|
.set_issuer("auth.mydomain.io")
|
||||||
|
.set_audience("mydomain.io")
|
||||||
|
.set_issued_at(time)
|
||||||
|
.set_not_before(time)
|
||||||
|
.set_expires_at(time + sec{15} + min{2})
|
||||||
|
.set_payload_claim("boolean", picojson::value(true))
|
||||||
|
.set_payload_claim("integer", picojson::value(int64_t{12345}))
|
||||||
|
.set_payload_claim("precision", picojson::value(12.345))
|
||||||
|
.set_payload_claim("strings", jwt::claim(list))
|
||||||
|
.set_payload_claim("array", jwt::claim(big_numbers.begin(), big_numbers.end()))
|
||||||
|
.set_payload_claim("object", from_raw_json)
|
||||||
|
.sign(jwt::algorithm::none{});
|
||||||
|
//.sign(jwt::algorithm::hs256{"secret"});
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "token = " << token << std::endl;
|
||||||
|
const auto decoded = jwt::decode(token);
|
||||||
|
|
||||||
|
const auto api_array = decoded.get_payload_claims()["object"].to_json().get("api").get("array");
|
||||||
|
std::cout << "api array = " << api_array << std::endl;
|
||||||
|
|
||||||
|
jwt::verify()
|
||||||
|
.allow_algorithm(jwt::algorithm::none{})
|
||||||
|
.with_issuer("auth.mydomain.io")
|
||||||
|
.with_audience("mydomain.io")
|
||||||
|
.with_claim("object", from_raw_json)
|
||||||
|
.verify(decoded);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
6
bin/meson.build
Normal file
6
bin/meson.build
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
executable(
|
||||||
|
'jwt-cpp',
|
||||||
|
'main.cpp',
|
||||||
|
dependencies : deps,
|
||||||
|
cpp_args: args
|
||||||
|
)
|
25
meson.build
Normal file
25
meson.build
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
project(
|
||||||
|
'jwt-cpp',
|
||||||
|
'cpp',
|
||||||
|
version : '2.0.0',
|
||||||
|
default_options : ['cpp_std=c++20']
|
||||||
|
)
|
||||||
|
|
||||||
|
add_project_arguments (
|
||||||
|
'-pedantic',
|
||||||
|
'-Wno-comment',
|
||||||
|
'-Wno-gnu-zero-variadic-macro-arguments',
|
||||||
|
'-Wunused-but-set-variable',
|
||||||
|
language: 'cpp'
|
||||||
|
)
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
|
||||||
|
deps = []
|
||||||
|
args = []
|
||||||
|
inc = []
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
|
||||||
|
subdir('src')
|
||||||
|
subdir('bin')
|
18
run
Normal file
18
run
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
## test
|
||||||
|
PROJECT_NAME="jwt-cpp"
|
||||||
|
MODE1=$1
|
||||||
|
TEST="meson test $MODE1 -C build"
|
||||||
|
RUN="./build/bin/$PROJECT_NAME"
|
||||||
|
|
||||||
|
command meson compile -C build
|
||||||
|
|
||||||
|
if [[ $MODE1 == "test" ]]; then
|
||||||
|
command $TEST
|
||||||
|
else
|
||||||
|
command $RUN
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
208
src/jwt-cpp/base.h
Normal file
208
src/jwt-cpp/base.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#ifndef JWT_CPP_BASE_H
|
||||||
|
#define JWT_CPP_BASE_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef __has_cpp_attribute
|
||||||
|
#if __has_cpp_attribute(fallthrough)
|
||||||
|
#define JWT_FALLTHROUGH [[fallthrough]]
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JWT_FALLTHROUGH
|
||||||
|
#define JWT_FALLTHROUGH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief character maps when encoding and decoding
|
||||||
|
*/
|
||||||
|
namespace alphabet {
|
||||||
|
/**
|
||||||
|
* \brief valid list of characted when working with [Base64](https://tools.ietf.org/html/rfc3548)
|
||||||
|
*/
|
||||||
|
struct base64 {
|
||||||
|
static const std::array<char, 64>& data() {
|
||||||
|
static constexpr std::array<char, 64> data{
|
||||||
|
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
static const std::string& fill() {
|
||||||
|
static std::string fill{"="};
|
||||||
|
return fill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* \brief valid list of characted when working with [Base64URL](https://tools.ietf.org/html/rfc4648)
|
||||||
|
*/
|
||||||
|
struct base64url {
|
||||||
|
static const std::array<char, 64>& data() {
|
||||||
|
static constexpr std::array<char, 64> data{
|
||||||
|
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
static const std::string& fill() {
|
||||||
|
static std::string fill{"%3d"};
|
||||||
|
return fill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace alphabet
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Alphabet generic methods for working with encoding/decoding the base64 family
|
||||||
|
*/
|
||||||
|
class base {
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
static std::string encode(const std::string& bin) {
|
||||||
|
return encode(bin, T::data(), T::fill());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
static std::string decode(const std::string& base) {
|
||||||
|
return decode(base, T::data(), T::fill());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
static std::string pad(const std::string& base) {
|
||||||
|
return pad(base, T::fill());
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
static std::string trim(const std::string& base) {
|
||||||
|
return trim(base, T::fill());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string encode(const std::string& bin, const std::array<char, 64>& alphabet,
|
||||||
|
const std::string& fill) {
|
||||||
|
size_t size = bin.size();
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
// clear incomplete bytes
|
||||||
|
size_t fast_size = size - size % 3;
|
||||||
|
for (size_t i = 0; i < fast_size;) {
|
||||||
|
uint32_t octet_a = static_cast<unsigned char>(bin[i++]);
|
||||||
|
uint32_t octet_b = static_cast<unsigned char>(bin[i++]);
|
||||||
|
uint32_t octet_c = static_cast<unsigned char>(bin[i++]);
|
||||||
|
|
||||||
|
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||||
|
|
||||||
|
res += alphabet[(triple >> 3 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 2 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 1 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 0 * 6) & 0x3F];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fast_size == size) return res;
|
||||||
|
|
||||||
|
size_t mod = size % 3;
|
||||||
|
|
||||||
|
uint32_t octet_a = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
|
||||||
|
uint32_t octet_b = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
|
||||||
|
uint32_t octet_c = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
|
||||||
|
|
||||||
|
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||||
|
|
||||||
|
switch (mod) {
|
||||||
|
case 1:
|
||||||
|
res += alphabet[(triple >> 3 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 2 * 6) & 0x3F];
|
||||||
|
res += fill;
|
||||||
|
res += fill;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
res += alphabet[(triple >> 3 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 2 * 6) & 0x3F];
|
||||||
|
res += alphabet[(triple >> 1 * 6) & 0x3F];
|
||||||
|
res += fill;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string decode(const std::string& base, const std::array<char, 64>& alphabet,
|
||||||
|
const std::string& fill) {
|
||||||
|
size_t size = base.size();
|
||||||
|
|
||||||
|
size_t fill_cnt = 0;
|
||||||
|
while (size > fill.size()) {
|
||||||
|
if (base.substr(size - fill.size(), fill.size()) == fill) {
|
||||||
|
fill_cnt++;
|
||||||
|
size -= fill.size();
|
||||||
|
if (fill_cnt > 2) throw std::runtime_error("Invalid input: too much fill");
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size + fill_cnt) % 4 != 0) throw std::runtime_error("Invalid input: incorrect total size");
|
||||||
|
|
||||||
|
size_t out_size = size / 4 * 3;
|
||||||
|
std::string res;
|
||||||
|
res.reserve(out_size);
|
||||||
|
|
||||||
|
auto get_sextet = [&](size_t offset) {
|
||||||
|
for (size_t i = 0; i < alphabet.size(); i++) {
|
||||||
|
if (alphabet[i] == base[offset]) return static_cast<uint32_t>(i);
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Invalid input: not within alphabet");
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t fast_size = size - size % 4;
|
||||||
|
for (size_t i = 0; i < fast_size;) {
|
||||||
|
uint32_t sextet_a = get_sextet(i++);
|
||||||
|
uint32_t sextet_b = get_sextet(i++);
|
||||||
|
uint32_t sextet_c = get_sextet(i++);
|
||||||
|
uint32_t sextet_d = get_sextet(i++);
|
||||||
|
|
||||||
|
uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
|
||||||
|
|
||||||
|
res += static_cast<char>((triple >> 2 * 8) & 0xFFU);
|
||||||
|
res += static_cast<char>((triple >> 1 * 8) & 0xFFU);
|
||||||
|
res += static_cast<char>((triple >> 0 * 8) & 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fill_cnt == 0) return res;
|
||||||
|
|
||||||
|
uint32_t triple = (get_sextet(fast_size) << 3 * 6) + (get_sextet(fast_size + 1) << 2 * 6);
|
||||||
|
|
||||||
|
switch (fill_cnt) {
|
||||||
|
case 1:
|
||||||
|
triple |= (get_sextet(fast_size + 2) << 1 * 6);
|
||||||
|
res += static_cast<char>((triple >> 2 * 8) & 0xFFU);
|
||||||
|
res += static_cast<char>((triple >> 1 * 8) & 0xFFU);
|
||||||
|
break;
|
||||||
|
case 2: res += static_cast<char>((triple >> 2 * 8) & 0xFFU); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string pad(const std::string& base, const std::string& fill) {
|
||||||
|
std::string padding;
|
||||||
|
switch (base.size() % 4) {
|
||||||
|
case 1: padding += fill; JWT_FALLTHROUGH;
|
||||||
|
case 2: padding += fill; JWT_FALLTHROUGH;
|
||||||
|
case 3: padding += fill; JWT_FALLTHROUGH;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base + padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string trim(const std::string& base, const std::string& fill) {
|
||||||
|
auto pos = base.find(fill);
|
||||||
|
return base.substr(0, pos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif
|
3671
src/jwt-cpp/jwt.h
Normal file
3671
src/jwt-cpp/jwt.h
Normal file
File diff suppressed because it is too large
Load Diff
88
src/jwt-cpp/traits/boost-json/defaults.h
Normal file
88
src/jwt-cpp/traits/boost-json/defaults.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef JWT_CPP_BOOST_JSON_DEFAULTS_H
|
||||||
|
#define JWT_CPP_BOOST_JSON_DEFAULTS_H
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_PICOJSON
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "traits.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief a class to store a generic [Boost.JSON](https://github.com/boostorg/json) value as claim
|
||||||
|
*
|
||||||
|
* This type is the specialization of the \ref basic_claim class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using claim = basic_claim<traits::boost_json>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a verifier using the default clock
|
||||||
|
* \return verifier instance
|
||||||
|
*/
|
||||||
|
inline verifier<default_clock, traits::boost_json> verify() {
|
||||||
|
return verify<default_clock, traits::boost_json>(default_clock{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a builder instance to create a new token
|
||||||
|
*/
|
||||||
|
inline builder<traits::boost_json> create() { return builder<traits::boost_json>(); }
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_BASE64
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \param token Token to decode
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
inline decoded_jwt<traits::boost_json> decode(const std::string& token) {
|
||||||
|
return decoded_jwt<traits::boost_json>(token);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \tparam Decode is callabled, taking a string_type and returns a string_type.
|
||||||
|
* It should ensure the padding of the input and then base64url decode and
|
||||||
|
* return the results.
|
||||||
|
* \param token Token to decode
|
||||||
|
* \param decode The token to parse
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
template<typename Decode>
|
||||||
|
decoded_jwt<traits::boost_json> decode(const std::string& token, Decode decode) {
|
||||||
|
return decoded_jwt<traits::boost_json>(token, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwk
|
||||||
|
* \param token JWK Token to parse
|
||||||
|
* \return Parsed JWK
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwk<traits::boost_json> parse_jwk(const traits::boost_json::string_type& token) {
|
||||||
|
return jwk<traits::boost_json>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwks
|
||||||
|
* \param token JWKs Token to parse
|
||||||
|
* \return Parsed JWKs
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwks<traits::boost_json> parse_jwks(const traits::boost_json::string_type& token) {
|
||||||
|
return jwks<traits::boost_json>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is the specialization of the \ref verify_ops::verify_context class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using verify_context = verify_ops::verify_context<traits::boost_json>;
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_BOOST_JSON_DEFAULTS_H
|
80
src/jwt-cpp/traits/boost-json/traits.h
Normal file
80
src/jwt-cpp/traits/boost-json/traits.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef JWT_CPP_BOOSTJSON_TRAITS_H
|
||||||
|
#define JWT_CPP_BOOSTJSON_TRAITS_H
|
||||||
|
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#include "jwt-cpp/jwt.h"
|
||||||
|
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
// if not boost JSON standalone then error...
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
namespace traits {
|
||||||
|
namespace json = boost::json;
|
||||||
|
struct boost_json {
|
||||||
|
using value_type = json::value;
|
||||||
|
using object_type = json::object;
|
||||||
|
using array_type = json::array;
|
||||||
|
using string_type = std::string;
|
||||||
|
using number_type = double;
|
||||||
|
using integer_type = std::int64_t;
|
||||||
|
using boolean_type = bool;
|
||||||
|
|
||||||
|
static jwt::json::type get_type(const value_type& val) {
|
||||||
|
using jwt::json::type;
|
||||||
|
|
||||||
|
if (val.kind() == json::kind::bool_) return type::boolean;
|
||||||
|
if (val.kind() == json::kind::int64) return type::integer;
|
||||||
|
if (val.kind() == json::kind::uint64) // boost internally tracks two types of integers
|
||||||
|
return type::integer;
|
||||||
|
if (val.kind() == json::kind::double_) return type::number;
|
||||||
|
if (val.kind() == json::kind::string) return type::string;
|
||||||
|
if (val.kind() == json::kind::array) return type::array;
|
||||||
|
if (val.kind() == json::kind::object) return type::object;
|
||||||
|
|
||||||
|
throw std::logic_error("invalid type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static object_type as_object(const value_type& val) {
|
||||||
|
if (val.kind() != json::kind::object) throw std::bad_cast();
|
||||||
|
return val.get_object();
|
||||||
|
}
|
||||||
|
|
||||||
|
static array_type as_array(const value_type& val) {
|
||||||
|
if (val.kind() != json::kind::array) throw std::bad_cast();
|
||||||
|
return val.get_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
static string_type as_string(const value_type& val) {
|
||||||
|
if (val.kind() != json::kind::string) throw std::bad_cast();
|
||||||
|
return string_type{val.get_string()};
|
||||||
|
}
|
||||||
|
|
||||||
|
static integer_type as_int(const value_type& val) {
|
||||||
|
switch (val.kind()) {
|
||||||
|
case json::kind::int64: return val.get_int64();
|
||||||
|
case json::kind::uint64: return static_cast<int64_t>(val.get_uint64());
|
||||||
|
default: throw std::bad_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean_type as_bool(const value_type& val) {
|
||||||
|
if (val.kind() != json::kind::bool_) throw std::bad_cast();
|
||||||
|
return val.get_bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
static number_type as_number(const value_type& val) {
|
||||||
|
if (val.kind() != json::kind::double_) throw std::bad_cast();
|
||||||
|
return val.get_double();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse(value_type& val, string_type str) {
|
||||||
|
val = json::parse(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string serialize(const value_type& val) { return json::serialize(val); }
|
||||||
|
};
|
||||||
|
} // namespace traits
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_BOOSTJSON_TRAITS_H
|
88
src/jwt-cpp/traits/danielaparker-jsoncons/defaults.h
Normal file
88
src/jwt-cpp/traits/danielaparker-jsoncons/defaults.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
|
||||||
|
#define JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_PICOJSON
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "traits.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief a class to store a generic [jsoncons](https://github.com/danielaparker/jsoncons) value as claim
|
||||||
|
*
|
||||||
|
* This type is the specialization of the \ref basic_claim class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using claim = basic_claim<traits::danielaparker_jsoncons>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a verifier using the default clock
|
||||||
|
* \return verifier instance
|
||||||
|
*/
|
||||||
|
inline verifier<default_clock, traits::danielaparker_jsoncons> verify() {
|
||||||
|
return verify<default_clock, traits::danielaparker_jsoncons>(default_clock{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a builder instance to create a new token
|
||||||
|
*/
|
||||||
|
inline builder<traits::danielaparker_jsoncons> create() { return builder<traits::danielaparker_jsoncons>(); }
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_BASE64
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \param token Token to decode
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
inline decoded_jwt<traits::danielaparker_jsoncons> decode(const std::string& token) {
|
||||||
|
return decoded_jwt<traits::danielaparker_jsoncons>(token);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \tparam Decode is callabled, taking a string_type and returns a string_type.
|
||||||
|
* It should ensure the padding of the input and then base64url decode and
|
||||||
|
* return the results.
|
||||||
|
* \param token Token to decode
|
||||||
|
* \param decode The token to parse
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
template<typename Decode>
|
||||||
|
decoded_jwt<traits::danielaparker_jsoncons> decode(const std::string& token, Decode decode) {
|
||||||
|
return decoded_jwt<traits::danielaparker_jsoncons>(token, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwk
|
||||||
|
* \param token JWK Token to parse
|
||||||
|
* \return Parsed JWK
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwk<traits::danielaparker_jsoncons> parse_jwk(const traits::danielaparker_jsoncons::string_type& token) {
|
||||||
|
return jwk<traits::danielaparker_jsoncons>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwks
|
||||||
|
* \param token JWKs Token to parse
|
||||||
|
* \return Parsed JWKs
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwks<traits::danielaparker_jsoncons> parse_jwks(const traits::danielaparker_jsoncons::string_type& token) {
|
||||||
|
return jwks<traits::danielaparker_jsoncons>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is the specialization of the \ref verify_ops::verify_context class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using verify_context = verify_ops::verify_context<traits::danielaparker_jsoncons>;
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
|
123
src/jwt-cpp/traits/danielaparker-jsoncons/traits.h
Normal file
123
src/jwt-cpp/traits/danielaparker-jsoncons/traits.h
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#define JSONCONS_NO_DEPRECATED
|
||||||
|
|
||||||
|
#include "jwt-cpp/jwt.h"
|
||||||
|
|
||||||
|
#include "jsoncons/json.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
namespace traits {
|
||||||
|
struct danielaparker_jsoncons {
|
||||||
|
// Needs at least https://github.com/danielaparker/jsoncons/commit/28c56b90ec7337f98a5b8942574590111a5e5831
|
||||||
|
static_assert(jsoncons::version().minor >= 167, "A higher version of jsoncons is required!");
|
||||||
|
|
||||||
|
using json = jsoncons::json;
|
||||||
|
using value_type = json;
|
||||||
|
struct object_type : json::object {
|
||||||
|
// Add missing C++11 member types
|
||||||
|
// https://github.com/danielaparker/jsoncons/commit/1b1ceeb572f9a2db6d37cff47ac78a4f14e072e2#commitcomment-45391411
|
||||||
|
using value_type = key_value_type; // Enable optional jwt-cpp methods
|
||||||
|
using mapped_type = key_value_type::value_type;
|
||||||
|
using size_type = size_t; // for implementing count
|
||||||
|
|
||||||
|
object_type() = default;
|
||||||
|
object_type(const object_type&) = default;
|
||||||
|
explicit object_type(const json::object& o) : json::object(o) {}
|
||||||
|
object_type(object_type&&) = default;
|
||||||
|
explicit object_type(json::object&& o) : json::object(o) {}
|
||||||
|
~object_type() = default;
|
||||||
|
object_type& operator=(const object_type& o) = default;
|
||||||
|
object_type& operator=(object_type&& o) noexcept = default;
|
||||||
|
|
||||||
|
// Add missing C++11 subscription operator
|
||||||
|
mapped_type& operator[](const key_type& key) {
|
||||||
|
// https://github.com/microsoft/STL/blob/2914b4301c59dc7ffc09d16ac6f7979fde2b7f2c/stl/inc/map#L325
|
||||||
|
return try_emplace(key).first->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing C++11 element access
|
||||||
|
const mapped_type& at(const key_type& key) const {
|
||||||
|
auto target = find(key);
|
||||||
|
if (target != end()) return target->value();
|
||||||
|
|
||||||
|
throw std::out_of_range("invalid key");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing C++11 lookup method
|
||||||
|
size_type count(const key_type& key) const {
|
||||||
|
struct compare {
|
||||||
|
bool operator()(const value_type& val, const key_type& key) const { return val.key() < key; }
|
||||||
|
bool operator()(const key_type& key, const value_type& val) const { return key < val.key(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://en.cppreference.com/w/cpp/algorithm/binary_search#Complexity
|
||||||
|
if (std::binary_search(this->begin(), this->end(), key, compare{})) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using array_type = json::array;
|
||||||
|
using string_type = std::string; // current limitation of traits implementation
|
||||||
|
using number_type = double;
|
||||||
|
using integer_type = int64_t;
|
||||||
|
using boolean_type = bool;
|
||||||
|
|
||||||
|
static jwt::json::type get_type(const json& val) {
|
||||||
|
using jwt::json::type;
|
||||||
|
|
||||||
|
if (val.type() == jsoncons::json_type::bool_value) return type::boolean;
|
||||||
|
if (val.type() == jsoncons::json_type::int64_value) return type::integer;
|
||||||
|
if (val.type() == jsoncons::json_type::uint64_value) return type::integer;
|
||||||
|
if (val.type() == jsoncons::json_type::half_value) return type::number;
|
||||||
|
if (val.type() == jsoncons::json_type::double_value) return type::number;
|
||||||
|
if (val.type() == jsoncons::json_type::string_value) return type::string;
|
||||||
|
if (val.type() == jsoncons::json_type::array_value) return type::array;
|
||||||
|
if (val.type() == jsoncons::json_type::object_value) return type::object;
|
||||||
|
|
||||||
|
throw std::logic_error("invalid type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static object_type as_object(const json& val) {
|
||||||
|
if (val.type() != jsoncons::json_type::object_value) throw std::bad_cast();
|
||||||
|
return object_type(val.object_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
static array_type as_array(const json& val) {
|
||||||
|
if (val.type() != jsoncons::json_type::array_value) throw std::bad_cast();
|
||||||
|
return val.array_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
static string_type as_string(const json& val) {
|
||||||
|
if (val.type() != jsoncons::json_type::string_value) throw std::bad_cast();
|
||||||
|
return val.as_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
static number_type as_number(const json& val) {
|
||||||
|
if (get_type(val) != jwt::json::type::number) throw std::bad_cast();
|
||||||
|
return val.as_double();
|
||||||
|
}
|
||||||
|
|
||||||
|
static integer_type as_int(const json& val) {
|
||||||
|
if (get_type(val) != jwt::json::type::integer) throw std::bad_cast();
|
||||||
|
return val.as<integer_type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean_type as_bool(const json& val) {
|
||||||
|
if (val.type() != jsoncons::json_type::bool_value) throw std::bad_cast();
|
||||||
|
return val.as_bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse(json& val, const std::string& str) {
|
||||||
|
val = json::parse(str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string serialize(const json& val) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << jsoncons::print(val);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace traits
|
||||||
|
} // namespace jwt
|
90
src/jwt-cpp/traits/defaults.h.mustache
Normal file
90
src/jwt-cpp/traits/defaults.h.mustache
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#ifndef JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
|
||||||
|
#define JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
|
||||||
|
{{#disable_default_traits}}
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_PICOJSON
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#endif
|
||||||
|
{{/disable_default_traits}}
|
||||||
|
|
||||||
|
#include "traits.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief a class to store a generic [{{library_name}}]({{{library_url}}}) value as claim
|
||||||
|
*
|
||||||
|
* This type is the specialization of the \ref basic_claim class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using claim = basic_claim<traits::{{traits_name}}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a verifier using the default clock
|
||||||
|
* \return verifier instance
|
||||||
|
*/
|
||||||
|
inline verifier<default_clock, traits::{{traits_name}}> verify() {
|
||||||
|
return verify<default_clock, traits::{{traits_name}}>(default_clock{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a builder instance to create a new token
|
||||||
|
*/
|
||||||
|
inline builder<traits::{{traits_name}}> create() { return builder<traits::{{traits_name}}>(); }
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_BASE64
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \param token Token to decode
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
inline decoded_jwt<traits::{{traits_name}}> decode(const std::string& token) {
|
||||||
|
return decoded_jwt<traits::{{traits_name}}>(token);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \tparam Decode is callabled, taking a string_type and returns a string_type.
|
||||||
|
* It should ensure the padding of the input and then base64url decode and
|
||||||
|
* return the results.
|
||||||
|
* \param token Token to decode
|
||||||
|
* \param decode The token to parse
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
template<typename Decode>
|
||||||
|
decoded_jwt<traits::{{traits_name}}> decode(const std::string& token, Decode decode) {
|
||||||
|
return decoded_jwt<traits::{{traits_name}}>(token, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwk
|
||||||
|
* \param token JWK Token to parse
|
||||||
|
* \return Parsed JWK
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwk<traits::{{traits_name}}> parse_jwk(const traits::{{traits_name}}::string_type& token) {
|
||||||
|
return jwk<traits::{{traits_name}}>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwks
|
||||||
|
* \param token JWKs Token to parse
|
||||||
|
* \return Parsed JWKs
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwks<traits::{{traits_name}}> parse_jwks(const traits::{{traits_name}}::string_type& token) {
|
||||||
|
return jwks<traits::{{traits_name}}>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is the specialization of the \ref verify_ops::verify_context class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using verify_context = verify_ops::verify_context<traits::{{traits_name}}>;
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
|
84
src/jwt-cpp/traits/kazuho-picojson/defaults.h
Normal file
84
src/jwt-cpp/traits/kazuho-picojson/defaults.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
|
||||||
|
#define JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
|
||||||
|
|
||||||
|
#include "traits.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief a class to store a generic [picojson](https://github.com/kazuho/picojson) value as claim
|
||||||
|
*
|
||||||
|
* This type is the specialization of the \ref basic_claim class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using claim = basic_claim<traits::kazuho_picojson>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a verifier using the default clock
|
||||||
|
* \return verifier instance
|
||||||
|
*/
|
||||||
|
inline verifier<default_clock, traits::kazuho_picojson> verify() {
|
||||||
|
return verify<default_clock, traits::kazuho_picojson>(default_clock{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a builder instance to create a new token
|
||||||
|
*/
|
||||||
|
inline builder<traits::kazuho_picojson> create() { return builder<traits::kazuho_picojson>(); }
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_BASE64
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \param token Token to decode
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
inline decoded_jwt<traits::kazuho_picojson> decode(const std::string& token) {
|
||||||
|
return decoded_jwt<traits::kazuho_picojson>(token);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \tparam Decode is callabled, taking a string_type and returns a string_type.
|
||||||
|
* It should ensure the padding of the input and then base64url decode and
|
||||||
|
* return the results.
|
||||||
|
* \param token Token to decode
|
||||||
|
* \param decode The token to parse
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
template<typename Decode>
|
||||||
|
decoded_jwt<traits::kazuho_picojson> decode(const std::string& token, Decode decode) {
|
||||||
|
return decoded_jwt<traits::kazuho_picojson>(token, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwk
|
||||||
|
* \param token JWK Token to parse
|
||||||
|
* \return Parsed JWK
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwk<traits::kazuho_picojson> parse_jwk(const traits::kazuho_picojson::string_type& token) {
|
||||||
|
return jwk<traits::kazuho_picojson>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwks
|
||||||
|
* \param token JWKs Token to parse
|
||||||
|
* \return Parsed JWKs
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwks<traits::kazuho_picojson> parse_jwks(const traits::kazuho_picojson::string_type& token) {
|
||||||
|
return jwks<traits::kazuho_picojson>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is the specialization of the \ref verify_ops::verify_context class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using verify_context = verify_ops::verify_context<traits::kazuho_picojson>;
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
|
76
src/jwt-cpp/traits/kazuho-picojson/traits.h
Normal file
76
src/jwt-cpp/traits/kazuho-picojson/traits.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#ifndef JWT_CPP_PICOJSON_TRAITS_H
|
||||||
|
#define JWT_CPP_PICOJSON_TRAITS_H
|
||||||
|
|
||||||
|
#ifndef PICOJSON_USE_INT64
|
||||||
|
#define PICOJSON_USE_INT64
|
||||||
|
#endif
|
||||||
|
#include "picojson/picojson.h"
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_PICOJSON
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#endif
|
||||||
|
#include "jwt-cpp/jwt.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
namespace traits {
|
||||||
|
struct kazuho_picojson {
|
||||||
|
using value_type = picojson::value;
|
||||||
|
using object_type = picojson::object;
|
||||||
|
using array_type = picojson::array;
|
||||||
|
using string_type = std::string;
|
||||||
|
using number_type = double;
|
||||||
|
using integer_type = int64_t;
|
||||||
|
using boolean_type = bool;
|
||||||
|
|
||||||
|
static json::type get_type(const picojson::value& val) {
|
||||||
|
using json::type;
|
||||||
|
if (val.is<bool>()) return type::boolean;
|
||||||
|
if (val.is<int64_t>()) return type::integer;
|
||||||
|
if (val.is<double>()) return type::number;
|
||||||
|
if (val.is<std::string>()) return type::string;
|
||||||
|
if (val.is<picojson::array>()) return type::array;
|
||||||
|
if (val.is<picojson::object>()) return type::object;
|
||||||
|
|
||||||
|
throw std::logic_error("invalid type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static picojson::object as_object(const picojson::value& val) {
|
||||||
|
if (!val.is<picojson::object>()) throw std::bad_cast();
|
||||||
|
return val.get<picojson::object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string as_string(const picojson::value& val) {
|
||||||
|
if (!val.is<std::string>()) throw std::bad_cast();
|
||||||
|
return val.get<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static picojson::array as_array(const picojson::value& val) {
|
||||||
|
if (!val.is<picojson::array>()) throw std::bad_cast();
|
||||||
|
return val.get<picojson::array>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t as_int(const picojson::value& val) {
|
||||||
|
if (!val.is<int64_t>()) throw std::bad_cast();
|
||||||
|
return val.get<int64_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool as_bool(const picojson::value& val) {
|
||||||
|
if (!val.is<bool>()) throw std::bad_cast();
|
||||||
|
return val.get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static double as_number(const picojson::value& val) {
|
||||||
|
if (!val.is<double>()) throw std::bad_cast();
|
||||||
|
return val.get<double>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse(picojson::value& val, const std::string& str) {
|
||||||
|
return picojson::parse(val, str).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string serialize(const picojson::value& val) { return val.serialize(); }
|
||||||
|
};
|
||||||
|
} // namespace traits
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif
|
88
src/jwt-cpp/traits/nlohmann-json/defaults.h
Normal file
88
src/jwt-cpp/traits/nlohmann-json/defaults.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
|
||||||
|
#define JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_PICOJSON
|
||||||
|
#define JWT_DISABLE_PICOJSON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "traits.h"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
/**
|
||||||
|
* \brief a class to store a generic [JSON for Modern C++](https://github.com/nlohmann/json) value as claim
|
||||||
|
*
|
||||||
|
* This type is the specialization of the \ref basic_claim class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using claim = basic_claim<traits::nlohmann_json>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a verifier using the default clock
|
||||||
|
* \return verifier instance
|
||||||
|
*/
|
||||||
|
inline verifier<default_clock, traits::nlohmann_json> verify() {
|
||||||
|
return verify<default_clock, traits::nlohmann_json>(default_clock{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a builder instance to create a new token
|
||||||
|
*/
|
||||||
|
inline builder<traits::nlohmann_json> create() { return builder<traits::nlohmann_json>(); }
|
||||||
|
|
||||||
|
#ifndef JWT_DISABLE_BASE64
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \param token Token to decode
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
inline decoded_jwt<traits::nlohmann_json> decode(const std::string& token) {
|
||||||
|
return decoded_jwt<traits::nlohmann_json>(token);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a token
|
||||||
|
* \tparam Decode is callabled, taking a string_type and returns a string_type.
|
||||||
|
* It should ensure the padding of the input and then base64url decode and
|
||||||
|
* return the results.
|
||||||
|
* \param token Token to decode
|
||||||
|
* \param decode The token to parse
|
||||||
|
* \return Decoded token
|
||||||
|
* \throw std::invalid_argument Token is not in correct format
|
||||||
|
* \throw std::runtime_error Base64 decoding failed or invalid json
|
||||||
|
*/
|
||||||
|
template<typename Decode>
|
||||||
|
decoded_jwt<traits::nlohmann_json> decode(const std::string& token, Decode decode) {
|
||||||
|
return decoded_jwt<traits::nlohmann_json>(token, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwk
|
||||||
|
* \param token JWK Token to parse
|
||||||
|
* \return Parsed JWK
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwk<traits::nlohmann_json> parse_jwk(const traits::nlohmann_json::string_type& token) {
|
||||||
|
return jwk<traits::nlohmann_json>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a jwks
|
||||||
|
* \param token JWKs Token to parse
|
||||||
|
* \return Parsed JWKs
|
||||||
|
* \throw std::runtime_error Token is not in correct format
|
||||||
|
*/
|
||||||
|
inline jwks<traits::nlohmann_json> parse_jwks(const traits::nlohmann_json::string_type& token) {
|
||||||
|
return jwks<traits::nlohmann_json>(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is the specialization of the \ref verify_ops::verify_context class which
|
||||||
|
* uses the standard template types.
|
||||||
|
*/
|
||||||
|
using verify_context = verify_ops::verify_context<traits::nlohmann_json>;
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif // JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
|
77
src/jwt-cpp/traits/nlohmann-json/traits.h
Normal file
77
src/jwt-cpp/traits/nlohmann-json/traits.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#ifndef JWT_CPP_NLOHMANN_JSON_TRAITS_H
|
||||||
|
#define JWT_CPP_NLOHMANN_JSON_TRAITS_H
|
||||||
|
|
||||||
|
#include "jwt-cpp/jwt.h"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
namespace traits {
|
||||||
|
struct nlohmann_json {
|
||||||
|
using json = nlohmann::json;
|
||||||
|
using value_type = json;
|
||||||
|
using object_type = json::object_t;
|
||||||
|
using array_type = json::array_t;
|
||||||
|
using string_type = std::string; // current limitation of traits implementation
|
||||||
|
using number_type = json::number_float_t;
|
||||||
|
using integer_type = json::number_integer_t;
|
||||||
|
using boolean_type = json::boolean_t;
|
||||||
|
|
||||||
|
static jwt::json::type get_type(const json& val) {
|
||||||
|
using jwt::json::type;
|
||||||
|
|
||||||
|
if (val.type() == json::value_t::boolean) return type::boolean;
|
||||||
|
// nlohmann internally tracks two types of integers
|
||||||
|
if (val.type() == json::value_t::number_integer) return type::integer;
|
||||||
|
if (val.type() == json::value_t::number_unsigned) return type::integer;
|
||||||
|
if (val.type() == json::value_t::number_float) return type::number;
|
||||||
|
if (val.type() == json::value_t::string) return type::string;
|
||||||
|
if (val.type() == json::value_t::array) return type::array;
|
||||||
|
if (val.type() == json::value_t::object) return type::object;
|
||||||
|
|
||||||
|
throw std::logic_error("invalid type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static json::object_t as_object(const json& val) {
|
||||||
|
if (val.type() != json::value_t::object) throw std::bad_cast();
|
||||||
|
return val.get<json::object_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string as_string(const json& val) {
|
||||||
|
if (val.type() != json::value_t::string) throw std::bad_cast();
|
||||||
|
return val.get<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static json::array_t as_array(const json& val) {
|
||||||
|
if (val.type() != json::value_t::array) throw std::bad_cast();
|
||||||
|
return val.get<json::array_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t as_int(const json& val) {
|
||||||
|
switch (val.type()) {
|
||||||
|
case json::value_t::number_integer:
|
||||||
|
case json::value_t::number_unsigned: return val.get<int64_t>();
|
||||||
|
default: throw std::bad_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool as_bool(const json& val) {
|
||||||
|
if (val.type() != json::value_t::boolean) throw std::bad_cast();
|
||||||
|
return val.get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static double as_number(const json& val) {
|
||||||
|
if (val.type() != json::value_t::number_float) throw std::bad_cast();
|
||||||
|
return val.get<double>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse(json& val, std::string str) {
|
||||||
|
val = json::parse(str.begin(), str.end());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string serialize(const json& val) { return val.dump(); }
|
||||||
|
};
|
||||||
|
} // namespace traits
|
||||||
|
} // namespace jwt
|
||||||
|
|
||||||
|
#endif
|
20
src/meson.build
Normal file
20
src/meson.build
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
inc += include_directories('.')
|
||||||
|
|
||||||
|
headers = []
|
||||||
|
|
||||||
|
sources = []
|
||||||
|
|
||||||
|
lib = library(
|
||||||
|
'jwt',
|
||||||
|
include_directories : inc,
|
||||||
|
sources: [headers, sources],
|
||||||
|
dependencies : deps,
|
||||||
|
cpp_args: args
|
||||||
|
)
|
||||||
|
|
||||||
|
jwt_dep = declare_dependency(
|
||||||
|
include_directories: inc,
|
||||||
|
link_with: lib,
|
||||||
|
)
|
||||||
|
|
||||||
|
deps += jwt_dep
|
25447
src/nlohmann/json.hpp
Normal file
25447
src/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1200
src/picojson/picojson.h
Normal file
1200
src/picojson/picojson.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user