Skip to content

Commit 4e37ea4

Browse files
committed
Keep track of the authenticated external users
Build a map containing all of the authenticated external users to avoid having to rebuild that by iterating over all of the connections when requested Change-Id: I2e7779214b9ecf4eebe8f3ec6b7c85a946f1b3bf Reviewed-on: http://review.couchbase.org/100261 Tested-by: Build Bot <[email protected]> Reviewed-by: Daniel Owen <[email protected]>
1 parent 4d2c36d commit 4e37ea4

8 files changed

+86
-176
lines changed

daemon/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ ADD_LIBRARY(memcached_daemon STATIC
126126
protocol/mcbp/flush_command_context.h
127127
protocol/mcbp/gat_context.cc
128128
protocol/mcbp/gat_context.h
129-
protocol/mcbp/get_active_external_users_command_context.cc
130-
protocol/mcbp/get_active_external_users_command_context.h
131129
protocol/mcbp/get_cmd_timer_executor.cc
132130
protocol/mcbp/get_context.cc
133131
protocol/mcbp/get_context.h

daemon/connection.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "buckets.h"
2121
#include "connections.h"
22+
#include "external_auth_manager_thread.h"
2223
#include "mc_time.h"
2324
#include "mcaudit.h"
2425
#include "memcached.h"
@@ -240,6 +241,9 @@ nlohmann::json Connection::toJSON() const {
240241
}
241242

242243
void Connection::restartAuthentication() {
244+
if (authenticated && domain == cb::sasl::Domain::External) {
245+
externalAuthManager->logoff(username);
246+
}
243247
sasl_conn.reset();
244248
internal = false;
245249
authenticated = false;
@@ -1274,6 +1278,10 @@ Connection::Connection(SOCKET sfd, event_base* b, const ListeningPort& ifc)
12741278
}
12751279

12761280
Connection::~Connection() {
1281+
if (authenticated && domain == cb::sasl::Domain::External) {
1282+
externalAuthManager->logoff(username);
1283+
}
1284+
12771285
releaseReservedItems();
12781286
for (auto* ptr : temp_alloc) {
12791287
cb_free(ptr);

daemon/external_auth_manager_thread.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,43 @@ void ExternalAuthManagerThread::purgePendingDeadConnections() {
267267
mutex.lock();
268268
}
269269
}
270+
271+
void ExternalAuthManagerThread::login(const std::string& user) {
272+
activeUsers.login(user);
273+
}
274+
275+
void ExternalAuthManagerThread::logoff(const std::string& user) {
276+
activeUsers.logoff(user);
277+
}
278+
279+
nlohmann::json ExternalAuthManagerThread::getActiveUsers() const {
280+
return activeUsers.to_json();
281+
}
282+
283+
void ExternalAuthManagerThread::ActiveUsers::login(const std::string& user) {
284+
std::lock_guard<std::mutex> guard(mutex);
285+
users[user]++;
286+
}
287+
288+
void ExternalAuthManagerThread::ActiveUsers::logoff(const std::string& user) {
289+
std::lock_guard<std::mutex> guard(mutex);
290+
auto iter = users.find(user);
291+
if (iter == users.end()) {
292+
throw std::runtime_error("ActiveUsers::logoff: Failed to find user");
293+
}
294+
iter->second--;
295+
if (iter->second == 0) {
296+
users.erase(iter);
297+
}
298+
}
299+
300+
nlohmann::json ExternalAuthManagerThread::ActiveUsers::to_json() const {
301+
std::lock_guard<std::mutex> guard(mutex);
302+
auto ret = nlohmann::json::array();
303+
304+
for (const auto& entry : users) {
305+
ret.push_back(entry.first);
306+
}
307+
308+
return ret;
309+
}

daemon/external_auth_manager_thread.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
#pragma once
1919

2020
#include <mcbp/protocol/response.h>
21-
21+
#include <mcbp/protocol/status.h>
22+
#include <nlohmann/json_fwd.hpp>
2223
#include <platform/thread.h>
23-
24-
#include <include/mcbp/protocol/status.h>
2524
#include <gsl/gsl>
2625
#include <mutex>
2726
#include <queue>
@@ -46,6 +45,21 @@ class ExternalAuthManagerThread : public Couchbase::Thread {
4645
}
4746
ExternalAuthManagerThread(const ExternalAuthManagerThread&) = delete;
4847

48+
/**
49+
* The named (external) user logged on to the system
50+
*/
51+
void login(const std::string& user);
52+
53+
/**
54+
* The named (external) user logged off the system
55+
*/
56+
void logoff(const std::string& user);
57+
58+
/**
59+
* Get the list of active users defined in the system
60+
*/
61+
nlohmann::json getActiveUsers() const;
62+
4963
/**
5064
* Add the provided connection to the list of available authentication
5165
* providers
@@ -166,6 +180,19 @@ class ExternalAuthManagerThread : public Couchbase::Thread {
166180
std::queue<std::unique_ptr<AuthResponse>> incommingResponse;
167181

168182
std::vector<Connection*> pendingRemoveConnection;
183+
184+
class ActiveUsers {
185+
public:
186+
void login(const std::string& user);
187+
188+
void logoff(const std::string& user);
189+
190+
nlohmann::json to_json() const;
191+
192+
private:
193+
mutable std::mutex mutex;
194+
std::unordered_map<std::string, uint32_t> users;
195+
} activeUsers;
169196
};
170197

171198
extern std::unique_ptr<ExternalAuthManagerThread> externalAuthManager;

daemon/mcbp_executors.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "protocol/mcbp/executors.h"
4040
#include "protocol/mcbp/flush_command_context.h"
4141
#include "protocol/mcbp/gat_context.h"
42-
#include "protocol/mcbp/get_active_external_users_command_context.h"
4342
#include "protocol/mcbp/get_context.h"
4443
#include "protocol/mcbp/get_locked_context.h"
4544
#include "protocol/mcbp/get_meta_context.h"
@@ -560,7 +559,13 @@ static void auth_provider_executor(Cookie& cookie) {
560559
}
561560

562561
static void get_active_external_users_executor(Cookie& cookie) {
563-
cookie.obtainContext<GetActiveExternalUsersCommandContext>(cookie).drive();
562+
auto users = externalAuthManager->getActiveUsers().dump();
563+
cookie.sendResponse(cb::mcbp::Status::Success,
564+
{},
565+
{},
566+
cb::const_char_buffer{users},
567+
cb::mcbp::Datatype::JSON,
568+
0);
564569
}
565570

566571
static void no_support_executor(Cookie& cookie) {

daemon/protocol/mcbp/get_active_external_users_command_context.cc

Lines changed: 0 additions & 127 deletions
This file was deleted.

daemon/protocol/mcbp/get_active_external_users_command_context.h

Lines changed: 0 additions & 42 deletions
This file was deleted.

daemon/start_sasl_auth_task.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ void StartSaslAuthTask::externalAuthResponse(cb::mcbp::Status status,
117117
void StartSaslAuthTask::successfull_external_auth() {
118118
try {
119119
response.first = cb::sasl::Error::OK;
120+
externalAuthManager->login(serverContext.getUsername());
120121
serverContext.setDomain(cb::sasl::Domain::External);
121122
} catch (const std::exception& e) {
122123
LOG_WARNING(R"({} successfull_external_auth() failed. UUID[{}] "{}")",

0 commit comments

Comments
 (0)