#!/usr/bin/python
import asyncio
+import base64
import datetime
import dateutil.parser
import functools
def referrer(self):
return self.request.headers.get("Referer", None)
+ def _request_basic_authentication(self):
+ """
+ Called to ask the client to perform HTTP Basic authentication
+ """
+ # Ask for authentication
+ self.set_status(401)
+
+ # Say that we support Basic
+ self.set_header("WWW-Authenticate", "Basic realm=Restricted")
+
+ self.finish()
+
+ def perform_basic_authentication(self):
+ """
+ This handles HTTP Basic authentication.
+ """
+ # Fetch credentials
+ cred = self.request.headers.get("Authorization", None)
+ if not cred:
+ return self._request_basic_authentication()
+
+ # No basic auth? We cannot handle that
+ if not cred.startswith("Basic "):
+ return self._request_basic_authentication()
+
+ # Decode the credentials
+ try:
+ # Convert into bytes()
+ cred = cred[6:].encode()
+
+ # Decode base64
+ cred = base64.b64decode(cred).decode()
+
+ username, password = cred.split(":", 1)
+
+ # Fail if any of those steps failed
+ except:
+ raise e
+ raise tornado.web.HTTPError(400, "Authorization data was malformed")
+
+ # Find the user in the database
+ return self.backend.accounts.auth(username, password)
+
+ # Log something
+ if account:
+ log.info("%s authenticated successfully using HTTP Basic authentication" % account.uid)
+ else:
+ log.warning("Could not authenticate %s" % username)
+
+ return account
+
def get_argument_int(self, *args, **kwargs):
arg = self.get_argument(*args, **kwargs)
# cURL Interface
+ def get_current_user(self):
+ if self.request.method == "PUT":
+ return self.perform_basic_authentication()
+
+ # Perform the usual authentication
+ return super().get_current_user()
+
def check_xsrf_cookie(self):
# Skip the check on PUT
if self.request.method == "PUT":
# Perform the check as usual
super().check_xsrf_cookie()
- # XXX implement HTTP Basic authentication
-
+ @tornado.web.authenticated
@base.ratelimit(minutes=15, requests=5)
def put(self):
with self.db.transaction():
paste = self.backend.nopaste.create(
- self.request.body, address=self.get_remote_ip())
+ self.request.body, account=account, address=self.get_remote_ip())
# Send a message to the client
self.write("https://%s/view/%s\n" % (self.request.host, paste.uuid))