feat: add support to capabilities

Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
Vitor Mattos 2025-04-02 16:00:37 -03:00
parent a6cca5e468
commit 7f2e3b3661
No known key found for this signature in database
GPG key ID: B7AB4B76A7CA7318
13 changed files with 296 additions and 0 deletions

View file

@ -11,6 +11,7 @@ namespace OCA\Libresign\AppInfo;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files\Event\LoadSidebar;
use OCA\Libresign\Activity\Listener as ActivityListener;
use OCA\Libresign\Capabilities;
use OCA\Libresign\Events\SendSignNotificationEvent;
use OCA\Libresign\Events\SignedEvent;
use OCA\Libresign\Files\TemplateLoader as FilesTemplateLoader;
@ -55,6 +56,7 @@ class Application extends App implements IBootstrap {
public function register(IRegistrationContext $context): void {
$context->registerMiddleWare(GlobalInjectionMiddleware::class, true);
$context->registerMiddleWare(InjectionMiddleware::class);
$context->registerCapability(Capabilities::class);
$context->registerNotifierService(Notifier::class);

50
lib/Capabilities.php Normal file
View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Libresign;
use OCA\Libresign\ResponseDefinitions;
use OCA\Libresign\Service\SignerElementsService;
use OCP\App\IAppManager;
use OCP\Capabilities\IPublicCapability;
/**
* @psalm-import-type LibresignCapabilities from ResponseDefinitions
*/
class Capabilities implements IPublicCapability {
public const FEATURES = [
'customize-signature'
];
public function __construct(
protected SignerElementsService $signerElementsService,
protected IAppManager $appManager,
) {
}
/**
* @return array{
* libresign?: LibresignCapabilities,
* }
*/
public function getCapabilities(): array {
$capabilities = [
'features' => self::FEATURES,
'config' => [
'sign-elements' => [
'is-available' => $this->signerElementsService->isSignElementsAvailable(),
],
],
'version' => $this->appManager->getAppVersion('libresign'),
];
return [
'libresign' => $capabilities,
];
}
}

View file

@ -230,6 +230,15 @@ namespace OCA\Libresign;
* starred: 0|1,
* createdAt: string,
* }
* @psalm-type LibresignCapabilities = array{
* features: list<string>,
* config: array{
* sign-elements: array{
* is-available: bool,
* },
* },
* version: string,
* }
*/
class ResponseDefinitions {
}

View file

@ -60,6 +60,10 @@ class SignatureBackgroundService {
return $this->appConfig->getValueString(Application::APP_ID, 'signature_background_type', 'default');
}
public function isEnabled(): bool {
return $this->getSignatureBackgroundType() !== 'deleted';
}
public function wasBackgroundScaled(): bool {
return $this->wasBackgroundScaled;
}

View file

@ -174,4 +174,8 @@ class SignatureTextService {
public function getRenderMode(): string {
return $this->appConfig->getValueString(Application::APP_ID, 'signature_render_mode', 'GRAPHIC_AND_DESCRIPTION');
}
public function isEnabled(): bool {
return !empty($this->getTemplate());
}
}

View file

@ -27,6 +27,8 @@ class SignerElementsService {
private SessionService $sessionService,
private IURLGenerator $urlGenerator,
private UserElementMapper $userElementMapper,
private SignatureBackgroundService $signatureBackgroundService,
private SignatureTextService $signatureTextService,
) {
}
@ -130,4 +132,8 @@ class SignerElementsService {
}
return $return;
}
public function isSignElementsAvailable(): bool {
return $this->signatureBackgroundService->isEnabled() || $this->signatureTextService->isEnabled();
}
}

View file

@ -20,6 +20,44 @@
}
},
"schemas": {
"Capabilities": {
"type": "object",
"required": [
"features",
"config",
"version"
],
"properties": {
"features": {
"type": "array",
"items": {
"type": "string"
}
},
"config": {
"type": "object",
"required": [
"sign-elements"
],
"properties": {
"sign-elements": {
"type": "object",
"required": [
"is-available"
],
"properties": {
"is-available": {
"type": "boolean"
}
}
}
}
},
"version": {
"type": "string"
}
}
},
"CetificateDataGenerated": {
"allOf": [
{
@ -107,6 +145,14 @@
}
}
},
"PublicCapabilities": {
"type": "object",
"properties": {
"libresign": {
"$ref": "#/components/schemas/Capabilities"
}
}
},
"RootCertificate": {
"type": "object",
"required": [

View file

@ -37,6 +37,44 @@
}
}
},
"Capabilities": {
"type": "object",
"required": [
"features",
"config",
"version"
],
"properties": {
"features": {
"type": "array",
"items": {
"type": "string"
}
},
"config": {
"type": "object",
"required": [
"sign-elements"
],
"properties": {
"sign-elements": {
"type": "object",
"required": [
"is-available"
],
"properties": {
"is-available": {
"type": "boolean"
}
}
}
}
},
"version": {
"type": "string"
}
}
},
"CertificatePfxData": {
"type": "object",
"required": [
@ -547,6 +585,14 @@
}
}
},
"PublicCapabilities": {
"type": "object",
"properties": {
"libresign": {
"$ref": "#/components/schemas/Capabilities"
}
}
},
"RootCertificate": {
"type": "object",
"required": [

View file

@ -37,6 +37,44 @@
}
}
},
"Capabilities": {
"type": "object",
"required": [
"features",
"config",
"version"
],
"properties": {
"features": {
"type": "array",
"items": {
"type": "string"
}
},
"config": {
"type": "object",
"required": [
"sign-elements"
],
"properties": {
"sign-elements": {
"type": "object",
"required": [
"is-available"
],
"properties": {
"is-available": {
"type": "boolean"
}
}
}
}
},
"version": {
"type": "string"
}
}
},
"CertificatePfxData": {
"type": "object",
"required": [
@ -484,6 +522,14 @@
}
}
},
"PublicCapabilities": {
"type": "object",
"properties": {
"libresign": {
"$ref": "#/components/schemas/Capabilities"
}
}
},
"Settings": {
"type": "object",
"required": [

View file

@ -187,6 +187,15 @@ export type paths = {
export type webhooks = Record<string, never>;
export type components = {
schemas: {
Capabilities: {
features: string[];
config: {
"sign-elements": {
"is-available": boolean;
};
};
version: string;
};
CetificateDataGenerated: components["schemas"]["EngineHandler"] & {
generated: boolean;
};
@ -209,6 +218,9 @@ export type components = {
totalitems?: string;
itemsperpage?: string;
};
PublicCapabilities: {
libresign?: components["schemas"]["Capabilities"];
};
RootCertificate: {
commonName: string;
names: components["schemas"]["RootCertificateName"][];

View file

@ -1102,6 +1102,15 @@ export type components = {
name?: string;
type?: string;
};
Capabilities: {
features: string[];
config: {
"sign-elements": {
"is-available": boolean;
};
};
version: string;
};
CertificatePfxData: {
name: string;
subject: string;
@ -1249,6 +1258,9 @@ export type components = {
last: string | null;
first: string | null;
};
PublicCapabilities: {
libresign?: components["schemas"]["Capabilities"];
};
RootCertificate: {
commonName: string;
names: components["schemas"]["RootCertificateName"][];

View file

@ -923,6 +923,15 @@ export type components = {
name?: string;
type?: string;
};
Capabilities: {
features: string[];
config: {
"sign-elements": {
"is-available": boolean;
};
};
version: string;
};
CertificatePfxData: {
name: string;
subject: string;
@ -1055,6 +1064,9 @@ export type components = {
last: string | null;
first: string | null;
};
PublicCapabilities: {
libresign?: components["schemas"]["Capabilities"];
};
Settings: {
canSign: boolean;
canRequestSign: boolean;

View file

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
use OCA\Libresign\Capabilities;
use OCA\Libresign\Service\SignerElementsService;
use OCP\App\IAppManager;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
final class CapabilitiesTest extends \OCA\Libresign\Tests\Unit\TestCase {
private Capabilities $capabilities;
private SignerElementsService&MockObject $signerElementsService;
private IAppManager&MockObject $appManager;
public function setUp(): void {
$this->signerElementsService = $this->createMock(SignerElementsService::class);
$this->appManager = $this->createMock(IAppManager::class);
}
private function getClass(): Capabilities {
$this->capabilities = new Capabilities(
$this->signerElementsService,
$this->appManager,
);
return $this->capabilities;
}
#[DataProvider('providerSignElementsIsAvailable')]
public function testSignElementsIsAvailable($isEnabled, $expected): void {
$this->signerElementsService->method('isSignElementsAvailable')->willReturn($isEnabled);
$capabilities = $this->getClass()->getCapabilities();
$this->assertEquals($expected, $capabilities['libresign']['config']['sign-elements']['is-available']);
}
public static function providerSignElementsIsAvailable(): array {
return [
[true, true],
[false, false],
];
}
}