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
18 changes: 18 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@
['name' => 'Admin#editConfig', 'url' => '/admin/{emulated}/circles/{circleId}/config', 'verb' => 'PUT'],
['name' => 'Admin#link', 'url' => '/admin/{emulated}/link/{circleId}/{singleId}', 'verb' => 'GET'],

// AdminApiController — simplified admin API (no user emulation)
['name' => 'AdminApi#index', 'url' => '/manage/circles', 'verb' => 'GET'],
['name' => 'AdminApi#show', 'url' => '/manage/circles/{circleId}', 'verb' => 'GET'],
['name' => 'AdminApi#create', 'url' => '/manage/circles', 'verb' => 'POST'],
['name' => 'AdminApi#update', 'url' => '/manage/circles/{circleId}', 'verb' => 'PUT'],
['name' => 'AdminApi#destroy', 'url' => '/manage/circles/{circleId}', 'verb' => 'DELETE'],
['name' => 'AdminApi#members', 'url' => '/manage/circles/{circleId}/members', 'verb' => 'GET'],
['name' => 'AdminApi#addMember', 'url' => '/manage/circles/{circleId}/members', 'verb' => 'POST'],
[
'name' => 'AdminApi#removeMember', 'url' => '/manage/circles/{circleId}/members/{memberId}',
'verb' => 'DELETE'
],
[
'name' => 'AdminApi#setMemberLevel',
'url' => '/manage/circles/{circleId}/members/{memberId}/level',
'verb' => 'PUT'
],

['name' => 'Settings#getValues', 'url' => '/settings/', 'verb' => 'GET'],
['name' => 'Settings#setValue', 'url' => '/settings/{key}/', 'verb' => 'POST'],
],
Expand Down
201 changes: 201 additions & 0 deletions lib/Controller/AdminApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 SURF
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Circles\Controller;

use OCA\Circles\Service\AdminApiService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use Psr\Log\LoggerInterface;

class AdminApiController extends OCSController {

private AdminApiService $service;
private LoggerInterface $logger;
private string $userId;

public function __construct(
string $appName,
IRequest $request,
AdminApiService $service,
LoggerInterface $logger,
?string $userId,
) {
parent::__construct($appName, $request);
$this->service = $service;
$this->logger = $logger;
$this->userId = $userId ?? '';
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function index(): DataResponse {
try {
return new DataResponse($this->service->listAll());
} catch (\Exception $e) {
$this->logger->error('circlesadmin: list failed: ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function show(string $circleId): DataResponse {
try {
return new DataResponse($this->service->getCircle($circleId));
} catch (\Exception $e) {
$this->logger->error('circlesadmin: show failed for ' . $circleId . ': ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_NOT_FOUND
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function create(string $name, string $owner = ''): DataResponse {
$ownerUserId = $owner ?: $this->userId;
// Get description from request params (not a method param to avoid Dispatcher issues)
$params = $this->request->getParams();
$description = isset($params['description']) ? (string)$params['description'] : null;
$federated = !empty($params['federated']);
try {
return new DataResponse(
$this->service->createCircle($name, $ownerUserId, $description, $federated),
Http::STATUS_CREATED
);
} catch (\Exception $e) {
$this->logger->error('circlesadmin: create failed: ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function update(string $circleId, ?string $name = null, ?string $description = null): DataResponse {
if ($name === null && $description === null) {
return new DataResponse(
['message' => 'Provide at least one of: name, description'],
Http::STATUS_BAD_REQUEST
);
}
try {
return new DataResponse($this->service->updateCircle($circleId, $name, $description));
} catch (\Exception $e) {
$this->logger->error('circlesadmin: update failed for ' . $circleId . ': ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function destroy(string $circleId): DataResponse {
try {
$this->service->destroyCircle($circleId);
return new DataResponse(['message' => 'Circle deleted']);
} catch (\Exception $e) {
$this->logger->error('circlesadmin: destroy failed for ' . $circleId . ': ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function members(string $circleId): DataResponse {
try {
return new DataResponse($this->service->getMembers($circleId));
} catch (\Exception $e) {
$this->logger->error('circlesadmin: members list failed for ' . $circleId . ': ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_NOT_FOUND
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function addMember(string $circleId, string $userId): DataResponse {
try {
return new DataResponse(
$this->service->addMember($circleId, $userId),
Http::STATUS_CREATED
);
} catch (\Exception $e) {
$this->logger->error('circlesadmin: add member failed for ' . $circleId . '/' . $userId . ': ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function removeMember(string $circleId, string $memberId): DataResponse {
try {
$this->service->removeMember($circleId, $memberId);
return new DataResponse(['message' => 'Member removed']);
} catch (\Exception $e) {
$this->logger->error('circlesadmin: remove member failed: ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}

/**
* @AdminRequired
* @NoCSRFRequired
*/
public function setMemberLevel(string $circleId, string $memberId, int $level): DataResponse {
try {
$this->service->setMemberLevel($circleId, $memberId, $level);
return new DataResponse(['message' => 'Level updated']);
} catch (\Exception $e) {
$this->logger->error('circlesadmin: set level failed: ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage()],
Http::STATUS_BAD_REQUEST
);
}
}
}
Loading
Loading