feat: add Page Rules For Matching Tags (#1418)

* Added Page Rules For Matching Tags

* fix: use T as Tag Match icon

* fix: reorder page rules in checkAccess

* fix: common controller tags code refactor

Co-authored-by: Nicolas Giard <github@ngpixel.com>
pull/1430/head
BobbyB 5 years ago committed by GitHub
parent 4e9d4071fd
commit b82c788e5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -157,8 +157,8 @@
solo solo
v-model='rule.path' v-model='rule.path'
label='Path' label='Path'
:prefix='rule.match !== `END` ? `/` : null' :prefix='(rule.match !== `END` && rule.match !== `TAG`) ? `/` : null'
:placeholder='rule.match === `REGEX` ? `Regular Expression` : `Path`' :placeholder='rule.match === `REGEX` ? `Regular Expression` : rule.match === `TAG` ? `Tag` : `Path`'
:suffix='rule.match === `REGEX` ? `/` : null' :suffix='rule.match === `REGEX` ? `/` : null'
hide-details hide-details
:color='$vuetify.theme.dark ? `grey` : `blue-grey`' :color='$vuetify.theme.dark ? `grey` : `blue-grey`'
@ -181,6 +181,8 @@
strong Path Ends With... strong Path Ends With...
li li
strong Path Matches Regex... strong Path Matches Regex...
li
strong Tag Matches...
li li
strong Path Is Exactly... strong Path Is Exactly...
em.caption.pl-1 (highest) em.caption.pl-1 (highest)
@ -222,7 +224,8 @@ export default {
{ text: 'Path Starts With...', value: 'START', icon: '/...' }, { text: 'Path Starts With...', value: 'START', icon: '/...' },
{ text: 'Path is Exactly...', value: 'EXACT', icon: '=' }, { text: 'Path is Exactly...', value: 'EXACT', icon: '=' },
{ text: 'Path Ends With...', value: 'END', icon: '.../' }, { text: 'Path Ends With...', value: 'END', icon: '.../' },
{ text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' } { text: 'Path Matches Regex...', value: 'REGEX', icon: '$.*' },
{ text: 'Tag Matches...', value: 'TAG', icon: 'T' }
], ],
locales: [ locales: [
{ text: 'English', value: 'en' } { text: 'English', value: 'en' }

@ -59,6 +59,8 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
isPrivate: false isPrivate: false
}) })
pageArgs.tags = _.get(page, 'tags', [])
const injectCode = { const injectCode = {
css: WIKI.config.theming.injectCSS, css: WIKI.config.theming.injectCSS,
head: WIKI.config.theming.injectHead, head: WIKI.config.theming.injectHead,
@ -109,17 +111,20 @@ router.get(['/h', '/h/*'], async (req, res, next) => {
_.set(res, 'locals.siteConfig.lang', pageArgs.locale) _.set(res, 'locals.siteConfig.lang', pageArgs.locale)
if (!WIKI.auth.checkAccess(req.user, ['read:history'], pageArgs)) {
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
return res.render('unauthorized', { action: 'history' })
}
const page = await WIKI.models.pages.getPageFromDb({ const page = await WIKI.models.pages.getPageFromDb({
path: pageArgs.path, path: pageArgs.path,
locale: pageArgs.locale, locale: pageArgs.locale,
userId: req.user.id, userId: req.user.id,
isPrivate: false isPrivate: false
}) })
pageArgs.tags = _.get(page, 'tags', [])
if (!WIKI.auth.checkAccess(req.user, ['read:history'], pageArgs)) {
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
return res.render('unauthorized', { action: 'history' })
}
if (page) { if (page) {
_.set(res.locals, 'pageMeta.title', page.title) _.set(res.locals, 'pageMeta.title', page.title)
_.set(res.locals, 'pageMeta.description', page.description) _.set(res.locals, 'pageMeta.description', page.description)
@ -149,7 +154,8 @@ router.get(['/i', '/i/:id'], async (req, res, next) => {
path: page.path, path: page.path,
private: page.isPrivate, private: page.isPrivate,
privateNS: page.privateNS, privateNS: page.privateNS,
explicitLocale: false explicitLocale: false,
tags: page.tags
})) { })) {
_.set(res.locals, 'pageMeta.title', 'Unauthorized') _.set(res.locals, 'pageMeta.title', 'Unauthorized')
return res.render('unauthorized', { action: 'view' }) return res.render('unauthorized', { action: 'view' })
@ -175,6 +181,14 @@ router.get(['/p', '/p/*'], (req, res, next) => {
*/ */
router.get(['/s', '/s/*'], async (req, res, next) => { router.get(['/s', '/s/*'], async (req, res, next) => {
const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) const pageArgs = pageHelper.parsePath(req.path, { stripExt: true })
const page = await WIKI.models.pages.getPageFromDb({
path: pageArgs.path,
locale: pageArgs.locale,
userId: req.user.id,
isPrivate: false
})
pageArgs.tags = _.get(page, 'tags', [])
if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) { if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) {
return res.redirect(`/s/${pageArgs.locale}/${pageArgs.path}`) return res.redirect(`/s/${pageArgs.locale}/${pageArgs.path}`)
@ -186,12 +200,6 @@ router.get(['/s', '/s/*'], async (req, res, next) => {
return res.render('unauthorized', { action: 'source' }) return res.render('unauthorized', { action: 'source' })
} }
const page = await WIKI.models.pages.getPageFromDb({
path: pageArgs.path,
locale: pageArgs.locale,
userId: req.user.id,
isPrivate: false
})
if (page) { if (page) {
_.set(res.locals, 'pageMeta.title', page.title) _.set(res.locals, 'pageMeta.title', page.title)
_.set(res.locals, 'pageMeta.description', page.description) _.set(res.locals, 'pageMeta.description', page.description)
@ -224,14 +232,6 @@ router.get('/*', async (req, res, next) => {
req.i18n.changeLanguage(pageArgs.locale) req.i18n.changeLanguage(pageArgs.locale)
if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) {
if (pageArgs.path === 'home') {
return res.redirect('/login')
}
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
return res.status(403).render('unauthorized', { action: 'view' })
}
try { try {
const page = await WIKI.models.pages.getPage({ const page = await WIKI.models.pages.getPage({
path: pageArgs.path, path: pageArgs.path,
@ -239,6 +239,17 @@ router.get('/*', async (req, res, next) => {
userId: req.user.id, userId: req.user.id,
isPrivate: false isPrivate: false
}) })
pageArgs.tags = _.get(page, 'tags', [])
if (!WIKI.auth.checkAccess(req.user, ['read:pages'], pageArgs)) {
if (pageArgs.path === 'home') {
return res.redirect('/login')
}
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
return res.status(403).render('unauthorized', {
action: 'view'
})
}
_.set(res, 'locals.siteConfig.lang', pageArgs.locale) _.set(res, 'locals.siteConfig.lang', pageArgs.locale)

@ -176,20 +176,31 @@ module.exports = {
switch (rule.match) { switch (rule.match) {
case 'START': case 'START':
if (_.startsWith(`/${page.path}`, `/${rule.path}`)) { if (_.startsWith(`/${page.path}`, `/${rule.path}`)) {
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['END', 'REGEX', 'EXACT'] }) checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['END', 'REGEX', 'EXACT', 'TAG'] })
} }
break break
case 'END': case 'END':
if (_.endsWith(page.path, rule.path)) { if (_.endsWith(page.path, rule.path)) {
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['REGEX', 'EXACT'] }) checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['REGEX', 'EXACT', 'TAG'] })
} }
break break
case 'REGEX': case 'REGEX':
const reg = new RegExp(rule.path) const reg = new RegExp(rule.path)
if (reg.test(page.path)) { if (reg.test(page.path)) {
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['EXACT'] }) checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['EXACT', 'TAG'] })
} }
break break
case 'TAG':
_.get(page, 'tags', []).forEach(tag => {
if (tag.tag === rule.path) {
checkState = this._applyPageRuleSpecificity({
rule,
checkState,
higherPriority: ['EXACT']
})
}
})
break
case 'EXACT': case 'EXACT':
if (`/${page.path}` === `/${rule.path}`) { if (`/${page.path}` === `/${rule.path}`) {
checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: [] }) checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: [] })

@ -108,4 +108,5 @@ enum PageRuleMatch {
EXACT EXACT
END END
REGEX REGEX
TAG
} }

Loading…
Cancel
Save