Skip to content

Commit 77ecc51

Browse files
committed
Merge branch 'development' of https://git01.codeplex.com/forks/tsone/casadev into development
2 parents 9cd1e66 + 417477f commit 77ecc51

39 files changed

+3610
-98
lines changed

Release/include/cpprest/asyncrt_utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ namespace conversions
147147
/// </summary>
148148
_ASYNCRTIMP std::vector<unsigned char> __cdecl from_base64(const utility::string_t& str);
149149

150+
/// <summary>
151+
/// Convert string to body data
152+
/// </summary>
153+
_ASYNCRTIMP std::vector<unsigned char> __cdecl to_body_data(const utility::string_t& str);
154+
150155
template <typename Source>
151156
utility::string_t print_string(const Source &val)
152157
{

Release/include/cpprest/http_client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ namespace http
6767
namespace client
6868
{
6969

70+
using namespace web::http::client::experimental;
71+
7072
#ifdef _MS_WINDOWS
7173
namespace details {
7274
#ifdef __cplusplus_winrt

Release/include/cpprest/http_client_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ using namespace utility;
5757
# define CRLF std::string("\r\n")
5858
#endif
5959

60-
60+
using namespace web::http::client::experimental;
6161
using namespace web::http::details;
6262

6363
namespace web { namespace http { namespace client { namespace details

Release/include/cpprest/http_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ namespace details
8181
/// Parses the given Content-Type header value to get out actual content type and charset.
8282
/// If the charset isn't specified the default charset for the content type will be set.
8383
/// </summary>
84-
void parse_content_type_and_charset(const utility::string_t &content_type, utility::string_t &content, utility::string_t &charset);
84+
_ASYNCRTIMP void parse_content_type_and_charset(const utility::string_t &content_type, utility::string_t &content, utility::string_t &charset);
8585

8686
/// <summary>
8787
/// Gets the default charset for given content type. If the MIME type is not textual or recognized Latin1 will be returned.

Release/include/cpprest/oauth1_handler.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ namespace http
3838
{
3939
namespace client
4040
{
41+
class http_client_config;
42+
namespace experimental
43+
{
4144

4245

4346
/// <summary>
@@ -92,7 +95,7 @@ struct oauth1_config
9295
bool is_enabled() const { return !m_key.empty() && !m_secret.empty() && !m_token.empty() && !m_token_secret.empty(); }
9396

9497
private:
95-
friend class http_client_config;
98+
friend class web::http::client::http_client_config;
9699
oauth1_config() {}
97100

98101
// Required.
@@ -113,13 +116,13 @@ struct oauth1_config
113116
class oauth1_handler : public http_pipeline_stage
114117
{
115118
public:
116-
oauth1_handler(oauth1_config config) :
119+
oauth1_handler(oauth1_config cfg) :
117120
m_random((unsigned int)utility::datetime::utc_timestamp()),
118-
m_config(std::move(config))
121+
m_config(std::move(cfg))
119122
{}
120123

121-
void set_config(oauth1_config config) { m_config = std::move(config); }
122-
const oauth1_config& get_config() const { return m_config; }
124+
const oauth1_config& config() const { return m_config; }
125+
void set_config(oauth1_config cfg) { m_config = std::move(cfg); }
123126

124127
_ASYNCRTIMP virtual pplx::task<http_response> propagate(http_request request) override;
125128

@@ -147,6 +150,6 @@ class oauth1_handler : public http_pipeline_stage
147150
};
148151

149152

150-
}}} // namespace web::http::client
153+
}}}} // namespace web::http::client::experimental
151154

152155
#endif /* _CASA_OAUTH1_HANDLER_H */

Release/include/cpprest/oauth2_handler.h

Lines changed: 163 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,53 +37,198 @@ namespace http
3737
{
3838
namespace client
3939
{
40+
class http_client_config;
41+
namespace experimental
42+
{
43+
44+
45+
/// <summary>
46+
/// Exception type for OAuth 2.0 errors.
47+
/// </summary>
48+
class oauth2_exception : public std::exception
49+
{
50+
public:
51+
oauth2_exception(utility::string_t msg) : m_msg(utility::conversions::to_utf8string(std::move(msg))) {}
52+
~oauth2_exception() _noexcept {}
53+
const char* what() const _noexcept { return m_msg.c_str(); }
54+
55+
private:
56+
std::string m_msg;
57+
};
4058

4159

4260
/// <summary>
43-
/// Oauth2 configuration.
61+
/// OAuth 2.0 configuration.
62+
///
63+
/// Encapsulates functionality for:
64+
/// - Authenticating requests with an access token.
65+
/// - Performing the OAuth 2.0 authorization code grant authorization flow.
66+
/// See: http://tools.ietf.org/html/rfc6749#section-4.1
67+
///
68+
/// Usage for authorization:
69+
/// 1. Set service and client/app parameters:
70+
/// - Client/app key & secret (as provided by the service).
71+
/// - The service authorization endpoint and token endpoint.
72+
/// - Your client/app redirect URI.
73+
/// - Set if bearer token is passed in query or header field (default: header).
74+
/// See: http://tools.ietf.org/html/rfc6750#section-2
75+
/// - If the service uses "non-standard" access token key, set it also (default: "access_token").
76+
/// 2. Open web browser with URI from build_authorization_uri().
77+
/// - The passed state string should be unique for this authorization session.
78+
/// 3. In the web browser, the resource owner clicks "Yes" to authorize your client/app.
79+
/// 4. To signal authorization, web browser is redirected to redirect_uri().
80+
/// 5. The redirect contains the authorization code and the state string.
81+
/// 6. Check the state string equals the one in step 2.
82+
/// 7. Pass the authorization code to fetch_token() to create a token fetch task.
83+
///
84+
/// Usage for issuing authenticated requests:
85+
/// 1. Obtain token. (Perform authorization as above or get token otherwise.)
86+
/// 2. Use http_client_config::set_oauth2() to set configuration, and construct http_client using it.
87+
/// 3. All requests issued with that http_client will be OAuth 2.0 -authenticated.
88+
///
4489
/// </summary>
45-
struct oauth2_config
90+
class oauth2_config
4691
{
47-
oauth2_config(utility::string_t token) : m_token(std::move(token)) {}
92+
public:
93+
oauth2_config(utility::string_t client_key, utility::string_t client_secret,
94+
utility::string_t auth_endpoint, utility::string_t token_endpoint,
95+
utility::string_t redirect_uri) :
96+
m_client_key(client_key),
97+
m_client_secret(client_secret),
98+
m_auth_endpoint(auth_endpoint),
99+
m_token_endpoint(token_endpoint),
100+
m_redirect_uri(redirect_uri),
101+
m_bearer_auth(true),
102+
m_http_basic_auth(true),
103+
m_access_token_key(_XPLATSTR("access_token"))
104+
{
105+
}
106+
107+
oauth2_config(utility::string_t token) :
108+
m_token(std::move(token)),
109+
m_bearer_auth(true),
110+
m_http_basic_auth(true),
111+
m_access_token_key(_XPLATSTR("access_token"))
112+
{
113+
}
114+
115+
/// <summary>
116+
/// Builds an authorization URI to be loaded in the web browser.
117+
/// The URI is built with auth_endpoint() as basis.
118+
/// </summary>
119+
_ASYNCRTIMP utility::string_t build_authorization_uri() const;
120+
121+
/// <summary>
122+
/// Parses authorization code from the redirected URI when resource owner
123+
/// has accepted the authorization.
124+
/// Redirected URI must satisfy the following (otherwise an exception is thrown):
125+
/// - Must contain both 'code' and 'state' query parameters.
126+
/// - The 'state' parameter must be equal to state().
127+
/// </summary>
128+
_ASYNCRTIMP utility::string_t parse_code_from_redirected_uri(uri redirected_uri) const;
129+
130+
/// <summary>
131+
/// Creates a task to fetch token from the token endpoint.
132+
/// The task creates a request to the token_endpoint() which is used exchange an authorization code to an access token.
133+
/// If successful, resulting token is set as active via set_token().
134+
/// </summary>
135+
/// <param name="authorization_code">Code received via redirect upon successful authorization.</param>
136+
_ASYNCRTIMP pplx::task<void> fetch_token(utility::string_t authorization_code);
137+
138+
bool is_enabled() const { return !m_token.empty(); }
139+
140+
const utility::string_t& client_key() const { return m_client_key; }
141+
void set_client_key(utility::string_t client_key) { m_client_key = std::move(client_key); }
142+
143+
const utility::string_t& client_secret() const { return m_client_secret; }
144+
void set_client_secret(utility::string_t client_secret) { m_client_secret = std::move(client_secret); }
145+
146+
const utility::string_t& auth_endpoint() const { return m_auth_endpoint; }
147+
void set_auth_endpoint(utility::string_t auth_endpoint) { m_auth_endpoint = std::move(auth_endpoint); }
148+
149+
const utility::string_t& token_endpoint() const { return m_token_endpoint; }
150+
void set_token_endpoint(utility::string_t token_endpoint) { m_token_endpoint = std::move(token_endpoint); }
151+
152+
const utility::string_t& redirect_uri() const { return m_redirect_uri; }
153+
void set_redirect_uri(utility::string_t redirect_uri) { m_redirect_uri = std::move(redirect_uri); }
154+
155+
const utility::string_t& scope() const { return m_scope; }
156+
void set_scope(utility::string_t scope) { m_scope = std::move(scope); }
157+
158+
const utility::string_t& state() const { return m_state; }
159+
/// <summary>
160+
/// State string should be unique for each authorization session.
161+
/// This state string should be returned by the authorization server on redirect
162+
/// </summary>
163+
void set_state(utility::string_t state) { m_state = std::move(state); }
48164

49165
const utility::string_t& token() const { return m_token; }
50166
void set_token(utility::string_t token) { m_token = std::move(token); }
51167

52-
bool is_enabled() const { return !m_token.empty(); }
168+
bool bearer_auth() const { return m_bearer_auth; }
169+
/// <summary>
170+
/// Bearer token passing method. This must be selected based on what the service accepts.
171+
/// True means token is passed in the request header. (http://tools.ietf.org/html/rfc6750#section-2.1)
172+
/// False means token in passed in the query parameters. (http://tools.ietf.org/html/rfc6750#section-2.3)
173+
/// Default: True.
174+
/// </summary>
175+
void set_bearer_auth(bool enable) { m_bearer_auth = std::move(enable); }
176+
177+
bool http_basic_auth() const { return m_http_basic_auth; }
178+
/// <summary>
179+
/// Token endpoint authorization method. This must be selected based on what the service accepts.
180+
/// True means HTTP Basic is used for authentication.
181+
/// False means client key & secret are passed in the HTTP request body.
182+
/// Default: True.
183+
/// </summary>
184+
void set_http_basic_auth(bool enable) { m_http_basic_auth = std::move(enable); }
185+
186+
const utility::string_t& access_token_key() const { return m_access_token_key; }
187+
/// <summary>
188+
/// Set custom access token key field in the case service requires a "non-standard" key.
189+
/// Default access token key is "access_token".
190+
/// </summary>
191+
void set_access_token_key(utility::string_t access_token_key) { m_access_token_key = std::move(access_token_key); }
53192

54193
private:
55-
friend class http_client_config;
194+
friend class web::http::client::http_client_config;
56195
oauth2_config() {}
57196

197+
utility::string_t m_client_key;
198+
utility::string_t m_client_secret;
199+
utility::string_t m_auth_endpoint;
200+
utility::string_t m_token_endpoint;
201+
utility::string_t m_redirect_uri;
202+
utility::string_t m_scope;
203+
utility::string_t m_state;
204+
205+
bool m_bearer_auth;
206+
bool m_http_basic_auth;
207+
utility::string_t m_access_token_key;
208+
58209
utility::string_t m_token;
59210
};
60211

61212

62213
/// <summary>
63-
/// Oauth2 handler. Specialization of http_pipeline_stage.
214+
/// OAuth 2.0 handler.
215+
/// Specialization of http_pipeline_stage to perform OAuth 2.0 request authentication.
64216
/// </summary>
65217
class oauth2_handler : public http_pipeline_stage
66218
{
67219
public:
68-
oauth2_handler(oauth2_config config) : m_config(std::move(config)) {}
220+
oauth2_handler(oauth2_config cfg) : m_config(std::move(cfg)) {}
69221

70-
void set_config(oauth2_config config) { m_config = std::move(config); }
71-
const oauth2_config& get_config() const { return m_config; }
222+
const oauth2_config& config() const { return m_config; }
223+
void set_config(oauth2_config cfg) { m_config = std::move(cfg); }
72224

73-
virtual pplx::task<http_response> propagate(http_request request) override
74-
{
75-
if (m_config.is_enabled())
76-
{
77-
request.headers().add(_XPLATSTR("Authorization"), _XPLATSTR("Bearer ") + m_config.token());
78-
}
79-
return next_stage()->propagate(request);
80-
}
225+
_ASYNCRTIMP virtual pplx::task<http_response> propagate(http_request request) override;
81226

82227
private:
83228
oauth2_config m_config;
84229
};
85230

86231

87-
}}} // namespace web::http::client
232+
}}}} // namespace web::http::client::experimental
88233

89234
#endif /* _CASA_OAUTH2_HANDLER_H */
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Application
2+
x:Class="OAuth2Live.App"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:local="using:OAuth2Live">
6+
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
11+
<!--
12+
Styles that define common aspects of the platform look and feel
13+
Required by Visual Studio project and item templates
14+
-->
15+
<ResourceDictionary Source="Common/StandardStyles.xaml"/>
16+
</ResourceDictionary.MergedDictionaries>
17+
18+
</ResourceDictionary>
19+
</Application.Resources>
20+
</Application>

0 commit comments

Comments
 (0)