From: Michael Tremer Date: Wed, 22 Jan 2025 17:17:06 +0000 (+0000) Subject: web: Go back to statically set current_user X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44aa5d2d65815009420d9ee1dc6e23f94893fcf3;p=pbs.git web: Go back to statically set current_user This changes it so that we will always try to log in the user. That way, we don't have to always call the get_current_user() function which makes the code rather messy. Signed-off-by: Michael Tremer --- diff --git a/src/web/auth.py b/src/web/auth.py index 19dd17cb..1d4c5fea 100644 --- a/src/web/auth.py +++ b/src/web/auth.py @@ -10,8 +10,7 @@ log = logging.getLogger("pbs.web.auth") class LoginHandler(base.KerberosAuthMixin, base.BaseHandler): async def get(self, username=None, failed=False): - current_user = await self.get_current_user() - if current_user: + if self.current_user: raise tornado.web.HTTPError(403, "Already logged in") await self.render("login.html", username=username, failed=failed) diff --git a/src/web/base.py b/src/web/base.py index 8d70eb53..038e0982 100644 --- a/src/web/base.py +++ b/src/web/base.py @@ -206,10 +206,6 @@ class BaseHandler(tornado.web.RequestHandler): if session: return session.user - @property - def current_user(self): - raise NotImplementedError("We don't use this any more") - async def get_user_locale(self): # Get the locale from the user settings current_user = await self.get_current_user() @@ -298,9 +294,6 @@ class BaseHandler(tornado.web.RequestHandler): return JinjaTemplateLoader(env) async def get_template_namespace(self): - # Fetch the current user - current_user = await self.get_current_user() - # Fetch the locale locale = await self.get_user_locale() @@ -309,7 +302,7 @@ class BaseHandler(tornado.web.RequestHandler): ns = { "handler" : self, - "current_user" : current_user, + "current_user" : self.current_user, "hostname" : self.request.host, "now" : datetime.datetime.now(), @@ -393,6 +386,9 @@ class BaseHandler(tornado.web.RequestHandler): if not self.request.method in ("GET", "HEAD", "OPTIONS"): self.check_xsrf_cookie() + # Automatically log the user + self.current_user = await self.get_current_user() + # Prepare the request result = self.prepare() if result: @@ -499,9 +495,6 @@ class BaseHandler(tornado.web.RequestHandler): self.finish() async def write_error(self, code, exc_info=None, **kwargs): - # Fetch the current user - current_user = await self.get_current_user() - # Translate the HTTP status code try: message = http.client.responses[code] @@ -512,8 +505,8 @@ class BaseHandler(tornado.web.RequestHandler): # Collect more information about the exception if possible. if exc_info: - if current_user and isinstance(current_user, users.User): - if current_user.is_admin(): + if self.current_user and isinstance(self.current_user, users.User): + if self.current_user.is_admin(): tb += traceback.format_exception(*exc_info) await self.render("errors/error.html", @@ -543,8 +536,7 @@ class BaseHandler(tornado.web.RequestHandler): ) if version is None: - current_user = await self.get_current_user() - if current_user and "expires_days" not in cookie_kwargs: + if self.current_user and "expires_days" not in cookie_kwargs: cookie_kwargs["expires_days"] = 30 cookie_name = self.settings.get("xsrf_cookie_name", "_xsrf") self.set_cookie(cookie_name, self._xsrf_token, **cookie_kwargs) @@ -609,15 +601,12 @@ class BaseHandler(tornado.web.RequestHandler): # Uploads async def _get_upload(self, uuid): - # Fetch the current user - current_user = await self.get_current_user() - # Fetch the upload upload = await self.backend.uploads.get_by_uuid(uuid) # Check permissions - if upload and not upload.has_perm(current_user): - raise tornado.web.HTTPError(403, "%s has no permissions for upload %s" % (current_user, upload)) + if upload and not upload.has_perm(self.current_user): + raise tornado.web.HTTPError(403, "%s has no permissions for upload %s" % (self.current_user, upload)) return upload @@ -768,42 +757,8 @@ class JinjaTemplateLoader(tornado.template.BaseLoader): return self.env.get_template(name=name) -def authenticated(method): - """ - This is our custom authentication wrapper which supports an - asynchronous implementation of "get_current_user()". - """ - @functools.wraps(method) - async def wrapper(self, *args, **kwargs): - current_user = await self.get_current_user() - - if not current_user: - if self.request.method in ("GET", "HEAD"): - url = self.get_login_url() - if "?" not in url: - if urllib.parse.urlsplit(url).scheme: - # if login url is absolute, make next absolute too - next_url = self.request.full_url() - else: - assert self.request.uri is not None - next_url = self.request.uri - url += "?" + urllib.parse.urlencode(dict(next=next_url)) - self.redirect(url) - return None - - # Authentication has failed - raise tornado.web.HTTPError(403) - - # Call the wrapped method - result = method(self, *args, **kwargs) - - # Support coroutines - if asyncio.iscoroutine(result): - result = await result - - return result - - return wrapper +# An alias for Tornado's authentication decorator +authenticated = tornado.web.authenticated def negotiate(method): """ @@ -811,9 +766,7 @@ def negotiate(method): """ @functools.wraps(method) async def wrapper(self, *args, **kwargs): - current_user = await self.get_current_user() - - if not current_user: + if not self.current_user: # Send the Negotiate header self.add_header("WWW-Authenticate", "Negotiate") @@ -869,9 +822,6 @@ class AdminHandler(BaseHandler): """ @authenticated async def prepare(self): - # Fetch the current user - current_user = await self.get_current_user() - # Fail if we don't have admin right - if not current_user.is_admin(): + if not self.current_user.is_admin(): raise tornado.web.HTTPError(403, "admin rights required") diff --git a/src/web/builders.py b/src/web/builders.py index efda1958..f7f66d7b 100644 --- a/src/web/builders.py +++ b/src/web/builders.py @@ -108,7 +108,7 @@ class CreateHandler(base.AdminHandler): async with await self.db.transaction(): builder = await self.backend.builders.create( name = self.get_argument("name"), - created_by = await self.get_current_user(), + created_by = self.current_user, ) self.redirect("/builders/%s/edit" % builder.name) @@ -121,11 +121,8 @@ class EditHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found") - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) await self.render("builders/edit.html", builder=builder) @@ -136,11 +133,8 @@ class EditHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) async with await self.db.transaction(): @@ -161,11 +155,8 @@ class DeleteHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) await self.render("builders/delete.html", builder=builder) @@ -176,16 +167,13 @@ class DeleteHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % hostname) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Delete the builder async with await self.db.transaction(): - await builder.delete(deleted_by=current_user) + await builder.delete(deleted_by=self.current_user) self.redirect("/builders") @@ -197,11 +185,8 @@ class StartHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Builders must be in maintenance mode @@ -216,11 +201,8 @@ class StartHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Builders must be in maintenance mode @@ -245,11 +227,8 @@ class StopHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Builders must be in maintenance mode @@ -264,11 +243,8 @@ class StopHandler(base.BaseHandler): if not builder: raise tornado.web.HTTPError(404, "Builder not found: %s" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Check permissions - if not builder.has_perm(current_user): + if not builder.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Builders must be in maintenance mode diff --git a/src/web/builds.py b/src/web/builds.py index 8cd0db13..e9ce5e97 100644 --- a/src/web/builds.py +++ b/src/web/builds.py @@ -14,16 +14,13 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): @base.negotiate async def post(self): - # Fetch the current user - current_user = await self.get_current_user() - # Fetch the upload upload = await self.get_argument_upload("upload") if not upload: raise tornado.web.HTTPError(404, "Could not find upload") # Check permissions of the upload - if not upload.has_perm(current_user): + if not upload.has_perm(self.current_user): raise base.APIError(errno.ENOPERM, "No permission for using upload %s" % upload) # Fetch the repository @@ -44,7 +41,7 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): try: # Find the repository - repo = self.current_user.get_repo(package.distro, repo_name) + repo = await self.current_user.get_repo(package.distro, repo_name) if not repo: raise base.APIError(errno.ENOENT, "Could not find repository") @@ -54,7 +51,7 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): # If anything goes wrong, we will try to delete the package again except Exception as e: - await package.delete(current_user) + await package.delete(self.current_user) raise e diff --git a/src/web/packages.py b/src/web/packages.py index f69f0cff..aae1e99b 100644 --- a/src/web/packages.py +++ b/src/web/packages.py @@ -21,9 +21,6 @@ class NameHandler(base.BaseHandler): if not build: raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) - # Fetch the current user - current_user = await self.get_current_user() - # Fetch all distributions distros = {} @@ -39,10 +36,10 @@ class NameHandler(base.BaseHandler): ) # Fetch scratch builds - if current_user: + if self.current_user: scratch_builds[distro] = tasks.create_task( self.backend.builds.get( - user=current_user, scratch=True, name=name, distro=distro), + user=self.current_user, scratch=True, name=name, distro=distro), ) # Map all bugs diff --git a/src/web/repos.py b/src/web/repos.py index f2d167a4..d7fa976f 100644 --- a/src/web/repos.py +++ b/src/web/repos.py @@ -152,32 +152,24 @@ class BuildsHandler(BaseHandler): class CreateCustomHandler(BaseHandler): @base.authenticated async def get(self, user_slug): - # Fetch current user - current_user = await self.get_current_user() - - # Fetch user user = await self.backend.users.get_by_name(user_slug) if not user: raise tornado.web.HTTPError(404, "Could not find user: %s" % user_slug) # Check for permissions - if not user.has_perm(current_user): + if not user.has_perm(self.current_user): raise tornado.web.HTTPError(403) await self.render("repos/create-custom.html", user=user, distros=self.backend.distros) @base.authenticated async def post(self, user_slug): - # Fetch current user - current_user = await self.get_current_user() - - # Fetch user user = await self.backend.users.get_by_name(user_slug) if not user: raise tornado.web.HTTPError(404, "Could not find user: %s" % user_slug) # Check for permissions - if not user.has_perm(current_user): + if not user.has_perm(self.current_user): raise tornado.web.HTTPError(403) # Create the repository diff --git a/src/web/uploads.py b/src/web/uploads.py index 6c36b23e..1313a1f7 100644 --- a/src/web/uploads.py +++ b/src/web/uploads.py @@ -35,11 +35,8 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): async def get(self): uploads = [] - # Fetch the current user - current_user = await self.get_current_user() - # Send information about all uploads - async for upload in current_user.get_uploads(): + async for upload in self.current_user.get_uploads(): uploads.append({ "id" : "%s" % upload.uuid, "filename" : upload.filename, @@ -61,9 +58,6 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): """ Creates a new upload and returns its UUID """ - # Fetch the current user - current_user = await self.get_current_user() - # Fetch the filename filename = self.get_argument("filename") @@ -88,7 +82,7 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): upload = await self.backend.uploads.create( filename = filename, size = size, - owner = current_user, + owner = self.current_user, digest_algo = digest_algo, digest = digest, ) @@ -97,7 +91,7 @@ class APIv1IndexHandler(base.APIMixin, base.BaseHandler): raise base.APIError(errno.ENOTSUP, "Unsupported digest %s" % digest_algo) from e except users.QuotaExceededError as e: - raise base.APIError(errno.EDQUOT, "Quota exceeded for %s" % current_user) from e + raise base.APIError(errno.EDQUOT, "Quota exceeded for %s" % self.current_user) from e except ValueError as e: raise base.APIError(errno.EINVAL, "%s" % e) from e @@ -156,16 +150,12 @@ class APIv1DetailHandler(base.APIMixin, base.BaseHandler): """ Deletes an upload with a certain UUID """ - # Fetch the current user - current_user = await self.get_current_user() - - # Fetch the upload upload = await self.backend.uploads.get_by_uuid(uuid) if not upload: raise tornado.web.HTTPError(404, "Could not find upload %s" % uuid) # Check for permissions - if not upload.has_perm(current_user): + if not upload.has_perm(self.current_user): raise tornado.web.HTTPError(403, "%s has no permission to delete %s" \ % (current_user, upload))