mirror of
https://github.com/chenasraf/nextcloud-forum.git
synced 2026-05-18 01:28:58 +00:00
215 lines
6.2 KiB
PHP
215 lines
6.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
namespace OCA\Forum\Controller;
|
|
|
|
use OCA\Forum\Db\RoleMapper;
|
|
use OCA\Forum\Migration\SeedHelper;
|
|
use OCA\Forum\Service\StatsService;
|
|
use OCA\Forum\Service\UserRoleService;
|
|
use OCP\AppFramework\Http;
|
|
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
|
use OCP\AppFramework\Http\DataResponse;
|
|
use OCP\AppFramework\OCSController;
|
|
use OCP\IRequest;
|
|
use OCP\IUserManager;
|
|
use OCP\Migration\IOutput;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class ServerAdminController extends OCSController {
|
|
|
|
public function __construct(
|
|
string $appName,
|
|
IRequest $request,
|
|
private RoleMapper $roleMapper,
|
|
private UserRoleService $userRoleService,
|
|
private IUserManager $userManager,
|
|
private StatsService $statsService,
|
|
private LoggerInterface $logger,
|
|
) {
|
|
parent::__construct($appName, $request);
|
|
}
|
|
|
|
/**
|
|
* Get all available roles (for server admin panel)
|
|
*
|
|
* @return DataResponse<Http::STATUS_OK, array{roles: list<array<string, mixed>>}, array{}>
|
|
*
|
|
* 200: Roles list returned
|
|
*/
|
|
#[ApiRoute(verb: 'GET', url: '/api/server-admin/roles')]
|
|
public function getRoles(): DataResponse {
|
|
try {
|
|
$roles = $this->roleMapper->findAll();
|
|
$rolesData = array_map(fn ($role) => [
|
|
'id' => $role->getId(),
|
|
'name' => $role->getName(),
|
|
'roleType' => $role->getRoleType(),
|
|
], $roles);
|
|
return new DataResponse(['roles' => $rolesData]);
|
|
} catch (\Exception $e) {
|
|
$this->logger->error('Error fetching roles: ' . $e->getMessage());
|
|
return new DataResponse(['error' => 'Failed to fetch roles'], Http::STATUS_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assign a role to a user (from server admin panel)
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param int $roleId The role ID to assign
|
|
* @return DataResponse<Http::STATUS_OK, array{success: bool, message: string}, array{}>
|
|
*
|
|
* 200: Role assigned successfully
|
|
*/
|
|
#[ApiRoute(verb: 'POST', url: '/api/server-admin/users/{userId}/roles')]
|
|
public function assignRole(string $userId, int $roleId): DataResponse {
|
|
try {
|
|
$user = $this->userManager->get($userId);
|
|
if ($user === null) {
|
|
return new DataResponse([
|
|
'success' => false,
|
|
'message' => "User '$userId' does not exist.",
|
|
], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
try {
|
|
$role = $this->roleMapper->find($roleId);
|
|
} catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
|
|
return new DataResponse([
|
|
'success' => false,
|
|
'message' => "Role with ID '$roleId' does not exist.",
|
|
], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
if ($this->userRoleService->hasRole($userId, $roleId)) {
|
|
return new DataResponse([
|
|
'success' => true,
|
|
'message' => "User '$userId' already has the role '{$role->getName()}'.",
|
|
]);
|
|
}
|
|
|
|
$this->userRoleService->assignRole($userId, $roleId, skipIfExists: false);
|
|
$this->logger->info("Assigned role '{$role->getName()}' to user '$userId'");
|
|
|
|
return new DataResponse([
|
|
'success' => true,
|
|
'message' => "Successfully assigned role '{$role->getName()}' to user '$userId'.",
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->logger->error('Error assigning role: ' . $e->getMessage());
|
|
return new DataResponse([
|
|
'success' => false,
|
|
'message' => 'Failed to assign role: ' . $e->getMessage(),
|
|
], Http::STATUS_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run the repair seeds command to restore default forum data
|
|
*
|
|
* @return DataResponse<Http::STATUS_OK, array{success: bool, message: string}, array{}>
|
|
*
|
|
* 200: Seeds repaired successfully
|
|
*/
|
|
#[ApiRoute(verb: 'POST', url: '/api/server-admin/repair-seeds')]
|
|
public function repairSeeds(): DataResponse {
|
|
try {
|
|
$messages = [];
|
|
$migrationOutput = new class($messages) implements IOutput {
|
|
/** @var array<string> */
|
|
private array $messages;
|
|
|
|
public function __construct(array &$messages) {
|
|
$this->messages = &$messages;
|
|
}
|
|
|
|
public function info($message): void {
|
|
$this->messages[] = $message;
|
|
}
|
|
|
|
public function warning($message): void {
|
|
$this->messages[] = '[Warning] ' . $message;
|
|
}
|
|
|
|
public function debug($message): void {
|
|
$this->messages[] = '[Debug] ' . $message;
|
|
}
|
|
|
|
public function startProgress($max = 0): void {
|
|
}
|
|
|
|
public function advance($step = 1, $description = ''): void {
|
|
}
|
|
|
|
public function finishProgress(): void {
|
|
}
|
|
};
|
|
|
|
SeedHelper::seedAll($migrationOutput, true);
|
|
|
|
$this->logger->info('Forum repair seeds completed successfully');
|
|
return new DataResponse([
|
|
'success' => true,
|
|
'message' => implode("\n", $messages),
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->logger->error('Error running repair seeds: ' . $e->getMessage());
|
|
return new DataResponse([
|
|
'success' => false,
|
|
'message' => 'Failed to repair seeds: ' . $e->getMessage(),
|
|
], Http::STATUS_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rebuild all forum statistics (users, categories, threads)
|
|
*
|
|
* @return DataResponse<Http::STATUS_OK, array{success: bool, message: string}, array{}>
|
|
*
|
|
* 200: Stats rebuilt successfully
|
|
*/
|
|
#[ApiRoute(verb: 'POST', url: '/api/server-admin/rebuild-stats')]
|
|
public function rebuildStats(): DataResponse {
|
|
try {
|
|
$userResult = $this->statsService->rebuildAllUserStats();
|
|
$categoryResult = $this->statsService->rebuildAllCategoryStats();
|
|
$threadResult = $this->statsService->rebuildAllThreadStats();
|
|
|
|
$messages = [];
|
|
$messages[] = sprintf(
|
|
'Users processed: %d, created: %d, updated: %d',
|
|
$userResult['users'],
|
|
$userResult['created'],
|
|
$userResult['updated']
|
|
);
|
|
$messages[] = sprintf(
|
|
'Categories processed: %d, updated: %d',
|
|
$categoryResult['categories'],
|
|
$categoryResult['updated']
|
|
);
|
|
$messages[] = sprintf(
|
|
'Threads processed: %d, updated: %d',
|
|
$threadResult['threads'],
|
|
$threadResult['updated']
|
|
);
|
|
|
|
$this->logger->info('Forum stats rebuild completed successfully');
|
|
return new DataResponse([
|
|
'success' => true,
|
|
'message' => implode("\n", $messages),
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->logger->error('Error rebuilding stats: ' . $e->getMessage());
|
|
return new DataResponse([
|
|
'success' => false,
|
|
'message' => 'Failed to rebuild stats: ' . $e->getMessage(),
|
|
], Http::STATUS_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
}
|