Skip to content

Instantly share code, notes, and snippets.

@nklatt
Last active September 10, 2022 08:10
Show Gist options
  • Save nklatt/3d53f37bf6a88693861dd1add5815b94 to your computer and use it in GitHub Desktop.
Save nklatt/3d53f37bf6a88693861dd1add5815b94 to your computer and use it in GitHub Desktop.
For Concrete5 v8, how to programmatically set file permissions so that they are only accessible by a single user plus a single group of users and are stored outside of the webroot.
use Concrete\Core\Entity\File\File;
use Concrete\Core\File\Set\Set as FileSet;
use Concrete\Core\File\StorageLocation\StorageLocationFactory as FileStorageLocationFactory;
use Concrete\Core\Permission\Access\Entity\GroupEntity as GroupPermissionAccessEntity;
use Concrete\Core\Permission\Access\Entity\UserEntity as UserPermissionAccessEntity;
use Concrete\Core\Support\Facade\Application;
use Concrete\Core\User\Group\Group as UserGroup;
use PermissionKey;
use UserInfo;
// assumes Advanced Permissions have been enabled
function adjustPermissions(
File $f,
string $fileSetName,
string $fileStorageLocationName, // for security, this should reside outside of webroot
string $groupName,
int $uID)
{
// add file to file set
$fs = FileSet::createAndGetSet($fileSetName, FileSet::TYPE_PUBLIC, 1);
$fs->addFileToSet($f);
// assign storage location
$app = Application::getFacadeApplication();
$location = $app[FileStorageLocationFactory::class]->fetchByName($fileStorageLocationName)[0];
$f->setFileStorageLocation($location);
// override parent folder permissions
$f->resetPermissions(1);
// remove Guest access
$pk = PermissionKey::getByHandle('view_file');
$pk->setPermissionObject($f);
$pa = $pk->getPermissionAccessObject();
$pe = GroupPermissionAccessEntity::getOrCreate(UserGroup::getByID(GUEST_GROUP_ID));
$pa->removeListItem($pe);
// enable access by passed-in group
$g = UserGroup::getByName($groupName);
if (is_object($g)) {
$pae = GroupPermissionAccessEntity::getOrCreate($g);
$pa->addListItem($pae, false, PermissionKey::ACCESS_TYPE_INCLUDE);
}
// enable access by passed-in user
$ui = UserInfo::getByID($uID);
if (is_object($ui)) {
$pae = UserPermissionAccessEntity::getOrCreate($ui);
$pa->addListItem($pae, false, PermissionKey::ACCESS_TYPE_INCLUDE);
}
// apply the above access settings
$pa->markAsInUse();
}
@MathiasReker
Copy link

Nice script. Thanks for sharing. :-)
I would like to share a library I have coded with the same goal.

Example of usage:

<?php

use MathiasReker\PhpChmod\Scanner;

require __DIR__ . '/vendor/autoload.php';

(new Scanner())
    ->setDefaultFileMode(0644)
    ->setDefaultDirectoryMode(0755)
    ->setExcludedFileModes([0400, 0444, 0640])
    ->setExcludedDirectoryModes([0750])
    ->scan([__DIR__])
    ->fix();

Full documentation: https://github.com/MathiasReker/php-chmod

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment