Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions daemon/core/application/services/AuthService.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move header appendices to the corresponding commit where you change the file.

* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
#include "AuthService.h"

#include "core/application/dtos/UserDTO.h"
#include "core/application/errors/AuthError.h"
#include "presentation/Token.h"
namespace bxt::Core::Application {

coro::task<AuthService::Result<void>> AuthService::auth(std::string name,
Expand All @@ -31,4 +34,22 @@ coro::task<AuthService::Result<void>>
AuthService::verify(const std::string token) const {
}

coro::task<AuthService::Result<std::set<std::string>>>
AuthService::verify_user(const Presentation::Token token) const {
auto value = co_await m_user_repository.find_by_id_async(
token.name(), co_await m_uow_factory());
if (!value.has_value()) {
co_return bxt::make_error_with_source<AuthError>(
std::move(value.error()), AuthError::ErrorType::InternalError);
}

auto user_permissions = UserDTOMapper::to_dto(*value).permissions;
if (!user_permissions.has_value()) {
co_return bxt::make_error<AuthError>(
AuthError::ErrorType::InternalError);
}

co_return *user_permissions;
}

} // namespace bxt::Core::Application
5 changes: 5 additions & 0 deletions daemon/core/application/services/AuthService.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
#pragma once
#include "core/application/errors/AuthError.h"
#include "core/domain/repositories/UnitOfWorkBase.h"
#include "core/domain/repositories/UserRepository.h"
#include "presentation/Token.h"
#include "utilities/Error.h"
#include "utilities/errors/Macro.h"

Expand All @@ -30,6 +32,9 @@ class AuthService {

coro::task<Result<void>> verify(const std::string token) const;

coro::task<Result<std::set<std::string>>>
verify_user(const Presentation::Token token) const;

private:
Domain::UserRepository& m_user_repository;
Domain::UnitOfWorkBaseFactory& m_uow_factory;
Expand Down
14 changes: 14 additions & 0 deletions daemon/core/application/services/UserService.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
#include "UserService.h"

#include "core/application/dtos/UserDTO.h"
#include "core/application/errors/CrudError.h"
#include "utilities/Error.h"

Expand Down Expand Up @@ -117,4 +119,16 @@ coro::task<UserService::Result<std::vector<UserDTO>>>

co_return result;
}

coro::task<UserService::Result<UserDTO>>
UserService::get_user(std::string user_name) const {
auto value = co_await m_repository.find_by_id_async(
user_name, co_await m_uow_factory());
if (!value.has_value()) {
co_return bxt::make_error_with_source<CrudError>(
std::move(value.error()), CrudError::ErrorType::InternalError);
}

co_return UserDTOMapper::to_dto(*value);
}
} // namespace bxt::Core::Application
3 changes: 3 additions & 0 deletions daemon/core/application/services/UserService.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
Expand All @@ -23,6 +24,8 @@ class UserService {
virtual coro::task<Result<void>> remove_user(const std::string name);
virtual coro::task<Result<void>> update_user(const UserDTO user);
virtual coro::task<Result<std::vector<UserDTO>>> get_users() const;
virtual coro::task<Result<UserDTO>>
get_user(const std::string user_name) const;

private:
bxt::Core::Domain::UserRepository& m_repository;
Expand Down
19 changes: 19 additions & 0 deletions daemon/presentation/web-controllers/AuthController.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
Expand Down Expand Up @@ -164,6 +165,24 @@ drogon::Task<drogon::HttpResponsePtr>
co_return response;
}

drogon::Task<drogon::HttpResponsePtr>
AuthController::verify(drogon::HttpRequestPtr req) {
auto accesss_token = drogon_helpers::get_access_token(req, m_options.issuer,
m_options.secret);
if (!accesss_token.has_value()) {
co_return drogon_helpers::make_error_response(accesss_token.error(),
drogon::k401Unauthorized);
}

auto user_permissions = co_await m_service.verify_user(*accesss_token);
if (!user_permissions.has_value()) {
co_return drogon_helpers::make_error_response(
user_permissions.error().what());
}

co_return drogon_helpers::make_json_response(*user_permissions);
}

auto time_point_to_trantor_date(
const std::chrono::system_clock::time_point& time) {
auto microseconds_since_epoch =
Expand Down
3 changes: 3 additions & 0 deletions daemon/presentation/web-controllers/AuthController.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
Expand Down Expand Up @@ -39,12 +40,14 @@ class AuthController : public drogon::HttpController<AuthController, false> {
"/api/auth/refresh",
drogon::Get);
BXT_ADD_METHOD_TO(AuthController::revoke, "/api/auth/revoke", drogon::Post);
BXT_ADD_METHOD_TO(AuthController::verify, "/api/auth/verify", drogon::Get);

METHOD_LIST_END

drogon::Task<drogon::HttpResponsePtr> auth(drogon::HttpRequestPtr req);
drogon::Task<drogon::HttpResponsePtr> refresh(drogon::HttpRequestPtr req);
drogon::Task<drogon::HttpResponsePtr> revoke(drogon::HttpRequestPtr req);
drogon::Task<drogon::HttpResponsePtr> verify(drogon::HttpRequestPtr req);

private:
drogon::HttpResponsePtr make_token_response(Token& access_token,
Expand Down
16 changes: 16 additions & 0 deletions daemon/presentation/web-controllers/UserController.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
Expand Down Expand Up @@ -101,4 +102,19 @@ drogon::Task<drogon::HttpResponsePtr>
| std::ranges::to<std::vector>());
}

drogon::Task<drogon::HttpResponsePtr>
UserController::get_user(drogon::HttpRequestPtr req,
std::string user_name) {
BXT_JWT_CHECK_PERMISSIONS("users.get", req)

const auto user = co_await m_service.get_user(user_name);

if (!user.has_value()) {
co_return drogon_helpers::make_error_response(user.error().what());
}

co_return drogon_helpers::make_json_response(UserResponse {
user->name, user->permissions.value_or(std::set<std::string> {})});
}

} // namespace bxt::Presentation
9 changes: 9 additions & 0 deletions daemon/presentation/web-controllers/UserController.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2022 Artem Grinev <agrinev@manjaro.org>
* SPDX-FileCopyrightText: 2024 Daniil Lyudvig <thricht3r@yandex.ru>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
#pragma once
#include "core/application/services/PermissionService.h"
#include "core/application/services/UserService.h"
#include "drogon/HttpTypes.h"
#include "drogon/drogon_callbacks.h"
#include "utilities/drogon/Macro.h"

#include <drogon/HttpController.h>
Expand Down Expand Up @@ -38,6 +40,10 @@ class UserController : public drogon::HttpController<UserController, false> {

BXT_JWT_ADD_METHOD_TO(UserController::get_users, "/api/users", drogon::Get);

BXT_JWT_ADD_METHOD_TO(UserController::get_user,
"/api/users/{1}",
drogon::Get);

METHOD_LIST_END

drogon::Task<drogon::HttpResponsePtr> add_user(drogon::HttpRequestPtr req);
Expand All @@ -50,6 +56,9 @@ class UserController : public drogon::HttpController<UserController, false> {

drogon::Task<drogon::HttpResponsePtr> get_users(drogon::HttpRequestPtr req);

drogon::Task<drogon::HttpResponsePtr> get_user(drogon::HttpRequestPtr req,
std::string user_name);

private:
Core::Application::UserService& m_service;
Core::Application::PermissionService& m_permission_service;
Expand Down
40 changes: 40 additions & 0 deletions daemon/swagger/openapi.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ paths:
description: Invalid request
"401":
description: Unauthorized
/api/auth/verify:
get:
summary: Get current user permissions based on token provided
operationId: verify
responses:
"200":
description: List of user permissions
content:
application/json:
schema:
type: array
items:
type: string
"400":
description: Invalid request
"401":
description: Unauthorized
"500":
description: Internal error
/api/logs:
get:
summary: Get package logs
Expand Down Expand Up @@ -324,6 +343,27 @@ paths:
description: Invalid request
"403":
description: No permissions
/api/users/{user_name}:
get:
summary: Get user info
operationId: getUser
parameters:
- name: user_name
in: path
required: true
schema:
type: string
responses:
"200":
description: User info
content:
application/json:
schema:
$ref: "#/components/schemas/UserResponse"
"400":
description: Invalid request
"500":
description: Internal error

components:
securitySchemes:
Expand Down