Skip to content

Commit e0ebd7b

Browse files
authored
Change handling token_endpoint_url (#1284)
Move removing url handling from TokenEndpoint to TokenEndpointImpl Added reading token_endpoint_url from credentials.properties Add checking network protocol Resolves: OLPEDGE-1029 Signed-off-by: Yevhenii Dudnyk <[email protected]>
1 parent 6c51999 commit e0ebd7b

File tree

8 files changed

+122
-51
lines changed

8 files changed

+122
-51
lines changed

olp-cpp-sdk-authentication/include/olp/authentication/AuthenticationCredentials.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ class AUTHENTICATION_API AuthenticationCredentials {
9494
*/
9595
AuthenticationCredentials(std::string key, std::string secret);
9696

97+
/**
98+
* @brief Creates the `AuthenticationCredentials` instance.
99+
*
100+
* @param key The access key ID.
101+
* @param secret The access key secret.
102+
* @param endpoint_url The token endpoint URL.
103+
*/
104+
AuthenticationCredentials(std::string key, std::string secret,
105+
std::string endpoint_url);
106+
97107
/**
98108
* @brief Gets the access key ID from the `AuthenticationCredentials`
99109
* instance.
@@ -110,9 +120,18 @@ class AUTHENTICATION_API AuthenticationCredentials {
110120
*/
111121
const std::string& GetSecret() const;
112122

123+
/**
124+
* @brief Gets the token endpoint URL from the `AuthenticationCredentials`
125+
* instance.
126+
*
127+
* @return A const reference to the access token endpoint URL member.
128+
*/
129+
const std::string& GetEndpointUrl() const;
130+
113131
private:
114132
std::string key_;
115133
std::string secret_;
134+
std::string endpoint_url_;
116135
};
117136

118137
} // namespace authentication

olp-cpp-sdk-authentication/src/AuthenticationCredentials.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace {
2828
const std::regex kRegex{"\\s*=\\s*"};
2929
const std::string kHereAccessKeyId = "here.access.key.id";
3030
const std::string kHereAccessKeySecret = "here.access.key.secret";
31+
const std::string kHereTokenEndpointUrl = "here.token.endpoint.url";
3132

3233
/// Forms a default path that is valid for the current OS.
3334
std::string GetDefaultPath() {
@@ -57,6 +58,7 @@ boost::optional<AuthenticationCredentials>
5758
AuthenticationCredentials::ReadFromStream(std::istream& stream) {
5859
std::string access_key_id;
5960
std::string access_key_secret;
61+
std::string token_endpoint_url;
6062
std::string line;
6163

6264
while (std::getline(stream, line)) {
@@ -72,12 +74,15 @@ AuthenticationCredentials::ReadFromStream(std::istream& stream) {
7274
access_key_id = token[1];
7375
} else if (token[0] == kHereAccessKeySecret) {
7476
access_key_secret = token[1];
77+
} else if (token[0] == kHereTokenEndpointUrl) {
78+
token_endpoint_url = token[1];
7579
}
7680
}
7781

7882
return (!access_key_id.empty() && !access_key_secret.empty())
7983
? boost::make_optional<AuthenticationCredentials>(
80-
{std::move(access_key_id), std::move(access_key_secret)})
84+
{std::move(access_key_id), std::move(access_key_secret),
85+
std::move(token_endpoint_url)})
8186
: boost::none;
8287
}
8388

@@ -95,10 +100,22 @@ AuthenticationCredentials::AuthenticationCredentials(std::string key,
95100
std::string secret)
96101
: key_(std::move(key)), secret_(std::move(secret)) {}
97102

103+
AuthenticationCredentials::AuthenticationCredentials(std::string key,
104+
std::string secret,
105+
std::string endpoint_url)
106+
: key_(std::move(key)),
107+
secret_(std::move(secret)),
108+
endpoint_url_(std::move(endpoint_url)) {}
109+
98110
const std::string& AuthenticationCredentials::GetKey() const { return key_; }
99111

100112
const std::string& AuthenticationCredentials::GetSecret() const {
101113
return secret_;
102114
}
115+
116+
const std::string& AuthenticationCredentials::GetEndpointUrl() const {
117+
return endpoint_url_;
118+
}
119+
103120
} // namespace authentication
104121
} // namespace olp

olp-cpp-sdk-authentication/src/AutoRefreshingToken.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include "TokenRequest.h"
2929

3030
namespace {
31-
constexpr auto kLogTag = "authentication::AutoRefreshingToken";
31+
constexpr auto kLogTag = "AutoRefreshingToken";
3232

3333
std::chrono::steady_clock::time_point ComputeRefreshTime(
3434
const olp::authentication::TokenResponse& current_token,

olp-cpp-sdk-authentication/src/TokenEndpoint.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,8 @@
2828
namespace olp {
2929
namespace authentication {
3030

31-
namespace {
32-
static const std::string kOauth2TokenEndpoint = "/oauth2/token";
33-
static constexpr auto kLogTag = "TokenEndpoint";
34-
} // namespace
35-
36-
TokenEndpoint::TokenEndpoint(Settings settings) {
37-
// The underlying auth library expects a base URL and appends /oauth2/token
38-
// endpoint to it. Therefore if /oauth2/token is found it is stripped from the
39-
// endpoint URL provided. The underlying auth library should be updated to
40-
// support an arbitrary token endpoint URL.
41-
auto pos = settings.token_endpoint_url.find(kOauth2TokenEndpoint);
42-
if (pos != std::string::npos) {
43-
settings.token_endpoint_url.erase(pos, kOauth2TokenEndpoint.size());
44-
} else {
45-
OLP_SDK_LOG_ERROR(
46-
kLogTag,
47-
"Expected '/oauth2/token' endpoint in the token_endpoint_url. Only "
48-
"standard OAuth2 token endpoint URLs are supported.");
49-
}
50-
51-
impl_ = std::make_shared<TokenEndpointImpl>(std::move(settings));
52-
}
31+
TokenEndpoint::TokenEndpoint(Settings settings)
32+
: impl_(std::make_shared<TokenEndpointImpl>(std::move(settings))) {}
5333

5434
client::CancellationToken TokenEndpoint::RequestToken(
5535
const TokenRequest& token_request,

olp-cpp-sdk-authentication/src/TokenEndpointImpl.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,29 @@ constexpr auto kClientGrantType = "client_credentials";
5151
constexpr auto kLogTag = "TokenEndpointImpl";
5252
constexpr auto kErrorWrongTimestamp = 401204;
5353

54+
std::string GetBasePath(const std::string& base_string) {
55+
// Remove /oauth2/token from url to make sure only the base url is used
56+
auto new_base_string = base_string;
57+
auto pos = new_base_string.find(kOauthEndpoint);
58+
if (pos != std::string::npos) {
59+
new_base_string.erase(pos, std::strlen(kOauthEndpoint));
60+
}
61+
62+
OLP_SDK_LOG_INFO_F(
63+
kLogTag,
64+
"GetBasePath: old_token_endpoint_url='%s', token_endpoint_url='%s'",
65+
base_string.c_str(), new_base_string.c_str());
66+
67+
return new_base_string;
68+
}
69+
5470
AuthenticationSettings ConvertSettings(Settings settings) {
5571
AuthenticationSettings auth_settings;
5672
auth_settings.network_proxy_settings =
5773
std::move(settings.network_proxy_settings);
5874
auth_settings.network_request_handler =
5975
std::move(settings.network_request_handler);
60-
auth_settings.token_endpoint_url = std::move(settings.token_endpoint_url);
76+
auth_settings.token_endpoint_url = GetBasePath(settings.token_endpoint_url);
6177
auth_settings.use_system_time = settings.use_system_time;
6278
auth_settings.retry_settings = std::move(settings.retry_settings);
6379

olp-cpp-sdk-authentication/tests/AuthenticationCredentialsTest.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@
2323
#include <gtest/gtest.h>
2424
#include "olp/authentication/AuthenticationCredentials.h"
2525

26-
using namespace olp::authentication;
26+
namespace auth = olp::authentication;
2727

2828
namespace {
29-
const std::string valid_file_path = "existing.file";
30-
const std::string invalid_file_path = "nonexisting.file";
31-
const std::string valid_credentials =
29+
constexpr auto valid_file_path = "existing.file";
30+
constexpr auto invalid_file_path = "nonexisting.file";
31+
constexpr auto valid_credentials =
3232
"here.user.id = HERE-111\n"
3333
"here.client.id = 123\n"
3434
"here.access.key.id = 234\n"
3535
"here.access.key.secret = 345\n"
3636
"here.token.endpoint.url = https://account.api.here.com/oauth2/token";
37-
const std::string invalid_credentials =
37+
constexpr auto invalid_credentials =
3838
"here.user.id = HERE-111\n"
3939
"here.client.id = 222\n"
4040
"here.access.key.id = 333\n"
@@ -47,7 +47,8 @@ TEST(AuthenticationCredentialsTest, ReadFromStream) {
4747
SCOPED_TRACE("Credentials parse succeeds");
4848

4949
std::stringstream ss(valid_credentials);
50-
const auto credentials = AuthenticationCredentials::ReadFromStream(ss);
50+
const auto credentials =
51+
auth::AuthenticationCredentials::ReadFromStream(ss);
5152

5253
EXPECT_TRUE(credentials);
5354

@@ -58,7 +59,8 @@ TEST(AuthenticationCredentialsTest, ReadFromStream) {
5859
SCOPED_TRACE("Bad content in the stream");
5960

6061
std::stringstream ss(invalid_credentials);
61-
const auto credentials = AuthenticationCredentials::ReadFromStream(ss);
62+
const auto credentials =
63+
auth::AuthenticationCredentials::ReadFromStream(ss);
6264

6365
EXPECT_FALSE(credentials);
6466
}
@@ -74,27 +76,28 @@ TEST(AuthenticationCredentialsTest, ReadFromFile) {
7476
stream.close();
7577

7678
const auto credentials =
77-
AuthenticationCredentials::ReadFromFile(valid_file_path);
79+
auth::AuthenticationCredentials::ReadFromFile(valid_file_path);
7880

7981
EXPECT_TRUE(credentials);
82+
EXPECT_NE(credentials.value().GetEndpointUrl(), "");
8083

8184
// Remove the file.
82-
remove(valid_file_path.c_str());
85+
remove(valid_file_path);
8386
}
8487
{
8588
SCOPED_TRACE("Missing credential file");
8689

8790
const auto credentials =
88-
AuthenticationCredentials::ReadFromFile(invalid_file_path);
91+
auth::AuthenticationCredentials::ReadFromFile(invalid_file_path);
8992

9093
EXPECT_FALSE(credentials);
9194
}
9295
}
9396

9497

9598
TEST(AuthenticationCredentialsTest, CanBeCopied) {
96-
AuthenticationCredentials credentials("test_key", "test_secred");
97-
AuthenticationCredentials copy = credentials;
99+
auth::AuthenticationCredentials credentials("test_key", "test_secret");
100+
auth::AuthenticationCredentials copy = credentials;
98101
EXPECT_EQ(credentials.GetKey(), copy.GetKey());
99102
EXPECT_EQ(credentials.GetSecret(), copy.GetSecret());
100103
}

olp-cpp-sdk-core/src/client/OlpClient.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
namespace {
3939
constexpr auto kLogTag = "OlpClient";
4040
constexpr auto kApiKeyParam = "apiKey=";
41+
constexpr auto kHttpPrefix = "http://";
42+
constexpr auto kHttpsPrefix = "https://";
4143

4244
struct RequestSettings {
4345
explicit RequestSettings(const int initial_backdown_period_ms,
@@ -381,6 +383,8 @@ class OlpClient::OlpClientImpl {
381383
ParametersType default_headers_;
382384
OlpClientSettings settings_;
383385
PendingUrlRequestsPtr pending_requests_;
386+
387+
bool ValidateBaseUrl() const;
384388
};
385389

386390
OlpClient::OlpClientImpl::OlpClientImpl()
@@ -452,6 +456,13 @@ boost::optional<client::ApiError> OlpClient::OlpClientImpl::AddBearer(
452456
return boost::none;
453457
}
454458

459+
bool OlpClient::OlpClientImpl::ValidateBaseUrl() const {
460+
return base_url_.locked([](const std::string& base_url) {
461+
return base_url == "" || (base_url.find(kHttpPrefix) != std::string::npos ||
462+
base_url.find(kHttpsPrefix) != std::string::npos);
463+
});
464+
}
465+
455466
std::shared_ptr<http::NetworkRequest> OlpClient::OlpClientImpl::CreateRequest(
456467
const std::string& path, const std::string& method,
457468
const OlpClient::ParametersType& query_params,
@@ -505,6 +516,12 @@ CancellationToken OlpClient::OlpClientImpl::CallApi(
505516
return CancellationToken();
506517
}
507518

519+
if (!ValidateBaseUrl()) {
520+
callback({static_cast<int>(http::ErrorCode::INVALID_URL_ERROR),
521+
"Base URI does not contain a protocol"});
522+
return CancellationToken();
523+
}
524+
508525
auto network_request = CreateRequest(path, method, query_params,
509526
header_params, post_body, content_type);
510527

@@ -585,6 +602,12 @@ HttpResponse OlpClient::OlpClientImpl::CallApi(
585602
"Network request handler is empty.");
586603
}
587604

605+
if (!ValidateBaseUrl()) {
606+
return HttpResponse(
607+
static_cast<int>(olp::http::ErrorCode::INVALID_URL_ERROR),
608+
"Base URI does not contain a protocol");
609+
}
610+
588611
const auto& retry_settings = settings_.retry_settings;
589612
auto network_settings =
590613
http::NetworkSettings()
@@ -679,7 +702,7 @@ HttpResponse OlpClient::OlpClientImpl::CallApi(
679702
return response;
680703
}
681704

682-
OlpClient::OlpClient() : impl_(std::make_shared<OlpClientImpl>()){};
705+
OlpClient::OlpClient() : impl_(std::make_shared<OlpClientImpl>()) {}
683706
OlpClient::OlpClient(const OlpClientSettings& settings, std::string base_url)
684707
: impl_(std::make_shared<OlpClientImpl>(settings, std::move(base_url))) {}
685708
OlpClient::~OlpClient() = default;

0 commit comments

Comments
 (0)