mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-15 09:18:33 +00:00
Added decode error codes and exceptions
This commit is contained in:
parent
234411a550
commit
9e69389caf
7 changed files with 131 additions and 18 deletions
|
@ -282,7 +282,8 @@ std::string base64_uri_decode(const char* data, size_t len)
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
for (; i < len; ++i) {
|
for (; i < len; ++i)
|
||||||
|
{
|
||||||
switch (data[i]) {
|
switch (data[i]) {
|
||||||
case '-':
|
case '-':
|
||||||
uri_dec[i] = '+';
|
uri_dec[i] = '+';
|
||||||
|
|
|
@ -21,11 +21,25 @@ enum class AlgorithmFailureSource
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode error conditions
|
||||||
|
*/
|
||||||
|
enum class DecodeErrc
|
||||||
|
{
|
||||||
|
JsonParseError = 1,
|
||||||
|
AlgHeaderMiss,
|
||||||
|
TypHeaderMiss,
|
||||||
|
TypMismatch,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
std::error_code make_error_code(AlgorithmErrc err);
|
std::error_code make_error_code(AlgorithmErrc err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
std::error_code make_error_code(DecodeErrc err);
|
||||||
|
|
||||||
} // END namespace jwt
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +51,9 @@ namespace std
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct is_error_code_enum<jwt::AlgorithmErrc> : true_type {};
|
struct is_error_code_enum<jwt::AlgorithmErrc> : true_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct is_error_code_enum<jwt::DecodeErrc>: true_type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "jwt/impl/error_codes.ipp"
|
#include "jwt/impl/error_codes.ipp"
|
||||||
|
|
|
@ -29,6 +29,19 @@ private:
|
||||||
const char* msg_ = nullptr;
|
const char* msg_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class DecodeError final: public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
DecodeError(std::string msg)
|
||||||
|
: std::runtime_error(std::move(msg))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // END namespace jwt
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,38 @@ struct AlgorithmErrCategory: std::error_category
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
struct DecodeErrorCategory: std::error_category
|
||||||
|
{
|
||||||
|
const char* name() const noexcept override
|
||||||
|
{
|
||||||
|
return "decode";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string message(int ev) const override
|
||||||
|
{
|
||||||
|
switch (static_cast<DecodeErrc>(ev))
|
||||||
|
{
|
||||||
|
case DecodeErrc::AlgHeaderMiss:
|
||||||
|
return "missing algorithm header";
|
||||||
|
case DecodeErrc::TypHeaderMiss:
|
||||||
|
return "missing type header";
|
||||||
|
case DecodeErrc::TypMismatch:
|
||||||
|
return "type mismatch";
|
||||||
|
case DecodeErrc::JsonParseError:
|
||||||
|
return "json parse failed";
|
||||||
|
};
|
||||||
|
|
||||||
|
assert (0 && "Code not reached");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Create global object for the error categories
|
// Create global object for the error categories
|
||||||
const AlgorithmErrCategory theAlgorithmErrCategory {};
|
const AlgorithmErrCategory theAlgorithmErrCategory {};
|
||||||
|
|
||||||
|
const DecodeErrorCategory theDecodeErrorCategory {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,6 +71,11 @@ std::error_code make_error_code(AlgorithmErrc err)
|
||||||
return { static_cast<int>(err), theAlgorithmErrCategory };
|
return { static_cast<int>(err), theAlgorithmErrCategory };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::error_code make_error_code(DecodeErrc err)
|
||||||
|
{
|
||||||
|
return { static_cast<int>(err), theDecodeErrorCategory };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // END namespace jwt
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
|
@ -36,40 +36,80 @@ std::ostream& operator<< (std::ostream& os, const T& obj)
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
void jwt_header::decode(const string_view enc_str)
|
void jwt_header::decode(const string_view enc_str, std::error_code& ec) noexcept
|
||||||
{
|
{
|
||||||
|
ec.clear();
|
||||||
std::string json_str = base64_decode(enc_str);
|
std::string json_str = base64_decode(enc_str);
|
||||||
json_t obj = json_t::parse(std::move(json_str));
|
json_t obj;
|
||||||
|
|
||||||
|
try {
|
||||||
|
obj = json_t::parse(std::move(json_str));
|
||||||
|
} catch(const std::exception& e) {
|
||||||
|
ec = DecodeErrc::JsonParseError;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Look for the algorithm field
|
//Look for the algorithm field
|
||||||
auto alg_itr = obj.find("alg");
|
auto alg_itr = obj.find("alg");
|
||||||
assert (alg_itr != obj.end() && "Algorithm header is missing");
|
if (alg_itr == obj.end()) {
|
||||||
std::error_code ec;
|
ec = DecodeErrc::AlgHeaderMiss;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
alg_ = str_to_alg(alg_itr.value().get<std::string>());
|
alg_ = str_to_alg(alg_itr.value().get<std::string>());
|
||||||
|
|
||||||
if (alg_ != algorithm::NONE) {
|
if (alg_ != algorithm::NONE)
|
||||||
|
{
|
||||||
auto itr = obj.find("typ");
|
auto itr = obj.find("typ");
|
||||||
if (itr == obj.end()) {
|
if (itr == obj.end()) {
|
||||||
//TODO: set error code
|
ec = DecodeErrc::TypHeaderMiss;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto typ = itr.value().get<std::string>();
|
|
||||||
|
const auto& typ = itr.value().get<std::string>();
|
||||||
if (strcasecmp(typ.c_str(), "JWT")) {
|
if (strcasecmp(typ.c_str(), "JWT")) {
|
||||||
//TODO: set error code
|
ec = DecodeErrc::TypMismatch;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typ_ = str_to_type(typ);
|
typ_ = str_to_type(typ);
|
||||||
|
} else {
|
||||||
|
//TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jwt_header::decode(const string_view enc_str) throw(DecodeError)
|
||||||
void jwt_payload::decode(const string_view enc_str)
|
|
||||||
{
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
decode(enc_str, ec);
|
||||||
|
if (ec) {
|
||||||
|
throw DecodeError(ec.message());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void jwt_payload::decode(const string_view enc_str, std::error_code& ec) noexcept
|
||||||
|
{
|
||||||
|
ec.clear();
|
||||||
std::string json_str = base64_decode(enc_str);
|
std::string json_str = base64_decode(enc_str);
|
||||||
|
try {
|
||||||
payload_ = json_t::parse(std::move(json_str));
|
payload_ = json_t::parse(std::move(json_str));
|
||||||
|
} catch(const std::exception& e) {
|
||||||
|
ec = DecodeErrc::JsonParseError;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void jwt_payload::decode(const string_view enc_str) throw(DecodeError)
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
decode(enc_str, ec);
|
||||||
|
if (ec) {
|
||||||
|
throw DecodeError(ec.message());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,9 +346,9 @@ jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool
|
||||||
|
|
||||||
auto parts = jwt_object::three_parts(encoded_str);
|
auto parts = jwt_object::three_parts(encoded_str);
|
||||||
|
|
||||||
//throws verification error
|
//throws decode error
|
||||||
jobj.header(jwt_header{parts[0]});
|
jobj.header(jwt_header{parts[0]});
|
||||||
//throws verification error
|
//throws decode error
|
||||||
jobj.payload(jwt_payload{parts[1]});
|
jobj.payload(jwt_payload{parts[1]});
|
||||||
|
|
||||||
jwt_signature jsign{key};
|
jwt_signature jsign{key};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "jwt/algorithm.hpp"
|
#include "jwt/algorithm.hpp"
|
||||||
#include "jwt/string_view.hpp"
|
#include "jwt/string_view.hpp"
|
||||||
#include "jwt/parameters.hpp"
|
#include "jwt/parameters.hpp"
|
||||||
|
#include "jwt/exceptions.hpp"
|
||||||
#include "jwt/json/json.hpp"
|
#include "jwt/json/json.hpp"
|
||||||
|
|
||||||
// For convenience
|
// For convenience
|
||||||
|
@ -237,9 +238,13 @@ public: // Exposed APIs
|
||||||
return base64_encode(pprint);
|
return base64_encode(pprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
*/
|
*/
|
||||||
void decode(const string_view enc_str);
|
void decode(const string_view enc_str, std::error_code& ec) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
void decode(const string_view enc_str) throw(DecodeError);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*/
|
*/
|
||||||
|
@ -350,8 +355,11 @@ public: // Exposed APIs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
//TODO: what about error_code ?
|
void decode(const string_view enc_str, std::error_code& ec) noexcept;
|
||||||
void decode(const string_view enc_str);
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
void decode(const string_view enc_str) throw(DecodeError);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue