Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
17cb5b9
Add .DS_Store to .gitignore
medofrh Jul 1, 2026
00ecd4b
replace old utility with strategy pattern for Scalability
medofrh Jul 1, 2026
e417347
Fix login check in BeLoginAccessUtility to use user UID
medofrh Jul 2, 2026
8bb5901
Refactor error handling in AccessMiddleware to use a dedicated transl…
medofrh Jul 2, 2026
b8c8384
Fix type casting for protected fields in FileStorageRepository and up…
medofrh Jul 2, 2026
ab66f9c
Add folder identifier to edit and htaccess URIs in FolderController
medofrh Jul 7, 2026
bb80233
Make protection properties display dynamic with one partial per acces…
medofrh Jul 7, 2026
f62073a
Remove translate in AccessMiddleware
medofrh Jul 7, 2026
0c5a06b
run phpstan
YannikSMYLIE Jul 13, 2026
40bcb2c
add typo3 14 compatibility
YannikSMYLIE Jul 14, 2026
4a9c16e
remove cache from git
YannikSMYLIE Jul 15, 2026
54bfec0
use database records to check access
YannikSMYLIE Jul 15, 2026
0b5e0b4
move fe_settings to own tca file
YannikSMYLIE Jul 15, 2026
cd5c7ed
move partials
YannikSMYLIE Jul 15, 2026
0b2480a
check rights with tca and remove models
YannikSMYLIE Jul 15, 2026
a3db71f
check rights with tca and remove model
YannikSMYLIE Jul 15, 2026
e2382e9
add phpstan
YannikSMYLIE Jul 15, 2026
84cc8ad
move access types to own folder
YannikSMYLIE Jul 15, 2026
79ad68b
update documentation
YannikSMYLIE Jul 15, 2026
13345ca
use same naming convention
YannikSMYLIE Jul 15, 2026
65e86ec
change labels and backend templates
YannikSMYLIE Jul 15, 2026
575b5e3
update di
YannikSMYLIE Jul 15, 2026
6eeb21d
update readme
YannikSMYLIE Jul 15, 2026
4f5928a
use other icon in TYPO3 14
YannikSMYLIE Jul 15, 2026
d3243c9
remove typoscript completly and save everything to pid=0
YannikSMYLIE Jul 15, 2026
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
5 changes: 5 additions & 0 deletions .build-v12/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Isolated v12 analysis toolchain: only the manifests are tracked.
/*
!.gitignore
!composer.json
!phpstan.neon
31 changes: 31 additions & 0 deletions .build-v12/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "fixpunkt/fp-fileprotector-cs-tools-v12",
"description": "Isolated tooling to static-analyse fp_fileprotector against TYPO3 12.4 (lowest supported). Mirror of .build/ but pinned to the v12 line.",
"autoload": {
"psr-4": {
"Fixpunkt\\FpFileprotector\\": "../Classes/"
}
},
"require-dev": {
"phpstan/extension-installer": "^1.4",
"saschaegerer/phpstan-typo3": "^1.10",
"typo3/cms-core": "^12.4",
"typo3/cms-extbase": "*",
"typo3/cms-fluid": "*",
"typo3/cms-frontend": "*",
"typo3/cms-backend": "*",
"typo3/cms-install": "*"
},
"config": {
"allow-plugins": {
"typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true,
"phpstan/extension-installer": true
},
"policy": {
"advisories": {
"block": false
}
}
}
}
6 changes: 6 additions & 0 deletions .build-v12/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parameters:
level: 5
paths:
- ../Classes
bootstrapFiles:
- vendor/autoload.php
5 changes: 5 additions & 0 deletions .build-v13/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Isolated dev toolchain: only the manifest is tracked, everything that
# composer/TYPO3 generates here (vendor, lock, published public assets, …) is not.
/*
!.gitignore
!composer.json
26 changes: 26 additions & 0 deletions .build-v13/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "fixpunkt/fp-fileprotector-cs-tools-v13",
"description": "Isolated dev tooling (coding standards + static analysis) for fp_fileprotector — not part of the extension package. Mirror of .build/ but pinned to the v13 line.",
"autoload": {
"psr-4": {
"Fixpunkt\\FpFileprotector\\": "../Classes/"
}
},
"require-dev": {
"phpstan/extension-installer": "^1.4",
"saschaegerer/phpstan-typo3": "^2.1",
"typo3/cms-core": "^13.4",
"typo3/cms-extbase": "*",
"typo3/cms-fluid": "*",
"typo3/cms-frontend": "*",
"typo3/cms-backend": "*",
"typo3/cms-install": "*"
},
"config": {
"allow-plugins": {
"typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true,
"phpstan/extension-installer": true
}
}
}
6 changes: 6 additions & 0 deletions .build-v13/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parameters:
level: 5
paths:
- ../Classes
bootstrapFiles:
- vendor/autoload.php
5 changes: 5 additions & 0 deletions .build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Isolated v14 analysis toolchain: only the manifests are tracked.
/*
!.gitignore
!composer.json
!phpstan.neon
27 changes: 27 additions & 0 deletions .build/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "fixpunkt/fp-fileprotector-cs-tools",
"description": "Isolated tooling to static-analyse fp_fileprotector against TYPO3 14.3 (highest supported).",
"autoload": {
"psr-4": {
"Fixpunkt\\FpFileprotector\\": "../Classes/"
}
},
"require-dev": {
"typo3/coding-standards": "^0.8",
"phpstan/extension-installer": "^1.4",
"saschaegerer/phpstan-typo3": "^3",
"typo3/cms-core": "^14.3",
"typo3/cms-extbase": "*",
"typo3/cms-fluid": "*",
"typo3/cms-frontend": "*",
"typo3/cms-backend": "*",
"typo3/cms-install": "*"
},
"config": {
"allow-plugins": {
"typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true,
"phpstan/extension-installer": true
}
}
}
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

# Static analysis + coding standards across the supported TYPO3 versions.
# Reuses the isolated toolchains in .build/ (v14), .build-v13/ (v13, also hosts
# the coding-standards tooling) and .build-v12/ (v12) — see DEVELOPMENT.md.
# All jobs run on PHP 8.4 because fp-social-bridge (dev-feature/typo3-14) requires ^8.4.

on:
push:
pull_request:

jobs:
phpstan:
name: PHPStan (TYPO3 ${{ matrix.typo3 }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- { typo3: '12.4', php: '8.4', build: '.build-v12', config: '.build-v12/phpstan.neon' }
- { typo3: '13.4', php: '8.4', build: '.build-v13', config: '.build-v13/phpstan.neon' }
- { typo3: '14.3', php: '8.4', build: '.build', config: 'phpstan.neon' }
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '${{ matrix.php }}'
tools: composer:v2
coverage: none
- name: Install tooling (${{ matrix.build }})
run: composer update --working-dir=${{ matrix.build }} --no-progress --no-interaction
- name: PHPStan
run: ${{ matrix.build }}/vendor/bin/phpstan analyse -c ${{ matrix.config }} --no-progress

coding-standards:
name: Coding Standards
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
tools: composer:v2
coverage: none
- name: Install tooling
run: composer update --working-dir=.build --no-progress --no-interaction
- name: php-cs-fixer (dry-run)
run: .build/vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run --diff --using-cache=no
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ vendor/
vendor/*
Documentation-GENERATED-temp/
Documentation-GENERATED-temp/*
.php-cs-fixer.cache

.env
public
public/*
index.html
composer.lock
.DS_Store


# User-specific stuff:
Expand Down
1 change: 0 additions & 1 deletion .php-cs-fixer.cache

This file was deleted.

12 changes: 12 additions & 0 deletions Classes/AccessType/AccessTypeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Fixpunkt\FpFileprotector\AccessType;

interface AccessTypeInterface
{
/** @param array<string, mixed> $protection Raw protection database record */
public function isGranted(array $protection): bool;
public function getPartials(): string;
}
43 changes: 43 additions & 0 deletions Classes/AccessType/BeLoginAccessType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Fixpunkt\FpFileprotector\AccessType;

use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;

class BeLoginAccessType implements AccessTypeInterface
{
/** @param array<string, mixed> $protection Raw protection database record */
public function isGranted(array $protection): bool
{
/** @var BackendUserAuthentication|null $beUser */
$beUser = $GLOBALS['BE_USER'] ?? null;
if (!$beUser || empty($beUser->user['uid'])) {
return false;
}

if ($beUser->isAdmin()) {
return true;
}

foreach ($beUser->getFileStorages() as $storage) {
if ($storage->getUid() !== (int)$protection['storage']) {
continue;
}
try {
$folder = $storage->getFolder((string)$protection['folder']);
return $storage->isWithinFileMountBoundaries($folder, false);
} catch (\Exception) {
return false;
}
}

return false;
}

public function getPartials(): string
{
return 'Access/Be';
}
}
78 changes: 78 additions & 0 deletions Classes/AccessType/FeLoginAccessType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Fixpunkt\FpFileprotector\AccessType;

use Doctrine\DBAL\ParameterType;
use Fixpunkt\FpFileprotector\Utility\FrontendUserUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;

class FeLoginAccessType implements AccessTypeInterface
{
private const USERS_MM = 'tx_fpfileprotector_protection_feusers_mm';
private const GROUPS_MM = 'tx_fpfileprotector_protection_fegroups_mm';

public function __construct(
private readonly FrontendUserUtility $frontendUserUtility,
private readonly ConnectionPool $connectionPool,
) {}

/** @param array<string, mixed> $protection Raw protection database record */
public function isGranted(array $protection): bool
{
if (!(bool)$protection['fe_login']) {
return false;
}

$feUser = $this->frontendUserUtility->getCurrentFrontendUser();
if (!$feUser || !$feUser->isLoggedIn()) {
return false;
}

$protectionUid = (int)$protection['uid'];
$userUids = $this->getRelatedUids(self::USERS_MM, $protectionUid);
$userGroupUids = $this->getRelatedUids(self::GROUPS_MM, $protectionUid);

if ($userGroupUids === [] && $userUids === []) {
return true;
}

if (in_array($feUser->get('id'), $userUids, true)) {
return true;
}

foreach ($feUser->get('groupIds') as $userGroupId) {
if (in_array($userGroupId, $userGroupUids, true)) {
return true;
}
}

return false;
}

/**
* Reads the related foreign uids from an MM table for a protection record.
*
* @return int[]
*/
private function getRelatedUids(string $mmTable, int $protectionUid): array
{
$queryBuilder = $this->connectionPool->getConnectionForTable($mmTable)->createQueryBuilder();
$uids = $queryBuilder
->select('uid_foreign')
->from($mmTable)
->where(
$queryBuilder->expr()->eq('uid_local', $queryBuilder->createNamedParameter($protectionUid, ParameterType::INTEGER))
)
->executeQuery()
->fetchFirstColumn();

return array_map('intval', $uids);
}

public function getPartials(): string
{
return 'Access/Fe';
}
}
1 change: 0 additions & 1 deletion Classes/Controller/FileStorageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public function editAction(string $id, int $fileStorageUid): ResponseInterface
/**
* Updates settings of a file storage.
*
* @param int $id
* @param int $fileStorageUid
* @param bool $protected
* @param bool $protectedByDefault
Expand Down
Loading
Loading