Skip to content

Commit eba62fd

Browse files
UgnineSirdisGazizonoki
authored andcommitted
Fix ydb cli auth file options (#19577)
1 parent d1c65a2 commit eba62fd

File tree

8 files changed

+187
-165
lines changed

8 files changed

+187
-165
lines changed

.github/last_commit.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a01853cb85b51ba9c678dffd9d2c0cda8e7e55f3
1+
8e0f901efb6d5580fe9f5409b4cf761160fb7f24

include/ydb-cpp-sdk/client/iam/common/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct TIamEndpoint {
3333
TDuration RefreshPeriod = NIam::DEFAULT_REFRESH_PERIOD;
3434
TDuration RequestTimeout = NIam::DEFAULT_REQUEST_TIMEOUT;
3535
bool EnableSsl = NIam::DEFAULT_ENABLE_SSL;
36+
std::string CaCerts;
3637
};
3738

3839
struct TIamJwtFilename : TIamEndpoint { std::string JwtFilename; };

src/client/iam/common/iam.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class TGrpcIamCredentialsProvider : public ICredentialsProvider {
4545
NYdbGrpc::TGRpcClientConfig grpcConf;
4646
grpcConf.Locator = IamEndpoint_.Endpoint;
4747
grpcConf.EnableSsl = IamEndpoint_.EnableSsl;
48+
if (!IamEndpoint_.CaCerts.empty()) {
49+
grpcConf.SslCredentials.pem_root_certs = IamEndpoint_.CaCerts;
50+
}
4851
Connection_ = std::unique_ptr<NYdbGrpc::TServiceConnection<TService>>(Client->CreateGRpcServiceConnection<TService>(grpcConf).release());
4952
}
5053

tests/unit/client/oauth2_token_exchange/credentials_ut.cpp

Lines changed: 1 addition & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
#include <ydb-cpp-sdk/client/types/credentials/oauth2_token_exchange/credentials.h>
22
#include <ydb-cpp-sdk/client/types/credentials/oauth2_token_exchange/from_file.h>
3-
#include "jwt_check_helper.h"
3+
#include <tests/unit/client/oauth2_token_exchange/helpers/test_token_exchange_server.h>
44

55
#include <src/library/string_utils/base64/base64.h>
66

7-
#include <library/cpp/cgiparam/cgiparam.h>
8-
#include <library/cpp/http/misc/parsed_request.h>
9-
#include <library/cpp/http/server/http.h>
10-
#include <library/cpp/http/server/response.h>
117
#include <library/cpp/json/json_writer.h>
128
#include <library/cpp/testing/unittest/registar.h>
139
#include <library/cpp/testing/unittest/tests_data.h>
@@ -24,164 +20,6 @@ extern const std::string TestECPrivateKeyContent;
2420
extern const std::string TestECPublicKeyContent;
2521
extern const std::string TestHMACSecretKeyBase64Content;
2622

27-
class TTestTokenExchangeServer: public THttpServer::ICallBack {
28-
public:
29-
struct TCheck {
30-
bool ExpectRequest = true;
31-
HttpCodes StatusCode = HTTP_OK;
32-
TCgiParameters ExpectedInputParams;
33-
std::optional<TCgiParameters> InputParams;
34-
std::string Response;
35-
std::string ExpectedErrorPart;
36-
std::string Error;
37-
std::optional<TJwtCheck> SubjectJwtCheck;
38-
std::optional<TJwtCheck> ActorJwtCheck;
39-
40-
void Check() {
41-
UNIT_ASSERT_C(InputParams || !ExpectRequest, "Request error: " << Error);
42-
if (InputParams) {
43-
if (SubjectJwtCheck || ActorJwtCheck) {
44-
TCgiParameters inputParamsCopy = *InputParams;
45-
if (SubjectJwtCheck) {
46-
std::string subjectJwt;
47-
UNIT_ASSERT(inputParamsCopy.Has("subject_token"));
48-
UNIT_ASSERT(inputParamsCopy.Has("subject_token_type", "urn:ietf:params:oauth:token-type:jwt"));
49-
subjectJwt = inputParamsCopy.Get("subject_token");
50-
inputParamsCopy.Erase("subject_token");
51-
inputParamsCopy.Erase("subject_token_type");
52-
SubjectJwtCheck->Check(subjectJwt);
53-
}
54-
if (ActorJwtCheck) {
55-
std::string actorJwt;
56-
UNIT_ASSERT(inputParamsCopy.Has("actor_token"));
57-
UNIT_ASSERT(inputParamsCopy.Has("actor_token_type", "urn:ietf:params:oauth:token-type:jwt"));
58-
actorJwt = inputParamsCopy.Get("actor_token");
59-
inputParamsCopy.Erase("actor_token");
60-
inputParamsCopy.Erase("actor_token_type");
61-
ActorJwtCheck->Check(actorJwt);
62-
}
63-
UNIT_ASSERT_VALUES_EQUAL(ExpectedInputParams.Print(), inputParamsCopy.Print());
64-
} else {
65-
UNIT_ASSERT_VALUES_EQUAL(ExpectedInputParams.Print(), InputParams->Print());
66-
}
67-
}
68-
69-
if (!ExpectedErrorPart.empty()) {
70-
UNIT_ASSERT_STRING_CONTAINS(Error, ExpectedErrorPart);
71-
} else {
72-
UNIT_ASSERT(Error.empty());
73-
}
74-
}
75-
76-
void Reset() {
77-
Error.clear();
78-
InputParams = std::nullopt;
79-
}
80-
};
81-
82-
class TRequest: public TRequestReplier {
83-
public:
84-
explicit TRequest(TTestTokenExchangeServer* server)
85-
: Server(server)
86-
{
87-
}
88-
89-
bool DoReply(const TReplyParams& params) override {
90-
with_lock (Server->Lock) {
91-
const TParsedHttpFull parsed(params.Input.FirstLine());
92-
UNIT_ASSERT_VALUES_EQUAL(parsed.Path, "/exchange/token");
93-
const std::string bodyStr = params.Input.ReadAll();
94-
95-
Server->Check.InputParams.emplace(bodyStr);
96-
THttpResponse resp(Server->Check.StatusCode);
97-
resp.SetContent(TString{Server->Check.Response});
98-
resp.OutTo(params.Output);
99-
return true;
100-
}
101-
}
102-
103-
public:
104-
TTestTokenExchangeServer* Server = nullptr;
105-
};
106-
107-
TTestTokenExchangeServer()
108-
: HttpOptions(PortManager.GetPort())
109-
, HttpServer(this, HttpOptions)
110-
{
111-
HttpServer.Start();
112-
}
113-
114-
TClientRequest* CreateClient() override {
115-
return new TRequest(this);
116-
}
117-
118-
std::string GetEndpoint() const {
119-
return TStringBuilder() << "http://localhost:" << HttpOptions.Port << "/exchange/token";
120-
}
121-
122-
void Run(const std::function<void()>& f, bool checkExpectations = true) {
123-
Check.Reset();
124-
try {
125-
f();
126-
} catch (const std::exception& ex) {
127-
Check.Error = ex.what();
128-
}
129-
130-
if (checkExpectations) {
131-
CheckExpectations();
132-
}
133-
}
134-
135-
void Run(const TOauth2TokenExchangeParams& params, const std::string& expectedToken = {}, bool checkExpectations = true) {
136-
std::string token;
137-
Run([&]() {
138-
auto factory = CreateOauth2TokenExchangeCredentialsProviderFactory(params);
139-
if (!expectedToken.empty()) {
140-
token = factory->CreateProvider()->GetAuthInfo();
141-
}
142-
},
143-
checkExpectations);
144-
145-
if (!expectedToken.empty()) {
146-
UNIT_ASSERT_VALUES_EQUAL(expectedToken, token);
147-
}
148-
}
149-
150-
void RunFromConfig(const std::string& fileName, const std::string& expectedToken = {}, bool checkExpectations = true, const std::string& explicitTokenEndpoint = {}) {
151-
std::string token;
152-
Run([&]() {
153-
auto factory = CreateOauth2TokenExchangeFileCredentialsProviderFactory(fileName, explicitTokenEndpoint);
154-
if (!expectedToken.empty()) {
155-
token = factory->CreateProvider()->GetAuthInfo();
156-
}
157-
},
158-
checkExpectations);
159-
160-
if (!expectedToken.empty()) {
161-
UNIT_ASSERT_VALUES_EQUAL(expectedToken, token);
162-
}
163-
}
164-
165-
void CheckExpectations() {
166-
with_lock (Lock) {
167-
Check.Check();
168-
}
169-
}
170-
171-
void WithLock(const std::function<void()>& f) {
172-
with_lock (Lock) {
173-
f();
174-
}
175-
}
176-
177-
public:
178-
TAdaptiveLock Lock;
179-
TPortManager PortManager;
180-
THttpServer::TOptions HttpOptions;
181-
THttpServer HttpServer;
182-
TCheck Check;
183-
};
184-
18523
template <class TParent>
18624
struct TJsonFillerArray {
18725
TJsonFillerArray(TParent* parent, NJson::TJsonWriter* writer)
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "test_token_exchange_server.h"
2+
3+
void TTestTokenExchangeServer::Run(const std::function<void()>& f, bool checkExpectations) {
4+
Check.Reset();
5+
try {
6+
f();
7+
} catch (const std::exception& ex) {
8+
Check.Error = ex.what();
9+
}
10+
11+
if (checkExpectations) {
12+
CheckExpectations();
13+
}
14+
}
15+
16+
void TTestTokenExchangeServer::Run(const NYdb::TOauth2TokenExchangeParams& params, const std::string& expectedToken, bool checkExpectations) {
17+
std::string token;
18+
Run([&]() {
19+
auto factory = CreateOauth2TokenExchangeCredentialsProviderFactory(params);
20+
if (!expectedToken.empty()) {
21+
token = factory->CreateProvider()->GetAuthInfo();
22+
}
23+
},
24+
checkExpectations);
25+
26+
if (!expectedToken.empty()) {
27+
UNIT_ASSERT_VALUES_EQUAL(expectedToken, token);
28+
}
29+
}
30+
31+
void TTestTokenExchangeServer::RunFromConfig(const std::string& fileName, const std::string& expectedToken, bool checkExpectations, const std::string& explicitTokenEndpoint) {
32+
std::string token;
33+
Run([&]() {
34+
auto factory = NYdb::CreateOauth2TokenExchangeFileCredentialsProviderFactory(fileName, explicitTokenEndpoint);
35+
if (!expectedToken.empty()) {
36+
token = factory->CreateProvider()->GetAuthInfo();
37+
}
38+
},
39+
checkExpectations);
40+
41+
if (!expectedToken.empty()) {
42+
UNIT_ASSERT_VALUES_EQUAL(expectedToken, token);
43+
}
44+
}
45+
46+
void TTestTokenExchangeServer::TCheck::Check() {
47+
UNIT_ASSERT_C(InputParams || !ExpectRequest, "Request error: " << Error);
48+
if (InputParams) {
49+
if (SubjectJwtCheck || ActorJwtCheck) {
50+
TCgiParameters inputParamsCopy = *InputParams;
51+
if (SubjectJwtCheck) {
52+
std::string subjectJwt;
53+
UNIT_ASSERT(inputParamsCopy.Has("subject_token"));
54+
UNIT_ASSERT(inputParamsCopy.Has("subject_token_type", "urn:ietf:params:oauth:token-type:jwt"));
55+
subjectJwt = inputParamsCopy.Get("subject_token");
56+
inputParamsCopy.Erase("subject_token");
57+
inputParamsCopy.Erase("subject_token_type");
58+
SubjectJwtCheck->Check(subjectJwt);
59+
}
60+
if (ActorJwtCheck) {
61+
std::string actorJwt;
62+
UNIT_ASSERT(inputParamsCopy.Has("actor_token"));
63+
UNIT_ASSERT(inputParamsCopy.Has("actor_token_type", "urn:ietf:params:oauth:token-type:jwt"));
64+
actorJwt = inputParamsCopy.Get("actor_token");
65+
inputParamsCopy.Erase("actor_token");
66+
inputParamsCopy.Erase("actor_token_type");
67+
ActorJwtCheck->Check(actorJwt);
68+
}
69+
UNIT_ASSERT_VALUES_EQUAL(ExpectedInputParams.Print(), inputParamsCopy.Print());
70+
} else {
71+
UNIT_ASSERT_VALUES_EQUAL(ExpectedInputParams.Print(), InputParams->Print());
72+
}
73+
}
74+
75+
if (!ExpectedErrorPart.empty()) {
76+
UNIT_ASSERT_STRING_CONTAINS(Error, ExpectedErrorPart);
77+
} else {
78+
UNIT_ASSERT(Error.empty());
79+
}
80+
}
81+
82+
bool TTestTokenExchangeServer::TRequest::DoReply(const TReplyParams& params) {
83+
with_lock (Server->Lock) {
84+
const TParsedHttpFull parsed(params.Input.FirstLine());
85+
UNIT_ASSERT_VALUES_EQUAL(parsed.Path, "/exchange/token");
86+
const std::string bodyStr = params.Input.ReadAll();
87+
88+
Server->Check.InputParams.emplace(bodyStr);
89+
THttpResponse resp(Server->Check.StatusCode);
90+
resp.SetContent(TString{Server->Check.Response});
91+
resp.OutTo(params.Output);
92+
return true;
93+
}
94+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#pragma once
2+
#include "jwt_check_helper.h"
3+
4+
#include <ydb-cpp-sdk/client/types/credentials/oauth2_token_exchange/credentials.h>
5+
#include <ydb-cpp-sdk/client/types/credentials/oauth2_token_exchange/from_file.h>
6+
7+
#include <library/cpp/cgiparam/cgiparam.h>
8+
#include <library/cpp/http/misc/parsed_request.h>
9+
#include <library/cpp/http/server/http.h>
10+
#include <library/cpp/http/server/response.h>
11+
#include <library/cpp/json/json_writer.h>
12+
#include <library/cpp/testing/unittest/tests_data.h>
13+
14+
class TTestTokenExchangeServer: public THttpServer::ICallBack {
15+
public:
16+
struct TCheck {
17+
bool ExpectRequest = true;
18+
HttpCodes StatusCode = HTTP_OK;
19+
TCgiParameters ExpectedInputParams;
20+
std::optional<TCgiParameters> InputParams;
21+
std::string Response;
22+
std::string ExpectedErrorPart;
23+
std::string Error;
24+
std::optional<TJwtCheck> SubjectJwtCheck;
25+
std::optional<TJwtCheck> ActorJwtCheck;
26+
27+
void Check();
28+
29+
void Reset() {
30+
Error.clear();
31+
InputParams = std::nullopt;
32+
}
33+
};
34+
35+
class TRequest: public TRequestReplier {
36+
public:
37+
explicit TRequest(TTestTokenExchangeServer* server)
38+
: Server(server)
39+
{
40+
}
41+
42+
bool DoReply(const TReplyParams& params) override;
43+
44+
public:
45+
TTestTokenExchangeServer* Server = nullptr;
46+
};
47+
48+
TTestTokenExchangeServer()
49+
: HttpOptions(PortManager.GetPort())
50+
, HttpServer(this, HttpOptions)
51+
{
52+
HttpServer.Start();
53+
}
54+
55+
TClientRequest* CreateClient() override {
56+
return new TRequest(this);
57+
}
58+
59+
std::string GetEndpoint() const {
60+
return TStringBuilder() << "http://localhost:" << HttpOptions.Port << "/exchange/token";
61+
}
62+
63+
void Run(const std::function<void()>& f, bool checkExpectations = true);
64+
void Run(const NYdb::TOauth2TokenExchangeParams& params, const std::string& expectedToken = {}, bool checkExpectations = true);
65+
66+
void RunFromConfig(const std::string& fileName, const std::string& expectedToken = {}, bool checkExpectations = true, const std::string& explicitTokenEndpoint = {});
67+
68+
void CheckExpectations() {
69+
with_lock (Lock) {
70+
Check.Check();
71+
}
72+
}
73+
74+
void WithLock(const std::function<void()>& f) {
75+
with_lock (Lock) {
76+
f();
77+
}
78+
}
79+
80+
public:
81+
TAdaptiveLock Lock;
82+
TPortManager PortManager;
83+
THttpServer::TOptions HttpOptions;
84+
THttpServer HttpServer;
85+
TCheck Check;
86+
};

tests/unit/client/oauth2_token_exchange/jwt_token_source_ut.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <ydb-cpp-sdk/client/types/credentials/oauth2_token_exchange/jwt_token_source.h>
2-
#include "jwt_check_helper.h"
2+
#include <tests/unit/client/oauth2_token_exchange/helpers/jwt_check_helper.h>
33

44
#include <library/cpp/testing/unittest/registar.h>
55

0 commit comments

Comments
 (0)