Skip to content

Commit e9f85f3

Browse files
authored
Feat[MQB]: Add authn plugin (#990)
Signed-off-by: Emelia Lei <[email protected]>
1 parent 1573133 commit e9f85f3

18 files changed

+6997
-938
lines changed

src/groups/mqb/group/mqb.mem

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mqba
2+
mqbauthn
23
mqbblp
34
mqbc
45
mqbcfg
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// Copyright 2016-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+
#include <mqbauthn_anonauthenticator.h>
17+
18+
// MQB
19+
#include <mqbcfg_messages.h>
20+
#include <mqbplug_authenticator.h>
21+
22+
// BDE
23+
#include <bsl_iostream.h>
24+
#include <bsl_memory.h>
25+
#include <bsl_string.h>
26+
#include <bsl_string_view.h>
27+
#include <bsla_annotations.h>
28+
#include <bslma_allocator.h>
29+
#include <bslma_managedptr.h>
30+
#include <bsls_assert.h>
31+
32+
namespace BloombergLP {
33+
namespace mqbauthn {
34+
35+
const char* AnonAuthenticator::k_NAME = "AnonAuthenticator";
36+
const char* AnonAuthenticator::k_MECHANISM = "ANONYMOUS";
37+
38+
// ------------------------------
39+
// class AnonAuthenticationResult
40+
// ------------------------------
41+
42+
AnonAuthenticationResult::AnonAuthenticationResult(
43+
bsl::string_view principal,
44+
bsl::optional<bsls::Types::Int64> lifetimeMs,
45+
bslma::Allocator* allocator)
46+
: d_principal(principal, allocator)
47+
, d_lifetimeMs(lifetimeMs)
48+
{
49+
}
50+
51+
AnonAuthenticationResult::~AnonAuthenticationResult()
52+
{
53+
}
54+
55+
bsl::string_view AnonAuthenticationResult::principal() const
56+
{
57+
return d_principal;
58+
}
59+
60+
const bsl::optional<bsls::Types::Int64>&
61+
AnonAuthenticationResult::lifetimeMs() const
62+
{
63+
return d_lifetimeMs;
64+
}
65+
66+
// -----------------------
67+
// class AnonAuthenticator
68+
// -----------------------
69+
70+
AnonAuthenticator::AnonAuthenticator(
71+
const mqbcfg::AuthenticatorPluginConfig* config,
72+
bslma::Allocator* allocator)
73+
: d_allocator_p(allocator)
74+
, d_isStarted(false)
75+
, d_shouldPass(true)
76+
{
77+
if (!config) {
78+
BALL_LOG_INFO << "No configuration provided, using the default "
79+
"shouldPass = true";
80+
return;
81+
}
82+
83+
// Load the configured `shouldPass` argument
84+
bool isShouldPassFound = false;
85+
bsl::vector<mqbcfg::PluginSettingKeyValue>::const_iterator it =
86+
config->settings().cbegin();
87+
for (; it != config->settings().cend(); ++it) {
88+
if (it->key() == "shouldPass") {
89+
if (!it->value().isBoolValValue()) {
90+
BALL_LOG_WARN
91+
<< "Expected bool for 'shouldPass' setting, got type id = "
92+
<< it->value().selectionId();
93+
continue;
94+
}
95+
if (isShouldPassFound) {
96+
BALL_LOG_WARN << "Encountered duplicating setting "
97+
"'shouldPass', overriding";
98+
}
99+
d_shouldPass = it->value().boolVal();
100+
isShouldPassFound = true;
101+
}
102+
}
103+
if (isShouldPassFound) {
104+
BALL_LOG_INFO << "Setting found in configuration: using shouldPass = "
105+
<< (d_shouldPass ? "true" : "false");
106+
}
107+
else {
108+
BALL_LOG_INFO << "Setting not found in configuration: using the "
109+
"default shouldPass = "
110+
<< (d_shouldPass ? "true" : "false");
111+
}
112+
}
113+
114+
AnonAuthenticator::~AnonAuthenticator()
115+
{
116+
// PRECONDITIONS
117+
BSLS_ASSERT_OPT(!d_isStarted &&
118+
"stop() must be called before destroying this object");
119+
}
120+
121+
bsl::string_view AnonAuthenticator::name() const
122+
{
123+
return k_NAME;
124+
}
125+
126+
bsl::string_view AnonAuthenticator::mechanism() const
127+
{
128+
return k_MECHANISM;
129+
}
130+
131+
int AnonAuthenticator::authenticate(
132+
bsl::ostream& errorDescription,
133+
bsl::shared_ptr<mqbplug::AuthenticationResult>* result,
134+
BSLA_UNUSED const mqbplug::AuthenticationData& input) const
135+
{
136+
// PRECONDITIONS
137+
BSLS_ASSERT_SAFE(result);
138+
139+
if (d_shouldPass) {
140+
BALL_LOG_INFO << "AnonAuthenticator: "
141+
<< "authentication passed for mechanism '" << mechanism()
142+
<< "' unconditionally (shouldPass = true).";
143+
144+
// No `lifetime` is returned since we don't expect a user to
145+
// reauthenticate if they don't know how to authenticate in the first
146+
// place.
147+
*result = bsl::allocate_shared<AnonAuthenticationResult>(d_allocator_p,
148+
"",
149+
bsl::nullopt);
150+
return 0; // RETURN
151+
}
152+
else {
153+
BALL_LOG_INFO << "AnonAuthenticator: "
154+
<< "authentication failed for mechanism '" << mechanism()
155+
<< "' unconditionally (shouldPass = false).";
156+
157+
errorDescription << "Authentication rejected by AnonAuthenticator";
158+
159+
// Always return failure - do not populate result
160+
return -1; // RETURN
161+
}
162+
}
163+
164+
int AnonAuthenticator::start(bsl::ostream& errorDescription)
165+
{
166+
if (d_isStarted) {
167+
errorDescription << "start() can only be called once on this object";
168+
return -1; // RETURN
169+
}
170+
171+
d_isStarted = true;
172+
173+
BALL_LOG_INFO << "AnonAuthenticator started with shouldPass = "
174+
<< (d_shouldPass ? "true" : "false");
175+
176+
return 0;
177+
}
178+
179+
void AnonAuthenticator::stop()
180+
{
181+
if (!d_isStarted) {
182+
return; // RETURN
183+
}
184+
185+
d_isStarted = false;
186+
187+
BALL_LOG_INFO << "AnonAuthenticator stopped";
188+
}
189+
190+
// ------------------------------------
191+
// class AnonAuthenticatorPluginFactory
192+
// ------------------------------------
193+
194+
AnonAuthenticatorPluginFactory::AnonAuthenticatorPluginFactory()
195+
{
196+
// NOTHING
197+
}
198+
199+
AnonAuthenticatorPluginFactory::~AnonAuthenticatorPluginFactory()
200+
{
201+
// NOTHING
202+
}
203+
204+
bslma::ManagedPtr<mqbplug::Authenticator>
205+
AnonAuthenticatorPluginFactory::create(bslma::Allocator* allocator)
206+
{
207+
const mqbcfg::AuthenticatorPluginConfig* config =
208+
mqbplug::AuthenticatorUtil::findAuthenticatorConfig(
209+
AnonAuthenticator::k_NAME);
210+
211+
return bslma::ManagedPtr<mqbplug::Authenticator>(
212+
new (*allocator) AnonAuthenticator(config, allocator),
213+
allocator);
214+
}
215+
216+
} // close package namespace
217+
} // close enterprise namespace

0 commit comments

Comments
 (0)