Skip to content
This repository was archived by the owner on Dec 28, 2025. It is now read-only.

Commit cf0bbc2

Browse files
authored
feat: update to v1.3.0 (#182)
Update master to v1.3.0
2 parents 26c9e42 + 7e1efc5 commit cf0bbc2

34 files changed

+959
-86
lines changed

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ about: Suggest an idea for this project
44

55
---
66

7-
**Is your feature request related to a problem? Please describe.**
7+
**User Story / Use Case**
8+
Is your feature request related to a problem? Please describe.
89
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
910

10-
**Describe the solution you'd like**
11+
**Possible solution**
1112
A clear and concise description of what you want to happen.
1213

13-
**Describe alternatives you've considered**
14+
**Alternative solution**
1415
A clear and concise description of any alternative solutions or features you've considered.
1516

1617
**Additional context**

.github/ISSUE_TEMPLATE/question.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: Question
3+
about: Ask questions about this project or about how to use it
4+
5+
---
6+
7+
> Please provide a clear description of your question and include all (technical) details, in case they are relevant for the question.
8+
> Please remove this line before creating the issue!
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Changelog Reminder
2+
3+
on: pull_request
4+
5+
jobs:
6+
remind:
7+
name: Changelog Reminder
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@master
12+
- name: Changelog Reminder
13+
uses: peterjgrainger/[email protected]
14+
with:
15+
changelog_regex: '/CHANGELOG.md'
16+
customPrMessage: "We couldn't find any modification to the CHANGELOG.md file. If your changes are not suitable for the changelog, that's fine. Otherwise please add them to the changelog!"
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/stylecheck.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Stylecheck
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- name: wemake-python-styleguide
12+
uses: wemake-services/[email protected]

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.3.0] - 2020-03-03
11+
### Added
12+
- Implemented base64analyzer, which matches if a found base64 string decodes to valid ascii ([b535781](https://github.com/d-Rickyy-b/pastepwn/commit/b535781d7e1760c7f846432d7ef87b97784e2d49))
13+
- Implemented IrcAction - the previous implementation was not working ([546b87f](https://github.com/d-Rickyy-b/pastepwn/commit/546b87f508420da0a9ea6f54f1df65684b73648f))
14+
### Changed
15+
- SaveFileAction now got a parameter to set the file ending and a template ([c3d75f7](https://github.com/d-Rickyy-b/pastepwn/commit/c3d75f72036fa1284eebc8f3c1967a4374428dca))
16+
### Fixed
17+
- Analyzers now check if a passed action is a subclass of BasicAction, which prevents issues such as [#175](https://github.com/d-Rickyy-b/pastepwn/issues/175)
18+
- The DiscordAction now also uses the templating engine - it was forgotten in a previous update ([#176](https://github.com/d-Rickyy-b/pastepwn/issues/176))
19+
- The SyslogAction now also uses the templating engine - it was forgotten in a previous update ([54d3652](https://github.com/d-Rickyy-b/pastepwn/commit/54d3652e4de3fdbaedfdd522f8750aa241890c3c))
20+
- The SaveFileAction does now store each paste in a different file as it should be ([#179](https://github.com/d-Rickyy-b/pastepwn/issues/179))
21+
- The IrcAction did not send the correct data. This was fixed and eventually the action was rewritten from scratch (see "Added")
22+
1023
## [1.2.0] - 2020-02-05
1124
### Added
1225
- Analyzers can now return a boolean or **a list of matched results**
@@ -145,7 +158,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
145158
## [1.0.8] - 2018-10-22
146159
First stable release
147160

148-
[unreleased]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.2.0...HEAD
161+
[unreleased]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.3.0...HEAD
162+
[1.3.0]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.2.0...v1.3.0
149163
[1.2.0]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.1.0...v1.2.0
150164
[1.1.0]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.0.16...v1.1.0
151165
[1.0.16]: https://github.com/d-Rickyy-b/pastepwn/compare/v1.0.15...v1.0.16

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
To use the pastepwn framework you need to follow these simple steps:
1919

2020
1) **Make sure** to have a [Pastebin premium](https://pastebin.com/pro) account!
21-
2) Install pastepwn via pip (`pip install pastepwn`
21+
2) Install pastepwn via pip (`pip3 install pastepwn`
2222
3) Create a file (e.g. `main.py`) in your project root, where you put your code in²
2323
4) Fill that file with content - add analyzers and actions. Check the [example](https://github.com/d-Rickyy-b/pastepwn/tree/master/examples/example.py) implementation.
2424

25-
¹ Note that pastepwn only works with python3.5 or higher (so better use pip3)
25+
¹ Note that pastepwn **only works with python3.5 or above** (so better use pip3)
2626
² *(If you want to store all pastes, make sure to setup a `mongodb`, `mysql` or `sqlite` instance)*
2727

2828
### Behind a proxy
@@ -32,11 +32,12 @@ There are 2 ways to use this tool behind a proxy:
3232
- Define the following environment variables: `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`.
3333
- When initializing the PastePwn object, use the `proxies` argument. `proxies` is a dict as defined in [requests' documentation](http://docs.python-requests.org/en/master/user/advanced/#proxies).
3434

35-
### ToDos
36-
There are quite some features which will be implemented in the (near) future.
35+
### Troubleshooting
36+
If you are having troubles, check out the [wiki pages](https://github.com/d-Rickyy-b/pastepwn/wiki) first.
37+
If your question/issue is not resolved there, feel free to [create an issue](https://github.com/d-Rickyy-b/pastepwn/issues/new/choose) or [contact me on Telegram](https://t.me/d_Rickyy_b).
38+
39+
### Roadmap and ToDos
3740
Check the [bug tracker](https://github.com/d-Rickyy-b/pastepwn/issues) on GitHub to get an up-to-date status about features and ToDos.
3841

39-
- REST API for querying paste data
40-
- Adding more analyzers and actions, based on community input
41-
- Adding support for other paste sites
42+
- REST API for querying paste data (will be another project)
4243
- Add a helpful wiki with instructions and examples

pastepwn/actions/discordaction.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,40 @@
33
import json
44
import logging
55
import sys
6-
from string import Template
76

8-
from pastepwn.util import Request, DictWrapper
7+
from pastepwn.util import Request
8+
from pastepwn.util import TemplatingEngine
99
from .basicaction import BasicAction
1010

1111

1212
class DiscordAction(BasicAction):
1313
"""Action to send a Discord message to a certain webhook or channel."""
1414
name = "DiscordAction"
1515

16-
def __init__(self, webhook=None, token=None, channel_id=None, template=None):
16+
def __init__(self, webhook_url=None, token=None, channel_id=None, template=None):
17+
"""
18+
Action to send a Discord message to a certain webhook or channel.
19+
Either the webhook parameter or the token & channel_id parameters are needed.
20+
21+
1) You can setup a webhook in the discord server settings. A webhook is tied to one server & text channel
22+
> https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks
23+
24+
25+
2) Setup a discord bot (token) in the developer portal:
26+
> https://discordapp.com/developers/applications/
27+
After creating an app you can obtain the token by going to
28+
> https://discordapp.com/developers/applications/{your_app_id}/bot
29+
Format:
30+
> NTI5MzI1MzY4OTAyMDI1MjI3.DwvNFQ.5aNKUvYlAKqKKq6UJ1fRiARKNXQ
31+
32+
3) Obtain the channel_id (18 digit number):
33+
> User Settings > Appearance > Enable Developer Mode and after that right click on any text channel to copy the ID
34+
35+
:param webhook_url: The url obtained from the server settings
36+
:param token: A bot token obtained from the developer portal
37+
:param channel_id: The channel ID of a text channel you want to send messages into
38+
:param template: A template string describing how the paste variables should be filled in
39+
"""
1740
super().__init__()
1841
self.logger = logging.getLogger(__name__)
1942
self.bot_available = True
@@ -24,10 +47,11 @@ def __init__(self, webhook=None, token=None, channel_id=None, template=None):
2447
self.logger.warning("Could not import 'websockets' module. So you can only use webhooks for discord.")
2548
self.bot_available = False
2649

27-
self.webhook = webhook
28-
if webhook is None:
50+
self.webhook_url = webhook_url
51+
if webhook_url is None:
52+
# When there is no webhook_url, we need both token and channel_id
2953
if token is None or channel_id is None:
30-
raise ValueError('Invalid arguments: requires either webhook or token+channel_id arguments')
54+
raise ValueError('Invalid arguments: requires either webhook_url or token+channel_id arguments')
3155

3256
if not self.bot_available:
3357
raise NotImplementedError("You can't use bot functionality without the 'websockets' module. Please import it or use webhooks!")
@@ -36,10 +60,7 @@ def __init__(self, webhook=None, token=None, channel_id=None, template=None):
3660
self.channel_id = channel_id
3761
self.identified = False
3862

39-
if template is not None:
40-
self.template = Template(template)
41-
else:
42-
self.template = None
63+
self.template = template
4364

4465
@asyncio.coroutine
4566
def _identify(self, ws_url):
@@ -83,10 +104,11 @@ def _identify(self, ws_url):
83104

84105
def initialize_gateway(self):
85106
"""Initialize the bot token so Discord identifies it properly."""
86-
if self.webhook is not None:
107+
if self.webhook_url is not None:
87108
raise NotImplementedError('Gateway initialization is only necessary for bot accounts.')
88109

89110
# Call Get Gateway Bot to get the websocket URL
111+
# https://discordapp.com/developers/docs/reference#authentication
90112
r = Request()
91113
r.headers = {'Authorization': 'Bot {}'.format(self.token)}
92114
res = json.loads(r.get('https://discordapp.com/api/gateway/bot'))
@@ -101,16 +123,11 @@ def initialize_gateway(self):
101123
def perform(self, paste, analyzer_name=None, matches=None):
102124
"""Send a message via Discord to a specified channel, without checking for errors"""
103125
r = Request()
104-
if self.template is None:
105-
text = "New paste matched by analyzer '{0}' - Link: {1}".format(analyzer_name, paste.full_url)
106-
else:
107-
paste_dict = paste.to_dict()
108-
paste_dict["analyzer_name"] = analyzer_name
109-
text = self.template.safe_substitute(DictWrapper(paste_dict))
126+
text = TemplatingEngine.fill_template(paste, analyzer_name, template_string=self.template, matches=matches)
110127

111-
if self.webhook is not None:
128+
if self.webhook_url is not None:
112129
# Send to a webhook (no authentication)
113-
url = self.webhook
130+
url = self.webhook_url
114131
else:
115132
# Send through Discord bot API (header-based authentication)
116133
url = 'https://discordapp.com/api/channels/{0}/messages'.format(self.channel_id)
@@ -123,7 +140,7 @@ def perform(self, paste, analyzer_name=None, matches=None):
123140

124141
res = json.loads(res)
125142

126-
if res.get('code') == 40001 and self.bot_available and self.webhook is None and not self.identified:
143+
if res.get('code') == 40001 and self.bot_available and self.webhook_url is None and not self.identified:
127144
# Unauthorized access, bot token hasn't been identified to Discord Gateway
128145
self.logger.info('Accessing Discord Gateway to initialize token')
129146
self.initialize_gateway()

0 commit comments

Comments
 (0)