Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117905954
D4310.1775389262.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None
D4310.1775389262.diff
View Options
diff --git a/src/app/Http/Controllers/API/V4/RoomsController.php b/src/app/Http/Controllers/API/V4/RoomsController.php
--- a/src/app/Http/Controllers/API/V4/RoomsController.php
+++ b/src/app/Http/Controllers/API/V4/RoomsController.php
@@ -256,9 +256,7 @@
$room->description = request()->input('description');
$room->save();
- if (!empty($request->skus)) {
- SkusController::updateEntitlements($room, $request->skus);
- }
+ SkusController::updateEntitlements($room, $request->skus);
if (!$room->hasSKU('group-room')) {
$room->setSetting('acl', null);
diff --git a/src/app/Http/Controllers/API/V4/SkusController.php b/src/app/Http/Controllers/API/V4/SkusController.php
--- a/src/app/Http/Controllers/API/V4/SkusController.php
+++ b/src/app/Http/Controllers/API/V4/SkusController.php
@@ -131,23 +131,25 @@
return;
}
- // list of skus, [id=>obj]
- $skus = Sku::withEnvTenantContext()->get()->mapWithKeys(
+ if (!\config('app.with_subscriptions')) {
+ throw new \Exception("Subscriptions disabled");
+ }
+
+ // available SKUs, [id => obj]
+ $skus = Sku::withObjectTenantContext($object)->get()->mapWithKeys(
function ($sku) {
return [$sku->id => $sku];
}
);
- // existing entitlement's SKUs
- $eSkus = [];
-
- $object->entitlements()->groupBy('sku_id')
- ->selectRaw('count(*) as total, sku_id')->each(
- function ($e) use (&$eSkus) {
- $eSkus[$e->sku_id] = $e->total;
- }
- );
+ // existing object SKUs, [id => total]
+ $eSkus = $object->entitlements()->groupBy('sku_id')->selectRaw('count(*) as total, sku_id')->get()->mapWithKeys(
+ function ($e) {
+ return [$e->sku_id => $e->total];
+ }
+ )->all();
+ // compare current and requested state and apply changes (add/remove entitlements)
foreach ($skus as $skuID => $sku) {
$e = array_key_exists($skuID, $eSkus) ? $eSkus[$skuID] : 0;
$r = array_key_exists($skuID, $rSkus) ? $rSkus[$skuID] : 0;
diff --git a/src/app/Http/Controllers/API/V4/UsersController.php b/src/app/Http/Controllers/API/V4/UsersController.php
--- a/src/app/Http/Controllers/API/V4/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/UsersController.php
@@ -202,6 +202,7 @@
'enableResources' => $isController && $hasCustomDomain && $hasBeta,
'enableRooms' => $hasMeet,
'enableSettings' => $isController,
+ 'enableSubscriptions' => $isController && \config('app.with_subscriptions'),
'enableUsers' => $isController,
'enableWallets' => $isController && \config('app.with_wallet'),
'enableWalletMandates' => $isController,
diff --git a/src/config/app.php b/src/config/app.php
--- a/src/config/app.php
+++ b/src/config/app.php
@@ -257,7 +257,6 @@
'methods_recurring' => env('PAYMENT_METHODS_RECURRING', 'creditcard'),
],
-
'with_ldap' => (bool) env('APP_LDAP', true),
'with_imap' => (bool) env('APP_IMAP', false),
@@ -265,8 +264,9 @@
'with_files' => (bool) env('APP_WITH_FILES', false),
'with_reseller' => (bool) env('APP_WITH_RESELLER', false),
'with_services' => (bool) env('APP_WITH_SERVICES', false),
- 'with_wallet' => (bool) env('APP_WITH_WALLET', true),
'with_signup' => (bool) env('APP_WITH_SIGNUP', true),
+ 'with_subscriptions' => (bool) env('APP_WITH_SUBSCRIPTIONS', true),
+ 'with_wallet' => (bool) env('APP_WITH_WALLET', true),
'signup' => [
'email_limit' => (int) env('SIGNUP_LIMIT_EMAIL', 0),
diff --git a/src/resources/vue/Distlist/Info.vue b/src/resources/vue/Distlist/Info.vue
--- a/src/resources/vue/Distlist/Info.vue
+++ b/src/resources/vue/Distlist/Info.vue
@@ -38,7 +38,7 @@
<list-input id="members" :list="list.members"></list-input>
</div>
</div>
- <div v-if="list_id === 'new' || list.id" id="distlist-skus" class="row mb-3">
+ <div v-if="$root.hasPermission('subscriptions') && (list_id === 'new' || list.id)" id="distlist-skus" class="row mb-3">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select class="col-sm-8 pt-sm-1" ref="skus" :object="list" type="group" :readonly="true"></subscription-select>
</div>
diff --git a/src/resources/vue/Domain/Info.vue b/src/resources/vue/Domain/Info.vue
--- a/src/resources/vue/Domain/Info.vue
+++ b/src/resources/vue/Domain/Info.vue
@@ -29,7 +29,7 @@
<label class="col-sm-4 col-form-label">{{ $t('user.package') }}</label>
<package-select class="col-sm-8 pt-sm-1" type="domain"></package-select>
</div>
- <div v-if="domain.id" id="domain-skus" class="row">
+ <div v-if="$root.hasPermission('subscriptions') && domain.id" id="domain-skus" class="row">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select v-if="domain.id" class="col-sm-8 pt-sm-1" ref="skus" type="domain" :object="domain" :readonly="true"></subscription-select>
</div>
diff --git a/src/resources/vue/Resource/Info.vue b/src/resources/vue/Resource/Info.vue
--- a/src/resources/vue/Resource/Info.vue
+++ b/src/resources/vue/Resource/Info.vue
@@ -40,7 +40,7 @@
<input type="text" class="form-control" id="email" disabled v-model="resource.email">
</div>
</div>
- <div v-if="resource_id === 'new' || resource.id" id="resource-skus" class="row mb-3">
+ <div v-if="$root.hasPermission('subscriptions') && (resource_id === 'new' || resource.id)" id="resource-skus" class="row mb-3">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select class="col-sm-8 pt-sm-1" ref="skus" :object="resource" type="resource" :readonly="true"></subscription-select>
</div>
diff --git a/src/resources/vue/Room/Info.vue b/src/resources/vue/Room/Info.vue
--- a/src/resources/vue/Room/Info.vue
+++ b/src/resources/vue/Room/Info.vue
@@ -24,7 +24,7 @@
<small class="form-text">{{ $t('room.description-hint') }}</small>
</div>
</div>
- <div v-if="room_id === 'new' || room.isOwner" id="room-skus" class="row mb-3">
+ <div v-if="$root.hasPermission('subscriptions') && (room_id === 'new' || room.isOwner)" id="room-skus" class="row mb-3">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select class="col-sm-8 pt-sm-1" ref="skus" :object="room" type="room"></subscription-select>
</div>
diff --git a/src/resources/vue/SharedFolder/Info.vue b/src/resources/vue/SharedFolder/Info.vue
--- a/src/resources/vue/SharedFolder/Info.vue
+++ b/src/resources/vue/SharedFolder/Info.vue
@@ -48,7 +48,7 @@
<list-input id="aliases" :list="folder.aliases"></list-input>
</div>
</div>
- <div v-if="folder_id === 'new' || folder.id" id="folder-skus" class="row mb-3">
+ <div v-if="$root.hasPermission('subscriptions') && (folder_id === 'new' || folder.id)" id="folder-skus" class="row mb-3">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select class="col-sm-8 pt-sm-1" ref="skus" :object="folder" type="shared-folder" :readonly="true"></subscription-select>
</div>
diff --git a/src/resources/vue/User/Info.vue b/src/resources/vue/User/Info.vue
--- a/src/resources/vue/User/Info.vue
+++ b/src/resources/vue/User/Info.vue
@@ -81,7 +81,7 @@
<label class="col-sm-4 col-form-label">{{ $t('user.package') }}</label>
<package-select class="col-sm-8 pt-sm-1"></package-select>
</div>
- <div v-if="user_id !== 'new' && isController" id="user-skus" class="row mb-3">
+ <div v-if="user_id !== 'new' && $root.hasPermission('subscriptions')" id="user-skus" class="row mb-3">
<label class="col-sm-4 col-form-label">{{ $t('form.subscriptions') }}</label>
<subscription-select v-if="user.id" class="col-sm-8 pt-sm-1" :object="user" ref="skus"></subscription-select>
</div>
diff --git a/src/tests/Feature/Controller/SkusTest.php b/src/tests/Feature/Controller/SkusTest.php
--- a/src/tests/Feature/Controller/SkusTest.php
+++ b/src/tests/Feature/Controller/SkusTest.php
@@ -2,6 +2,7 @@
namespace Tests\Feature\Controller;
+use App\Http\Controllers\API\V4\SkusController;
use App\Sku;
use App\Tenant;
use Tests\TestCase;
@@ -100,4 +101,71 @@
$this->assertSame('domain-hosting', $json[0]['title']);
$this->assertSame(0, $json[0]['nextCost']); // first domain costs 0
}
+
+ /**
+ * Test updateEntitlements() method
+ */
+ public function testUpdateEntitlements(): void
+ {
+ $jane = $this->getTestUser('jane@kolabnow.com');
+ $wallet = $jane->wallets()->first();
+ $mailbox_sku = Sku::withEnvTenantContext()->where('title', 'mailbox')->first();
+ $storage_sku = Sku::withEnvTenantContext()->where('title', 'storage')->first();
+
+ // Invalid empty input
+ SkusController::updateEntitlements($jane, null, $wallet);
+
+ $this->assertSame(0, $wallet->entitlements()->count());
+
+ // Add mailbox SKU
+ SkusController::updateEntitlements($jane, [$mailbox_sku->id => 1], $wallet);
+
+ $this->assertSame(1, $wallet->entitlements()->count());
+ $this->assertSame($mailbox_sku->id, $wallet->entitlements()->first()->sku_id);
+
+ // Add 2 storage SKUs
+ $skus = [$mailbox_sku->id => 1, $storage_sku->id => 2];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+
+ $this->assertSame(1, $wallet->entitlements()->where('sku_id', $mailbox_sku->id)->count());
+ $this->assertSame(2, $wallet->entitlements()->where('sku_id', $storage_sku->id)->count());
+
+ // Add two more storage SKUs
+ $skus = [$mailbox_sku->id => 1, $storage_sku->id => 7];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+
+ $this->assertSame(1, $wallet->entitlements()->where('sku_id', $mailbox_sku->id)->count());
+ $this->assertSame(7, $wallet->entitlements()->where('sku_id', $storage_sku->id)->count());
+
+ // Remove two storage SKUs
+ $skus = [$mailbox_sku->id => 1, $storage_sku->id => 3];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+
+ $this->assertSame(1, $wallet->entitlements()->where('sku_id', $mailbox_sku->id)->count());
+ // Note: 5 not 4 because of free_units=5
+ $this->assertSame(5, $wallet->entitlements()->where('sku_id', $storage_sku->id)->count());
+
+ // Request SKU that can't be assigned to a User object
+ // Such SKUs are being ignored silently
+ $group_sku = Sku::withEnvTenantContext()->where('title', 'group')->first();
+ $skus = [$mailbox_sku->id => 1, $storage_sku->id => 5, $group_sku->id => 1];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+
+ $this->assertSame(0, $wallet->entitlements()->where('sku_id', $group_sku->id)->count());
+
+ // Error - add extra mailbox SKU
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('Invalid quantity of mailboxes');
+
+ $skus = [$mailbox_sku->id => 2, $storage_sku->id => 5];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+
+ // Error - disabled subscriptions
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('Subscriptions disabled');
+
+ \config(['app.with_subscriptions' => false]);
+ $skus = [$mailbox_sku->id => 1];
+ SkusController::updateEntitlements($jane, $skus, $wallet);
+ }
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 11:41 AM (3 d, 2 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822709
Default Alt Text
D4310.1775389262.diff (12 KB)
Attached To
Mode
D4310: Add option to disable access to subscriptions (APP_WITH_SUBSCRIPTIONS)
Attached
Detach File
Event Timeline