From: Michael Tremer Date: Fri, 18 Aug 2023 15:27:31 +0000 (+0000) Subject: repo: Add simple API operations X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e5645830a2c316c331f48a931fc9dfd2cc0aded;p=pbs.git repo: Add simple API operations Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/repository.py b/src/buildservice/repository.py index b3c24a17..df4c5c6c 100644 --- a/src/buildservice/repository.py +++ b/src/buildservice/repository.py @@ -134,10 +134,30 @@ class Repository(base.DataObject): return NotImplemented + def to_json(self): + ret = { + "name" : self.name, + "slug" : self.slug, + "description" : self.description, + "created_at" : self.created_at.isoformat(), + + # Distribution + "distro" : self.distro.slug, + } + + if self.owner: + ret["owner"] = self.owner.to_json() + + return ret + @lazy_property def distro(self): return self.backend.distros.get_by_id(self.data.distro_id) + @property + def created_at(self): + return self.data.created_at + # Repo Types def is_user(self): diff --git a/src/buildservice/users.py b/src/buildservice/users.py index c262ec83..49dcf955 100644 --- a/src/buildservice/users.py +++ b/src/buildservice/users.py @@ -473,6 +473,11 @@ class User(base.DataObject): return NotImplemented + def to_json(self): + return { + "name" : self.name, + } + @property def name(self): return self.data.name diff --git a/src/web/__init__.py b/src/web/__init__.py index d92ffe72..4da396ba 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -245,6 +245,10 @@ class Application(tornado.web.Application): # Log (r"/log", handlers.LogHandler), + # Repositories + (r"/api/v1/repos/([\w\d\-]+)", repos.APIv1IndexHandler), + (r"/api/v1/repos/([\w\d\-]+)/([\w\d\-]+)", repos.APIv1ShowHandler), + # Uploads (r"/api/v1/uploads", uploads.APIv1IndexHandler), (r"/api/v1/uploads/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", diff --git a/src/web/base.py b/src/web/base.py index b7c96d96..dbfc74b2 100644 --- a/src/web/base.py +++ b/src/web/base.py @@ -52,6 +52,7 @@ class KerberosAuthMixin(object): # Set status to 401 self.set_status(401) + @functools.cache def get_authenticated_user(self): auth_header = self.request.headers.get("Authorization", None) diff --git a/src/web/repos.py b/src/web/repos.py index 8fbb4e38..fb3de897 100644 --- a/src/web/repos.py +++ b/src/web/repos.py @@ -25,6 +25,80 @@ import tornado.web from . import base from . import ui_modules +class APIv1IndexHandler(base.APIMixin, base.BaseHandler): + # Allow users to create builds + allow_users = True + + @tornado.web.authenticated + async def get(self, distro_slug): + with self.db.transaction(): + # Fetch distro + distro = self.backend.distros.get_by_slug(distro_slug) + if not distro: + raise tornado.web.HTTPError(404, "Could not find distro '%s'" % distro_slug) + + # Fetch all repositories + try: + repos = self.current_user.repos[distro] + except KeyError: + repos = [] + + self.finish({ + "repos" : [repo.to_json() for repo in repos], + }) + + @tornado.web.authenticated + async def post(self, distro_slug): + with self.db.transaction(): + # Fetch distro + distro = self.backend.distros.get_by_slug(distro_slug) + if not distro: + raise tornado.web.HTTPError(404, "Could not find distro '%s'" % distro_slug) + + # Fetch name + name = self.get_argument("name") + + # Create a new repository + repo = await self.backend.repos.create(distro=distro, + name=name, owner=self.current_user) + + # Set description + repo.description = self.get_argument("description", None) + + # Return the result + self.finish(repo.to_json()) + + +class APIv1ShowHandler(base.APIMixin, base.BaseHandler): + def _get_repo(self, distro_slug, repo_slug): + # Fetch distro + self.distro = self.backend.distros.get_by_slug(distro_slug) + if not self.distro: + raise tornado.web.HTTPError(404, "Could not find distro '%s'" % distro_slug) + + # Fetch repository + self.repo = self.current_users.get_repo(self.distro, repo_slug) + if not self.repo: + raise tornado.web.HTTPError(404, "Could not find repository '%s" % repo_slug) + + @tornado.web.authenticated + async def get(self, distro_slug, name): + with self.db.transaction(): + repo = self._get_repo(distro_slug, name) + + self.finish(repo.to_json()) + + @tornado.web.authenticated + async def delete(self, distro_slug, name): + with self.db.transaction(): + repo = self._get_repo(distro_slug, name) + + # XXX check permissions + + # Delete the repository + await self.repo.delete(self.current_user) + + class BaseHandler(base.BaseHandler): def _get_repo(self, distro_slug, repo_slug, user_slug=None): user = None