Added decode error codes and exceptions

This commit is contained in:
Arun M 2017-12-04 13:17:48 +05:30
parent 234411a550
commit 9e69389caf
7 changed files with 131 additions and 18 deletions

View file

@ -282,7 +282,8 @@ std::string base64_uri_decode(const char* data, size_t len)
size_t i = 0;
for (; i < len; ++i) {
for (; i < len; ++i)
{
switch (data[i]) {
case '-':
uri_dec[i] = '+';

View file

@ -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(DecodeErrc err);
} // END namespace jwt
@ -37,6 +51,9 @@ namespace std
{
template <>
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"

View file

@ -29,6 +29,19 @@ private:
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

View file

@ -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
const AlgorithmErrCategory theAlgorithmErrCategory {};
const DecodeErrorCategory theDecodeErrorCategory {};
}
@ -42,6 +71,11 @@ std::error_code make_error_code(AlgorithmErrc err)
return { static_cast<int>(err), theAlgorithmErrCategory };
}
std::error_code make_error_code(DecodeErrc err)
{
return { static_cast<int>(err), theDecodeErrorCategory };
}
} // END namespace jwt

View file

@ -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);
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
auto alg_itr = obj.find("alg");
assert (alg_itr != obj.end() && "Algorithm header is missing");
std::error_code ec;
if (alg_itr == obj.end()) {
ec = DecodeErrc::AlgHeaderMiss;
return;
}
alg_ = str_to_alg(alg_itr.value().get<std::string>());
if (alg_ != algorithm::NONE) {
if (alg_ != algorithm::NONE)
{
auto itr = obj.find("typ");
if (itr == obj.end()) {
//TODO: set error code
ec = DecodeErrc::TypHeaderMiss;
return;
}
auto typ = itr.value().get<std::string>();
const auto& typ = itr.value().get<std::string>();
if (strcasecmp(typ.c_str(), "JWT")) {
//TODO: set error code
ec = DecodeErrc::TypMismatch;
return;
}
typ_ = str_to_type(typ);
} else {
//TODO:
}
return;
}
void jwt_payload::decode(const string_view enc_str)
void jwt_header::decode(const string_view enc_str) throw(DecodeError)
{
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);
try {
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;
}
@ -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);
//throws verification error
//throws decode error
jobj.header(jwt_header{parts[0]});
//throws verification error
//throws decode error
jobj.payload(jwt_payload{parts[1]});
jwt_signature jsign{key};

View file

@ -12,6 +12,7 @@
#include "jwt/algorithm.hpp"
#include "jwt/string_view.hpp"
#include "jwt/parameters.hpp"
#include "jwt/exceptions.hpp"
#include "jwt/json/json.hpp"
// For convenience
@ -237,9 +238,13 @@ public: // Exposed APIs
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);
void decode(const string_view enc_str, std::error_code& ec) noexcept;
/**
*/
void decode(const string_view enc_str) throw(DecodeError);
/**
*/

Binary file not shown.