# The Builder object and the passphrase are returned.
return builder, passphrase
- def auth(self, name, passphrase):
- # If either name or passphrase is None, we don't check at all.
- if None in (name, passphrase):
- return
-
- # Search for the hostname in the database.
- builder = self._get_builder("SELECT * FROM builders \
- WHERE name = %s AND deleted IS FALSE", name)
-
- # If the builder was not found or the passphrase does not match,
- # you have bad luck.
- if not builder or not builder.validate_passphrase(passphrase):
- return
-
- # Otherwise we return the Builder object.
- return builder
-
def get_by_id(self, builder_id):
return self._get_builder("SELECT * FROM builders WHERE id = %s", builder_id)
#!/usr/bin/python
-import base64
import json
import logging
import tornado.web
from .. import builders
from .. import users
+from ..web.auth import KerberosAuthMixin
+
log = logging.getLogger("pakfire.hub")
-class BackendMixin(object):
+class AuthMixin(KerberosAuthMixin):
+ """
+ Requires a builder or user to authenticate
+ """
+ def get_current_user(self):
+ # Fetch the Kerberos ticket
+ principal = self.get_authenticated_user()
+
+ # Return nothing if we did not receive any credentials
+ if not principal:
+ return
+
+ log.debug("Searching for principal %s..." % principal)
+
+ # Strip the realm
+ principal, delimiter, realm = principal.partition("@")
+
+ # Return any builders
+ if principal.startswith("host/"):
+ hostname = principal.removeprefix("host/")
+
+ return self.backend.builders.get_by_name(hostname)
+
+ # Return users
+ return self.backend.users.get_by_name(principal)
+
+
+class BackendMixin(AuthMixin):
@property
def backend(self):
"""
return self.backend.db
-class HTTPBasicAuthMixin(object):
- def get_basic_auth_credentials(self):
- """
- This handles HTTP Basic authentication.
- """
- auth_header = self.request.headers.get("Authorization", None)
-
- # If no authentication information was provided, we stop here.
- if not auth_header:
- return None, None
-
- # No basic auth? We cannot handle that.
- if not auth_header.startswith("Basic "):
- raise tornado.web.HTTPError(400, "Can only handle Basic auth.")
-
- try:
- # Convert into bytes()
- auth_header = auth_header[6:].encode()
-
- # Decode base64
- auth_header = base64.b64decode(auth_header).decode()
-
- name, password = auth_header.split(":", 1)
- except:
- raise tornado.web.HTTPError(400, "Authorization data was malformed")
-
- return name, password
-
-
-class BaseHandler(BackendMixin, HTTPBasicAuthMixin, tornado.web.RequestHandler):
- def get_current_user(self):
- name, password = self.get_basic_auth_credentials()
- if name is None:
- return
-
- builder = self.backend.builders.auth(name, password)
- if builder:
- return builder
-
- user = self.backend.users.auth(name, password)
- if user:
- return user
-
+class BaseHandler(BackendMixin, tornado.web.RequestHandler):
@property
def builder(self):
if isinstance(self.current_user, builders.Builder):
return self.backend.uploads.get_by_uuid(uuid)
+# Hello World
+
+class TestHandler(BaseHandler):
+ """
+ This handler is for checking whether authentication works, etc...
+ """
+ @tornado.web.authenticated
+ def get(self):
+ self.write("Hello, %s!\n" % self.current_user)
+
# Builds
class BuildsGetHandler(BaseHandler):
import logging
import tornado.websocket
-from .handlers import BackendMixin, HTTPBasicAuthMixin
+from .handlers import BackendMixin
log = logging.getLogger("pakfire.hub.queue")
# If there is no job for the builder, we might as well shut it down
await builder.stop()
-class QueueHandler(BackendMixin, HTTPBasicAuthMixin, tornado.websocket.WebSocketHandler):
+class QueueHandler(BackendMixin, tornado.websocket.WebSocketHandler):
"""
Builders connect to this handler which will add them to a list of connections.
-
+
For all connections, we regularly check if we have any new build jobs, and if so,
we will send them the job.
"""