Skip to content

observation/FOUR-21853 Disable settings edit on remote bundles #8003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 10, 2025
Merged
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
82 changes: 80 additions & 2 deletions ProcessMaker/Http/Controllers/Api/DevLinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Notification;
use Illuminate\Validation\Rule;
use ProcessMaker\Events\CustomizeUiUpdated;
use ProcessMaker\Exception\ValidationException;
use ProcessMaker\Http\Controllers\Controller;
use ProcessMaker\Http\Resources\ApiCollection;
use ProcessMaker\Jobs\CompileSass;
use ProcessMaker\Jobs\DevLinkInstall;
use ProcessMaker\Models\Bundle;
use ProcessMaker\Models\BundleAsset;
Expand Down Expand Up @@ -198,6 +201,8 @@ public function bundleUpdated($bundleId, $token)

public function deleteBundle(Bundle $bundle)
{
$bundle->assets()->delete();
$bundle->settings()->delete();
$bundle->delete();
}

Expand Down Expand Up @@ -255,7 +260,7 @@ public function exportLocalBundleSettings(Bundle $bundle)
public function exportLocalBundleSettingPayloads(Bundle $bundle)
{
if ($bundle->settings->isEmpty()) {
return ['payloads' => [0 => []]];
return ['payloads' => []];
}

return ['payloads' => $bundle->exportSettingPayloads()];
Expand Down Expand Up @@ -384,6 +389,79 @@ public function getBundleSetting(Bundle $bundle, $settingKey)

public function getBundleAllSettings($settingKey)
{
return Setting::where([['group_id', SettingsMenus::getId($settingKey)], ['hidden', 0]])->get();
if ($settingKey === 'ui_settings') {
return Setting::whereIn('key', ['css-override', 'login-footer', 'logo-alt-text'])
->get();
}

return Setting::where([
['group_id', SettingsMenus::getId($settingKey)],
['hidden', 0],
])->get();
}

public function refreshUi()
{
$cssOverride = Setting::where('key', 'css-override')->first();

$config = $cssOverride->config;
$variables = json_decode($config['variables']);
$sansSerif = json_decode($config['sansSerifFont'], true);

$this->writeColors($variables);
$this->writeFonts($sansSerif);
$this->compileSass(auth()->user()->id);
CustomizeUiUpdated::dispatch([], [], false);
}

private function writeColors($data)
{
// Now generate the _colors.scss file
$contents = "// Changed theme colors\n";
foreach ($data as $value) {
$contents .= $value->id . ': ' . $value->value . ";\n";
}
File::put(app()->resourcePath('sass') . '/_colors.scss', $contents);
}

/**
* Write variables font in file
*
* @param $sansSerif
* @param $serif
*/
private function writeFonts($sansSerif)
{
$sansSerif = $sansSerif ? $sansSerif : $this->sansSerifFontDefault();
// Generate the _fonts.scss file
$contents = "// Changed theme fonts\n";
$contents .= '$font-family-sans-serif: ' . $sansSerif['id'] . " !default;\n";
File::put(app()->resourcePath('sass') . '/_fonts.scss', $contents);
}

/**
* run jobs compile
*/
private function compileSass($userId)
{
// Compile the Sass files
$this->dispatch(new CompileSass([
'tag' => 'sidebar',
'origin' => 'resources/sass/sidebar/sidebar.scss',
'target' => 'public/css/sidebar.css',
'user' => $userId,
]));
$this->dispatch(new CompileSass([
'tag' => 'app',
'origin' => 'resources/sass/app.scss',
'target' => 'public/css/app.css',
'user' => $userId,
]));
$this->dispatch(new CompileSass([
'tag' => 'queues',
'origin' => 'resources/sass/admin/queues.scss',
'target' => 'public/css/admin/queues.css',
'user' => $userId,
]));
}
}
102 changes: 63 additions & 39 deletions ProcessMaker/Models/Bundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ public function addSettings($setting, $newId, $type = null)
}
}

if ($type === 'ui_settings') {
$config['id'] = ['css-override', 'login-footer', 'logo-alt-text'];
$config['type'] = $type;
}

BundleSetting::create([
'bundle_id' => $this->id,
'setting' => $setting,
Expand Down Expand Up @@ -292,8 +297,16 @@ public function newestVersionFile()
return $this->filesSortedByVersion()->first();
}

public function savePayloadsToFile(array $payloads)
public function savePayloadsToFile(array $payloads, array $payloadsSettings, $logger = null)
{
if ($logger === null) {
$logger = new Logger();
}
$logger->status('Saving the bundle locally');
if (isset($payloadsSettings[0])) {
$payloads = array_merge($payloads, $payloadsSettings[0]);
}

$this->addMediaFromString(
gzencode(
json_encode($payloads)
Expand Down Expand Up @@ -338,51 +351,63 @@ public function installSettingsPayloads(array $payloads, $mode, $logger = null)
$logger->status('Installing bundle settings on the this instance');
$logger->setSteps($payloads[0]);
$assets[] = DevLink::import($payload[0], $options, $logger);
} else {
switch ($payload[0]['setting_type']) {
case 'auth_clients':
$clientRepository->create(
null,
$payload[0]['name'],
$payload[0]['redirect'],
$payload[0]['provider'],
$payload[0]['personal_access_client'],
$payload[0]['password_client']
);
break;
case 'User Settings':
case 'Email':
case 'Integrations':
case 'Log-In & Auth':
$settingsMenu = SettingsMenus::where('menu_group', $payload[0]['setting_type'])->first();
Setting::updateOrCreate([
'key' => $payload[0]['key'],
], [
'config' => $payload[0]['config'],
'name' => $payload[0]['name'],
'helper' => $payload[0]['helper'],
'format' => $payload[0]['format'],
'hidden' => $payload[0]['hidden'],
'readonly' => $payload[0]['readonly'],
'ui' => $payload[0]['ui'],
'group_id' => $settingsMenu->id,
'group' => $payload[0]['group'],
]);
break;
} elseif (isset($payload[0]['setting_type'])) {
foreach ($payload as $setting) {
switch ($setting['setting_type']) {
case 'auth_clients':
$clientRepository->create(
null,
$setting['name'],
$setting['redirect'],
$setting['provider'],
$setting['personal_access_client'],
$setting['password_client']
);
break;
case 'User Settings':
case 'Email':
case 'Integrations':
case 'Log-In & Auth':
$settingsMenu = SettingsMenus::where('menu_group', $setting['setting_type'])->first();
Setting::updateOrCreate([
'key' => $setting['key'],
], [
'config' => $setting['config'],
'name' => $setting['name'],
'helper' => $setting['helper'],
'format' => $setting['format'],
'hidden' => $setting['hidden'],
'readonly' => $setting['readonly'],
'ui' => $setting['ui'],
'group_id' => $settingsMenu->id,
'group' => $setting['group'],
]);
break;
case 'ui_settings':
Setting::updateOrCreate([
'key' => $setting['key'],
], [
'config' => $setting['config'],
'name' => $setting['name'],
'helper' => $setting['helper'],
'format' => $setting['format'],
'hidden' => $setting['hidden'],
'readonly' => $setting['readonly'],
'ui' => $setting['ui'],
]);
break;
}
}
}
}
}

public function install(array $payloads, $mode, $logger = null)
public function install(array $payloads, $mode, $logger = null, $reinstall = false)
{
if ($logger === null) {
$logger = new Logger();
}

$logger->status('Saving the bundle locally');
$this->savePayloadsToFile($payloads);

$logger->status('Installing bundle on the this instance');
$logger->setSteps($payloads);

Expand All @@ -394,7 +419,7 @@ public function install(array $payloads, $mode, $logger = null)
$assets[] = DevLink::import($payload, $options, $logger);
}

if ($mode === 'update') {
if ($mode === 'update' && $reinstall === false) {
$logger->status('Syncing bundle assets');
$this->syncAssets($assets);
}
Expand All @@ -406,8 +431,7 @@ public function reinstall(string $mode, Logger $logger = null)

$content = file_get_contents($media->getPath());
$payloads = json_decode(gzdecode($content), true);

$this->install($payloads, $mode, $logger);
$this->install($payloads, $mode, $logger, true);

$logger?->setStatus('done');
}
Expand Down
28 changes: 9 additions & 19 deletions ProcessMaker/Models/BundleSetting.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use ProcessMaker\Enums\ExporterMap;
use ProcessMaker\ImportExport\Exporter;
use ProcessMaker\ImportExport\Exporters\GroupExporter;
use ProcessMaker\ImportExport\Exporters\MediaExporter;
use ProcessMaker\ImportExport\Exporters\ScriptExecutorExporter;
use ProcessMaker\ImportExport\Exporters\UserExporter;
use ProcessMaker\Models\ProcessMakerModel;
Expand Down Expand Up @@ -91,31 +92,22 @@ public function export()
return $uiMenus->map(function ($uiMenu) {
return $this->exportHelper($uiMenu, MenuExporter::class);
});
case 'translations':
case 'public_files':
if (empty($this->config)) {
$translations = Translatable::all();
$publicFiles = Media::all()->filter(function ($media) {
return $media->isPublicFile();
});
} else {
$translations = Translatable::whereIn('key', $ids)->get();
$publicFiles = Media::whereIn('id', $ids)->get();
}

return $translations->map(function ($translation) {
return $this->exportHelper($translation, TranslatableExporter::class);
});
case 'auth_clients':
if (empty($this->config)) {
$authClients = \Laravel\Passport\Client::where('revoked', false)->get();
} else {
$authClients = \Laravel\Passport\Client::where('revoked', false)->whereIn('id', $ids)->get();
}

return $authClients->map(function ($authClient) {
$authClient->setting_type = $this->setting;

return $authClient;
return $publicFiles->map(function ($publicFile) {
return $this->exportHelper($publicFile, MediaExporter::class);
});
case 'Log-In & Auth':
case 'User Settings':
case 'Email':
case 'ui_settings':
case 'Integrations':
$bundleSettings = Setting::whereIn('key', $ids)->get();

Expand All @@ -125,8 +117,6 @@ public function export()
return $bundleSetting;
});
}

return [];
}

public function exportHelper($model, $exporterClass, $options = null, $ignoreExplicitExport = true)
Expand Down
2 changes: 2 additions & 0 deletions ProcessMaker/Models/DevLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ public function installRemoteBundle($remoteBundleId, $updateType)
]
);

$bundle->savePayloadsToFile($bundleExport['payloads'], $bundleSettingsPayloads['payloads']);

$bundle->install($bundleExport['payloads'], $updateType, $this->logger);
$bundle->installSettingsPayloads($bundleSettingsPayloads['payloads'], $updateType, $this->logger);
$bundle->installSettings($bundleSettingsExport['settings']);
Expand Down
3 changes: 3 additions & 0 deletions devhub/pm-font/svg/add-outlined.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading