#ifndef CPP_JWT_PARAMETERS_HPP #define CPP_JWT_PARAMETERS_HPP #include #include #include #include #include #include #include "jwt/algorithm.hpp" #include "jwt/detail/meta.hpp" #include "jwt/string_view.hpp" namespace jwt { using system_time_t = std::chrono::time_point; namespace params { namespace detail { /** * Parameter for providing the payload. * Takes a Mapping concept representing * key-value pairs. * * NOTE: MappingConcept allows only strings * for both keys and values. Use `add_header` * API of `jwt_object` otherwise. * * Modeled as ParameterConcept. */ template struct payload_param { payload_param(MappingConcept&& mc) : payload_(std::forward(mc)) {} MappingConcept get() && { return std::move(payload_); } const MappingConcept& get() const& { return payload_; } MappingConcept payload_; }; /** * Parameter for providing the secret key. * Stores only the view of the provided string * as string_view. Later the implementation may or * may-not copy it. * * Modeled as ParameterConcept. */ struct secret_param { secret_param(string_view sv) : secret_(sv) {} string_view get() { return secret_; } string_view secret_; }; /** * Parameter for providing the algorithm to use. * The parameter can accept either the string representation * or the enum class. * * Modeled as ParameterConcept. */ struct algorithm_param { algorithm_param(const string_view alg) : alg_(str_to_alg(alg)) {} algorithm_param(jwt::algorithm alg) : alg_(alg) {} jwt::algorithm get() const noexcept { return alg_; } typename jwt::algorithm alg_; }; /** * Parameter for providing additional headers. * Takes a mapping concept representing * key-value pairs. * * Modeled as ParameterConcept. */ template struct headers_param { headers_param(MappingConcept&& mc) : headers_(std::forward(mc)) {} MappingConcept get() && { return std::move(headers_); } const MappingConcept& get() const& { return headers_; } MappingConcept headers_; }; /** */ struct verify_param { verify_param(bool v) : verify_(v) {} bool get() const { return verify_; } bool verify_; }; /** */ template struct algorithms_param { algorithms_param(Sequence&& seq) : seq_(std::forward(seq)) {} Sequence get() && { return std::move(seq_); } const Sequence& get() const& { return seq_; } Sequence seq_; }; /** */ struct leeway_param { leeway_param(uint32_t v) : leeway_(v) {} uint32_t get() const noexcept { return leeway_; } uint32_t leeway_; }; /** */ struct audience_param { audience_param(std::string aud) : aud_(std::move(aud)) {} const std::string& get() const& noexcept { return aud_; } std::string get() && noexcept { return aud_; } std::string aud_; }; /** */ struct issuer_param { issuer_param(std::string iss) : iss_(std::move(iss)) {} const std::string& get() const& noexcept { return iss_; } std::string get() && noexcept { return iss_; } std::string iss_; }; /** */ struct nbf_param { nbf_param(const jwt::system_time_t tp) : duration_(std::chrono::duration_cast< std::chrono::seconds>(tp.time_since_epoch()).count()) {} nbf_param(const uint64_t epoch) : duration_(epoch) {} uint64_t get() const noexcept { return duration_; } uint64_t duration_; }; } // END namespace detail // Useful typedef using param_init_list_t = std::initializer_list>; using param_seq_list_t = std::initializer_list; /** */ detail::payload_param> payload(const param_init_list_t& kvs) { std::unordered_map m; for (const auto& elem : kvs) { m.emplace(elem.first.data(), elem.second.data()); } return { std::move(m) }; } /** */ template detail::payload_param payload(MappingConcept&& mc) { static_assert (jwt::detail::meta::is_mapping_concept::value, "Template parameter does not meet the requirements for MappingConcept."); return { std::forward(mc) }; } /** */ detail::secret_param secret(const string_view sv) { return { sv }; } /** */ detail::algorithm_param algorithm(const string_view sv) { return { sv }; } /** */ detail::algorithm_param algorithm(jwt::algorithm alg) { return { alg }; } /** */ detail::headers_param> headers(const param_init_list_t& kvs) { std::map m; for (const auto& elem : kvs) { m.emplace(elem.first.data(), elem.second.data()); } return { std::move(m) }; } /** */ template detail::headers_param headers(MappingConcept&& mc) { static_assert (jwt::detail::meta::is_mapping_concept::value, "Template parameter does not meet the requirements for MappingConcept."); return { std::forward(mc) }; } /** */ detail::verify_param verify(bool v) { return { v }; } /** */ detail::leeway_param leeway(uint32_t l) { return { l }; } /** */ detail::algorithms_param> algorithms(const param_seq_list_t& seq) { std::vector vec; vec.reserve(seq.size()); for (const auto& e: seq) { vec.emplace_back(e.data(), e.length()); } return { std::move(vec) }; } template detail::algorithms_param algorithms(SequenceConcept&& sc) { return { std::forward(sc) }; } /** */ detail::audience_param aud(const string_view aud) { return { aud.data() }; } /** */ detail::issuer_param issuer(const string_view iss) { return { iss.data() }; } /** */ detail::nbf_param nbf(const system_time_t tp) { return { tp }; } /** */ detail::nbf_param nbf(const uint64_t epoch) { return { epoch }; } } // END namespace params } // END namespace jwt #endif