diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 20438ea06893f3abf141cb4a82cc474812f362b9..66d8b3660215477bf3e0ba83b7f115d7637352fe 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Connection::ListUsers method + ### Changed - Updated dependency versions. diff --git a/include/caosdb/connection.h b/include/caosdb/connection.h index d0414f2e84f81fe9e86a50f2e6411788cf0befeb..e2a17390293f43bf2d6cc8a2af77f5ca23ab13d0 100644 --- a/include/caosdb/connection.h +++ b/include/caosdb/connection.h @@ -43,6 +43,9 @@ #include <map> // for map #include <memory> // for shared_ptr, unique_ptr #include <string> // for string, basic_string +#ifdef BUILD_ACM +#include <vector> // for vector +#endif namespace caosdb::connection { #ifdef BUILD_ACM @@ -122,6 +125,11 @@ public: // TODO(tf) find a way to deal with this: // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) auto DeleteSingleUser(const std::string &realm, const std::string &name) const -> void; + + /** + * List known users. + */ + auto ListUsers() const -> std::vector<User>; #endif private: diff --git a/requirements.txt b/requirements.txt index b0410ad5624768205f16743a17bef2d9e34ead66..c3029f4aa360788c3c32abbae097f5a0023a5c42 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ pluginbase==1.0.1 Pygments==2.13.0 PyJWT==2.6.0 python-dateutil==2.8.2 -PyYAML==6.0 +PyYAML==6.0.1 requests==2.28.1 six==1.16.0 tqdm==4.64.1 diff --git a/src/caosdb/connection.cpp b/src/caosdb/connection.cpp index 4c77c5254c1300e908622882cd01d29d7b0aab65..550e35aac5c58383b7a8129bc68330769c5260ad 100644 --- a/src/caosdb/connection.cpp +++ b/src/caosdb/connection.cpp @@ -36,6 +36,9 @@ #include <grpcpp/create_channel.h> // for CreateChannel #include <grpcpp/support/status.h> // for Status #include <string> // for string, operator+ +#ifdef BUILD_ACM +#include <vector> // for vector +#endif // IWYU pragma: no_include "net/proto2/public/repeated_field.h" namespace caosdb::connection { @@ -46,6 +49,8 @@ using caosdb::acm::v1alpha1::CreateSingleUserRequest; using caosdb::acm::v1alpha1::CreateSingleUserResponse; using caosdb::acm::v1alpha1::DeleteSingleUserRequest; using caosdb::acm::v1alpha1::DeleteSingleUserResponse; +using caosdb::acm::v1alpha1::ListUsersRequest; +using caosdb::acm::v1alpha1::ListUsersResponse; using caosdb::acm::v1alpha1::RetrieveSingleUserRequest; using caosdb::acm::v1alpha1::RetrieveSingleUserResponse; #endif @@ -204,6 +209,37 @@ auto Connection::CreateSingleUser(const User &user) const -> void { } status.ThrowExceptionIfError(); } + +auto Connection::ListUsers() const -> std::vector<User> { + ListUsersRequest request; + ListUsersResponse response; + grpc::ClientContext context; + const grpc::Status grpc_status = + this->access_controll_management_service->ListUsers(&context, request, &response); + auto status = TransactionStatus::SUCCESS(); + if (!grpc_status.ok()) { + switch (grpc_status.error_code()) { + case grpc::StatusCode::UNAUTHENTICATED: + status = TransactionStatus::AUTHENTICATION_ERROR(grpc_status.error_message()); + break; + case grpc::StatusCode::UNAVAILABLE: + status = TransactionStatus::CONNECTION_ERROR(); + break; + default: + auto error_message = grpc_status.error_message(); + status = TransactionStatus::RPC_ERROR(std::to_string(grpc_status.error_code()) + " - " + + error_message); + } + } + status.ThrowExceptionIfError(); + + std::vector<User> results; + for (auto &user : *(response.mutable_users())) { + results.push_back(User(std::make_unique<UserImpl>(&user))); + } + + return results; +} #endif auto ConnectionManager::mHasConnection(const std::string &name) const -> bool {