Skip to content

Commit fbfddab

Browse files
committed
add CredentialProvider and AuthnCredential
Signed-off-by: Emelia Lei <[email protected]>
1 parent d875d88 commit fbfddab

15 files changed

+576
-29
lines changed

src/groups/bmq/bmqa/bmqa_session.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <bmqp_ctrlmsg_messages.h>
3434
#include <bmqp_messageguidgenerator.h>
3535
#include <bmqp_protocol.h>
36+
#include <bmqpi_credentialprovider.h>
37+
#include <bmqt_authncredential.h>
3638
#include <bmqt_correlationid.h>
3739
#include <bmqt_queueflags.h>
3840

@@ -59,6 +61,7 @@
5961
#include <bsls_assert.h>
6062
#include <bsls_atomic.h>
6163
#include <bsls_performancehint.h>
64+
#include <bslstl_sharedptr.h>
6265

6366
namespace BloombergLP {
6467
namespace bmqa {
@@ -251,11 +254,18 @@ int SessionUtil::createApplication(SessionImpl* sessionImpl)
251254

252255
// Authentication Message
253256
bmqp_ctrlmsg::AuthenticationMessage authenticaionMessage;
254-
bmqp_ctrlmsg::AuthenticateRequest& ar =
255-
authenticaionMessage.makeAuthenticateRequest();
256-
bsl::string str = "username:password";
257-
ar.mechanism() = "basic";
258-
ar.data() = bsl::vector<char>(str.begin(), str.end()); // hexBinary
257+
258+
bmqt::AuthnCredential credential;
259+
const bsl::shared_ptr<bmqpi::CredentialProvider>& credentialProvider =
260+
sessionImpl->d_sessionOptions.credentialProvider();
261+
if (credentialProvider) {
262+
credentialProvider->loadCredential(&credential);
263+
264+
bmqp_ctrlmsg::AuthenticateRequest& ar =
265+
authenticaionMessage.makeAuthenticateRequest();
266+
ar.mechanism() = credential.mechanism();
267+
ar.data() = credential.data();
268+
}
259269

260270
// Negotiation Message
261271
bmqp_ctrlmsg::NegotiationMessage negotiationMessage;

src/groups/bmq/bmqimp/bmqimp_application.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,12 @@ Application::Application(
605605
allocator),
606606
allocator)
607607
, d_initialConnectionChannelFactory(
608-
InitialConnectionChannelFactoryConfig(
609-
&d_statChannelFactory,
610-
authenticationMessage,
611-
sessionOptions.connectTimeout(), // TODO: different for authn?
612-
negotiationMessage,
613-
sessionOptions.connectTimeout(),
614-
d_blobSpPool_sp.get(),
615-
allocator),
608+
InitialConnectionChannelFactoryConfig(&d_statChannelFactory,
609+
authenticationMessage,
610+
negotiationMessage,
611+
sessionOptions.connectTimeout(),
612+
d_blobSpPool_sp.get(),
613+
allocator),
616614
allocator)
617615
, d_connectHandle_mp()
618616
, d_brokerSession(&d_scheduler,

src/groups/bmq/bmqimp/bmqimp_initialconnectionchannelfactory.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,14 @@ enum RcEnum {
6868
InitialConnectionChannelFactoryConfig::InitialConnectionChannelFactoryConfig(
6969
bmqio::ChannelFactory* base,
7070
const bmqp_ctrlmsg::AuthenticationMessage& authenticationMessage,
71-
const bsls::TimeInterval& authenticationTimeout,
7271
const bmqp_ctrlmsg::NegotiationMessage& negotiationMessage,
73-
const bsls::TimeInterval& negotiationTimeout,
72+
const bsls::TimeInterval& connectTimeout,
7473
BlobSpPool* blobSpPool_p,
7574
bslma::Allocator* basicAllocator)
7675
: d_baseFactory_p(base)
7776
, d_authenticationMessage(authenticationMessage, basicAllocator)
78-
, d_authenticationTimeout(authenticationTimeout)
7977
, d_negotiationMessage(negotiationMessage, basicAllocator)
80-
, d_negotiationTimeout(negotiationTimeout)
78+
, d_connectTimeout(connectTimeout)
8179
, d_blobSpPool_p(blobSpPool_p)
8280
, d_allocator_p(bslma::Default::allocator(basicAllocator))
8381
{
@@ -90,9 +88,8 @@ InitialConnectionChannelFactoryConfig::InitialConnectionChannelFactoryConfig(
9088
bslma::Allocator* basicAllocator)
9189
: d_baseFactory_p(original.d_baseFactory_p)
9290
, d_authenticationMessage(original.d_authenticationMessage, basicAllocator)
93-
, d_authenticationTimeout(original.d_authenticationTimeout)
9491
, d_negotiationMessage(original.d_negotiationMessage, basicAllocator)
95-
, d_negotiationTimeout(original.d_negotiationTimeout)
92+
, d_connectTimeout(original.d_connectTimeout)
9693
, d_blobSpPool_p(original.d_blobSpPool_p)
9794
, d_allocator_p(bslma::Default::allocator(basicAllocator))
9895
{
@@ -215,17 +212,15 @@ void InitialConnectionChannelFactory::readResponse(
215212

216213
bsl::string actionStr;
217214
bsl::string errorProperty;
218-
bsls::TimeInterval timeout;
215+
bsls::TimeInterval timeout = d_config.d_connectTimeout;
219216

220217
if (action == AUTHENTICATION) {
221218
actionStr = "authentication";
222219
errorProperty = "authenticationError";
223-
timeout = d_config.d_authenticationTimeout;
224220
}
225221
else if (action == NEGOTIATION) {
226222
actionStr = "negotiation";
227223
errorProperty = "negotiationError";
228-
timeout = d_config.d_negotiationTimeout;
229224
}
230225

231226
BALL_LOG_INFO << "Read response (" << actionStr << ")";
@@ -255,6 +250,16 @@ void InitialConnectionChannelFactory::authenticate(
255250
const ResultCallback& cb) const
256251
{
257252
BALL_LOG_INFO << "Client authenticate";
253+
254+
// If the authentication message is not an AuthenticateRequest,
255+
// then we assume that the broker is not using authentication.
256+
// In this case, we will skip the authentication step and proceed
257+
// directly to the negotiation step.
258+
if (!d_config.d_authenticationMessage.isAuthenticateRequestValue()) {
259+
negotiate(channel, cb);
260+
return; // RETURN
261+
}
262+
258263
sendRequest(channel, AUTHENTICATION, cb);
259264
readResponse(channel, AUTHENTICATION, cb);
260265
}
@@ -457,7 +462,7 @@ void InitialConnectionChannelFactory::onBrokerAuthenticationResponse(
457462
// Authentication SUCCEEDED
458463
BALL_LOG_INFO << "Authentication with broker was successful: " << response;
459464

460-
// TODO: do something
465+
// TODO: reauthenticate
461466

462467
negotiate(channel, cb);
463468
}

src/groups/bmq/bmqimp/bmqimp_initialconnectionchannelfactory.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ class InitialConnectionChannelFactoryConfig {
6666
// PRIVATE DATA
6767
bmqio::ChannelFactory* d_baseFactory_p;
6868
bmqp_ctrlmsg::AuthenticationMessage d_authenticationMessage;
69-
bsls::TimeInterval d_authenticationTimeout;
7069
bmqp_ctrlmsg::NegotiationMessage d_negotiationMessage;
71-
bsls::TimeInterval d_negotiationTimeout;
70+
bsls::TimeInterval d_connectTimeout;
7271
BlobSpPool* d_blobSpPool_p;
7372
bslma::Allocator* d_allocator_p;
7473

@@ -84,9 +83,8 @@ class InitialConnectionChannelFactoryConfig {
8483
InitialConnectionChannelFactoryConfig(
8584
bmqio::ChannelFactory* base,
8685
const bmqp_ctrlmsg::AuthenticationMessage& authenticationMessage,
87-
const bsls::TimeInterval& authenticationTimeout,
8886
const bmqp_ctrlmsg::NegotiationMessage& negotiationMessage,
89-
const bsls::TimeInterval& negotiationTimeout,
87+
const bsls::TimeInterval& d_connectTimeout,
9088
BlobSpPool* blobSpPool_p,
9189
bslma::Allocator* basicAllocator = 0);
9290

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2021-2025 Bloomberg Finance L.P.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
// bmqpi_credentialprovider.cpp -*-C++-*-
17+
#include <bmqpi_credentialprovider.h>
18+
19+
#include <bmqscm_version.h>
20+
namespace BloombergLP {
21+
namespace bmqpi {
22+
23+
// ------------------------
24+
// class CredentialProvider
25+
// ------------------------
26+
27+
CredentialProvider::~CredentialProvider()
28+
{
29+
// NOTHING
30+
}
31+
32+
} // close package namespace
33+
} // close enterprise namespace
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2021-2025 Bloomberg Finance L.P.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
// bmqpi_credentialprovider.h -*-C++-*-
17+
#ifndef INCLUDED_BMQPI_CREDENTIALPROVIDER
18+
#define INCLUDED_BMQPI_CREDENTIALPROVIDER
19+
20+
/// @file bmqpi_credentialprovider.h
21+
///
22+
/// @brief Provide an interface for providing the credential of the client.
23+
24+
// BMQ
25+
#include <bmqt_authncredential.h>
26+
27+
// BDE
28+
#include <bsl_functional.h>
29+
30+
namespace BloombergLP {
31+
namespace bmqpi {
32+
33+
// ========================
34+
// class CredentialProvider
35+
// ========================
36+
37+
/// A pure interface for providing the credential of the client.
38+
class CredentialProvider {
39+
public:
40+
// CREATORS
41+
42+
/// Destructor
43+
virtual ~CredentialProvider();
44+
45+
// MANIPULATORS
46+
47+
virtual void loadCredential(bmqt::AuthnCredential* credential) const = 0;
48+
};
49+
50+
} // close package namespace
51+
} // close enterprise namespace
52+
53+
#endif
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Copyright 2025 Bloomberg Finance L.P.
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
// bmqpi_credentialprovide.t.cpp -*-C++-*-
17+
#include <bmqpi_credentialprovider.h>
18+
19+
// BMQ
20+
#include <bmqt_authncredential.h>
21+
#include <bsla_unused.h>
22+
#include <bsls_protocoltest.h>
23+
24+
// TEST DRIVER
25+
#include <bmqtst_testhelper.h>
26+
27+
// CONVENIENCE
28+
using namespace BloombergLP;
29+
using namespace bsl;
30+
31+
/// A test implementation of the 'bmqpi::CredentialProvider` protocol.
32+
struct CredentialProviderTestImp
33+
: public bsls::ProtocolTestImp<bmqpi::CredentialProvider> {
34+
void loadCredential(bmqt::AuthnCredential* credential) const
35+
BSLS_KEYWORD_OVERRIDE;
36+
};
37+
38+
// Define one of CredentialProviderTestImp methods out-of-line, to instruct the
39+
// compiler to bake the class's vtable into *this* translation unit.
40+
void CredentialProviderTestImp::loadCredential(
41+
BSLA_UNUSED bmqt::AuthnCredential* credential) const
42+
{
43+
markDone();
44+
}
45+
46+
// ============================================================================
47+
// TESTS
48+
// ============================================================================
49+
50+
static void test1_breathingTest()
51+
// ------------------------------------------------------------------------
52+
// PROTOCOL TEST:
53+
// Ensure this class is a properly defined protocol class.
54+
//
55+
// Plan:
56+
//: 1 Define a concrete derived implementation, 'CredentialProviderTestImp',
57+
//: of the protocol.
58+
//:
59+
//: 2 Create an object of the 'bsls::ProtocolTest' class template
60+
//: parameterized by 'CredentialProviderTestImp', and use it to verify
61+
//: that:
62+
//:
63+
//: 1 The protocol is abstract. (C-1)
64+
//:
65+
//: 2 The protocol has no data members. (C-2)
66+
//:
67+
//: 3 The protocol has a virtual destructor. (C-3)
68+
//:
69+
//: 3 Use the 'BSLS_PROTOCOLTEST_ASSERT' macro to verify that
70+
//: non-creator methods of the protocol are:
71+
//:
72+
//: 1 virtual, (C-4)
73+
//:
74+
//: 2 publicly accessible. (C-5)
75+
//
76+
// Testing:
77+
// PROTOCOL TEST
78+
// ------------------------------------------------------------------------
79+
{
80+
bmqtst::TestHelper::printTestName("BREATHING TEST");
81+
82+
PV("Creating a concrete object");
83+
bsls::ProtocolTest<CredentialProviderTestImp> provider;
84+
85+
PV("Verify that the protocol is abstract");
86+
BMQTST_ASSERT(provider.testAbstract());
87+
88+
PV("Verify that there are no data members");
89+
BMQTST_ASSERT(provider.testNoDataMembers());
90+
91+
PV("Verify that the destructor is virtual");
92+
BMQTST_ASSERT(provider.testVirtualDestructor());
93+
94+
PV("Verify that all methods are public and virtual");
95+
96+
BSLS_PROTOCOLTEST_ASSERT(provider, loadCredential(NULL));
97+
}
98+
99+
// ============================================================================
100+
// MAIN PROGRAM
101+
// ----------------------------------------------------------------------------
102+
103+
int main(int argc, char* argv[])
104+
{
105+
TEST_PROLOG(bmqtst::TestHelper::e_DEFAULT);
106+
107+
switch (_testCase) {
108+
case 0:
109+
case 1: test1_breathingTest(); break;
110+
default: {
111+
cerr << "WARNING: CASE '" << _testCase << "' NOT FOUND." << bsl::endl;
112+
bmqtst::TestHelperUtil::testStatus() = -1;
113+
} break;
114+
}
115+
116+
TEST_EPILOG(bmqtst::TestHelper::e_CHECK_DEF_GBL_ALLOC);
117+
}

src/groups/bmq/bmqpi/package/bmqpi.mem

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
bmqpi_credentialprovider
12
bmqpi_dtcontext
23
bmqpi_dtspan
34
bmqpi_dttracer

0 commit comments

Comments
 (0)