Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add api.config module for Settings #392

Closed
wants to merge 22 commits into from

Conversation

JenySadadia
Copy link
Collaborator

@JenySadadia JenySadadia commented Oct 30, 2023

On top of #377

api: add api.config to define various module settings

Instead of defining multiple settings class in different API modules like pubsub, auth, email_sender, add api.config module to store all different settings classes.

Jeny Sadadia added 21 commits October 30, 2023 14:57
Add `fastapi-users` package with `beanie` and `oauth`
tools for user management. The specific `10.4.0` version
has been selected to make it compatible with `fastapi 0.68.1`
package version.

Signed-off-by: Jeny Sadadia <[email protected]>
Add `User` model and extend user model
provided by `fastapi-users`. Add an extra field
`username` and create `unique` index on it.
Also add field `groups` for user groups.
Also add schema for user CRUD operation. Use
`ModelId` as a parent class for `UserRead` to enable
json encoder for ObjectId.
Use `Settings` class to rename collection name
for `User` model from default `User` to `user`.
This change is needed to align the collection name
with `Database.COLLECTIONS`.

Signed-off-by: Jeny Sadadia <[email protected]>
Implement `Database.initialize_beanie` method
to initialize Beanie ODM to use `fastapi-users`
tools for MongoDB.

Signed-off-by: Jeny Sadadia <[email protected]>
In order to use `fastapi-users` package for
MongoDB, initialize Beanie on app startup
as per the package requirements.

Signed-off-by: Jeny Sadadia <[email protected]>
Implement `Authentication.get_user_authentication_backend` to
get authentication backend for user management.
Authentication backend for `fastapi-users` is composed of two
parts: Transaport and Strategy.
Transport is a mechanism for token transmisson i.e. bearer or cookie.
Strategy is a method to generate and secure tokens. It can be JWT,
database or Redis. To accommodate user management with current
API design, `Bearer` is selected as a transport method and `JWT`
is selected as strategy.

Signed-off-by: Jeny Sadadia <[email protected]>
Add `user_manager.py` to implement custom user management
logic. Extend `BaseUserManager` provided by `fastapi-users` to
have customized core logic for user management.
Add database adapter `get_user_db` to create
a link between user model from `fastapi-users` and API
database configuration.
Inject `UserManager` at a runtime in a database session.
Add `email_sender` module to send verification and
reset password token for user accounts via email. Add
email templates.

Signed-off-by: Jeny Sadadia <[email protected]>
Create an instance of `FastAPIUsers` to bind
`UserManager` with authentication backend.

Signed-off-by: Jeny Sadadia <[email protected]>
Register different routers provided by the package
to our application.

Signed-off-by: Jeny Sadadia <[email protected]>
Run pylint on newly created user related files
i.e. `api.user_manager` and `api.user_models`
in Github workflows.

Signed-off-by: Jeny Sadadia <[email protected]>
Update GET users endpoint as per `User` model
defined in `users_model.py`.
Also drop `/users/profile` endpoint as the
updated user schema doesn't have `profile` field.

Signed-off-by: Jeny Sadadia <[email protected]>
`fastapi-users` provides inbuilt router `/users/<user-id>`
for getting user matching ID. Hence, deleting
`get_user_by_id` handler that serves the similar purpose.

Signed-off-by: Jeny Sadadia <[email protected]>
Implement custom route for user registration to ensure
unique username. The route will also convert user group
names to `UserGroup` objects. Then the router will call endpoint
of `register_router` provided by `fastapi-users` to create a user
account. Drop old POST `/user/<username>` handler for user account
creation to use this route instead.

Signed-off-by: Jeny Sadadia <[email protected]>
`/login` endpoint has a field `username` that actually
accepts user email address for login. The reason is `fastapi-users`
uses `OAuth2PasswordRequestForm` to get login information  under
the hood that has `username` field. `login` handler
uses `BaseUserManager.authenticate` method to authenticate
user. Overload the authenticate method to use `username` for
authentication instead of `email`.

Signed-off-by: Jeny Sadadia <[email protected]>
Use dependency callable `FastAPIUsers.current_user` for
getting current active user for authenticated routes.
Use it for `/whoami`, POST `/node`, pubsub, and regression
related endpoints.

Signed-off-by: Jeny Sadadia <[email protected]>
Use dependency callable `FastAPIUsers.current_user` for
getting current active super user for authenticated routes.
Use it for POST `/user/register` endpoint which needs
a superuser for creating other regular users.

Signed-off-by: Jeny Sadadia <[email protected]>
Use latest `User` model schema implemented using
`fastapi-users` package.
Initialize Beanie as per the package requirement
before inserting document to database.

Signed-off-by: Jeny Sadadia <[email protected]>
Overload routes for updating users to ensure unique
usernames. It is also used to get user group names
as a list of strings and convert it to `UserGroup`
object to insert it into DB.
Removed all former user routers and update handlers
to use `fastapi-users` instead.
Drop `models.User` and `models.UserProfile` to use
latest user model from `user_models.py`.

Signed-off-by: Jeny Sadadia <[email protected]>
Now the authentication methods have been used from
`fastapi-users` package.
Hence, remove all the methods from `Authentication` class
related to access tokens, scopes, passwords, and getting
current user.
Also update signature of the class constructor
to drop unused variables.
Rename variable `Settings.access_token_expire_minutes`
to `Settings.access_token_expire_seconds` as `JWTStrategy`
class takes token expiry time in seconds.
Update logic to create an instance of `Authentication`
class in `api.main` module.

Signed-off-by: Jeny Sadadia <[email protected]>
At the moment, original `FastAPI` app instance and versioned
app instance both has same name `app`.
Renamed the versioned app instance in order to use original
app instace for mocking dependency callable with
`app.dependency_overrides`. This is required to mock calls
to `get_current_user` and `get_current_superuser` for user
related tests.
Update `Dockerfile` to use `versioned_app` instance
for running API.

Signed-off-by: Jeny Sadadia <[email protected]>
Use `versioned_app` instance for creating test
client instance. Update all user related tests
to use latest endpoints and user schema from
`fastapi-users` integration.
Add environment variables related to email settings
to Github actions workflow as `UserManager` needs
them to initialize `EmailSender` instance.

Signed-off-by: Jeny Sadadia <[email protected]>
Integrate `mongomock_motor` package to mock
async mongo client for Beanie initialization.
Add fixture to initialize Beanie on app startup.
Remove fixtures and add methods to get current active user.
Update `app.dependency_overrides` dictionary to mock
dependency callable from `fastapi-users` to get users
while creating `TestClient`.
Update all the user related tests.
Add environment variable to Github actions workflow
file.

Signed-off-by: Jeny Sadadia <[email protected]>
Instead of defining multiple settings class in different
API modules like `pubsub`, `auth`, `email_sender`,
add `api.config` module to store all different settings
classes.

Signed-off-by: Jeny Sadadia <[email protected]>
@JenySadadia JenySadadia added the staging-skip Don't test automatically on staging.kernelci.org label Oct 31, 2023
@gctucker
Copy link
Contributor

OK I've tested this which includes the changes from #377 and it's working with a few minor fixes and tweaks. I'll prepare the follow-up PRs and merge these two so we should have all this in place today, as well as the related kernelci-core changes with kci user etc.

Copy link
Contributor

@gctucker gctucker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguably this should have been called api.settings but that's a detail.

@gctucker
Copy link
Contributor

Replaced with #403 (rebase with just the last commit from this PR).

@gctucker gctucker closed this Nov 10, 2023
@JenySadadia JenySadadia deleted the rework-settings branch November 15, 2023 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
staging-skip Don't test automatically on staging.kernelci.org
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants