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

[WIP] Auto-Login via Header #253

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

LelouBil
Copy link

@LelouBil LelouBil commented Sep 25, 2024

What type of PR is this?

  • documentation
  • feature

What this PR does / why we need it:

The goal of this PR is to allow homebox to directly log in any request with a specified header mapping to a user, or create the user if it does not exist.

This is useful in reverse-proxy scenarios, where the reverse proxy already authenticates the user (for example, Home Assistant Ingress)

Which issue(s) this PR fixes:

It would improve #33 but there's no issue for specifically this

Special notes for your reviewer:

This is still a draft, with only basic backend logic and no frontend logic. I'm looking for help with which part of the code I would change. I started doing what I think it the correct way but since I don't know the project I'm not too sure.

Testing

Draft, not yet working

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced header-based authentication with the headerAuthEnabled property in API responses.
    • Added support for external user ID authentication, enhancing user login options.
    • New configuration options for proxy settings, including trusted hosts and external user headers.
  • Documentation

    • Updated API documentation to reflect new authentication features and configuration variables.
    • Enhanced configuration guides with new environment variables for proxy settings.
  • Bug Fixes

    • Improved validation checks for proxy configurations to ensure proper setup.

These changes enhance security and flexibility for user authentication and configuration management.

Copy link
Contributor

coderabbitai bot commented Sep 25, 2024

Walkthrough

The changes introduce a new header-based authentication mechanism within the application, adding support for external user identifiers. The updates include modifications to various components, such as controllers, middleware, routes, and database schemas, to accommodate the new functionality. Additionally, documentation and configuration files have been updated to reflect the new options available for proxy settings and authentication.

Changes

Files Change Summary
backend/app/api/handlers/v1/controller.go Added WithHeaderAuthEnabled function and headerAuthEnabled field to V1Controller struct; included HeaderAuthEnabled in JSON response.
backend/app/api/main.go Introduced validation checks for HeaderExternalUserName and HeaderExternalUserId fields; modified middleware setup based on TrustedHosts.
backend/app/api/middleware.go Added getHeader function for external user ID authentication; modified mwAuthToken middleware to include this new function.
backend/app/api/routes.go Updated mountRoutes function to include v1.WithHeaderAuthEnabled parameter based on HeaderExternalUserId configuration.
backend/app/api/static/docs/docs.go Added headerAuthEnabled field to JSON schema in docTemplate.
backend/app/api/static/docs/swagger.json Introduced headerAuthEnabled property in JSON schema.
backend/app/api/static/docs/swagger.yaml Added headerAuthEnabled property in the definitions section.
backend/internal/core/services/service_user.go Added LoginWithExternalIDHeader method to UserService for user login via external ID.
backend/internal/data/ent/migrate/schema.go Added external_user_id column to "users" table schema.
backend/internal/data/ent/mutation.go Introduced external_user_id field in UserMutation struct with associated methods for managing its state.
backend/internal/data/ent/schema/user.go Added external_user_id field to User schema, marked as sensitive.
backend/internal/data/ent/user.go Introduced ExternalUserID field in User struct, updated methods to handle this field.
backend/internal/data/ent/user/user.go Added FieldExternalUserID constant and ByExternalUserID function for ordering.
backend/internal/data/ent/user/where.go Added multiple query predicates for external_user_id.
backend/internal/data/ent/user_create.go Added methods to UserCreate for setting external_user_id.
backend/internal/data/ent/user_update.go Introduced methods for managing external_user_id in UserUpdate and UserUpdateOne.
backend/internal/data/migrations/migrations/20240925103037_add_external_user_id.sql Added SQL migration to include external_user_id column in users table.
backend/internal/data/repo/repo_users.go Added GetOneExternalID method to UserRepository for retrieving users by external ID.
backend/internal/sys/config/conf.go Introduced Proxy struct in Config for proxy-related settings.
backend/internal/web/mid/trustedips.go Added middleware for checking trusted IP addresses.
docker-compose.yml Added extra_hosts entry for resolving host machine address in Docker containers.
docs/docs/api/openapi-2.0.json Added headerAuthEnabled property in JSON schema.
docs/en/configure-homebox.md Updated documentation to include new environment variables for proxy configuration.
frontend/lib/api/types/data-contracts.ts Added headerAuthEnabled property to APISummary interface.

Poem

In the realm of code, new paths we pave,
With headers and tokens, our users we save.
External IDs now dance in the flow,
As trusted IPs guide where we go.
A sprinkle of docs, a dash of delight,
In this vibrant world, our future shines bright! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@LelouBil
Copy link
Author

Also, I added a trusted IP mechanism to enhance security with this feature and changed the Real IP middleware to only be active when some trusted IPs are set.
I am having troubles with go's localhost resolving, because net.LookupIP says it will get ipv4 and ipv6, and does so for remote hosts, but it doesn't with localhost, it only gives 127.0.0.1. Also when running in a docker container I didn't find a good way to only trust the host IP (as a host-gateway in extra_hosts mapped to my local IP address not in the docker network, I don't know if that's an error on my part)

@tankerkiller125
Copy link
Contributor

As a note with creating users, that don't exist, I haven't reviewed the code yet, but given the whole groups thing, how would that end up working header wise? Just a new header that auth services can set? And what happens if they don't? Just create a new group for the user?

@LelouBil
Copy link
Author

LelouBil commented Sep 25, 2024

Just a new header that auth services can set

Maybe this plus an environment variable to set the default group for all header-created users ?

I'm not using homebox (yet) so I'm not sure if a new group should be created for each user or if the more common use case is all users in a single group. If it's the second case the default group variable would be better.

So :

  • Group header
  • if no group header present, add the user to the default group env variable
  • if there's no default group environment variable, create a new group for the user ?

@tankerkiller125
Copy link
Contributor

The way it currently works, is if a user registers without a invite code it generates a new tenant entirely. However invite codes probably wouldn't work with header login. I know that at least with some auth software you can set custom user attributes, which would allow for setting the tenant via a header, but not all of them? I think we might need further community input on this overall to get more of a consensus on how to handle this.

@LelouBil
Copy link
Author

I don't think the header login mechanism should be very complicated, there is another pull request about OIDC support and I feel like this would handle the more complex authentication cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants