mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-14 16:58:34 +00:00
Code cleanup around jwt_object creation in decode step
This commit is contained in:
parent
cb925fee3a
commit
ffd6280026
3 changed files with 165 additions and 30 deletions
|
@ -211,6 +211,9 @@ template <typename Map, typename... Rest>
|
|||
void jwt_object::set_parameters(
|
||||
params::detail::payload_param<Map>&& payload, Rest&&... rargs)
|
||||
{
|
||||
for (const auto& elem : payload.get()) {
|
||||
payload_.add_claim(std::move(elem.first), std::move(elem.second));
|
||||
}
|
||||
set_parameters(std::forward<Rest>(rargs)...);
|
||||
}
|
||||
|
||||
|
@ -218,6 +221,7 @@ template <typename... Rest>
|
|||
void jwt_object::set_parameters(
|
||||
params::detail::secret_param secret, Rest&&... rargs)
|
||||
{
|
||||
secret_.assign(secret.get().data(), secret.get().length());
|
||||
set_parameters(std::forward<Rest>(rargs)...);
|
||||
}
|
||||
|
||||
|
@ -225,6 +229,7 @@ template <typename Map, typename... Rest>
|
|||
void jwt_object::set_parameters(
|
||||
params::detail::headers_param<Map>&& header, Rest&&... rargs)
|
||||
{
|
||||
//TODO: add kid support
|
||||
set_parameters(std::forward<Rest>(rargs)...);
|
||||
}
|
||||
|
||||
|
@ -235,37 +240,72 @@ void jwt_object::set_parameters()
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
jwt_payload& jwt_object::add_payload(const std::string& name, T&& value)
|
||||
jwt_payload& jwt_object::add_claim(const std::string& name, T&& value)
|
||||
{
|
||||
payload_.add_claim(name, std::forward<T>(value));
|
||||
return payload_;
|
||||
}
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
void jwt_decode(const string_view encoded_str, const string_view key, bool validate)
|
||||
jwt_payload& jwt_object::remove_claim(const std::string& name)
|
||||
{
|
||||
//TODO: implement error_code
|
||||
size_t fpos = encoded_str.find_first_of('.');
|
||||
payload_.remove_claim(name);
|
||||
return payload_;
|
||||
}
|
||||
|
||||
std::string jwt_object::signature() const
|
||||
{
|
||||
jwt_signature jws{secret_};
|
||||
|
||||
return jws.encode(header_, payload_);
|
||||
}
|
||||
|
||||
|
||||
std::array<string_view, 3>
|
||||
jwt_object::three_parts(const string_view enc_str)
|
||||
{
|
||||
std::array<string_view, 3> result;
|
||||
|
||||
size_t fpos = enc_str.find_first_of('.');
|
||||
assert (fpos != string_view::npos);
|
||||
|
||||
string_view head{&encoded_str[0], fpos};
|
||||
jwt_header hdr;
|
||||
hdr.decode(head);
|
||||
result[0] = string_view{&enc_str[0], fpos};
|
||||
|
||||
size_t spos = encoded_str.find_first_of('.', fpos + 1);
|
||||
size_t spos = enc_str.find_first_of('.', fpos + 1);
|
||||
if (spos == string_view::npos) {
|
||||
//TODO: Check for none algorithm
|
||||
}
|
||||
string_view body{&encoded_str[fpos + 1], spos - fpos - 1};
|
||||
|
||||
//Json objects or claims get set in the decode
|
||||
jwt_payload pld;
|
||||
pld.decode(body);
|
||||
result[1] = string_view{&enc_str[fpos + 1], spos - fpos - 1};
|
||||
|
||||
size_t tpos = enc_str.find_first_of('.', spos + 1);
|
||||
|
||||
if (tpos != string_view::npos) {
|
||||
result[2] = string_view{&enc_str[tpos + 1], tpos - spos - 1};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool validate)
|
||||
{
|
||||
//TODO: implement error_code
|
||||
jwt_object jobj;
|
||||
|
||||
auto parts = jwt_object::three_parts(encoded_str);
|
||||
|
||||
jobj.header(jwt_header{parts[0]});
|
||||
jobj.payload(jwt_payload{parts[1]});
|
||||
|
||||
jwt_signature jsign{key};
|
||||
jsign.verify(hdr, encoded_str.substr(0, spos), encoded_str);
|
||||
//length of the encoded header and payload only.
|
||||
//Addition of '1' to account for the '.' character.
|
||||
auto l = parts[0].length() + 1 + parts[1].length();
|
||||
jsign.verify(jobj.header(), encoded_str.substr(0, l), encoded_str);
|
||||
|
||||
return jobj;
|
||||
}
|
||||
|
||||
} // END namespace jwt
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef JWT_HPP
|
||||
#define JWT_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "jwt/base64.hpp"
|
||||
#include "jwt/algorithm.hpp"
|
||||
|
@ -233,6 +234,15 @@ public: // 'tors
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the header from an encoded string.
|
||||
* TODO: Throw an exception in case of error
|
||||
*/
|
||||
jwt_header(const string_view enc_str)
|
||||
{
|
||||
this->decode(enc_str);
|
||||
}
|
||||
|
||||
/// Default Copy and assignment
|
||||
jwt_header(const jwt_header&) = default;
|
||||
jwt_header& operator=(const jwt_header&) = default;
|
||||
|
@ -312,10 +322,19 @@ struct jwt_payload: write_interface
|
|||
, base64_enc_dec<jwt_payload>
|
||||
{
|
||||
public: // 'tors
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
jwt_payload() = default;
|
||||
|
||||
/**
|
||||
* Construct the payload from an encoded string.
|
||||
* TODO: Throw an exception in case of error.
|
||||
*/
|
||||
jwt_payload(const string_view enc_str)
|
||||
{
|
||||
this->decode(enc_str);
|
||||
}
|
||||
|
||||
/// Default copy and assignment operations
|
||||
jwt_payload(const jwt_payload&) = default;
|
||||
jwt_payload& operator=(const jwt_payload&) = default;
|
||||
|
@ -323,7 +342,7 @@ public: // 'tors
|
|||
~jwt_payload() = default;
|
||||
|
||||
public: // Exposed APIs
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
template <typename T>
|
||||
bool add_claim(const std::string& cname, T&& cvalue, bool overwrite=false)
|
||||
|
@ -346,14 +365,27 @@ public: // Exposed APIs
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
bool remove_claim(const std::string& cname)
|
||||
{
|
||||
auto itr = claim_names_.find(cname);
|
||||
if (itr == claim_names_.end()) return false;
|
||||
|
||||
claim_names_.erase(itr);
|
||||
payload_.erase(cname.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
bool has_claim(const std::string& cname) const noexcept
|
||||
{
|
||||
return claim_names_.count(cname);
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
template <typename T>
|
||||
bool has_claim_with_value(const std::string& cname, T&& cvalue) const
|
||||
|
@ -364,19 +396,19 @@ public: // Exposed APIs
|
|||
return (cvalue == payload_[cname]);
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
std::string encode(bool pprint = false)
|
||||
{
|
||||
return base64_encode(pprint);
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
//TODO: what about error_code ?
|
||||
void decode(const string_view enc_str);
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
const json_t& create_json_obj() const
|
||||
{
|
||||
|
@ -384,14 +416,35 @@ public: // Exposed APIs
|
|||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
struct case_compare {
|
||||
struct case_compare
|
||||
{
|
||||
using is_transparent = std::true_type;
|
||||
|
||||
bool operator()(const std::string& lhs, const std::string& rhs) const
|
||||
{
|
||||
int ret = strcasecmp(lhs.c_str(), rhs.c_str());
|
||||
return (ret < 0);
|
||||
}
|
||||
|
||||
bool operator()(const string_view lhs, const string_view rhs) const
|
||||
{
|
||||
int ret = strcasecmp(lhs.data(), rhs.data());
|
||||
return (ret < 0);
|
||||
}
|
||||
|
||||
bool operator()(const std::string& lhs, const string_view rhs) const
|
||||
{
|
||||
int ret = strcasecmp(lhs.data(), rhs.data());
|
||||
return (ret < 0);
|
||||
}
|
||||
|
||||
bool operator()(const string_view lhs, const std::string& rhs) const
|
||||
{
|
||||
int ret = strcasecmp(lhs.data(), rhs.data());
|
||||
return (ret < 0);
|
||||
}
|
||||
};
|
||||
|
||||
/// JSON object containing payload
|
||||
|
@ -449,7 +502,7 @@ private: // Data members;
|
|||
};
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
*/
|
||||
class jwt_object
|
||||
{
|
||||
|
@ -463,6 +516,12 @@ public: // 'tors
|
|||
template <typename... Args>
|
||||
jwt_object(Args&&... args);
|
||||
|
||||
public: // Exposed static APIs
|
||||
/**
|
||||
*/
|
||||
static std::array<string_view, 3>
|
||||
three_parts(const string_view enc_str);
|
||||
|
||||
public: // Exposed APIs
|
||||
/**
|
||||
*/
|
||||
|
@ -478,6 +537,34 @@ public: // Exposed APIs
|
|||
return payload_;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void payload(const jwt_payload& p)
|
||||
{
|
||||
payload_ = p;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void payload(jwt_payload&& p)
|
||||
{
|
||||
payload_ = std::move(p);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void header(const jwt_header& h)
|
||||
{
|
||||
header_ = h;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void header(jwt_header&& h)
|
||||
{
|
||||
header_ = std::move(h);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
jwt_header& header() noexcept
|
||||
|
@ -495,7 +582,15 @@ public: // Exposed APIs
|
|||
/**
|
||||
*/
|
||||
template <typename T>
|
||||
jwt_payload& add_payload(const std::string& name, T&& value);
|
||||
jwt_payload& add_claim(const std::string& name, T&& value);
|
||||
|
||||
/**
|
||||
*/
|
||||
jwt_payload& remove_claim(const std::string& name);
|
||||
|
||||
/**
|
||||
*/
|
||||
std::string signature() const;
|
||||
|
||||
private: // private APIs
|
||||
/**
|
||||
|
@ -536,7 +631,7 @@ private: // Data Members
|
|||
|
||||
/*!
|
||||
*/
|
||||
void jwt_decode(const string_view encoded_str, const string_view key, bool validate=true);
|
||||
jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool validate=true);
|
||||
|
||||
|
||||
} // END namespace jwt
|
||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue