Initial commit

This commit is contained in:
Sander Ferdinand 2018-06-26 23:48:25 +02:00
commit edb3d8f57b
55 changed files with 15544 additions and 0 deletions

View file

210
wowfunding/bin/anti_xss.py Normal file
View file

@ -0,0 +1,210 @@
# -*- coding: utf-8 -*-
"""
Python 富文本XSS过滤类
@package XssHtml
@version 0.1
@link http://phith0n.github.io/python-xss-filter
@since 20150407
@copyright (c) Phithon All Rights Reserved
Based on native Python module HTMLParser purifier of HTML, To Clear all javascript in html
You can use it in all python web framework
Written by Phithon <root@leavesongs.com> in 2015 and placed in the public domain.
phithon <root@leavesongs.com> 编写于20150407
From: XDSEC <www.xdsec.org> & 离别歌 <www.leavesongs.com>
GitHub Pages: https://github.com/phith0n/python-xss-filter
Usage:
parser = XssHtml()
parser.feed('<html code>')
parser.close()
html = parser.getHtml()
print html
Requirements
Python 2.6+ or 3.2+
Cannot defense xss in browser which is belowed IE7
浏览器版本IE7+ 或其他浏览器无法防御IE6及以下版本浏览器中的XSS
"""
import re
try:
from html.parser import HTMLParser
except:
from HTMLParser import HTMLParser
class XssHtml(HTMLParser):
allow_tags = ['a', 'img', 'br', 'strong', 'b', 'code', 'pre',
'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4',
'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td',
'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody',
'caption', 'small', 'q', 'sup', 'sub']
common_attrs = ["style", "class", "name"]
nonend_tags = ["img", "hr", "br", "embed"]
tags_own_attrs = {
"img": ["src", "width", "height", "alt", "align"],
"a": ["href", "target", "rel", "title"],
"embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"],
"table": ["border", "cellpadding", "cellspacing"],
}
_regex_url = re.compile(r'^(http|https|ftp)://.*', re.I | re.S)
_regex_style_1 = re.compile(r'(\\|&#|/\*|\*/)', re.I)
_regex_style_2 = re.compile(r'e.*x.*p.*r.*e.*s.*s.*i.*o.*n', re.I | re.S)
def __init__(self, allows=[]):
HTMLParser.__init__(self)
self.allow_tags = allows if allows else self.allow_tags
self.result = []
self.start = []
self.data = []
def getHtml(self):
"""
Get the safe html code
"""
for i in range(0, len(self.result)):
self.data.append(self.result[i])
return ''.join(self.data)
def handle_startendtag(self, tag, attrs):
self.handle_starttag(tag, attrs)
def handle_starttag(self, tag, attrs):
if tag not in self.allow_tags:
return
end_diagonal = ' /' if tag in self.nonend_tags else ''
if not end_diagonal:
self.start.append(tag)
attdict = {}
for attr in attrs:
attdict[attr[0]] = attr[1]
attdict = self._wash_attr(attdict, tag)
if hasattr(self, "node_%s" % tag):
attdict = getattr(self, "node_%s" % tag)(attdict)
else:
attdict = self.node_default(attdict)
attrs = []
for (key, value) in attdict.items():
attrs.append('%s="%s"' % (key, self._htmlspecialchars(value)))
attrs = (' ' + ' '.join(attrs)) if attrs else ''
self.result.append('<' + tag + attrs + end_diagonal + '>')
def handle_endtag(self, tag):
if self.start and tag == self.start[len(self.start) - 1]:
self.result.append('</' + tag + '>')
self.start.pop()
def handle_data(self, data):
self.result.append(self._htmlspecialchars(data))
def handle_entityref(self, name):
if name.isalpha():
self.result.append("&%s;" % name)
def handle_charref(self, name):
if name.isdigit():
self.result.append("&#%s;" % name)
def node_default(self, attrs):
attrs = self._common_attr(attrs)
return attrs
def node_a(self, attrs):
attrs = self._common_attr(attrs)
attrs = self._get_link(attrs, "href")
attrs = self._set_attr_default(attrs, "target", "_blank")
attrs = self._limit_attr(attrs, {
"target": ["_blank", "_self"]
})
return attrs
def node_embed(self, attrs):
attrs = self._common_attr(attrs)
attrs = self._get_link(attrs, "src")
attrs = self._limit_attr(attrs, {
"type": ["application/x-shockwave-flash"],
"wmode": ["transparent", "window", "opaque"],
"play": ["true", "false"],
"loop": ["true", "false"],
"menu": ["true", "false"],
"allowfullscreen": ["true", "false"]
})
attrs["allowscriptaccess"] = "never"
attrs["allownetworking"] = "none"
return attrs
def _true_url(self, url):
if self._regex_url.match(url):
return url
else:
return "http://%s" % url
def _true_style(self, style):
if style:
style = self._regex_style_1.sub('_', style)
style = self._regex_style_2.sub('_', style)
return style
def _get_style(self, attrs):
if "style" in attrs:
attrs["style"] = self._true_style(attrs.get("style"))
return attrs
def _get_link(self, attrs, name):
if name in attrs:
attrs[name] = self._true_url(attrs[name])
return attrs
def _wash_attr(self, attrs, tag):
if tag in self.tags_own_attrs:
other = self.tags_own_attrs.get(tag)
else:
other = []
_attrs = {}
if attrs:
for (key, value) in attrs.items():
if key in self.common_attrs + other:
_attrs[key] = value
return _attrs
def _common_attr(self, attrs):
attrs = self._get_style(attrs)
return attrs
def _set_attr_default(self, attrs, name, default=''):
if name not in attrs:
attrs[name] = default
return attrs
def _limit_attr(self, attrs, limit={}):
for (key, value) in limit.items():
if key in attrs and attrs[key] not in value:
del attrs[key]
return attrs
def _htmlspecialchars(self, html):
return html.replace("<", "&lt;")\
.replace(">", "&gt;")\
.replace('"', "&quot;")\
.replace("'", "&#039;")
def such_xss(inp):
"""Very ghetto anti-xss countermeasures. Possibly unsafe! :D
Needs testing, or a proper solution. wow."""
parser = XssHtml()
parser.feed(inp)
parser.close()
result = parser.getHtml()
# oh noes teh markdown blockquotes
lines = result.split('\n')
_lines = []
for line in lines:
if line.startswith('&gt;'):
line = line[4:]
line = '>%s' % line
_lines.append(line)
return "\n".join(_lines)

52
wowfunding/bin/daemon.py Normal file
View file

@ -0,0 +1,52 @@
import settings
import requests
class WowneroDaemon:
def __init__(self):
self.url = settings.RPC_LOCATION
self.headers = {"User-Agent": "Mozilla"}
def create_address(self, label_name):
data = {
'method': 'create_address',
'params': {'account_index': 0, 'label': label_name},
'jsonrpc': '2.0',
'id': '0'
}
return self._make_request(data)
def get_address(self, index):
data = {
'method': 'get_address',
'params': {'address_index': [index], 'account_index': 0},
'jsonrpc': '2.0',
'id': '0'
}
try:
result = self._make_request(data)
return next(z for z in result['result']['addresses'] if z['address_index'] == index)
except:
return
def get_transfers_in(self, index):
data = {
"method":"get_transfers",
"params": {"in": True, "account_index": 0, "subaddr_indices": [index]},
"jsonrpc": "2.0",
"id": "0",
}
data = self._make_request(data)
data = data['result'].get('in', [])
for d in data:
d['amount_human'] = float(d['amount'])/1e11
return {
'sum': sum([float(z['amount'])/1e11 for z in data]),
'txs': data
}
def _make_request(self, data):
r = requests.post(self.url, json=data, headers=self.headers)
r.raise_for_status()
return r.json()

8
wowfunding/bin/utils.py Normal file
View file

@ -0,0 +1,8 @@
from flask.json import JSONEncoder
from datetime import datetime, date
def json_encoder(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
raise TypeError ("Type %s not serializable" % type(obj))

View file

@ -0,0 +1,67 @@
from datetime import datetime
from flask import session, g
import settings
from wowfunding.factory import app, db_session, summary_data
from wowfunding.orm.orm import Proposal, User
@app.context_processor
def template_vars():
global summary_data
return dict(summary_data=summary_data[1])
def fetch_summary():
global summary_data
if summary_data:
if (datetime.now() - summary_data[0]).total_seconds() <= 120:
return
data = {}
categories = settings.FUNDING_CATEGORIES
statuses = [0, 1, 2]
for cat in categories:
q = db_session.query(Proposal)
q = q.filter(Proposal.category == cat)
res = q.count()
data.setdefault('cats', {})
data['cats'][cat] = res
for status in statuses:
q = db_session.query(Proposal)
q = q.filter(Proposal.status == status)
res = q.count()
data.setdefault('statuses', {})
data['statuses'][status] = res
data.setdefault('users', {})
data['users']['count'] = db_session.query(User.id).count()
summary_data = [datetime.now(), data]
@app.before_request
def before_request():
fetch_summary()
@app.after_request
def after_request(res):
res.headers.add('Accept-Ranges', 'bytes')
if settings.DEBUG:
res.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
res.headers['Pragma'] = 'no-cache'
res.headers['Expires'] = '0'
res.headers['Cache-Control'] = 'public, max-age=0'
return res
@app.teardown_appcontext
def shutdown_session(**kwargs):
db_session.remove()
@app.errorhandler(404)
def error(err):
return 'Error', 404