diff options
| author | 2018-06-17 21:32:51 +0000 | |
|---|---|---|
| committer | 2018-06-17 21:32:51 +0000 | |
| commit | 41728358a8b2b9c7f1a96d73d8b876750cf0d4d2 (patch) | |
| tree | 79d95eef0f265909961677b381b4e81f1a3c1925 | |
| parent | Merge branch 'code-jam-backend-teams' into 'master' (diff) | |
| parent | Wiki audit logs (diff) | |
Merge branch 'gists-to-snippets' into 'master'
Wiki audit logs
See merge request python-discord/projects/site!4
| -rw-r--r-- | pysite/constants.py | 8 | ||||
| -rw-r--r-- | pysite/views/wiki/delete.py | 32 | ||||
| -rw-r--r-- | pysite/views/wiki/edit.py | 97 | ||||
| -rw-r--r-- | pysite/views/wiki/move.py | 35 | 
4 files changed, 56 insertions, 116 deletions
| diff --git a/pysite/constants.py b/pysite/constants.py index 3177fe59..016ab9c5 100644 --- a/pysite/constants.py +++ b/pysite/constants.py @@ -101,14 +101,8 @@ JAM_QUESTION_TYPES = [  # CSRF  CSRF = CSRFProtect() -# GitHub Token -GITHUB_TOKEN = environ.get("GITHUB_TOKEN") or None - -# Audit Webhook -WIKI_AUDIT_WEBHOOK = environ.get("WIKI_AUDIT_WEBHOOK") or None -  # Bot key -BOT_API_KEY = environ.get("BOT_API_KEY") or None +BOT_API_KEY = environ.get("BOT_API_KEY")  # RabbitMQ settings  BOT_EVENT_QUEUE = "bot_events" diff --git a/pysite/views/wiki/delete.py b/pysite/views/wiki/delete.py index 38d7d087..d6718f64 100644 --- a/pysite/views/wiki/delete.py +++ b/pysite/views/wiki/delete.py @@ -1,16 +1,15 @@  import datetime -import requests  from flask import redirect, url_for  from werkzeug.exceptions import NotFound  from pysite.base_route import RouteView -from pysite.constants import EDITOR_ROLES, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, EDITOR_ROLES  from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin -class DeleteView(RouteView, DBMixin): +class DeleteView(RouteView, DBMixin, RMQMixin):      path = "/delete/<path:page>"  # "path" means that it accepts slashes      name = "delete"      table_name = "wiki" @@ -53,20 +52,13 @@ class DeleteView(RouteView, DBMixin):          return redirect(url_for("wiki.page", page="home"), code=303)  # Redirect, ensuring a GET      def audit_log(self, obj): -        if WIKI_AUDIT_WEBHOOK:  # If the audit webhook is not configured there is no point processing it -            audit_payload = { -                "username": "Wiki Updates", -                "embeds": [ -                    { -                        "title": "Page Deletion", -                        "description": f"**{obj['title']}** was deleted by **{self.user_data.get('username')}**", -                        "color": 4165079, -                        "timestamp": datetime.datetime.utcnow().isoformat(), -                        "thumbnail": { -                            "url": "https://pythondiscord.com/static/logos/logo_discord.png" -                        } -                    } -                ] +        self.rmq_bot_event( +            BotEventTypes.send_embed, +            { +                "target": CHANNEL_MOD_LOG, +                "title": f"Page Deletion", +                "description": f"**{obj['title']}** was deleted by **{self.user_data.get('username')}**", +                "color": 0x3F8DD7,  # Light blue +                "timestamp": datetime.datetime.now().isoformat()              } - -            requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) +        ) diff --git a/pysite/views/wiki/edit.py b/pysite/views/wiki/edit.py index 5f0129c2..76306cf4 100644 --- a/pysite/views/wiki/edit.py +++ b/pysite/views/wiki/edit.py @@ -1,22 +1,20 @@  import datetime -import difflib  import html  import re -import requests  from flask import redirect, request, url_for  from werkzeug.exceptions import BadRequest  from pysite.base_route import RouteView -from pysite.constants import DEBUG_MODE, EDITOR_ROLES, GITHUB_TOKEN, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, DEBUG_MODE, EDITOR_ROLES  from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin  from pysite.rst import render  STRIP_REGEX = re.compile(r"<[^<]+?>") -class EditView(RouteView, DBMixin): +class EditView(RouteView, DBMixin, RMQMixin):      path = "/edit/<path:page>"  # "path" means that it accepts slashes      name = "edit"      table_name = "wiki" @@ -78,8 +76,6 @@ class EditView(RouteView, DBMixin):              "headers": rendered["headers"]          } -        self.audit_log(page, obj) -          self.db.insert(              self.table_name,              obj, @@ -97,7 +93,17 @@ class EditView(RouteView, DBMixin):              del revision_payload["post"]["slug"] -            self.db.insert(self.revision_table_name, revision_payload) +            current_revisions = self.db.filter(self.revision_table_name, lambda rev: rev["slug"] == page) +            sorted_revisions = sorted(current_revisions, lambda rev: rev["date"], reverse=True) + +            if len(sorted_revisions) > 0: +                old_rev = sorted_revisions[0] +            else: +                old_rev = None + +            new_rev = self.db.insert(self.revision_table_name, revision_payload)["generated_keys"][0] + +        self.audit_log(page, new_rev, old_rev)          return redirect(url_for("wiki.page", page=page), code=303)  # Redirect, ensuring a GET @@ -120,63 +126,20 @@ class EditView(RouteView, DBMixin):              }, conflict="update")  # Update with new lock time          return "", 204 -    def audit_log(self, page, obj): -        if WIKI_AUDIT_WEBHOOK:  # If the audit webhook is not configured there is no point processing the diff -            before = self.db.get(self.table_name, page) -            if not before:  # If this is a new page, before will be None -                before = [] -            else: -                if before.get("rst") is None: -                    before = [] -                else: -                    before = before["rst"].splitlines(keepends=True) -                    if len(before) == 0: -                        pass -                    else: -                        if not before[-1].endswith("\n"): -                            before[-1] += "\n"  # difflib sometimes messes up if a newline is missing on last line - -            after = obj['rst'].splitlines(keepends=True) or [""] - -            if not after[-1].endswith("\n"): -                after[-1] += "\n"  # Does the same thing as L57 - -            diff = difflib.unified_diff(before, after, fromfile="before.rst", tofile="after.rst") -            diff = "".join(diff) - -            gist_payload = { -                "description": f"Changes to: {obj['title']}", -                "public": False, -                "files": { -                    "changes.md": { -                        "content": f"```diff\n{diff}\n```" -                    } -                } -            } - -            headers = { -                "Authorization": f"token {GITHUB_TOKEN}", -                "User-Agent": "Discord Python Wiki (https://gitlab.com/python-discord)" -            } - -            gist = requests.post("https://api.github.com/gists", -                                 json=gist_payload, -                                 headers=headers) - -            audit_payload = { -                "username": "Wiki Updates", -                "embeds": [ -                    { -                        "title": "Page Edit", -                        "description": f"**{obj['title']}** was edited by **{self.user_data.get('username')}**" -                                       f".\n\n[View diff]({gist.json().get('html_url')})", -                        "color": 4165079, -                        "timestamp": datetime.datetime.utcnow().isoformat(), -                        "thumbnail": { -                            "url": "https://pythondiscord.com/static/logos/logo_discord.png" -                        } -                    } -                ] +    def audit_log(self, page, new, old): +        if not old: +            link = f"https://wiki.pythondiscord.com/source/{page}" +        else: +            link = f"https://wiki.pythondiscord.com/history/compare/{old['id']}/{new}" + +        self.rmq_bot_event( +            BotEventTypes.send_embed, +            { +                "target": CHANNEL_MOD_LOG, +                "title": "Page Edit", +                "description": f"**{old['post']['title']}** edited by **{self.user_data.get('username')}**. " +                               f"[View the diff here]({link})", +                "color": 0x3F8DD7,  # Light blue +                "timestamp": datetime.datetime.now().isoformat()              } - -            requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) +        ) diff --git a/pysite/views/wiki/move.py b/pysite/views/wiki/move.py index 93ce8805..35fc5421 100644 --- a/pysite/views/wiki/move.py +++ b/pysite/views/wiki/move.py @@ -1,16 +1,15 @@  import datetime -import requests  from flask import redirect, request, url_for  from werkzeug.exceptions import BadRequest, NotFound  from pysite.base_route import RouteView -from pysite.constants import EDITOR_ROLES, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, EDITOR_ROLES  from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin -class MoveView(RouteView, DBMixin): +class MoveView(RouteView, DBMixin, RMQMixin):      path = "/move/<path:page>"  # "path" means that it accepts slashes      name = "move"      table_name = "wiki" @@ -72,22 +71,14 @@ class MoveView(RouteView, DBMixin):          return redirect(url_for("wiki.page", page=location), code=303)  # Redirect, ensuring a GET      def audit_log(self, obj): -        if WIKI_AUDIT_WEBHOOK:  # If the audit webhook is not configured there is no point processing it -            audit_payload = { -                "username": "Wiki Updates", -                "embeds": [ -                    { -                        "title": "Page Move", -                        "description": f"**{obj['title']}** was moved by " -                                       f"**{self.user_data.get('username')}** to " -                                       f"**{obj['slug']}**", -                        "color": 4165079, -                        "timestamp": datetime.datetime.utcnow().isoformat(), -                        "thumbnail": { -                            "url": "https://pythondiscord.com/static/logos/logo_discord.png" -                        } -                    } -                ] +        self.rmq_bot_event( +            BotEventTypes.send_embed, +            { +                "target": CHANNEL_MOD_LOG, +                "title": "Wiki Page Move", +                "description": f"**{obj['title']}** was moved by **{self.user_data.get('username')}** to " +                               f"**{obj['slug']}**", +                "color": 0x3F8DD7,  # Light blue +                "timestamp": datetime.datetime.now().isoformat()              } - -            requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) +        ) | 
