Skip to content

Commit 9b562f3

Browse files
authored
Merge pull request #7366 from LibreSign/feat/policy-signature-flow-phase1-groundwork
feat: policy signature flow
2 parents 95300d2 + e17152a commit 9b562f3

File tree

194 files changed

+32685
-3835
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+32685
-3835
lines changed

lib/AppInfo/Application.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ public function register(IRegistrationContext $context): void {
6060
$context->registerNotifierService(Notifier::class);
6161

6262
$context->registerSearchProvider(FileSearchProvider::class);
63-
6463
$context->registerEventListener(LoadSidebar::class, TemplateLoader::class);
6564
$context->registerEventListener(BeforeNodeDeletedEvent::class, BeforeNodeDeletedListener::class);
6665
$context->registerEventListener(CacheEntryRemovedEvent::class, BeforeNodeDeletedListener::class);

lib/Command/Developer/Reset.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ protected function configure(): void {
9696
mode: InputOption::VALUE_NONE,
9797
description: 'Reset config'
9898
)
99+
->addOption(
100+
name: 'policy',
101+
shortcut: null,
102+
mode: InputOption::VALUE_NONE,
103+
description: 'Reset policy data'
104+
)
99105
;
100106
}
101107

@@ -140,6 +146,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
140146
$this->resetConfig();
141147
$ok = true;
142148
}
149+
if ($input->getOption('policy') || $all) {
150+
$this->resetPolicy();
151+
$ok = true;
152+
}
143153
} catch (\Exception $e) {
144154
$this->logger->error($e->getMessage());
145155
throw $e;
@@ -254,4 +264,17 @@ private function resetConfig(): void {
254264
} catch (\Throwable) {
255265
}
256266
}
267+
268+
private function resetPolicy(): void {
269+
try {
270+
$delete = $this->db->getQueryBuilder();
271+
$delete->delete('libresign_permission_set_binding')
272+
->executeStatement();
273+
274+
$delete = $this->db->getQueryBuilder();
275+
$delete->delete('libresign_permission_set')
276+
->executeStatement();
277+
} catch (\Throwable) {
278+
}
279+
}
257280
}

lib/Controller/AdminController.php

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
use OCA\Libresign\Service\IdentifyMethodService;
2525
use OCA\Libresign\Service\Install\ConfigureCheckService;
2626
use OCA\Libresign\Service\Install\InstallService;
27+
use OCA\Libresign\Service\Policy\PolicyService;
2728
use OCA\Libresign\Service\ReminderService;
2829
use OCA\Libresign\Service\SignatureBackgroundService;
2930
use OCA\Libresign\Service\SignatureTextService;
3031
use OCA\Libresign\Settings\Admin;
3132
use OCP\AppFramework\Http;
3233
use OCP\AppFramework\Http\Attribute\ApiRoute;
34+
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
3335
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
3436
use OCP\AppFramework\Http\ContentSecurityPolicy;
3537
use OCP\AppFramework\Http\DataDownloadResponse;
@@ -83,6 +85,7 @@ public function __construct(
8385
private ReminderService $reminderService,
8486
private FooterService $footerService,
8587
private DocMdpConfigService $docMdpConfigService,
88+
private PolicyService $policyService,
8689
private IdentifyMethodService $identifyMethodService,
8790
private FileMapper $fileMapper,
8891
) {
@@ -875,7 +878,7 @@ public function getFooterTemplate(): DataResponse {
875878
public function saveFooterTemplate(string $template = '', int $width = 595, int $height = 50) {
876879
try {
877880
$this->footerService->saveTemplate($template);
878-
$pdf = $this->footerService->renderPreviewPdf('', $width, $height);
881+
$pdf = $this->footerService->renderPreviewPdf($template, $width, $height);
879882

880883
return new DataDownloadResponse($pdf, 'footer-preview.pdf', 'application/pdf');
881884
} catch (\Exception $e) {
@@ -894,15 +897,18 @@ public function saveFooterTemplate(string $template = '', int $width = 595, int
894897
* @param string $template Template to preview
895898
* @param int $width Width of preview in points (default: 595 - A4 width)
896899
* @param int $height Height of preview in points (default: 50)
900+
* @param ?bool $writeQrcodeOnFooter Whether to force QR code rendering in footer preview (null uses policy)
897901
* @return DataDownloadResponse<Http::STATUS_OK, 'application/pdf', array{}>|DataResponse<Http::STATUS_BAD_REQUEST, LibresignErrorResponse, array{}>
898902
*
899903
* 200: OK
900904
* 400: Bad request
901905
*/
906+
#[NoAdminRequired]
907+
#[NoCSRFRequired]
902908
#[ApiRoute(verb: 'POST', url: '/api/{apiVersion}/admin/footer-template/preview-pdf', requirements: ['apiVersion' => '(v1)'])]
903-
public function footerTemplatePreviewPdf(string $template = '', int $width = 595, int $height = 50) {
909+
public function footerTemplatePreviewPdf(string $template = '', int $width = 595, int $height = 50, ?bool $writeQrcodeOnFooter = null) {
904910
try {
905-
$pdf = $this->footerService->renderPreviewPdf($template ?: null, $width, $height);
911+
$pdf = $this->footerService->renderPreviewPdf($template ?: null, $width, $height, $writeQrcodeOnFooter);
906912
return new DataDownloadResponse($pdf, 'footer-preview.pdf', 'application/pdf');
907913
} catch (\Exception $e) {
908914
return new DataResponse([
@@ -960,57 +966,6 @@ private function saveOrDeleteConfig(string $key, ?string $value, string $default
960966
}
961967
}
962968

963-
/**
964-
* Set signature flow configuration
965-
*
966-
* @param bool $enabled Whether to force a signature flow for all documents
967-
* @param string|null $mode Signature flow mode: 'parallel' or 'ordered_numeric' (only used when enabled is true)
968-
* @return DataResponse<Http::STATUS_OK, LibresignMessageResponse, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, LibresignErrorResponse, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, LibresignErrorResponse, array{}>
969-
*
970-
* 200: Configuration saved successfully
971-
* 400: Invalid signature flow mode provided
972-
* 500: Internal server error
973-
*/
974-
#[ApiRoute(verb: 'POST', url: '/api/{apiVersion}/admin/signature-flow/config', requirements: ['apiVersion' => '(v1)'])]
975-
public function setSignatureFlowConfig(bool $enabled, ?string $mode = null): DataResponse {
976-
try {
977-
if (!$enabled) {
978-
$this->appConfig->deleteKey(Application::APP_ID, 'signature_flow');
979-
return new DataResponse([
980-
'message' => $this->l10n->t('Settings saved'),
981-
]);
982-
}
983-
984-
if ($mode === null) {
985-
return new DataResponse([
986-
'error' => $this->l10n->t('Mode is required when signature flow is enabled.'),
987-
], Http::STATUS_BAD_REQUEST);
988-
}
989-
990-
try {
991-
$signatureFlow = \OCA\Libresign\Enum\SignatureFlow::from($mode);
992-
} catch (\ValueError) {
993-
return new DataResponse([
994-
'error' => $this->l10n->t('Invalid signature flow mode. Use "parallel" or "ordered_numeric".'),
995-
], Http::STATUS_BAD_REQUEST);
996-
}
997-
998-
$this->appConfig->setValueString(
999-
Application::APP_ID,
1000-
'signature_flow',
1001-
$signatureFlow->value
1002-
);
1003-
1004-
return new DataResponse([
1005-
'message' => $this->l10n->t('Settings saved'),
1006-
]);
1007-
} catch (\Exception $e) {
1008-
return new DataResponse([
1009-
'error' => $e->getMessage(),
1010-
], Http::STATUS_INTERNAL_SERVER_ERROR);
1011-
}
1012-
}
1013-
1014969
/**
1015970
* Configure DocMDP signature restrictions
1016971
*

lib/Controller/FileController.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public function validateBinary(): DataResponse {
182182
->toArray();
183183
$statusCode = Http::STATUS_OK;
184184
} catch (InvalidArgumentException $e) {
185-
$message = $this->l10n->t($e->getMessage());
185+
$message = $e->getMessage();
186186
$return = [
187187
'action' => JSActions::ACTION_DO_NOTHING,
188188
'errors' => [['message' => $message]]
@@ -254,15 +254,15 @@ private function validate(
254254
->toArray();
255255
$statusCode = Http::STATUS_OK;
256256
} catch (LibresignException $e) {
257-
$message = $this->l10n->t($e->getMessage());
257+
$message = $e->getMessage();
258258
$return = [
259259
'action' => JSActions::ACTION_DO_NOTHING,
260260
'errors' => [['message' => $message]]
261261
];
262262
$statusCode = Http::STATUS_NOT_FOUND;
263263
} catch (\Throwable $th) {
264-
$message = $this->l10n->t($th->getMessage());
265-
$this->logger->error($message);
264+
$this->logger->error($th->getMessage(), ['exception' => $th]);
265+
$message = $this->l10n->t('Internal error. Contact admin.');
266266
$return = [
267267
'action' => JSActions::ACTION_DO_NOTHING,
268268
'errors' => [['message' => $message]]

lib/Controller/PageController.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use OCA\Libresign\Db\FileMapper;
1313
use OCA\Libresign\Db\SignRequestMapper;
1414
use OCA\Libresign\Exception\LibresignException;
15+
use OCA\Libresign\Handler\FooterHandler;
1516
use OCA\Libresign\Helper\JSActions;
1617
use OCA\Libresign\Helper\ValidateHelper;
1718
use OCA\Libresign\Middleware\Attribute\PrivateValidation;
@@ -23,6 +24,7 @@
2324
use OCA\Libresign\Service\FileService;
2425
use OCA\Libresign\Service\IdentifyMethod\SignatureMethod\TokenService;
2526
use OCA\Libresign\Service\IdentifyMethodService;
27+
use OCA\Libresign\Service\Policy\PolicyService;
2628
use OCA\Libresign\Service\RequestSignatureService;
2729
use OCA\Libresign\Service\SessionService;
2830
use OCA\Libresign\Service\SignerElementsService;
@@ -58,6 +60,8 @@ public function __construct(
5860
private AccountService $accountService,
5961
protected SignFileService $signFileService,
6062
protected RequestSignatureService $requestSignatureService,
63+
private PolicyService $policyService,
64+
private FooterHandler $footerHandler,
6165
private SignerElementsService $signerElementsService,
6266
protected IL10N $l10n,
6367
private IdentifyMethodService $identifyMethodService,
@@ -106,7 +110,14 @@ public function index(): TemplateResponse {
106110

107111
$this->provideSignerSignatues();
108112
$this->initialState->provideInitialState('identify_methods', $this->identifyMethodService->getIdentifyMethodsSettings());
109-
$this->initialState->provideInitialState('signature_flow', $this->appConfig->getValueString(Application::APP_ID, 'signature_flow', \OCA\Libresign\Enum\SignatureFlow::NONE->value));
113+
$resolvedPolicies = [];
114+
foreach ($this->policyService->resolveKnownPolicies() as $policyKey => $resolvedPolicy) {
115+
$resolvedPolicies[$policyKey] = $resolvedPolicy->toArray();
116+
}
117+
$this->initialState->provideInitialState('effective_policies', [
118+
'policies' => $resolvedPolicies,
119+
]);
120+
$this->initialState->provideInitialState('footer_template', $this->footerHandler->getTemplate());
110121
$this->initialState->provideInitialState('docmdp_config', $this->docMdpConfigService->getConfig());
111122
$this->initialState->provideInitialState('legal_information', $this->appConfig->getValueString(Application::APP_ID, 'legal_information'));
112123

@@ -120,7 +131,6 @@ public function index(): TemplateResponse {
120131
$response = new TemplateResponse(Application::APP_ID, 'main');
121132

122133
$policy = new ContentSecurityPolicy();
123-
$policy->allowEvalScript(true);
124134
$policy->addAllowedFrameDomain('\'self\'');
125135
$policy->addAllowedWorkerSrcDomain("'self'");
126136
$response->setContentSecurityPolicy($policy);
@@ -387,7 +397,6 @@ public function sign(string $uuid): TemplateResponse {
387397
$response = new TemplateResponse(Application::APP_ID, 'external', [], TemplateResponse::RENDER_AS_BASE);
388398

389399
$policy = new ContentSecurityPolicy();
390-
$policy->allowEvalScript(true);
391400
$policy->addAllowedWorkerSrcDomain("'self'");
392401
$response->setContentSecurityPolicy($policy);
393402

0 commit comments

Comments
 (0)