2
0
Эх сурвалжийг харах

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>
BobbyB 5 жил өмнө
parent
commit
b82c788e5c

+ 6 - 3
client/components/admin/admin-groups-edit-rules.vue

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

+ 31 - 20
server/controllers/common.js

@@ -59,6 +59,8 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
     isPrivate: false
   })
 
+  pageArgs.tags = _.get(page, 'tags', [])
+
   const injectCode = {
     css: WIKI.config.theming.injectCSS,
     head: WIKI.config.theming.injectHead,
@@ -109,17 +111,20 @@ router.get(['/h', '/h/*'], async (req, res, next) => {
 
   _.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({
     path: pageArgs.path,
     locale: pageArgs.locale,
     userId: req.user.id,
     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) {
     _.set(res.locals, 'pageMeta.title', page.title)
     _.set(res.locals, 'pageMeta.description', page.description)
@@ -149,7 +154,8 @@ router.get(['/i', '/i/:id'], async (req, res, next) => {
     path: page.path,
     private: page.isPrivate,
     privateNS: page.privateNS,
-    explicitLocale: false
+    explicitLocale: false,
+    tags: page.tags
   })) {
     _.set(res.locals, 'pageMeta.title', 'Unauthorized')
     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) => {
   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) {
     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' })
   }
 
-  const page = await WIKI.models.pages.getPageFromDb({
-    path: pageArgs.path,
-    locale: pageArgs.locale,
-    userId: req.user.id,
-    isPrivate: false
-  })
   if (page) {
     _.set(res.locals, 'pageMeta.title', page.title)
     _.set(res.locals, 'pageMeta.description', page.description)
@@ -224,14 +232,6 @@ router.get('/*', async (req, res, next) => {
 
     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 {
       const page = await WIKI.models.pages.getPage({
         path: pageArgs.path,
@@ -239,6 +239,17 @@ router.get('/*', async (req, res, next) => {
         userId: req.user.id,
         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)
 

+ 14 - 3
server/core/auth.js

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

+ 1 - 0
server/graph/schemas/group.graphql

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