mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Added message log view in new frontend.
This commit is contained in:
@@ -41,10 +41,10 @@
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"sass": "^1.26.5",
|
||||
"sass": "~1.32.12",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue-cli-plugin-axios": "~0.0.4",
|
||||
"vue-cli-plugin-vuetify": "~2.0.7",
|
||||
"vue-cli-plugin-vuetify": "~2.4.1",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuetify-loader": "^1.3.0"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ import repository from './repository'
|
||||
const resource = 'logs'
|
||||
|
||||
export default {
|
||||
getAll (params) {
|
||||
return repository.get(`/${resource}/`, { params })
|
||||
getAuditTrail (params) {
|
||||
return repository.get(`/${resource}/audit-trail/`, { params })
|
||||
},
|
||||
getMessages (params) {
|
||||
return repository.get(`/${resource}/messages/`, { params })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,8 +152,19 @@ export default {
|
||||
{
|
||||
icon: 'mdi-history',
|
||||
text: this.$gettext('Logs'),
|
||||
to: { name: 'AuditTrail' },
|
||||
roles: ['SuperAdmins']
|
||||
roles: ['SuperAdmins', 'Resellers', 'DomainAdmins'],
|
||||
children: [
|
||||
{
|
||||
text: this.$gettext('Audit trail'),
|
||||
to: { name: 'AuditTrail' },
|
||||
roles: ['SuperAdmins']
|
||||
},
|
||||
{
|
||||
text: this.$gettext('Messages'),
|
||||
to: { name: 'MessageLog' },
|
||||
roles: ['DomainAdmins', 'Resellers', 'SuperAdmins']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
icon: 'mdi-cog',
|
||||
|
||||
@@ -37,10 +37,10 @@ export default {
|
||||
return {
|
||||
logs: [],
|
||||
headers: [
|
||||
{ text: 'Date', value: 'date_created' },
|
||||
{ text: 'Level', value: 'level' },
|
||||
{ text: 'Logger', value: 'logger' },
|
||||
{ text: 'Message', value: 'message' }
|
||||
{ text: this.$gettext('Date'), value: 'date_created' },
|
||||
{ text: this.$gettext('Level'), value: 'level' },
|
||||
{ text: this.$gettext('Logger'), value: 'logger' },
|
||||
{ text: this.$gettext('Message'), value: 'message' }
|
||||
],
|
||||
loading: true,
|
||||
options: {},
|
||||
@@ -56,7 +56,7 @@ export default {
|
||||
if (level === 'WARNING') {
|
||||
return 'orange'
|
||||
}
|
||||
if (level === 'CRITICAL') {
|
||||
if (level === 'CRITICAL' || level === 'ERROR') {
|
||||
return 'red'
|
||||
}
|
||||
return ''
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
search: this.search
|
||||
}
|
||||
this.loading = true
|
||||
logs.getAll(params).then(response => {
|
||||
logs.getAuditTrail(params).then(response => {
|
||||
this.logs = response.data.results
|
||||
this.total = response.data.count
|
||||
this.loading = false
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<v-card class="mt-6">
|
||||
<v-toolbar flat>
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field
|
||||
v-model="search"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
:placeholder="'Search'|translate"
|
||||
filled
|
||||
outlined
|
||||
dense
|
||||
hide-details
|
||||
/>
|
||||
</v-toolbar>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="messages"
|
||||
:search="search"
|
||||
class="elevation-1"
|
||||
:options.sync="options"
|
||||
:server-items-length="total"
|
||||
>
|
||||
<template v-slot:item.date="{ item }">
|
||||
{{ item.date|date }}
|
||||
</template>
|
||||
<template v-slot:item.sender="{ item }">
|
||||
{{ item.sender|truncate(50) }}
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import logs from '@/api/logs'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
messages: [],
|
||||
headers: [
|
||||
{ text: this.$gettext('Queue ID'), value: 'queue_id' },
|
||||
{ text: this.$gettext('Date'), value: 'date', width: '20%' },
|
||||
{ text: this.$gettext('Status'), value: 'status' },
|
||||
{ text: this.$gettext('To'), value: 'rcpt' },
|
||||
{ text: this.$gettext('From'), value: 'sender' }
|
||||
],
|
||||
loading: true,
|
||||
options: {},
|
||||
search: '',
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchMessages () {
|
||||
let order
|
||||
if (this.options.sortBy.length) {
|
||||
order = (this.options.sortDesc[0] ? '-' : '') + this.options.sortBy[0]
|
||||
}
|
||||
const params = {
|
||||
ordering: order,
|
||||
page: this.options.page,
|
||||
page_size: this.options.itemsPerPage,
|
||||
search: this.search
|
||||
}
|
||||
this.loading = true
|
||||
logs.getMessages(params).then(response => {
|
||||
this.messages = response.data.results
|
||||
this.total = response.data.count
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler () {
|
||||
this.fetchMessages()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
search (val) {
|
||||
this.fetchMessages()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -13,3 +13,11 @@ Vue.filter('yesno', function (value) {
|
||||
Vue.filter('date', function (value) {
|
||||
return DateTime.fromISO(value).setLocale('en').toLocaleString(DateTime.DATETIME_MED)
|
||||
})
|
||||
|
||||
/*
|
||||
** Truncate given string.
|
||||
*/
|
||||
Vue.filter('truncate', function (text, length, clamp) {
|
||||
clamp = clamp || '...'
|
||||
return text.length > length ? text.slice(0, length) + clamp : text
|
||||
})
|
||||
|
||||
@@ -93,13 +93,22 @@ const routes = [
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/logs/',
|
||||
path: '/logs/audit_trail',
|
||||
name: 'AuditTrail',
|
||||
component: () => import('../views/logs/AuditTrail.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
allowedRoles: ['SuperAdmins']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/logs/messages',
|
||||
name: 'MessageLog',
|
||||
component: () => import('../views/logs/Messages.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
allowedRoles: ['DomainAdmins', 'SuperAdmins']
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-toolbar flat>
|
||||
<v-toolbar-title><translate>Message history</translate></v-toolbar-title>
|
||||
</v-toolbar>
|
||||
<message-list />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MessageList from '@/components/logs/MessageList'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MessageList
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+18
-47
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5":
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
|
||||
integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
|
||||
@@ -35,7 +35,7 @@
|
||||
semver "^6.3.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.11.5", "@babel/generator@^7.14.5":
|
||||
"@babel/generator@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785"
|
||||
integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==
|
||||
@@ -110,7 +110,7 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.14.5":
|
||||
"@babel/helper-function-name@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4"
|
||||
integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==
|
||||
@@ -206,14 +206,14 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.14.5":
|
||||
"@babel/helper-split-export-declaration@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a"
|
||||
integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.14.5":
|
||||
"@babel/helper-validator-identifier@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
|
||||
integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
|
||||
@@ -251,16 +251,11 @@
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.11.5", "@babel/parser@^7.12.0", "@babel/parser@^7.13.9", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6":
|
||||
"@babel/parser@^7.12.0", "@babel/parser@^7.13.9", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.6.0", "@babel/parser@^7.7.0", "@babel/parser@^7.9.6":
|
||||
version "7.14.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
|
||||
integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
|
||||
|
||||
"@babel/parser@^7.7.0":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
|
||||
integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
|
||||
|
||||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e"
|
||||
@@ -893,7 +888,7 @@
|
||||
"@babel/parser" "^7.14.5"
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5":
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.0":
|
||||
version "7.14.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753"
|
||||
integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==
|
||||
@@ -908,22 +903,7 @@
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.7.0":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
|
||||
integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.11.5"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.11.0"
|
||||
"@babel/parser" "^7.11.5"
|
||||
"@babel/types" "^7.11.5"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.11.5", "@babel/types@^7.12.0", "@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.6":
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.12.0", "@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.7.0", "@babel/types@^7.9.6":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
|
||||
integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==
|
||||
@@ -931,15 +911,6 @@
|
||||
"@babel/helper-validator-identifier" "^7.14.5"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.7.0":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
|
||||
integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@hapi/address@2.x.x":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
|
||||
@@ -8244,7 +8215,7 @@ resolve-url@^0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||
|
||||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.20.0:
|
||||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.20.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
@@ -8252,7 +8223,7 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.10.1, resolve@^1.12.0:
|
||||
resolve@^1.10.1:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
|
||||
@@ -8381,10 +8352,10 @@ sass-loader@^8.0.2:
|
||||
schema-utils "^2.6.1"
|
||||
semver "^6.3.0"
|
||||
|
||||
sass@^1.26.5:
|
||||
version "1.35.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.35.1.tgz#90ecf774dfe68f07b6193077e3b42fb154b9e1cd"
|
||||
integrity sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==
|
||||
sass@~1.32.12:
|
||||
version "1.32.13"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.13.tgz#8d29c849e625a415bce71609c7cf95e15f74ed00"
|
||||
integrity sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
|
||||
@@ -9692,10 +9663,10 @@ vue-cli-plugin-axios@~0.0.4:
|
||||
resolved "https://registry.yarnpkg.com/vue-cli-plugin-axios/-/vue-cli-plugin-axios-0.0.4.tgz#29d4eb48275c7fe15b92e1fd5d95fbe2a966436f"
|
||||
integrity sha512-p2b/fvPJuPBnvU8027PAAuU5DiOzUn2lku8XLG/f6c8FU0N+/MXWZAlOuHhqd9e7+KIZitwe/c8qlmv7TglbTg==
|
||||
|
||||
vue-cli-plugin-vuetify@~2.0.7:
|
||||
version "2.0.9"
|
||||
resolved "https://registry.yarnpkg.com/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.9.tgz#982991aec28e79d1f0c2eb8f6e3d62e042087ee8"
|
||||
integrity sha512-J4fzpz27OmCCAA3CI56ulYsUrZ859dQAh58Z9XZilY03kd/M+svLlPkK45cBIrGGfjSqQ40oyWezA3NiPBEG8g==
|
||||
vue-cli-plugin-vuetify@~2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.4.1.tgz#a31a9ddb274c8e512aeca7dc2f29d828a18df0af"
|
||||
integrity sha512-ZfhvQ13X41atsCSKdSGiHnSJlhAccv4QIFOZmd8kyq6NktpeeWlvQz/dEKBf6u1AWKmKdwiCDuxS2VNT9fxhOA==
|
||||
dependencies:
|
||||
null-loader "^3.0.0"
|
||||
semver "^7.1.2"
|
||||
|
||||
@@ -13,7 +13,7 @@ from . import viewsets
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r"account", viewsets.AccountViewSet, basename="account")
|
||||
router.register(r"logs", viewsets.LogViewSet)
|
||||
router.register(r"logs/audit-trail", viewsets.LogViewSet)
|
||||
|
||||
urlpatterns = router.urls
|
||||
urlpatterns += [
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
"""Core API v2 viewsets."""
|
||||
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import filters, pagination, permissions, response, viewsets
|
||||
from rest_framework import filters, permissions, response, viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
|
||||
from modoboa.admin.api.v1 import serializers as admin_v1_serializers
|
||||
from modoboa.core.api.v1 import viewsets as core_v1_viewsets
|
||||
from modoboa.lib import pagination
|
||||
|
||||
from ... import constants
|
||||
from ... import models
|
||||
@@ -38,17 +39,13 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet):
|
||||
})
|
||||
|
||||
|
||||
class CustomPageNumberPagination(pagination.PageNumberPagination):
|
||||
page_size_query_param = "page_size"
|
||||
|
||||
|
||||
class LogViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Log viewset."""
|
||||
|
||||
filter_backends = [filters.OrderingFilter, filters.SearchFilter]
|
||||
ordering = ["-date_created"]
|
||||
ordering_fields = "__all__"
|
||||
pagination_class = CustomPageNumberPagination
|
||||
pagination_class = pagination.CustomPageNumberPagination
|
||||
permission_classes = (
|
||||
permissions.IsAuthenticated,
|
||||
permissions.DjangoModelPermissions,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Pagination utilities."""
|
||||
|
||||
from rest_framework import pagination
|
||||
|
||||
|
||||
class CustomPageNumberPagination(pagination.PageNumberPagination):
|
||||
page_size_query_param = "page_size"
|
||||
@@ -4,6 +4,8 @@ from django.utils.translation import ugettext as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from ... import models
|
||||
|
||||
|
||||
PERIODS = [
|
||||
("day", "Day"),
|
||||
@@ -62,3 +64,14 @@ class StatisticsSerializer(serializers.Serializer):
|
||||
"""Serializer to return statistics."""
|
||||
|
||||
graphs = GraphSerializer(many=True)
|
||||
|
||||
|
||||
class MaillogSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for Maillog model."""
|
||||
|
||||
class Meta:
|
||||
fields = (
|
||||
"id", "queue_id", "date", "sender", "rcpt", "original_rcpt",
|
||||
"size", "status"
|
||||
)
|
||||
model = models.Maillog
|
||||
|
||||
@@ -23,3 +23,11 @@ class StatisticsViewSetTestCase(ModoAPITestCase):
|
||||
"?gset=mailtraffic&period=custom&start=2021-05-01&end=2021-05-02"
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
|
||||
class MaillogViewSetTestCase(ModoAPITestCase):
|
||||
|
||||
def test_list(self):
|
||||
url = reverse("v2:maillog-list")
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@@ -7,5 +7,7 @@ from . import viewsets
|
||||
router = routers.SimpleRouter()
|
||||
router.register(
|
||||
r"statistics", viewsets.StatisticsViewSet, basename="statistics")
|
||||
router.register(
|
||||
r"logs/messages", viewsets.MaillogViewSet, basename="maillog")
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
|
||||
import time
|
||||
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import permissions, response, viewsets
|
||||
from django.db.models import Q
|
||||
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import filters, permissions, response, viewsets
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
from modoboa.lib import pagination
|
||||
|
||||
from ... import models
|
||||
from ... import signals
|
||||
from . import serializers
|
||||
|
||||
@@ -43,3 +49,22 @@ class StatisticsViewSet(viewsets.ViewSet):
|
||||
fname, start, end, serializer.validated_data.get("graphic")
|
||||
)
|
||||
return response.Response({"graphs": graphs})
|
||||
|
||||
|
||||
class MaillogViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Simple viewset to access message log."""
|
||||
|
||||
filter_backends = [filters.OrderingFilter, filters.SearchFilter]
|
||||
ordering = ["-date"]
|
||||
ordering_fields = "__all__"
|
||||
pagination_class = pagination.CustomPageNumberPagination
|
||||
permissions = (permissions.IsAuthenticated, )
|
||||
search_fields = ["queue_id", "sender", "rcpt", "original_rcpt", "status"]
|
||||
serializer_class = serializers.MaillogSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter queryset based on current user."""
|
||||
domains = admin_models.Domain.objects.get_for_admin(self.request.user)
|
||||
return models.Maillog.objects.filter(
|
||||
Q(from_domain__in=domains) | Q(to_domain__in=domains)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user