RESTinio
basic_auth.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
5 /*!
6  * @file
7  * @brief Helpers for dealing with basic authentification.
8  *
9  * @since v.0.6.7
10  */
11 
12 #pragma once
13 
14 #include <restinio/helpers/http_field_parsers/authorization.hpp>
15 
16 #include <restinio/utils/base64.hpp>
17 
18 #include <restinio/http_headers.hpp>
19 #include <restinio/request_handler.hpp>
20 #include <restinio/expected.hpp>
21 
22 #include <iostream>
23 
24 namespace restinio
25 {
26 
27 namespace http_field_parsers
28 {
29 
30 namespace basic_auth
31 {
32 
33 //
34 // params_t
35 //
36 /*!
37  * @brief Parameters for basic authentification.
38  *
39  * @since v.0.6.7
40  */
41 struct params_t
42 {
43  //! Name of a user.
44  /*!
45  * Can't be empty.
46  */
48 
49  //! Password for a user.
50  /*!
51  * Can be empty.
52  */
54 };
55 
56 //
57 // extraction_error_t
58 //
59 /*!
60  * @brief Error codes for failures of extraction of basic authentification
61  * parameters.
62  *
63  * @since v.0.6.7
64  */
66 {
67  //! There is no HTTP field with authentification parameters.
69 
70  //! The HTTP field with authentification parameters can't be parsed.
72 
73  //! Different authentification scheme found.
74  //! Basic authentification scheme is expected.
76 
77  //! Invalid value of parameter for basic authentification scheme.
78  //! The single parameter in the form of token68 is expected.
80 
81  //! Value of token68 parameter for basic authentification can't be decoded.
83 
84  //! Wrong format for username:password in decoded token68 parameter.
85  //! Maybe there is no colon symbol.
87 
88  //! Empty user name in username:password pair.
90 };
91 
92 /*!
93  * @brief Helper function to get a string name of extraction_error enum.
94  *
95  * @since v.0.6.9
96  */
98 inline string_view_t
100 {
101  string_view_t result{ "<unknown>" };
102 
103  switch( what )
104  {
106  result = string_view_t{ "no_auth_http_field" };
107  break;
108 
110  result = string_view_t{ "illegal_http_field_value" };
111  break;
112 
114  result = string_view_t{ "not_basic_auth_scheme" };
115  break;
116 
118  result = string_view_t{ "invalid_basic_auth_param" };
119  break;
120 
122  result = string_view_t{ "token68_decode_error" };
123  break;
124 
126  result = string_view_t{ "invalid_username_password_pair" };
127  break;
128 
130  result = string_view_t{ "empty_username" };
131  break;
132  }
133 
134  return result;
135 }
136 
137 //
138 // try_extract_params
139 //
140 /*!
141  * @brief Helper function for getting parameters of basic authentification
142  * from an already parsed HTTP-field.
143  *
144  * @attention
145  * This function doesn't check the content of
146  * authorization_value_t::auth_scheme. It's expected that this field was
147  * checked earlier.
148  *
149  * Usage example:
150  * @code
151  * auto on_request(restinio::request_handle_t & req) {
152  * using namespace restinio::http_field_parsers;
153  * const auto opt_field = req.header().opt_value_of(
154  * restinio::http_field::authorization);
155  * if(opt_field) {
156  * const auto parsed_field = authorization_value_t::try_parse(*opt_field);
157  * if(parsed_field) {
158  * if("basic" == parsed_field->auth_scheme) {
159  * using namespace restinio::http_field_parsers::basic_auth;
160  * const auto basic_params = try_extract_params(*parsed_field);
161  * if(basic_params) {
162  * const std::string & username = auth_params->username;
163  * const std::string & password = auth_params->password;
164  * ... // Do something with username and password.
165  * }
166  * }
167  * else if("bearer" == parsed_field->auth_scheme) {
168  * ... // Dealing with bearer authentification.
169  * }
170  * else {
171  * ... // Other authentification schemes.
172  * }
173  * }
174  * }
175  * ...
176  * }
177  * @endcode
178  *
179  * @since v.0.6.8
180  */
185 {
188  if( !token68 )
190 
191  const auto unbase64_result =
193  if( !unbase64_result )
195 
197  const auto first_colon = username_password.find( ':' );
198  if( std::string::npos == first_colon )
199  return make_unexpected(
201  if( 0u == first_colon )
203 
204  return params_t{
207  };
208 }
209 
210 namespace impl
211 {
212 
217 {
218  if( !opt_field_value )
220 
222  *opt_field_value );
225 
226  const auto & parsed_value = *field_value_parse_result;
227  if( "basic" != parsed_value.auth_scheme )
229 
231 }
232 
233 } /* namespace impl */
234 
235 //
236 // try_extract_params
237 //
238 /*!
239  * @brief Helper function for getting parameters of basic authentification
240  * from a set of HTTP-fields.
241  *
242  * This helper function is intended to be used for cases when authentification
243  * parameters are stored inside a HTTP-field with a custom name. For example:
244  * @code
245  * auto check_authorization(const restinio::http_header_fields_t & fields) {
246  * using namespace restinio::http_field_parsers::basic_auth;
247  * const auto auth_params = try_extract_params(fields, "X-My-Authorization");
248  * if(auth_params) {
249  * const std::string & username = auth_params->username;
250  * const std::string & password = auth_params->password;
251  * ... // Do something with username and password.
252  * }
253  * ...
254  * }
255  * @endcode
256  *
257  * @since v.0.6.9
258  */
262  //! A set of HTTP-fields.
264  //! The name of a HTTP-field with authentification parameters.
266 {
269 }
270 
271 /*!
272  * @brief Helper function for getting parameters of basic authentification
273  * from a request.
274  *
275  * This helper function is intended to be used for cases when authentification
276  * parameters are stored inside a HTTP-field with a custom name. For example:
277  * @code
278  * auto on_request(restinio::request_handle_t & req) {
279  * using namespace restinio::http_field_parsers::basic_auth;
280  * const auto auth_params = try_extract_params(*req, "X-My-Authorization");
281  * if(auth_params) {
282  * const std::string & username = auth_params->username;
283  * const std::string & password = auth_params->password;
284  * ... // Do something with username and password.
285  * }
286  * ...
287  * }
288  * @endcode
289  *
290  * @since v.0.6.7
291  */
292 template< typename Extra_Data >
296  //! A request that should hold a HTTP-field with authentification
297  //! parameters.
298  const generic_request_t< Extra_Data > & req,
299  //! The name of a HTTP-field with authentification parameters.
301 {
303 }
304 
305 /*!
306  * @brief Helper function for getting parameters of basic authentification
307  * from a set of HTTP-fields.
308  *
309  * Usage example:
310  * @code
311  * auto check_authorization(const restinio::http_header_fields_t & fields) {
312  * using namespace restinio::http_field_parsers::basic_auth;
313  * const auto auth_params = try_extract_params(
314  * fields, restinio::http_field::authorization);
315  * if(auth_params) {
316  * const std::string & username = auth_params->username;
317  * const std::string & password = auth_params->password;
318  * ... // Do something with username and password.
319  * }
320  * ...
321  * }
322  * @endcode
323  *
324  * @since v.0.6.9
325  */
329  //! A set of HTTP-fields.
331  //! The ID of a HTTP-field with authentification parameters.
333 {
336 }
337 
338 /*!
339  * @brief Helper function for getting parameters of basic authentification
340  * from a request.
341  *
342  * Usage example:
343  * @code
344  * auto on_request(restinio::request_handle_t & req) {
345  * using namespace restinio::http_field_parsers::basic_auth;
346  * const auto auth_params = try_extract_params(
347  * *req, restinio::http_field::authorization);
348  * if(auth_params) {
349  * const std::string & username = auth_params->username;
350  * const std::string & password = auth_params->password;
351  * ... // Do something with username and password.
352  * }
353  * ...
354  * }
355  * @endcode
356  *
357  * @since v.0.6.7
358  */
359 template< typename Extra_Data >
363  //! A request that should hold a HTTP-field with authentification
364  //! parameters.
365  const generic_request_t< Extra_Data > & req,
366  //! The ID of a HTTP-field with authentification parameters.
368 {
370 }
371 
372 } /* namespace basic_auth */
373 
374 } /* namespace http_field_parsers */
375 
376 } /* namespace restinio */
RESTINIO_NODISCARD 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 basic authentification from a request.
Definition: basic_auth.hpp:362
There is no HTTP field with authentification parameters.
RESTINIO_NODISCARD expected_t< params_t, extraction_error_t > perform_extraction_attempt(const optional_t< string_view_t > opt_field_value)
Definition: basic_auth.hpp:215
Invalid value of parameter for basic authentification scheme. The single parameter in the form of tok...
Wrong format for username:password in decoded token68 parameter. Maybe there is no colon symbol...
Value of token68 parameter for basic authentification can&#39;t be decoded.
std::string password
Password for a user.
Definition: basic_auth.hpp:53
extraction_error_t
Error codes for failures of extraction of basic authentification parameters.
Definition: basic_auth.hpp:65
The HTTP field with authentification parameters can&#39;t be parsed.
RESTINIO_NODISCARD auto try_parse_field(const generic_request_t< Extra_Data > &req, http_field_t field_id, string_view_t default_value=string_view_t{})
A helper function for extraction and parsing a value of HTTP-field.
Different authentification scheme found. Basic authentification scheme is expected.
Parameters for basic authentification.
Definition: basic_auth.hpp:41
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64