diff --git a/backend/UniVerse.Api.Tests/Authorization/EndpointAuthorizationTests.cs b/backend/UniVerse.Api.Tests/Authorization/EndpointAuthorizationTests.cs index b94eb92..9252436 100644 --- a/backend/UniVerse.Api.Tests/Authorization/EndpointAuthorizationTests.cs +++ b/backend/UniVerse.Api.Tests/Authorization/EndpointAuthorizationTests.cs @@ -47,10 +47,13 @@ public class EndpointAuthorizationTests : IClassFixtureПолучить отзывы к лекции. + /// Только Admin или Teacher. /// ID лекции. /// Параметры пагинации. /// Список отзывов (пагинированный). /// Требуется аутентификация. + /// Требуется роль Admin или Teacher. /// Лекция не найдена. + [Authorize(Roles = "Admin,Teacher")] [HttpGet("{id:int}/reviews")] [ProducesResponseType(typeof(PagedResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Reviews(int id, [FromQuery] PaginationRequest pagination) => Ok(await _reviews.GetByLectureAsync(id, pagination)); diff --git a/backend/UniVerse.Api/Controllers/ReviewsController.cs b/backend/UniVerse.Api/Controllers/ReviewsController.cs index 781c89d..6c4634d 100644 --- a/backend/UniVerse.Api/Controllers/ReviewsController.cs +++ b/backend/UniVerse.Api/Controllers/ReviewsController.cs @@ -44,13 +44,17 @@ public class ReviewsController : ControllerBase CreatedAtAction(nameof(Get), new { id = 0 }, await _reviews.CreateAsync(CurrentUserId, req)); /// Получить отзыв по ID. + /// Только Admin или Teacher. /// ID отзыва. /// Данные отзыва (включая LLM-статус и сентимент). /// Требуется аутентификация. + /// Требуется роль Admin или Teacher. /// Отзыв не найден. + [Authorize(Roles = "Admin,Teacher")] [HttpGet("{id:int}")] [ProducesResponseType(typeof(ReviewDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Get(int id) => Ok(await _reviews.GetByIdAsync(id)); diff --git a/backend/UniVerse.Api/Controllers/UsersController.cs b/backend/UniVerse.Api/Controllers/UsersController.cs index 0b08da8..bfe1d9b 100644 --- a/backend/UniVerse.Api/Controllers/UsersController.cs +++ b/backend/UniVerse.Api/Controllers/UsersController.cs @@ -86,13 +86,17 @@ public class UsersController : ControllerBase } /// Получить отзывы пользователя. + /// Только Admin или Teacher. /// ID пользователя. /// Параметры пагинации. /// Список отзывов (пагинированный). /// Требуется аутентификация. + /// Требуется роль Admin или Teacher. + [Authorize(Roles = "Admin,Teacher")] [HttpGet("{id:int}/reviews")] [ProducesResponseType(typeof(PagedResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task Reviews(int id, [FromQuery] PaginationRequest pagination) => Ok(await _reviews.GetByUserAsync(id, pagination)); diff --git a/backend/UniVerse.Api/openapi.json b/backend/UniVerse.Api/openapi.json index c7e2f32..223c948 100644 --- a/backend/UniVerse.Api/openapi.json +++ b/backend/UniVerse.Api/openapi.json @@ -1827,7 +1827,7 @@ "Lectures" ], "summary": "Получить отзывы к лекции.", - "description": "**Required:** any authenticated user", + "description": "Только Admin или Teacher.\n\n**Required roles:** Admin, Teacher", "parameters": [ { "name": "id", @@ -1877,6 +1877,16 @@ } } }, + "403": { + "description": "Требуется роль Admin или Teacher.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, "404": { "description": "Лекция не найдена.", "content": { @@ -2501,7 +2511,7 @@ "Reviews" ], "summary": "Получить отзыв по ID.", - "description": "**Required:** any authenticated user", + "description": "Только Admin или Teacher.\n\n**Required roles:** Admin, Teacher", "parameters": [ { "name": "id", @@ -2535,6 +2545,16 @@ } } }, + "403": { + "description": "Требуется роль Admin или Teacher.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, "404": { "description": "Отзыв не найден.", "content": { @@ -3679,7 +3699,7 @@ "Users" ], "summary": "Получить отзывы пользователя.", - "description": "**Required:** any authenticated user", + "description": "Только Admin или Teacher.\n\n**Required roles:** Admin, Teacher", "parameters": [ { "name": "id", @@ -3728,6 +3748,16 @@ } } } + }, + "403": { + "description": "Требуется роль Admin или Teacher.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } } }, "security": [ diff --git a/frontend/src/components/ui/LectureCard.vue b/frontend/src/components/ui/LectureCard.vue index e536109..a3d090f 100644 --- a/frontend/src/components/ui/LectureCard.vue +++ b/frontend/src/components/ui/LectureCard.vue @@ -6,6 +6,7 @@ import AppIcon from '@/components/ui/AppIcon.vue' const props = defineProps<{ lecture: Lecture registered?: boolean + showRating?: boolean }>() const emit = defineEmits<{ register: [id: string] }>() const router = useRouter() @@ -78,7 +79,7 @@ function goDetail() {