Page MenuHomePhorge

D2524.1775191682.diff
No OneTemporary

Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None

D2524.1775191682.diff

diff --git a/src/resources/js/app.js b/src/resources/js/app.js
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -188,7 +188,7 @@
isLoading() {
return isLoading > 0
},
- errorPage(code, msg) {
+ errorPage(code, msg, hint) {
// Until https://github.com/vuejs/vue-router/issues/977 is implemented
// we can't really use router to display error page as it has two side
// effects: it changes the URL and adds the error page to browser history.
@@ -203,8 +203,11 @@
}
if (!msg) msg = map[code] || "Unknown Error"
+ if (!hint) hint = ''
- const error_page = `<div id="error-page" class="error-page"><div class="code">${code}</div><div class="message">${msg}</div></div>`
+ const error_page = '<div id="error-page" class="error-page">'
+ + `<div class="code">${code}</div><div class="message">${msg}</div><div class="hint">${hint}</div>`
+ + '</div>'
$('#error-page').remove()
$('#app').append(error_page)
diff --git a/src/resources/js/routes-user.js b/src/resources/js/routes-user.js
--- a/src/resources/js/routes-user.js
+++ b/src/resources/js/routes-user.js
@@ -31,25 +31,25 @@
path: '/distlist/:list',
name: 'distlist',
component: DistlistInfoComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'distlists' }
},
{
path: '/distlists',
name: 'distlists',
component: DistlistListComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'distlists' }
},
{
path: '/domain/:domain',
name: 'domain',
component: DomainInfoComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'domains' }
},
{
path: '/domains',
name: 'domains',
component: DomainListComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'domains' }
},
{
path: '/login',
@@ -100,19 +100,19 @@
path: '/user/:user',
name: 'user',
component: UserInfoComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'users' }
},
{
path: '/users',
name: 'users',
component: UserListComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'users' }
},
{
path: '/wallet',
name: 'wallet',
component: WalletComponent,
- meta: { requiresAuth: true }
+ meta: { requiresAuth: true, perm: 'wallets' }
},
{
name: '404',
diff --git a/src/resources/themes/app.scss b/src/resources/themes/app.scss
--- a/src/resources/themes/app.scss
+++ b/src/resources/themes/app.scss
@@ -35,8 +35,10 @@
top: 0;
height: 100%;
width: 100%;
+ align-content: center;
align-items: center;
display: flex;
+ flex-wrap: wrap;
justify-content: center;
color: #636b6f;
z-index: 10;
@@ -53,6 +55,12 @@
font-size: 18px;
padding: 0 15px;
}
+
+ .hint {
+ margin-top: 3em;
+ text-align: center;
+ width: 100%;
+ }
}
.app-loader {
diff --git a/src/resources/vue/App.vue b/src/resources/vue/App.vue
--- a/src/resources/vue/App.vue
+++ b/src/resources/vue/App.vue
@@ -1,5 +1,5 @@
<template>
- <router-view v-if="!isLoading && !routerReloading" :key="key" @hook:mounted="childMounted"></router-view>
+ <router-view v-if="!isLoading && !routerReloading && key" :key="key" @hook:mounted="childMounted"></router-view>
</template>
<script>
@@ -12,6 +12,14 @@
},
computed: {
key() {
+ // Display 403 error page if the current user has no permission to a specified page
+ // Note that it's the only place I found that allows us to do this.
+ if (this.$route.meta.perm && !this.checkPermission(this.$route.meta.perm)) {
+ // Returning false here will block the page component from execution,
+ // as we're using the key in v-if condition on the router-view above
+ return false
+ }
+
// The 'key' property is used to reload the Page component
// whenever a route changes. Normally vue does not do that.
return this.$route.name == '404' ? this.$route.path : 'static'
@@ -41,6 +49,17 @@
}
},
methods: {
+ checkPermission(type) {
+ if (this.$root.hasPermission(type)) {
+ return true
+ }
+
+ const hint = type == 'wallets' ? "Only account owners can access a wallet." : ''
+
+ this.$root.errorPage(403, null, hint)
+
+ return false
+ },
childMounted() {
this.$root.updateBodyClass()
this.getFAQ()
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
@@ -56,11 +56,6 @@
}
},
created() {
- if (!this.$root.hasPermission('distlists')) {
- this.$root.errorPage(404)
- return
- }
-
this.list_id = this.$route.params.list
if (this.list_id != 'new') {
diff --git a/src/resources/vue/Distlist/List.vue b/src/resources/vue/Distlist/List.vue
--- a/src/resources/vue/Distlist/List.vue
+++ b/src/resources/vue/Distlist/List.vue
@@ -43,13 +43,6 @@
}
},
created() {
- // TODO: Find a way to do this in some more global way. Note that it cannot
- // be done in the vue-router, but maybe the app component?
- if (!this.$root.hasPermission('distlists')) {
- this.$root.errorPage(404)
- return
- }
-
this.$root.startLoading()
axios.get('/api/v4/groups')
diff --git a/src/tests/Browser.php b/src/tests/Browser.php
--- a/src/tests/Browser.php
+++ b/src/tests/Browser.php
@@ -76,9 +76,9 @@
/**
* Assert specified error page is displayed.
*/
- public function assertErrorPage(int $error_code)
+ public function assertErrorPage(int $error_code, string $hint = '')
{
- $this->with(new Error($error_code), function ($browser) {
+ $this->with(new Error($error_code, $hint), function ($browser) {
// empty, assertions will be made by the Error component itself
});
diff --git a/src/tests/Browser/Components/Error.php b/src/tests/Browser/Components/Error.php
--- a/src/tests/Browser/Components/Error.php
+++ b/src/tests/Browser/Components/Error.php
@@ -8,6 +8,7 @@
class Error extends BaseComponent
{
protected $code;
+ protected $hint;
protected $message;
protected $messages_map = [
400 => "Bad request",
@@ -18,9 +19,10 @@
500 => "Internal server error",
];
- public function __construct($code)
+ public function __construct($code, $hint = '')
{
$this->code = $code;
+ $this->hint = $hint;
$this->message = $this->messages_map[$code];
}
@@ -46,6 +48,12 @@
$browser->waitFor($this->selector())
->assertSeeIn('@code', $this->code);
+ if ($this->hint) {
+ $browser->assertSeeIn('@hint', $this->hint);
+ } else {
+ $browser->assertMissing('@hint');
+ }
+
$message = $browser->text('@message');
PHPUnit::assertSame(strtolower($message), strtolower($this->message));
}
@@ -62,6 +70,7 @@
return [
'@code' => "$selector .code",
'@message' => "$selector .message",
+ '@hint' => "$selector .hint",
];
}
}
diff --git a/src/tests/Browser/DistlistTest.php b/src/tests/Browser/DistlistTest.php
--- a/src/tests/Browser/DistlistTest.php
+++ b/src/tests/Browser/DistlistTest.php
@@ -76,7 +76,7 @@
// Test that Distribution lists page is not accessible without the 'distlist' entitlement
$this->browse(function (Browser $browser) {
$browser->visit('/distlists')
- ->assertErrorPage(404);
+ ->assertErrorPage(403);
});
// Create a single group, add beta+distlist entitlements
@@ -111,7 +111,7 @@
// Test that the page is not available accessible without the 'distlist' entitlement
$this->browse(function (Browser $browser) {
$browser->visit('/distlist/new')
- ->assertErrorPage(404);
+ ->assertErrorPage(403);
});
// Add beta+distlist entitlements
diff --git a/src/tests/Browser/Pages/Home.php b/src/tests/Browser/Pages/Home.php
--- a/src/tests/Browser/Pages/Home.php
+++ b/src/tests/Browser/Pages/Home.php
@@ -64,7 +64,8 @@
$wait_for_dashboard = false,
$config = []
) {
- $browser->type('@email-input', $username)
+ $browser->clearToasts()
+ ->type('@email-input', $username)
->type('@password-input', $password);
if ($username == 'ned@kolab.org') {
diff --git a/src/tests/Browser/UserProfileTest.php b/src/tests/Browser/UserProfileTest.php
--- a/src/tests/Browser/UserProfileTest.php
+++ b/src/tests/Browser/UserProfileTest.php
@@ -164,7 +164,6 @@
->on(new Home())
->submitLogon('profile-delete@kolabnow.com', 'simple123', true)
->on(new Dashboard())
- ->clearToasts()
->assertSeeIn('@links .link-profile', 'Your profile')
->click('@links .link-profile')
->on(new UserProfile())
diff --git a/src/tests/Browser/UsersTest.php b/src/tests/Browser/UsersTest.php
--- a/src/tests/Browser/UsersTest.php
+++ b/src/tests/Browser/UsersTest.php
@@ -508,11 +508,8 @@
$browser->visit('/logout')
->on(new Home())
->submitLogon('jack@kolab.org', 'simple123', true)
- ->visit(new UserList())
- ->whenAvailable('@table', function (Browser $browser) {
- $browser->assertElementsCount('tbody tr', 0)
- ->assertSeeIn('tfoot td', 'There are no users in this account.');
- });
+ ->visit('/users')
+ ->assertErrorPage(403);
});
// Test that controller user (Ned) can see all the users
diff --git a/src/tests/Browser/WalletTest.php b/src/tests/Browser/WalletTest.php
--- a/src/tests/Browser/WalletTest.php
+++ b/src/tests/Browser/WalletTest.php
@@ -257,4 +257,20 @@
});
});
}
+
+ /**
+ * Test that non-controller user has no access to wallet
+ */
+ public function testAccessDenied(): void
+ {
+ $this->browse(function (Browser $browser) {
+ $browser->visit('/logout')
+ ->on(new Home())
+ ->submitLogon('jack@kolab.org', 'simple123', true)
+ ->on(new Dashboard())
+ ->assertMissing('@links .link-wallet')
+ ->visit('/wallet')
+ ->assertErrorPage(403, "Only account owners can access a wallet.");
+ });
+ }
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 4:48 AM (2 d, 16 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18817347
Default Alt Text
D2524.1775191682.diff (11 KB)

Event Timeline