Skip to content
Snippets Groups Projects
Commit 984b4791 authored by Florian Spreckelsen's avatar Florian Spreckelsen
Browse files

Merge branch 'f-dot-in-username' into 'dev'

F dot in username

See merge request !40
parents c634d5df 30a9005f
No related branches found
No related tags found
2 merge requests!42Release 0.2.0,!40F dot in username
Pipeline #25278 passed
Pipeline: caosdb-cppinttest

#25279

    ......@@ -84,7 +84,8 @@ test:
    script:
    - mkdir build
    - cd build
    - conan install .. -s "compiler.libcxx=libstdc++11"
    - VERSION="$(conan inspect --raw version ..)"
    - conan install -s "compiler.libcxx=libstdc++11" -o build_acm=True .. "caosdb/$VERSION@_/_"
    - cmake -DCMAKE_BUILD_TYPE=Debug ..
    - cmake --build . -j
    - cmake --build . -j --target unit_test_coverage
    ......
    ......@@ -46,6 +46,11 @@ IF (WIN32)
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
    ENDIF()
    IF (BUILD_ACM)
    message(STATUS "BUILD_ACM")
    add_compile_definitions("BUILD_ACM")
    ENDIF()
    ###########################################
    ### DEPENDENCY MANAGEMENT with CONAN
    ###########################################
    ......@@ -83,6 +88,12 @@ set(PROTO_FILES
    ${PROJECT_SOURCE_DIR}/proto/proto/caosdb/entity/v1/main.proto
    )
    IF (BUILD_ACM)
    list(APPEND PROTO_FILES
    ${PROJECT_SOURCE_DIR}/proto/proto/caosdb/acm/v1alpha1/main.proto
    )
    ENDIF()
    set(PROTO_PATH ${PROJECT_SOURCE_DIR}/proto/proto)
    # compiler binaries
    ......@@ -173,6 +184,7 @@ target_link_libraries(caosdb
    target_include_directories(caosdb PUBLIC
    $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
    $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
    $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/src>
    $<INSTALL_INTERFACE:include>
    )
    target_include_directories(caosdb SYSTEM PUBLIC
    ......@@ -231,12 +243,6 @@ target_link_libraries(cxxcaosdbcli
    ### LINTING with CLANG-TIDY and INCLUDE-WHAT-YOU-USE
    #######################################################
    ###########################################
    ### PARANOID COMPILER SETTINGS
    ###########################################
    option(PARANOID_COMPILER_SETTINGS "Enable extra-paranoid compiler settings
    (which may even flag errors for code in the dependencies. These only apply in
    Debug BUILD_TYPE with SKIP_LINTING=Off or when LINTING=On." OFF)
    include(CheckCXXCompilerFlag)
    include(CheckCCompilerFlag)
    ......
    ......@@ -44,8 +44,10 @@ endif
    .PHONY: help
    help:
    @echo "Targets:"
    @echo " conan-install - Install locally with Conan."
    @echo " style - auto-format the source files."
    @echo " conan-install - Install locally with Conan."
    @echo -e " conan-create - Create conan binary package in the local conan\n"\
    " repostory."
    style:
    $(CLANG_FORMAT) -i --verbose \
    ......@@ -65,11 +67,12 @@ conan-install-debug:
    .PHONY: conan-install-debug
    conan-create:
    conan create . -s $(CONAN_SETTINGS)
    conan create -s $(CONAN_SETTINGS) -o caosdb:build_acm=True . "caosdb/$$(conan inspect --raw version .)@_/_"
    .PHONY: conan-create
    conan-create-debug:
    conan create . -s $(CONAN_SETTINGS) -s build_type=Debug
    conan create -s $(CONAN_SETTINGS) -s build_type=Debug -o caosdb:build_acm=True . "caosdb/$$(conan inspect --raw version .)@_/_"
    .PHONY: conan-create-debug
    conan: conan-install conan-create
    ......
    ......@@ -10,8 +10,16 @@ class CaosdbConan(ConanFile):
    description = "C++ library for the CaosDB project"
    topics = ("data management", "caosdb")
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}
    options = {
    "shared": [True, False],
    "fPIC": [True, False],
    "build_acm": [True, False],
    }
    default_options = {
    "shared": False,
    "fPIC": True,
    "build_acm": False,
    }
    generators = "cmake"
    requires = [
    ("grpc/1.45.2"),
    ......@@ -41,14 +49,12 @@ class CaosdbConan(ConanFile):
    def build(self):
    cmake = CMake(self)
    if self.options.build_acm:
    cmake.definitions["BUILD_ACM"] = "On"
    cmake.configure(source_folder="")
    cmake.build()
    # Explicit way:
    # self.run('cmake %s/hello %s'
    # % (self.source_folder, cmake.command_line))
    # self.run("cmake --build . %s" % cmake.build_config)
    def package(self):
    self.copy("*.h", dst="include", src="include")
    self.copy("*.dll", dst="bin", keep_path=False)
    ......
    ......@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
    ### Added
    * Simple `User` class and methods for user creation/retrieval/deletion.
    ### Changed
    * Transaction::ExecuteAsynchronously is actually asynchronous now.
    ......
    ......@@ -50,6 +50,12 @@ set(libcaosdb_INCL
    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/file_error.h
    )
    IF(BUILD_ACM)
    list(APPEND libcaosdb_INCL
    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/acm/user.h
    )
    ENDIF()
    # pass variable to parent scope
    set(libcaosdb_INCL ${libcaosdb_INCL} PARENT_SCOPE)
    ......
    /*
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Affero General Public License as
    * published by the Free Software Foundation, either version 3 of the
    * License, or (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU Affero General Public License for more details.
    *
    * You should have received a copy of the GNU Affero General Public License
    * along with this program. If not, see <https://www.gnu.org/licenses/>.
    *
    */
    /**
    * @brief Users, together with roles, and permissions are a fundamental concept
    * of the access controll management of CaosDB.
    *
    * @file caosdb/acm/user.h
    * @author Timm Fitchen
    * @date 2022-06-29
    */
    #ifdef BUILD_ACM
    #ifndef CAOSDB_ACM_USER_H
    #define CAOSDB_ACM_USER_H
    #include <memory> // for unique_ptr
    #include <string> // for string
    namespace caosdb::connection {
    class Connection;
    }
    namespace caosdb::acm {
    /**
    * The UserImpl class is the delegate of the User class. It hides the
    * implementation details from the clients.
    */
    class UserImpl;
    /**
    * The User class is a delegator. The actual data is stored in a wrapped
    * UserImpl object.
    */
    class User {
    public:
    /**
    * Default constructor.
    *
    * Initialize a user without any name, realm, password...
    */
    User();
    /**
    * Constructor. Initialize a user in the given realm with the given name.
    */
    explicit User(std::string realm, std::string name);
    /**
    * Constructor. Initialize a user with the given name.
    */
    explicit User(std::string name);
    /**
    * Copy constructor.
    */
    User(const User &user);
    /**
    * Move constructor.
    *
    * The moved-from user is empty, but still usable.
    */
    User(User &&user) noexcept;
    /**
    * Copy assignment.
    */
    auto operator=(const User &user) -> User &;
    /**
    * Move assignment.
    *
    * The moved-from user is empty, but still usable.
    */
    auto operator=(User &&user) noexcept -> User &;
    /**
    * Dtor.
    */
    ~User();
    /**
    * Return a string representation of this user.
    */
    auto ToString() const -> std::string;
    /**
    * Return the name of this user or the empty string.
    */
    [[nodiscard]] auto GetName() const -> const std::string &;
    /**
    * Set the name of this user.
    */
    auto SetName(const std::string &name) -> void;
    /**
    * Return the realm of this user or the empty.
    */
    [[nodiscard]] auto GetRealm() const -> const std::string &;
    /**
    * Set the realm of this user.
    */
    auto SetRealm(const std::string &realm) -> void;
    /**
    * Return the password of this user or the empty string.
    */
    [[nodiscard]] auto GetPassword() const -> const std::string &;
    /**
    * Set the password of this user.
    */
    auto SetPassword(const std::string &password) -> void;
    friend class caosdb::connection::Connection;
    private:
    /**
    * Constructor. Create a user object from the given UserImpl delegate.
    */
    explicit User(std::unique_ptr<UserImpl> wrapped);
    /**
    * The UserImpl delegate.
    */
    std::unique_ptr<UserImpl> wrapped;
    };
    } // namespace caosdb::acm
    #endif
    #endif
    ......@@ -27,6 +27,10 @@
    * @date 2021-05-18
    * @brief Configuration and setup of the connection.
    */
    #ifdef BUILD_ACM
    #include "caosdb/acm/user.h" // for User
    #include "caosdb/acm/v1alpha1/main.grpc.pb.h" // for AccessControlMan...
    #endif
    #include "caosdb/authentication.h" // for Authenticator
    #include "caosdb/configuration.h" // for ConnectionConfigura...
    #include "caosdb/entity/v1/main.grpc.pb.h" // for EntityTransactionSe...
    ......@@ -41,6 +45,10 @@
    #include <string> // for string, basic_string
    namespace caosdb::connection {
    #ifdef BUILD_ACM
    using caosdb::acm::User;
    using caosdb::acm::v1alpha1::AccessControlManagementService;
    #endif
    using caosdb::authentication::Authenticator;
    using caosdb::configuration::ConnectionConfiguration;
    using caosdb::entity::v1::EntityTransactionService;
    ......@@ -89,8 +97,33 @@ public:
    return this->version_info.get();
    };
    /**
    * Create a new transaction object which uses this connection and return it.
    */
    [[nodiscard]] auto CreateTransaction() const -> std::unique_ptr<Transaction>;
    #ifdef BUILD_ACM
    /**
    * Retrieve a single user.
    */
    // TODO(tf) find a way to deal with this:
    // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
    [[nodiscard]] auto RetrieveSingleUser(const std::string &realm, const std::string &name) const
    -> User;
    /**
    * Create a new user.
    */
    auto CreateSingleUser(const User &user) const -> void;
    /**
    * Delete an existing user.
    */
    // 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;
    #endif
    private:
    /// GRPC-Channel (HTTP/2 Connection plus Authentication). We use a shared
    /// pointer because Transaction instances also own the channel.
    ......@@ -107,6 +140,12 @@ private:
    /// Service for file transmission (download and upload). We use a shared
    /// pointer because Transaction instances also own this service stub.
    std::shared_ptr<FileTransmissionService::Stub> file_transmission_service;
    #ifdef BUILD_ACM
    /// Service for Access Controll Management (Role, Useraccounts, Permissions).
    /// We use a unique pointer because only this connection owns and uses this
    /// service.
    std::unique_ptr<AccessControlManagementService::Stub> access_controll_management_service;
    #endif
    };
    /**
    ......
    ......@@ -39,5 +39,12 @@ set(libcaosdb_SRC
    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/status_code_description.cpp
    )
    IF(BUILD_ACM)
    list(APPEND libcaosdb_SRC
    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/acm/user.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/acm/user_impl.h
    )
    ENDIF()
    # pass variable to parent scope
    set(libcaosdb_SRC ${libcaosdb_SRC} PARENT_SCOPE)
    /*
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Affero General Public License as
    * published by the Free Software Foundation, either version 3 of the
    * License, or (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU Affero General Public License for more details.
    *
    * You should have received a copy of the GNU Affero General Public License
    * along with this program. If not, see <https://www.gnu.org/licenses/>.
    *
    */
    #include "caosdb/acm/user.h"
    #include "caosdb/acm/user_impl.h" // for UserImpl
    #include "caosdb/acm/v1alpha1/main.pb.h" // for ProtoUser
    #include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper
    #include <utility> // for move
    namespace caosdb::acm {
    using caosdb::utility::ScalarProtoMessageWrapper;
    using ProtoUser = caosdb::acm::v1alpha1::User;
    UserImpl::UserImpl() = default;
    UserImpl::UserImpl(std::string realm, std::string name) {
    if (!name.empty()) {
    this->wrapped->set_name(name);
    }
    if (!realm.empty()) {
    this->wrapped->set_realm(realm);
    }
    }
    UserImpl::UserImpl(ProtoUser *user) : ScalarProtoMessageWrapper<ProtoUser>(user) {}
    UserImpl::UserImpl(std::string name) : UserImpl("", std::move(name)) {}
    User::User() : wrapped(std::make_unique<UserImpl>()) {}
    User::User(std::unique_ptr<UserImpl> wrapped) : wrapped(std::move(wrapped)) {}
    User::User(std::string realm, std::string name)
    : wrapped(std::make_unique<UserImpl>(std::move(realm), std::move(name))) {}
    User::User(std::string name) : User({""}, std::move(name)) {}
    User::User(const User &user) : User() {
    this->wrapped->wrapped->CopyFrom(*(user.wrapped->wrapped));
    }
    User::User(User &&user) noexcept : wrapped(std::move(user.wrapped)) {
    user.wrapped = std::make_unique<UserImpl>();
    }
    auto User::operator=(const User &user) -> User & {
    if (this == &user) {
    return *this;
    }
    this->wrapped->wrapped->CopyFrom(*(user.wrapped->wrapped));
    return *this;
    }
    auto User::operator=(User &&user) noexcept -> User & {
    if (this == &user) {
    return *this;
    }
    this->wrapped = std::move(user.wrapped);
    user.wrapped = std::make_unique<UserImpl>();
    return *this;
    }
    User::~User() = default;
    auto User::GetName() const -> const std::string & { return this->wrapped->wrapped->name(); }
    auto User::SetName(const std::string &name) -> void {
    if (!name.empty()) {
    this->wrapped->wrapped->set_name(name);
    } else {
    this->wrapped->wrapped->clear_name();
    }
    }
    auto User::GetRealm() const -> const std::string & { return this->wrapped->wrapped->realm(); }
    auto User::SetRealm(const std::string &realm) -> void {
    if (!realm.empty()) {
    this->wrapped->wrapped->set_realm(realm);
    } else {
    this->wrapped->wrapped->clear_realm();
    }
    }
    auto User::GetPassword() const -> const std::string & { return this->wrapped->password; }
    auto User::SetPassword(const std::string &password) -> void {
    if (!password.empty()) {
    this->wrapped->password = password;
    } else {
    this->wrapped->password.clear();
    }
    }
    auto User::ToString() const -> std::string { return this->wrapped->ToString(); }
    } // namespace caosdb::acm
    /*
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Affero General Public License as
    * published by the Free Software Foundation, either version 3 of the
    * License, or (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU Affero General Public License for more details.
    *
    * You should have received a copy of the GNU Affero General Public License
    * along with this program. If not, see <https://www.gnu.org/licenses/>.
    *
    */
    #include "caosdb/acm/user.h"
    #include "caosdb/acm/v1alpha1/main.pb.h" // for ProtoUser
    #include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper
    #include <memory> // for unique_ptr
    #include <utility> // for move
    namespace caosdb::acm {
    using caosdb::utility::ScalarProtoMessageWrapper;
    using ProtoUser = caosdb::acm::v1alpha1::User;
    /**
    * UserImpl class is designed to hide the implementation which makes direct use
    * of the protobuf objects underneath from the clients of the caosdb library.
    */
    class UserImpl : public ScalarProtoMessageWrapper<ProtoUser> {
    public:
    UserImpl();
    /**
    * Constructor. Instanciate a user with the given name.
    */
    explicit UserImpl(std::string name);
    /**
    * Constructor. Instanciate a user with the given realm and name.
    */
    UserImpl(std::string realm, std::string name);
    /**
    * Constructor. Instanciate a user from the server's responces.
    */
    UserImpl(ProtoUser *user);
    friend class User;
    friend class caosdb::connection::Connection;
    private:
    std::string password;
    };
    } // namespace caosdb::acm
    ......@@ -20,6 +20,11 @@
    *
    */
    #include "caosdb/connection.h"
    #ifdef BUILD_ACM
    #include "caosdb/acm/user_impl.h" // for UserImpl
    #include "caosdb/acm/v1alpha1/main.grpc.pb.h" // for AccessControlMan...
    #include "caosdb/acm/v1alpha1/main.pb.h" // for CreateSingleUser...
    #endif
    #include "caosdb/configuration.h" // for ConnectionConfigur...
    #include "caosdb/exceptions.h" // for ConfigurationError
    #include "caosdb/info.h" // for VersionInfo
    ......@@ -32,8 +37,19 @@
    #include <grpcpp/support/status.h> // for Status
    #include <grpcpp/support/status_code_enum.h> // for StatusCode, UNAUTHENTIC...
    #include <string> // for string, operator+
    // IWYU pragma: no_include "net/proto2/public/repeated_field.h"
    namespace caosdb::connection {
    #ifdef BUILD_ACM
    using caosdb::acm::UserImpl;
    using caosdb::acm::v1alpha1::AccessControlManagementService;
    using caosdb::acm::v1alpha1::CreateSingleUserRequest;
    using caosdb::acm::v1alpha1::CreateSingleUserResponse;
    using caosdb::acm::v1alpha1::DeleteSingleUserRequest;
    using caosdb::acm::v1alpha1::DeleteSingleUserResponse;
    using caosdb::acm::v1alpha1::RetrieveSingleUserRequest;
    using caosdb::acm::v1alpha1::RetrieveSingleUserResponse;
    #endif
    using caosdb::configuration::ConfigurationManager;
    using caosdb::configuration::ConnectionConfiguration;
    using caosdb::entity::v1::EntityTransactionService;
    ......@@ -53,6 +69,10 @@ Connection::Connection(const ConnectionConfiguration &configuration) {
    this->entity_transaction_service =
    std::make_shared<EntityTransactionService::Stub>(this->channel);
    this->file_transmission_service = std::make_shared<FileTransmissionService::Stub>(this->channel);
    #ifdef BUILD_ACM
    this->access_controll_management_service =
    std::make_unique<AccessControlManagementService::Stub>(this->channel);
    #endif
    }
    auto Connection::RetrieveVersionInfoNoExceptions() const noexcept -> TransactionStatus {
    ......@@ -97,6 +117,96 @@ auto Connection::RetrieveVersionInfo() const -> const VersionInfo & {
    return std::make_unique<Transaction>(entity_service, file_service);
    }
    #ifdef BUILD_ACM
    // TODO(tf) find a way to deal with this:
    // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
    [[nodiscard]] auto Connection::RetrieveSingleUser(const std::string &realm,
    const std::string &name) const -> User {
    RetrieveSingleUserRequest request;
    request.set_name(name);
    request.set_realm(realm);
    RetrieveSingleUserResponse response;
    grpc::ClientContext context;
    const grpc::Status grpc_status =
    this->access_controll_management_service->RetrieveSingleUser(&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();
    auto *user = response.release_user();
    return User(std::make_unique<UserImpl>(user));
    }
    // TODO(tf) find a way to deal with this:
    // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
    auto Connection::DeleteSingleUser(const std::string &realm, const std::string &name) const -> void {
    DeleteSingleUserRequest request;
    request.set_name(name);
    request.set_realm(realm);
    DeleteSingleUserResponse response;
    grpc::ClientContext context;
    const grpc::Status grpc_status =
    this->access_controll_management_service->DeleteSingleUser(&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();
    }
    auto Connection::CreateSingleUser(const User &user) const -> void {
    CreateSingleUserRequest request;
    request.set_allocated_user(user.wrapped->wrapped);
    request.mutable_password_setting()->set_password(user.GetPassword());
    CreateSingleUserResponse response;
    grpc::ClientContext context;
    const grpc::Status grpc_status =
    this->access_controll_management_service->CreateSingleUser(&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();
    }
    #endif
    auto ConnectionManager::mHasConnection(const std::string &name) const -> bool {
    auto it = connections.find(name);
    return it != connections.end();
    ......
    ......@@ -35,13 +35,19 @@ set(test_cases
    test_ccaosdb
    )
    IF(BUILD_ACM)
    list(APPEND test_cases
    test_user
    )
    ENDIF()
    ###################################################
    ### Set up tests using GoogleTest (GTest)
    ###################################################
    # special linting for tests
    set(_CMAKE_CXX_CLANG_TIDY_TEST_CHECKS
    "${_CMAKE_CXX_CLANG_TIDY_CHECKS},-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-function-cognitive-complexity,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-clang-analyzer-cplusplus.Move"
    "${_CMAKE_CXX_CLANG_TIDY_CHECKS},-cert-err58-cpp,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-owning-memory,-modernize-use-trailing-return-type,-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-function-cognitive-complexity,-cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,-clang-analyzer-cplusplus.Move,-clang-diagnostic-unused-result"
    )
    # add special cmake functions for gtest
    ......
    ......@@ -19,6 +19,9 @@
    * along with this program. If not, see <https://www.gnu.org/licenses/>.
    *
    */
    #ifdef BUILD_ACM
    #include "caosdb/acm/user.h" // for User
    #endif
    #include "caosdb/certificate_provider.h" // for PemCertificateProvider
    #include "caosdb/configuration.h" // for InsecureConnectionConfigura...
    #include "caosdb/connection.h" // for ConnectionManager
    ......@@ -31,6 +34,9 @@
    #include <string> // for operator+, string
    namespace caosdb::connection {
    #ifdef BUILD_ACM
    using caosdb::acm::User;
    #endif
    using caosdb::configuration::ConfigurationManager;
    using caosdb::configuration::InsecureConnectionConfiguration;
    using caosdb::configuration::PemCertificateProvider;
    ......@@ -87,4 +93,30 @@ TEST_F(test_connection, connection_manager_get_connection) {
    EXPECT_TRUE(ConnectionManager::GetConnection("local-caosdb-admin"));
    }
    #ifdef BUILD_ACM
    TEST_F(test_connection, test_create_single_user) {
    auto connection = ConnectionManager::GetDefaultConnection();
    User user;
    EXPECT_THROW_MESSAGE(connection->CreateSingleUser(user), caosdb::exceptions::ConnectionError,
    "The attempt to execute this transaction was not successful because the "
    "connection to the server could not be established.");
    }
    TEST_F(test_connection, test_delete_single_user) {
    auto connection = ConnectionManager::GetDefaultConnection();
    EXPECT_THROW_MESSAGE(connection->DeleteSingleUser("realm", "user"),
    caosdb::exceptions::ConnectionError,
    "The attempt to execute this transaction was not successful because the "
    "connection to the server could not be established.");
    }
    TEST_F(test_connection, test_retrieve_single_user) {
    auto connection = ConnectionManager::GetDefaultConnection();
    EXPECT_THROW_MESSAGE(auto results = connection->RetrieveSingleUser("realm", "user"),
    caosdb::exceptions::ConnectionError,
    "The attempt to execute this transaction was not successful because the "
    "connection to the server could not be established.");
    }
    #endif
    } // namespace caosdb::connection
    /*
    *
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Affero General Public License as
    * published by the Free Software Foundation, either version 3 of the
    * License, or (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU Affero General Public License for more details.
    *
    * You should have received a copy of the GNU Affero General Public License
    * along with this program. If not, see <https://www.gnu.org/licenses/>.
    *
    */
    #include "caosdb/acm/user.h" // for User
    #include <gtest/gtest-message.h> // for Message
    #include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiRe...
    #include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, TEST
    #include <string> // for allocator, string
    #include <utility> // for move
    namespace caosdb::acm {
    TEST(test_user, user_name) {
    auto user = User("user1");
    EXPECT_EQ(user.GetName(), "user1");
    user.SetName("user2");
    EXPECT_EQ(user.GetName(), "user2");
    }
    TEST(test_user, user_realm) {
    auto user1 = User("realm1", "user1");
    EXPECT_EQ(user1.GetName(), "user1");
    EXPECT_EQ(user1.GetRealm(), "realm1");
    user1.SetName("user3");
    EXPECT_EQ(user1.GetRealm(), "realm1");
    auto user2 = User("realm1", "user2");
    EXPECT_EQ(user2.GetRealm(), "realm1");
    EXPECT_EQ(user2.GetName(), "user2");
    user2.SetRealm("realm2");
    EXPECT_EQ(user2.GetRealm(), "realm2");
    EXPECT_EQ(user2.GetName(), "user2");
    }
    TEST(test_user, user_password) {
    auto user1 = User("realm1", "user1");
    user1.SetPassword("1234");
    EXPECT_EQ(user1.GetName(), "user1");
    EXPECT_EQ(user1.GetPassword(), "1234");
    user1.SetName("user3");
    EXPECT_EQ(user1.GetPassword(), "1234");
    auto user2 = User("realm1", "user2");
    user2.SetPassword("1234");
    EXPECT_EQ(user2.GetPassword(), "1234");
    EXPECT_EQ(user2.GetName(), "user2");
    user2.SetPassword("abcd");
    EXPECT_EQ(user2.GetPassword(), "abcd");
    EXPECT_EQ(user2.GetName(), "user2");
    }
    TEST(test_user, test_copy_constructor) {
    const auto user1 = User("user1");
    User user2(user1);
    EXPECT_EQ(user2.GetName(), "user1");
    EXPECT_EQ(user1.GetName(), "user1");
    user2.SetName("user2");
    EXPECT_EQ(user2.GetName(), "user2");
    EXPECT_EQ(user1.GetName(), "user1");
    }
    TEST(test_user, test_copy_assign) {
    const auto user1 = User("user1");
    auto user2 = user1;
    EXPECT_EQ(user2.GetName(), "user1");
    user2.SetName("user2");
    EXPECT_EQ(user2.GetName(), "user2");
    EXPECT_EQ(user1.GetName(), "user1");
    }
    TEST(test_user, test_move_constructor) {
    auto user1 = User("user1");
    User user2(std::move(user1));
    EXPECT_EQ(user2.GetName(), "user1");
    // NOLINTNEXTLINE
    EXPECT_EQ(user1.GetName(), "");
    }
    TEST(test_user, test_move_assign) {
    auto user1 = User("user2");
    user1.SetPassword("1234");
    EXPECT_EQ(user1.GetName(), "user2");
    EXPECT_EQ(user1.GetPassword(), "1234");
    User user2;
    user2 = std::move(user1);
    EXPECT_EQ(user2.GetName(), "user2");
    EXPECT_EQ(user2.GetPassword(), "1234");
    // NOLINTNEXTLINE
    EXPECT_EQ(user1.GetName(), "");
    // NOLINTNEXTLINE
    EXPECT_EQ(user1.GetPassword(), "");
    }
    } // namespace caosdb::acm
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment