There was one blazing issue with the previous implementation regardless
of the multiple records: we were generating fingerprints by storing
the key into a file and reading it with ssh-keygen. This is absolutely
terrible and was not meant to be left around (it was forgotten, my bad).
Took this opportunity to clean up a few things:
- simplify pubkey validation
- centralize things a bit better
Signed-off-by: Kevin Morris <kevr@0cost.org>
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>
Previously, we were just relying on the cookie expiration
for sessions to expire. We were not cleaning up Session
records either.
Rework timing to depend on an AURREMEMBER cookie which is
now emitted on login during BasicAuthBackend processing.
If the SID does still have a session but it's expired,
we now delete the session record before returning.
Otherwise, we update the session's LastUpdateTS to
the current time.
In addition, stored the unauthenticated result value
in a variable to reduce redundancy.
Signed-off-by: Kevin Morris <kevr@0cost.org>
We've seen a bug in the past where unique SID generation fails and
still ends up raising an exception.
This commit reworks how we deal with database exceptions internally,
tries for 36 iterations to set a fresh unique SID, and raises a 500
HTTPException if we were unable to.
Signed-off-by: Kevin Morris <kevr@0cost.org>
Changes:
-------
- Add aurweb.db.get_session()
- Returns aurweb.db's global `session` instance
- Provides us a way to change the implementation of the session
instance without interrupting user code.
- Use aurweb.db.get_session() in session API methods
- Add docstrings to session API methods
- Refactor aurweb.db.delete
- Normalize aurweb.db.delete to an alias of session.delete
- Refresh instances in places we depend on their non-PK columns
being up to date.
Signed-off-by: Kevin Morris <kevr@0cost.org>
We don't want to depend on the database to load up data
about the models we define. We now leverage the existing
`aurweb.schema` module for table definitions and set
__table_args__["autoload"] to False.
Signed-off-by: Kevin Morris <kevr@0cost.org>
Previously, we passed the straight up request type instance from
SQLAlchemy and had a .title() function that was transparently
treating the instance the same as the instance's Name in terms
of notify.py's use of it.
This commit removes that transparent behavior; it was not actually
intended.
Signed-off-by: Kevin Morris <kevr@0cost.org>
This gives developers the ability to import models without importing
them directly from their module:
from aurweb.models import Ban, AccountType
This provides more conciseness:
from aurweb import models
def some_func(ban: models.Ban):
pass
def some_other_func(user: models.User):
pass
This more aligns with a Django-style of core model bases.
NOTE: Docker images must be rebuilt with this change, as setup.cfg
has changed. Old Docker images will cause flake8 violation reports.
Signed-off-by: Kevin Morris <kevr@0cost.org>
Now, we allow the direct relationships and their foreign keys to
be set in all of our models. Previously, we constrained this to
direct relationships, and this forced users to perform a query
in most situations to satisfy that requirement. Now, IDs can be
passed directly.
Additionally, this change removes the need for extraneous imports
when users which to use relationships. We now import and use models
directly instead of passing string-references to them.
Signed-off-by: Kevin Morris <kevr@0cost.org>
This change implements the FastAPI version of the
/pkgbase/{name}/request form's action.
Changes from PHP:
- Additional errors are now displayed for the **merge_into** field,
which are only displayed when the Merge type is selected.
- If the **merge_into** field is empty, a new error is displayed:
'The "Merge into" field must not be empty.'
- If the **merge_into** field is given the name of a package base
which does not exist, a new error is displayed:
"The package base you want to merge into does not exist."
- If the **merge_into** field is given the name of the package
base that a request is being created for, a new error is
displayed: "You cannot merge a package base into itself."
- When an error is encountered, users are now brought back to
the request form which they submitted and an error is displayed
at the top of the page.
- If an invalid type is provided, users are returned to a BAD_REQUEST
status rendering of the request form.
Signed-off-by: Kevin Morris <kevr@0cost.org>
For SQLAlchemy to automatically understand updates from the
external world, it must use an `autocommit=True` in its session.
This change breaks how we were using commit previously, as
`autocommit=True` causes SQLAlchemy to commit when a
SessionTransaction context hits __exit__.
So, a refactoring was required of our tests: All usage of
any `db.{create,delete}` must be called **within** a
SessionTransaction context, created via new `db.begin()`.
From this point forward, we're going to require:
```
with db.begin():
db.create(...)
db.delete(...)
db.session.delete(object)
```
With this, we now get external DB modifications automatically
without reloading or restarting the FastAPI server, which we
absolutely need for production.
Signed-off-by: Kevin Morris <kevr@0cost.org>
Added:
- User.voted_for(package)
- Has a user voted for a particular package?
- User.notified(package)
- Is a user being notified about a particular package?
- User.packages()
- Entire collection of Package objects related to User.
Signed-off-by: Kevin Morris <kevr@0cost.org>
Just like some of the other tables, we have some constant
records that we use to denote types of things. This commit
adds constants which correlate with these record constants.
Signed-off-by: Kevin Morris <kevr@0cost.org>
A helper function which provides a textual string conversion
of a particular Status column.
In a PackageRequest, Status is split up into four different types:
- PENDING : "Pending", PENDING_ID: 0
- CLOSED : "Closed", CLOSED_ID: 1
- ACCEPTED : "Accepted", ACCEPTED_ID: 2
- REJECTED : "Rejected", REJECTED_ID: 3
This commit adds constants for the textual strings and the
IDs. It also adds a PackageRequest.status_display() function which
grabs the proper display string for a particular Status ID.
Signed-off-by: Kevin Morris <kevr@0cost.org>