RESTinio
Loading...
Searching...
No Matches
bearer_auth.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
5/*!
6 * @file
7 * @brief Helpers for dealing with bearer authentification.
8 *
9 * @since v.0.6.7.1
10 */
11
12#pragma once
13
14#include <restinio/helpers/http_field_parsers/authorization.hpp>
15
16#include <restinio/http_headers.hpp>
17#include <restinio/request_handler.hpp>
18#include <restinio/expected.hpp>
19
20#include <iostream>
21
22namespace restinio
23{
24
25namespace http_field_parsers
26{
27
28namespace bearer_auth
29{
30
31//
32// params_t
33//
34/*!
35 * @brief Parameters for bearer authentification.
36 *
37 * @since v.0.6.7.1
38 */
40{
41 //! Access Token.
42 /*!
43 * Can't be empty.
44 */
45 std::string token;
46};
47
48//
49// extraction_error_t
50//
51/*!
52 * @brief Error codes for failures of extraction of bearer authentification
53 * parameters.
54 *
55 * @since v.0.6.7.1
56 */
58{
59 //! There is no HTTP field with authentification parameters.
61
62 //! The HTTP field with authentification parameters can't be parsed.
64
65 //! Different authentification scheme found.
66 //! bearer authentification scheme is expected.
68
69 //! Invalid value of parameter for bearer authentification scheme.
70 //! The single parameter in the form of b64token is expected.
72};
73
74/*!
75 * @brief Helper function to get a string name of extraction_error enum.
76 *
77 * @since v.0.6.9
78 */
79[[nodiscard]]
80inline string_view_t
82{
83 string_view_t result{ "<unknown>" };
84
85 switch( what )
86 {
87 case extraction_error_t::no_auth_http_field:
88 result = string_view_t{ "no_auth_http_field" };
89 break;
90
91 case extraction_error_t::illegal_http_field_value:
92 result = string_view_t{ "illegal_http_field_value" };
93 break;
94
95 case extraction_error_t::not_bearer_auth_scheme:
96 result = string_view_t{ "not_bearer_auth_scheme" };
97 break;
98
99 case extraction_error_t::invalid_bearer_auth_param:
100 result = string_view_t{ "invalid_bearer_auth_param" };
101 break;
102 }
103
104 return result;
105}
106
107//
108// try_extract_params
109//
110/*!
111 * @brief Helper function for getting parameters of bearer authentification
112 * from an already parsed HTTP-field.
113 *
114 * @attention
115 * This function doesn't check the content of
116 * authorization_value_t::auth_scheme. It's expected that this field was
117 * checked earlier.
118 *
119 * Usage example:
120 * @code
121 * auto on_request(restinio::request_handle_t & req) {
122 * using namespace restinio::http_field_parsers;
123 * const auto opt_field = req.header().opt_value_of(
124 * restinio::http_field::authorization);
125 * if(opt_field) {
126 * const auto parsed_field = authorization_value_t::try_parse(*opt_field);
127 * if(parsed_field) {
128 * if("basic" == parsed_field->auth_scheme) {
129 * ... // Dealing with Basic authentification scheme.
130 * }
131 * else if("bearer" == parsed_field->auth_scheme) {
132 * using namespace restinio::http_field_parsers::bearer_auth;
133 * const auto bearer_params = try_extract_params(*parsed_field);
134 * if(bearer_params) {
135 * const std::string & token = auth_params->token;
136 * ... // Do something with token.
137 * }
138 * }
139 * else {
140 * ... // Other authentification schemes.
141 * }
142 * }
143 * }
144 * ...
145 * }
146 * @endcode
147 *
148 * @since v.0.6.8
149 */
150[[nodiscard]]
153 const authorization_value_t & http_field )
154{
155 const auto * b64token = std::get_if<authorization_value_t::token68_t>(
156 &http_field.auth_param );
157 if( !b64token )
158 return make_unexpected( extraction_error_t::invalid_bearer_auth_param );
159
160 return params_t{ b64token->value };
161}
162
163/*!
164 * @brief Helper function for getting parameters of bearer authentification
165 * from an already parsed HTTP-field.
166 *
167 * @attention
168 * This function doesn't check the content of
169 * authorization_value_t::auth_scheme. It's expected that this field was
170 * checked earlier.
171 *
172 * @note
173 * This function can be used if one wants to avoid memory allocation
174 * and can reuse value of auth_params.
175 *
176 * Usage example (please note that `const` is not used in code when
177 * authorization HTTP-field is parsed):
178 * @code
179 * auto on_request(restinio::request_handle_t & req) {
180 * using namespace restinio::http_field_parsers;
181 * const auto opt_field = req.header().opt_value_of(
182 * restinio::http_field::authorization);
183 * if(opt_field) {
184 * // parsed_field is a mutable object.
185 * // The content of parsed_field->auth_param can be moved out.
186 * auto parsed_field = authorization_value_t::try_parse(*opt_field);
187 * if(parsed_field) {
188 * if("basic" == parsed_field->auth_scheme) {
189 * ... // Dealing with Basic authentification scheme.
190 * }
191 * else if("bearer" == parsed_field->auth_scheme) {
192 * using namespace restinio::http_field_parsers::bearer_auth;
193 * const auto bearer_params =
194 * // Please note the usage of std::move here.
195 * try_extract_params(std::move(*parsed_field));
196 * if(bearer_params) {
197 * const std::string & token = auth_params->token;
198 * ... // Do something with token.
199 * }
200 * }
201 * else {
202 * ... // Other authentification schemes.
203 * }
204 * }
205 * }
206 * ...
207 * }
208 * @endcode
209 *
210 * @since v.0.6.8
211 */
212[[nodiscard]]
215 authorization_value_t && http_field )
216{
217 auto * b64token = std::get_if<authorization_value_t::token68_t>(
218 &http_field.auth_param );
219 if( !b64token )
220 return make_unexpected( extraction_error_t::invalid_bearer_auth_param );
221
222 return params_t{ std::move(b64token->value) };
223}
224
225namespace impl
226{
227
228[[nodiscard]]
231 const std::optional< string_view_t > opt_field_value )
232{
233 if( !opt_field_value )
234 return make_unexpected( extraction_error_t::no_auth_http_field );
235
236 auto field_value_parse_result = authorization_value_t::try_parse(
237 *opt_field_value );
238 if( !field_value_parse_result )
239 return make_unexpected( extraction_error_t::illegal_http_field_value );
240
241 auto & parsed_value = *field_value_parse_result;
242 if( "bearer" != parsed_value.auth_scheme )
243 return make_unexpected( extraction_error_t::not_bearer_auth_scheme );
244
245 return try_extract_params( std::move(parsed_value) );
246}
247
248} /* namespace impl */
249
250//
251// try_extract_params
252//
253/*!
254 * @brief Helper function for getting parameters of bearer authentification
255 * from a set of HTTP-fields.
256 *
257 * This helper function is intended to be used for cases when authentification
258 * parameters are stored inside a HTTP-field with a custom name. For example:
259 * @code
260 * auto check_authorization(const restinio::http_header_fields_t & fields) {
261 * using namespace restinio::http_field_parsers::bearer_auth;
262 * const auto auth_params = try_extract_params(fields, "X-My-Authorization");
263 * if(auth_params) {
264 * const std::string & token = auth_params->token;
265 * ... // Do something with token.
266 * }
267 * ...
268 * }
269 * @endcode
270 *
271 * @since v.0.6.9
272 */
273[[nodiscard]]
276 //! A set of HTTP-fields.
277 const http_header_fields_t & fields,
278 //! The name of a HTTP-field with authentification parameters.
279 string_view_t auth_field_name )
280{
281 return impl::perform_extraction_attempt(
282 fields.opt_value_of( auth_field_name ) );
283}
284
285/*!
286 * @brief Helper function for getting parameters of bearer authentification
287 * from a request.
288 *
289 * This helper function is intended to be used for cases when authentification
290 * parameters are stored inside a HTTP-field with a custom name. For example:
291 * @code
292 * auto on_request(restinio::request_handle_t & req) {
293 * using namespace restinio::http_field_parsers::bearer_auth;
294 * const auto auth_params = try_extract_params(*req, "X-My-Authorization");
295 * if(auth_params) {
296 * const std::string & token = auth_params->token;
297 * ... // Do something with token.
298 * }
299 * ...
300 * }
301 * @endcode
302 *
303 * @since v.0.6.7.1
304 */
305template< typename Extra_Data >
306[[nodiscard]]
309 //! A request that should hold a HTTP-field with authentification
310 //! parameters.
311 const generic_request_t< Extra_Data > & req,
312 //! The name of a HTTP-field with authentification parameters.
313 string_view_t auth_field_name )
314{
315 return try_extract_params( req.header(), auth_field_name );
316}
317
318/*!
319 * @brief Helper function for getting parameters of bearer authentification
320 * from a set of HTTP-fields.
321 *
322 * Usage example:
323 * @code
324 * auto check_authorization(const restinio::http_header_fields_t & fields) {
325 * using namespace restinio::http_field_parsers::bearer_auth;
326 * const auto auth_params = try_extract_params(
327 * fields, restinio::http_field::authorization);
328 * if(auth_params) {
329 * const std::string & token = auth_params->token;
330 * ... // Do something with token.
331 * }
332 * ...
333 * }
334 * @endcode
335 *
336 * @since v.0.6.9
337 */
338[[nodiscard]]
341 //! A set of HTTP-fields.
342 const http_header_fields_t & fields,
343 //! The ID of a HTTP-field with authentification parameters.
344 http_field_t auth_field_id )
345{
346 return impl::perform_extraction_attempt(
347 fields.opt_value_of( auth_field_id ) );
348}
349
350/*!
351 * @brief Helper function for getting parameters of bearer authentification
352 * from a request.
353 *
354 * Usage example:
355 * @code
356 * auto on_request(restinio::request_handle_t & req) {
357 * using namespace restinio::http_field_parsers::bearer_auth;
358 * const auto auth_params = try_extract_params(
359 * *req, restinio::http_field::authorization);
360 * if(auth_params) {
361 * const std::string & token = auth_params->token;
362 * ... // Do something with token.
363 * }
364 * ...
365 * }
366 * @endcode
367 *
368 * @since v.0.6.7.1
369 */
370template< typename Extra_Data >
371[[nodiscard]]
374 //! A request that should hold a HTTP-field with authentification
375 //! parameters.
376 const generic_request_t< Extra_Data > & req,
377 //! The ID of a HTTP-field with authentification parameters.
378 http_field_t auth_field_id )
379{
380 return try_extract_params( req.header(), auth_field_id );
381}
382
383} /* namespace bearer_auth */
384
385} /* namespace http_field_parsers */
386
387} /* namespace restinio */
expected_t< params_t, extraction_error_t > perform_extraction_attempt(const std::optional< string_view_t > opt_field_value)
expected_t< params_t, extraction_error_t > try_extract_params(const http_header_fields_t &fields, string_view_t auth_field_name)
Helper function for getting parameters of bearer authentification from a set of HTTP-fields.
string_view_t to_string_view(extraction_error_t what) noexcept
Helper function to get a string name of extraction_error enum.
expected_t< params_t, extraction_error_t > try_extract_params(authorization_value_t &&http_field)
Helper function for getting parameters of bearer authentification from an already parsed HTTP-field.
expected_t< params_t, extraction_error_t > try_extract_params(const generic_request_t< Extra_Data > &req, http_field_t auth_field_id)
Helper function for getting parameters of bearer authentification from a request.
extraction_error_t
Error codes for failures of extraction of bearer authentification parameters.
@ no_auth_http_field
There is no HTTP field with authentification parameters.
@ not_bearer_auth_scheme
Different authentification scheme found. bearer authentification scheme is expected.
@ invalid_bearer_auth_param
Invalid value of parameter for bearer authentification scheme. The single parameter in the form of b6...
@ illegal_http_field_value
The HTTP field with authentification parameters can't be parsed.
expected_t< params_t, extraction_error_t > try_extract_params(const http_header_fields_t &fields, http_field_t auth_field_id)
Helper function for getting parameters of bearer authentification from a set of HTTP-fields.
expected_t< params_t, extraction_error_t > try_extract_params(const authorization_value_t &http_field)
Helper function for getting parameters of bearer authentification from an already parsed HTTP-field.
expected_t< params_t, extraction_error_t > try_extract_params(const generic_request_t< Extra_Data > &req, string_view_t auth_field_name)
Helper function for getting parameters of bearer authentification from a request.
http_field_t
C++ enum that repeats nodejs c-style enum.
Tools for working with the value of Authorization HTTP-field.
authorization_details::token68_t token68_t
Type for holding a value of token68 from RFC7235.
Parameters for bearer authentification.