]> git.ipfire.org Git - ipfire.org.git/blob - src/web/nopaste.py
Deploy rate-limiting
[ipfire.org.git] / src / web / nopaste.py
1 #!/usr/bin/python
2
3 import tornado.web
4
5 from . import auth
6 from . import base
7 from . import ui_modules
8
9 class CreateHandler(auth.CacheMixin, base.BaseHandler):
10 MODES = ("paste", "upload")
11
12 @base.blacklisted
13 def get(self):
14 mode = self.get_argument("mode", "paste")
15 if not mode in self.MODES:
16 raise tornado.web.HTTPError(400)
17
18 self.render("nopaste/create.html", mode=mode,
19 max_size=self._max_size)
20
21 @base.blacklisted
22 @base.ratelimit(minutes=15, requests=5)
23 def post(self):
24 mode = self.get_argument("mode")
25 if not mode in self.MODES:
26 raise tornado.web.HTTPError(400)
27
28 mimetype = "text/plain"
29
30 if mode == "paste":
31 subject = self.get_argument("subject", None)
32 content = self.get_argument("content", "").encode("utf-8")
33
34 elif mode == "upload":
35 for f in self.request.files.get("file"):
36 subject = f.filename
37 content = f.body
38 mimetype = f.content_type
39 break
40
41 # Check maximum size
42 if len(content) > self._max_size:
43 raise tornado.web.HTTPError(400,
44 "You cannot upload more than %s bytes" % self._max_size)
45
46 expires = self.get_argument("expires", "0")
47 try:
48 expires = int(expires)
49 except (TypeError, ValueError):
50 expires = None
51
52 uid = self.backend.nopaste.create(subject, content, mimetype=mimetype,
53 expires=expires, account=self.current_user, address=self.get_remote_ip())
54
55 if uid:
56 return self.redirect("/view/%s" % uid)
57
58 raise tornado.web.HTTPError(500)
59
60 @property
61 def _max_size(self):
62 # Authenticated users are allowed to upload up to 25MB
63 if self.current_user:
64 return 25 * (1024 ** 2)
65
66 # The rest is only allowed to upload up to 2MB
67 return 2 * (1024 ** 2)
68
69
70 class RawHandler(base.BaseHandler):
71 @base.blacklisted
72 def get(self, uid):
73 entry = self.backend.nopaste.get(uid)
74 if not entry:
75 raise tornado.web.HTTPError(404)
76
77 # Set the filename
78 self.set_header("Content-Disposition", "inline; filename=\"%s\"" % entry.subject)
79
80 # Set mimetype
81 self.set_header("Content-Type", entry.mimetype)
82
83 # Set expiry headers
84 self.set_expires(3600)
85
86 # Send content
87 content = self.backend.nopaste.get_content(entry.uuid)
88 self.finish(content)
89
90
91 class ViewHandler(auth.CacheMixin, base.BaseHandler):
92 @base.blacklisted
93 def get(self, uid):
94 entry = self.backend.nopaste.get(uid)
95 if not entry:
96 raise tornado.web.HTTPError(404)
97
98 # Fetch the content if the output should be displayed
99 if entry.mimetype.startswith("text/"):
100 content = self.backend.nopaste.get_content(entry.uuid)
101 else:
102 content = None
103
104 # Set expiry headers
105 self.set_expires(3600)
106
107 self.render("nopaste/view.html", entry=entry, content=content)
108
109
110 class CodeModule(ui_modules.UIModule):
111 def render(self, content):
112 return self.render_string("nopaste/modules/code.html", content=content)
113
114 def javascript_files(self):
115 return "js/prettify.js"
116
117 def css_files(self):
118 return "css/prettify.css"
119
120 def embedded_javascript(self):
121 return """
122 // Run pretty print
123 prettyPrint();
124 """