Skip to content

Commit

Permalink
Ensure array_type has front() method + fix array_type on jsoncpp (#361)
Browse files Browse the repository at this point in the history
* Use operator[] instead of front to support jsoncpp

Replace the `front()` with `[0]` as front is not supported by jsoncpp on
array types.

Signed-off-by: Omar Mohamed <[email protected]>

* Revert "Use operator[] instead of front to support jsoncpp"

This reverts commit dfa7d29.

* Implement `front()` in jsoncpp array_type

Signed-off-by: Omar Mohamed <[email protected]>

* Check if array_type has a front() method

Signed-off-by: Omar Mohamed <[email protected]>

* Add `front()` to jsoncons array_type

* Remove non-const overloads of front()

Signed-off-by: Omar Mohamed <[email protected]>

* Fix check for front() in array_type

Signed-off-by: Omar Mohamed <[email protected]>

* Use std::decay

Signed-off-by: Omar Mohamed <[email protected]>

* fix example to print array value

* expose base class ctors

* update as_array traits helper

* fixup linter

---------

Signed-off-by: Omar Mohamed <[email protected]>
Co-authored-by: Chris Mc <[email protected]>
  • Loading branch information
omar-mohamed-khallaf and prince-chrismc authored Nov 17, 2024
1 parent 59cdb43 commit 71c3d36
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 32 deletions.
2 changes: 1 addition & 1 deletion example/traits/danielaparker-jsoncons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int main() {
const auto decoded = jwt::decode<traits>(token);

const auto array = traits::as_array(decoded.get_payload_claim("object").to_json()["api"]["array"]);
std::cout << "payload /object/api/array = " << array << std::endl;
std::cout << "payload /object/api/array = " << jsoncons::pretty_print(traits::json(array)) << std::endl;

jwt::verify<traits>()
.allow_algorithm(jwt::algorithm::none{})
Expand Down
60 changes: 31 additions & 29 deletions include/jwt-cpp/jwt.h
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ namespace jwt {
* \brief Load a public key from a string.
*
* The string should contain a pem encoded certificate or public key
*
*
* \deprecated Use the templated version helper::load_private_key_from_string with error::ecdsa_error
*
* \param key String containing the certificate encoded as pem
Expand Down Expand Up @@ -872,7 +872,7 @@ namespace jwt {
* The string should contain a pem encoded certificate or public key
*
* \deprecated Use the templated version helper::load_private_key_from_string with error::ecdsa_error
*
*
* \param key String containing the certificate or key encoded as pem
* \param password Password used to decrypt certificate or key (leave empty if not encrypted)
* \throw ecdsa_exception if an error occurred
Expand All @@ -887,7 +887,7 @@ namespace jwt {

/**
* \brief Load a private key from a string.
*
*
* \deprecated Use the templated version helper::load_private_key_from_string with error::ecdsa_error
*
* \param key String containing a private key as pem
Expand Down Expand Up @@ -1077,7 +1077,7 @@ namespace jwt {
* \brief Load a private key from a string.
*
* \deprecated Use the templated version helper::load_private_key_from_string with error::ecdsa_error
*
*
* \param key String containing a private key as pem
* \param password Password used to decrypt key (leave empty if not encrypted)
* \throw ecdsa_exception if an error occurred
Expand Down Expand Up @@ -1372,7 +1372,7 @@ namespace jwt {
struct hmacsha {
/**
* Construct new hmac algorithm
*
*
* \param key Key to use for HMAC
* \param md Pointer to hash function
* \param name Name of the algorithm
Expand All @@ -1381,7 +1381,7 @@ namespace jwt {
: secret(std::move(key)), md(md), alg_name(std::move(name)) {}
/**
* Sign jwt data
*
*
* \param data The data to sign
* \param ec error_code filled with details on error
* \return HMAC signature for the given data
Expand All @@ -1402,7 +1402,7 @@ namespace jwt {
}
/**
* Check if signature is valid
*
*
* \param data The data to check signature against
* \param signature Signature provided by the jwt
* \param ec Filled with details about failure.
Expand All @@ -1423,7 +1423,7 @@ namespace jwt {
}
/**
* Returns the algorithm name provided to the constructor
*
*
* \return algorithm's name
*/
std::string name() const { return alg_name; }
Expand All @@ -1442,7 +1442,7 @@ namespace jwt {
struct rsa {
/**
* Construct new rsa algorithm
*
*
* \param public_key RSA public key in PEM format
* \param private_key RSA private key or empty string if not available. If empty, signing will always fail.
* \param public_key_password Password to decrypt public key pem.
Expand Down Expand Up @@ -1495,7 +1495,7 @@ namespace jwt {
}
/**
* Check if signature is valid
*
*
* \param data The data to check signature against
* \param signature Signature provided by the jwt
* \param ec Filled with details on failure
Expand Down Expand Up @@ -2053,13 +2053,13 @@ namespace jwt {
};
/**
* RS256 algorithm.
*
*
* This data structure is used to describe the RSA256 and can be used to verify JWTs
*/
struct rs256 : public rsa {
/**
* \brief Construct new instance of algorithm
*
*
* \param public_key RSA public key in PEM format
* \param private_key RSA private key or empty string if not available. If empty, signing will always fail.
* \param public_key_password Password to decrypt public key pem.
Expand Down Expand Up @@ -2459,11 +2459,13 @@ namespace jwt {
struct is_valid_json_array {
template<typename T>
using value_type_t = typename T::value_type;
using front_base_type = typename std::decay<decltype(std::declval<array_type>().front())>::type;

static constexpr auto value = std::is_constructible<value_type, array_type>::value &&
is_iterable<array_type>::value &&
is_detected<value_type_t, array_type>::value &&
std::is_same<typename array_type::value_type, value_type>::value;
std::is_same<typename array_type::value_type, value_type>::value &&
std::is_same<front_base_type, value_type>::value;
};

template<typename string_type, typename integer_type>
Expand Down Expand Up @@ -3728,9 +3730,9 @@ namespace jwt {
* Specify a claim to check for using the specified operation.
* This is helpful for implementating application specific authentication checks
* such as the one seen in partial-claim-verifier.cpp
*
*
* \snippet{trimleft} partial-claim-verifier.cpp verifier check custom claim
*
*
* \param name Name of the claim to check for
* \param fn Function to use for verifying the claim
* \return *this to allow chaining
Expand All @@ -3743,9 +3745,9 @@ namespace jwt {
/**
* Specify a claim to check for equality (both type & value).
* See the private-claims.cpp example.
*
*
* \snippet{trimleft} private-claims.cpp verify exact claim
*
*
* \param name Name of the claim to check for
* \param c Claim to check for
* \return *this to allow chaining
Expand All @@ -3756,13 +3758,13 @@ namespace jwt {

/**
* \brief Add an algorithm available for checking.
*
*
* This is used to handle incomming tokens for predefined algorithms
* which the authorization server is provided. For example a small system
* where only a single RSA key-pair is used to sign tokens
*
*
* \snippet{trimleft} example/rsa-verify.cpp allow rsa algorithm
*
*
* \tparam Algorithm any algorithm such as those provided by jwt::algorithm
* \param alg Algorithm to allow
* \return *this to allow chaining
Expand Down Expand Up @@ -4122,18 +4124,18 @@ namespace jwt {
* Default clock class using std::chrono::system_clock as a backend.
*/
struct default_clock {
/**
/**
* Gets the current system time
* \return time_point of the host system
* \return time_point of the host system
*/
date now() const { return date::clock::now(); }
};

/**
* Create a verifier using the default_clock.
*
*
*
*
*
*
* \param c Clock instance to use
* \return verifier instance
*/
Expand All @@ -4153,7 +4155,7 @@ namespace jwt {
/**
* \brief Decode a token. This can be used to to help access important feild like 'x5c'
* for verifying tokens. See associated example rsa-verify.cpp for more details.
*
*
* \tparam json_traits JSON implementation traits
* \tparam Decode is callable, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
Expand All @@ -4172,7 +4174,7 @@ namespace jwt {
/**
* Decode a token. This can be used to to help access important feild like 'x5c'
* for verifying tokens. See associated example rsa-verify.cpp for more details.
*
*
* \tparam json_traits JSON implementation traits
* \param token Token to decode
* \return Decoded token
Expand All @@ -4194,10 +4196,10 @@ namespace jwt {
return jwk<json_traits>(jwk_);
}
/**
* Parse a JSON Web Key Set. This can be used to to help access
* Parse a JSON Web Key Set. This can be used to to help access
* important feild like 'x5c' for verifying tokens. See example
* jwks-verify.cpp for more information.
*
*
* \tparam json_traits JSON implementation traits
* \param jwks_ string buffer containing the JSON object
* \return Parsed JSON object containing the data of the JWK SET string
Expand Down
10 changes: 8 additions & 2 deletions include/jwt-cpp/traits/danielaparker-jsoncons/traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ namespace jwt {
return 0;
}
};
using array_type = json::array;
class array_type : public json::array {
public:
using json::array::array;
explicit array_type(const json::array& a) : json::array(a) {}
explicit array_type(json::array&& a) : json::array(a) {}
value_type const& front() const { return this->operator[](0U); }
};
using string_type = std::string; // current limitation of traits implementation
using number_type = double;
using integer_type = int64_t;
Expand Down Expand Up @@ -89,7 +95,7 @@ namespace jwt {

static array_type as_array(const json& val) {
if (val.type() != jsoncons::json_type::array_value) throw std::bad_cast();
return val.array_value();
return array_type(val.array_value());
}

static string_type as_string(const json& val) {
Expand Down
2 changes: 2 additions & 0 deletions include/jwt-cpp/traits/open-source-parsers-jsoncpp/traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ namespace jwt {
~array_type() = default;
array_type& operator=(const array_type& o) = default;
array_type& operator=(array_type&& o) noexcept = default;

value_type const& front() const { return this->operator[](0U); }
};
using number_type = double;
using integer_type = Json::Value::Int;
Expand Down

0 comments on commit 71c3d36

Please sign in to comment.