Commit graph

48 commits

Author SHA1 Message Date
moson
057685f304
fix: Fix package info for 404 errors
We try to find packages when a user enters a URL like /somepkg
or accidentally opens /somepkg.git in the browser.

However, it currently also does this for URL's like /pkgbase/doesnotexist
and falsely interprets "pkgbase" part as a package or pkgbase name.
This in combination with a pkgbase that is named "pkgbase" generates
some misleading 404 message for URL's like /pkgbase/doesnotexist.

That being said, we should probably add pkgbase to the blacklist check
as well (we do this for pkgname already) and add things like
"pkgbase" to the blacklist -> Will be picked up in another commit.

Signed-off-by: moson <moson@archlinux.org>
2024-02-17 14:12:09 +01:00
moson
baf97bd159
fix(test): FastAPI 0.104.1 - Fix warnings
FastAPI events are deprecated. Use "Lifespan" function instead.

Signed-off-by: moson <moson@archlinux.org>
2023-12-08 14:15:18 +01:00
moson
3005e82f60
fix: Cleanup prometheus metrics for dead workers
The current "cleanup" function that is removing orphan prometheus files
is actually never invoked.
We move this to a default gunicorn config file to register our hook(s).

https://docs.gunicorn.org/en/stable/configure.html
https://docs.gunicorn.org/en/stable/settings.html#child-exit
Signed-off-by: moson <moson@archlinux.org>
2023-08-18 22:04:55 +02:00
moson
bc03d8b8f2
fix: Fix middleware checking for accepted terms
The current query is a bit mixed up. The intention was to return the
number of unaccepted records. Now it does also count all records
that were accepted by some other user though.

Let's check the total number of terms vs. the number of accepted
records (by our user) instead.

Signed-off-by: moson <moson@archlinux.org>
2023-07-20 18:21:05 +02:00
moson-mo
97d0eac303
housekeep: copy static files
we copy static files used by PHP and Python versions into /static

preparation work for the removal of the PHP version

Signed-off-by: moson-mo <mo-son@mailbox.org>
2023-04-28 10:53:22 +02:00
moson-mo
52c962a590
fix(deps): fastapi 0.92.0 upgrade
middleware must be added before startup:

fixes: "RuntimeError: Cannot add middleware after an application has started"

https://fastapi.tiangolo.com/release-notes/#0910
Signed-off-by: moson-mo <mo-son@mailbox.org>
2023-03-04 10:29:54 +01:00
Leonidas Spyropoulos
9c0f8f053e
chore: rename logging.py and redis.py to avoid circular imports
Signed-off-by: Leonidas Spyropoulos <artafinde@archlinux.org>
2022-10-22 18:51:38 +01:00
Kevin Morris
adc3a21863
fix: add 'unsafe-inline' to script-src CSP
swagger-ui uses inline javascript to bootstrap itself, so we need to
allow unsafe inline because we can't give swagger-ui a nonce to embed.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-09-12 12:28:42 -07:00
Kevin Morris
9faa7b801d
feat: add cdn.jsdelivr.net to script/style CSP
Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-09-11 19:56:29 -07:00
Joakim Saario
9c6c13b78a
style: Run pre-commit 2022-08-22 22:40:45 +02:00
Kevin Morris
c83c5cdc42
change: log out details about PROMETHEUS_MULTIPROC_DIR
Additionally, respond with a 503 if the var is not set when
/metrics is requested.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-02-19 12:08:55 -08:00
Kevin Morris
7485cc231e
change: report unhandled tracebacks to a repository
As repeats of these traceback notifications were annoying some of
the devops staff, and it took coordination to share tracebacks with
developers, this commit removes that responsibility off of devops
by reporting tracebacks to Gitlab repositories in the form of issues.

- removed ServerErrorNotification
- removed notifications.postmaster configuration option
- added notifications.gitlab-instance option
- added notifications.error-project option
- added notifications.error-token option
- added aurweb.exceptions.handle_form_exceptions, a POST route decorator

Issues are filed confidentially. This change will need updates
in infrastructure's ansible configuration before this can be
applied to aur.archlinux.org.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-02-10 13:44:10 -08:00
Kevin Morris
211ca5e49c
housekeep: define filters in their own modules
This patch cleans up aurweb.templates and removes direct
module-level initialization of the environment.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-18 03:06:17 -08:00
Kevin Morris
d675c0dc26
feat(python): catch all exceptions thrown through fastapi route paths
This commit does quite a bit:
- Catches unhandled exceptions raised in the route handler and
  produces a 500 Internal Server Error Arch-themed response.
- Each unhandled exception causes a notification to be sent to new
  `notifications.postmaster` email with a "Traceback ID."
- Traceback ID is logged to the server along with the traceback which
  caused the 500: `docker-compose logs fastapi | grep '<traceback_id>'`
- If `options.traceback` is set to `1`, traceback is displayed in
  the new 500.html template.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-09 23:10:02 -08:00
Kevin Morris
9e7ae5904f
feat(python): handle RuntimeErrors raised through routes
This gets raised when a client closes a connection before receiving
a valid response; this is not controllable from our side.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-07 18:21:23 -08:00
Steven Guikal
e126d431d7
fix(FastAPI): add custom error templates for certain exceptions
Signed-off-by: Steven Guikal <void@fluix.one>
2022-01-03 18:22:03 -08:00
Kevin Morris
3e048e9675
change(python): centralize router inclusion
Now, when we want to add, remove routes, our base routes should
be defined in aurweb.routers.__init__.APP_ROUTES.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-02 01:52:28 -08:00
Kevin Morris
a1f46611e1
change(python): move request & pkgbase request routes
Move package request routes and related routes to their
respective routers. In addition, move some utility used
for requests over from `aurweb.packages`.

Introduced routers:
- `aurweb.routers.requests`

Introduced package:
- `aurweb.requests`

Introduced module:
- `aurweb.requests.util`

Changes:
- Moved `aurweb.packages.validate` to `aurweb.pkgbase.validate`
- Moved requests listing & request closure routes to
  `aurweb.routers.requests`
- Moved pkgbase request creation route to `aurweb.routers.pkgbase`
- Moved `get_pkgreq_by_id` from `aurweb.packages.util` to
  `aurweb.requests.util` and fixed its return type hint.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-02 01:44:36 -08:00
Kevin Morris
bd2ad9b616
change(python): put pkgbase routes & impl into their own modules
Introduces new router:
- `aurweb.routers.pkgbase`

Introduces new package:
- `aurweb.pkgbase`

Introduces new modules:
- `aurweb.pkgbase.actions`
- `aurweb.pkgbase.util`

Changes:
- `pkgbase_{action}_instance` functions are now located in
  `aurweb.pkgbase.actions`.
- `pkgbase`-wise routes have been moved to
  `aurweb.routers.pkgbase`.
- `make_single_context` was moved to
  `aurweb.pkgbase.util.make_context`.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2022-01-01 21:06:17 -08:00
Kevin Morris
abfd41f31e
change(fastapi): centralize HTTPException
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-12-02 23:23:27 -08:00
Kevin Morris
fb92fb509b
change(fastapi): use sys.getrecursionlimit() + 1000 as default
Without the increment, we've seen tests failed due to recursion
errors caused by starlette's base middleware. Just make it safe
in case nobody supplies TEST_RECURSION_LIMIT.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-11-17 01:36:19 -08:00
Kevin Morris
07aac768d6
change(fastapi): remove sqlite support
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-11-17 01:34:59 -08:00
Kevin Morris
dc397f6bd8
fix(fastapi): utilize PROMETHEUS_MULTIPROC_DIR in our own /metrics
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-11-01 13:23:48 -07:00
Kevin Morris
f21765bfe4
feat(fastapi): add prometheus /metrics
This commit provides custom metrics, so we can group requests
into their route paths and not by the arguments given, e.g.
/pkgbase/some-package -> /pkgbase/{name}. We also count RPC
requests as `http_api_requests_total`, split by the RPC
query "type" argument.

- `http_api_requests_total`
    - Labels: ["type", "status"]
- `http_requests_total`
    - Number of HTTP requests in total.
    - Labels: ["method", "path", "status"]

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-11-01 11:41:39 -07:00
Kevin Morris
94d494866f
fix(fastapi): increase recursion limit during tests
The default recursion limit used by Docker's archlinux:base-devel
Python package becomes problematic in some cases when running tests
against our FastAPI application using starlette.testclient.TestClient
(aliased to fastapi.testclient.TestClient). starlette ends up with
test failures because it exceeds the recursion limit, but this only
happens when using the `TestClient`. When the ASGI servers are run,
this is not an issue and so in that case, the recursion limit has
not been touched.

This change uses a `TEST_RECURSION_LIMIT` environment variable to
modify the recursion limit of the FastAPI application. This variable
is, by default, only supplied when running pytests in Docker, but
can be force-supplied by the user.

TEST_RECURSION_LIMIT=10000 has been added to `.env` and `.gitlab-ci.yml`.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-10-23 20:15:53 -07:00
Kevin Morris
28c4e9697b
change(fastapi): simplify model imports across code-base
Closes: #133

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-10-16 19:40:00 -07:00
Hunter Wittenborn
c2d3dc1daf Added info and multiinfo types for /rpc 2021-09-12 02:21:55 -05:00
Leonidas Spyropoulos
1e1c0c3fe5 [FastAPI] Basic pkgbase template
Co-author: Kevin Morris <kevr@0cost.org>

Signed-off-by: Leonidas Spyropoulos <artafinde@gmail.com>
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-07-27 20:48:40 -07:00
Kevin Morris
eec09dec3e [FastAPI] add /rss and /rss/modified
There are slight differences in that, with `python-feedgen`,
an empty description field completely omits the description,
but includes the description when there is one.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-07-01 11:09:09 -07:00
Kevin Morris
3a74f76ff9 FastAPI: use internal typeahead and remove jquery
Awesome!

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-29 22:56:48 -07:00
Kevin Morris
04ab98907a aurweb.asgi: patch invalid f-string
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-26 04:20:55 -07:00
Kevin Morris
bfffdd4d91 aurweb.asgi: Allow unsafe-inline style-src in CSP
Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-26 04:13:28 -07:00
Kevin Morris
dc4cc9b604 add aurweb.asgi.id_redirect_middleware
A new middleware which redirects requests going to '/route?id=some_id'
to '/route/some_id'. In the FastAPI application, we'll prefer using
restful layouts where possible where resource-based ids are
parameters of the request uri: '/route/{resource_id}'.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-26 01:11:52 -07:00
Kevin Morris
d674aaf736 add /tu/ (get) index
This commit implements the '/tu' Trusted User index page.

In addition to this functionality, this commit introduces
the following jinja2 filters:

- dt: util.timestamp_to_datetime
- as_timezone: util.as_timezone
- dedupe_qs: util.dedupe_qs
- urlencode: urllib.parse.quote_plus

There's also a new decorator that can be used to enforce
permissions: `account_type_required`. If a user does not
meet account type requirements, they are redirected to '/'.

```
@auth_required(True)
@account_type_required({"Trusted User"})
async def some_route(request: fastapi.Request):
    return Response("You are a Trusted User!")
```

Routes added:

- `GET /tu`: aurweb.routers.trusted_user.trusted_user

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-26 01:03:27 -07:00
Kevin Morris
adb42882c5 [FastAPI] add /tos routes (get, post)
This clones the end goal behavior of PHP, but it does not
concern itself with the revision form array at all.

Since this page on PHP renders out the entire list of
terms that a user needs to accept, we can treat a
POST request with the "accept" checkbox enabled as a
request to accept all unaccepted (or outdated revision)
terms.

This commit also adds in a new http middleware used to
redirect authenticated users to '/tos' if they have not
yet accepted all terms.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-24 19:12:49 -07:00
Kevin Morris
55c0637b98 add logging.config.fileConfig
This resolves logging issues with alembic on aurweb.initdb
in addition to adding more logging utilities for aurweb
and tests in general.

Developers should fetch a logger for their specific module
via `logging.getLogger(__name__)`.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-24 18:56:38 -07:00
Kevin Morris
865c414504 aurweb.asgi: add security headers middleware
This commit introduces a middleware function which adds
the following security headers to each response:

- Content-Security-Policy
    - This includes a new `nonce`, which is tied to a user
      via authentication middleware. Both an anonymous user
      and an authenticated user recieve their own random nonces.
- X-Content-Type-Options
- Referrer-Policy
- X-Frame-Options

They are then tested for existence in test/test_routes.py.

Note: The overcomplicated-looking asyncio behavior in the
middleware function is used to avoid a warning about the old
coroutine awaits being deprecated. See
https://docs.python.org/3/library/asyncio-task.html#asyncio.wait
for more detail.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-22 20:33:45 -07:00
Kevin Morris
822905be7d bugfix: relax next verification
AUR renders its own 404 Not Found page when a bad route
is encountered. Introducing the previous verification
caused an error in this case when setting a language
while viewing the Not Found page. So, instead of checking
through routes, just make sure that the next parameter
starts with a '/' character, which removes the possibility
of any cross attacks.

+ Removed aurweb.asgi.routes; no longer needed.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 20:11:17 -07:00
Kevin Morris
a33d076d8b add passreset routes
Introduced `get|post` `/passreset` routes. These routes mimic the
behavior of the existing PHP implementation, with the exception of
HTTP status code returns.

Routes added:
    GET /passreset
    POST /passreset

Routers added:
    aurweb.routers.accounts

* On an unknown user or mismatched resetkey (where resetkey must ==
  user.resetkey), return HTTP status NOT_FOUND (404).
* On another error in the request, return HTTP status BAD_REQUEST (400).

Both `get|post` routes requires that the current user is **not**
authenticated, hence `@auth_required(False, redirect="/")`.

+ Added auth_required decorator to aurweb.auth.
+ Added some more utility to aurweb.models.user.User.
+ Added `partials/error.html` template.
+ Added `passreset.html` template.
+ Added aurweb.db.ConnectionExecutor functor for paramstyle logic.
  Decoupling the executor logic from the database connection logic
  is needed for us to easily use the same logic with a fastapi
  database session, when we need to use aurweb.scripts modules.

At this point, notification configuration is now required to complete
tests involved with notifications properly, like passreset.
`conf/config.dev` has been modified to include [notifications] sendmail,
sender and reply-to overrides. Dockerfile and .gitlab-ci.yml have been
updated to setup /etc/hosts and start postfix before running tests.

* setup.cfg: ignore E741, C901 in aurweb.routers.accounts

These two warnings (shown in the commit) are not dangerous and a bi-product
of maintaining compatibility with our current code flow.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 20:11:17 -07:00
Kevin Morris
5d4a5deddf implement login + logout routes and templates
+ Added route: GET `/login` via `aurweb.routers.auth.login_get`
+ Added route: POST `/login` via `aurweb.routers.auth.login_post`
+ Added route: GET `/logout` via `aurweb.routers.auth.logout`
+ Added route: POST `/logout` via `aurweb.routers.auth.logout_post`
* Modify archdev-navbar.html template to toggle displays on auth state
+ Added login.html template

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 20:11:17 -07:00
Kevin Morris
56f2798279 add aurweb.auth and authentication to User
+ Added aurweb.auth.AnonymousUser
    * An instance of this model is returned as the request user
      when the request is not authenticated
+ Added aurweb.auth.BasicAuthBackend
+ Add starlette's AuthenticationMiddleware to app middleware,
  which uses our BasicAuthBackend facility
+ Added User.is_authenticated()
+ Added User.authenticate(password)
+ Added User.login(request, password)
+ Added User.logout(request)
+ Added repr(User(...)) representation
+ Added aurweb.auth.auth_required decorator.

This change uses the same AURSID logic in the PHP implementation.

Additionally, introduce a few helpers for authentication,
one of which being `User.update_password(password, rounds = 12)`
where `rounds` is a configurable number of salt rounds.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 20:11:17 -07:00
Marcus Andersson
f6744d3e39 Adding error 503 catcher 2021-06-05 19:52:56 -07:00
Kevin Morris
4238a9fc68 add aurweb.db.session
+ Added Session class and global session object to aurweb.db,
  these are sessions created by sqlalchemy ORM's sessionmaker
  and will allow us to use declarative/imperative models.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 19:52:40 -07:00
Kevin Morris
2df90ce280 port over base HTML layout from PHP to FastAPI+Jinja2
+ Mounted static files (at web/html) to /static.
+ Added AURWEB_VERSION to aurweb.config (this is used around HTML
  to refer back to aurweb's release on git.archlinux.org), so we
  need it easily accessible in the Python codebase.
+ Implemented basic Jinja2 partials to put together whole aurweb
  pages. This may be missing some things currently and is a WIP
  until this set is ready to be merged.
+ Added config [options] aurwebdir = YOUR_AUR_ROOT; this configuration
  option should specify the root directory of the aurweb project.
  It is used by various parts of the FastAPI codebase to target
  project directories.

Added routes via aurweb.routers.html:
    * POST /language: Set your session language.
    * GET /favicon.ico: Redirect to /static/images/favicon.ico.
        * Some browsers always look for $ROOT/favicon.ico to get an icon
          for the page being loaded, regardless of a specified "shortcut
          icon" given in a <link> directive.
    * GET /: Home page; WIP.

* Updated aurweb.routers.html.language passes query parameters to
  its next redirection.

When calling aurweb.templates.render_template, the context passed should
be formed via the aurweb.templates.make_context. See
aurweb.routers.html.index for an example of this.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 19:50:51 -07:00
Frédéric Mangano-Tarumi
5fb4fc12de HTML error pages for FastAPI
Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
2021-02-20 11:24:30 -05:00
Frédéric Mangano-Tarumi
3b347d3989 Crude OpenID Connect client using Authlib
Developers can go to /sso/login to get redirected to the SSO. On
successful login, the ID token is displayed.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
2021-02-20 11:24:30 -05:00
Frédéric Mangano-Tarumi
0e3bd8b596 Remove the FastAPI /hello test route
Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
2021-02-20 11:24:30 -05:00
Frédéric Mangano-Tarumi
5be07a8a9e aurweb.spawn: Integrate FastAPI and nginx
aurweb.spawn used to launch only PHP’s built-in server. Now it spawns a
dummy FastAPI application too. Since both stacks spawn their own HTTP
server, aurweb.spawn also spawns nginx as a reverse proxy to mount them
under the same base URL, defined by aur_location in the configuration.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
2021-02-20 11:24:30 -05:00