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

feat: validate github organization during OAuth login #6700

Open
wants to merge 2 commits into
base: preview
Choose a base branch
from

Conversation

SamuelTR20
Copy link
Contributor

@SamuelTR20 SamuelTR20 commented Mar 4, 2025

Description

A new functionality has been added to the existing OAuth2 authentication system. In addition to validating GitHub credentials, a new field for entering the Organization ID has been introduced. This field allows the system to verify whether the user belongs to the specified organization before granting access. If the user does not belong to the organization, access will be denied. If the Organization ID field is left empty, the behavior will remain the same as before, allowing access to any user with a valid GitHub account.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Before
image

After
image

Unauthorized
image

Test Scenarios

  1. Case 1: User enters valid GitHub credentials and a valid Organization ID they belong to.

    • Expected Result: The user can log in successfully.
  2. Case 2: User enters valid GitHub credentials but an Organization ID they do not belong to.

    • Expected Result: Access is denied.
  3. Case 3: User enters valid GitHub credentials but does not provide an Organization ID.

    • Expected Result: The user can log in as before, without organization restrictions.
  4. Case 4: User enters invalid GitHub credentials.

    • Expected Result: Access is denied, regardless of the Organization ID.

Summary by CodeRabbit

  • New Features
    • Added a GitHub organization input in the authentication configuration.
    • Integrated organization membership validation into the GitHub OAuth flow with enhanced error messaging.
    • Enhanced configuration options by including an environment-based GitHub organization identifier.

Copy link
Contributor

coderabbitai bot commented Mar 4, 2025

Walkthrough

The changes enhance GitHub authentication by integrating organization membership verification. A new configuration field, GITHUB_ORGANIZATION_ID, has been added to the authentication form (including default values, field definitions, and reset logic) and to the instance configuration. In the backend, a new error code "GITHUB_USER_NOT_IN_ORG": 5122 is introduced for handling organization membership issues. The GitHub OAuth provider now includes new variables, scope adjustments, and a method (is_user_in_organization) to verify if a user belongs to the specified organization, raising an exception if the check fails.

Changes

File(s) Change Summary
admin/app/.../github/form.tsx
apiserver/plane/license/…/configure_instance.py
Added new GitHub organization configuration using GITHUB_ORGANIZATION_ID: introduced in form default values, field definitions, reset logic, and as a config key sourced from environment variables.
apiserver/plane/authentication/adapter/error.py
apiserver/plane/authentication/provider/oauth/github.py
Included organizational verification changes: added error code "GITHUB_USER_NOT_IN_ORG": 5122 and enhanced GitHubOAuthProvider with new variables, scope extension, and a method to check user organization membership, raising an exception on failure.

Sequence Diagram(s)

Loading
sequenceDiagram
    participant User
    participant OAuthProvider as GitHubOAuthProvider
    participant GitHubAPI as OrgMembershipEndpoint
    User->>OAuthProvider: Initiate OAuth login
    OAuthProvider->>GitHubAPI: GET /orgs/{org}/members/{username}
    alt Membership confirmed (200 OK)
        GitHubAPI-->>OAuthProvider: Membership verified
        OAuthProvider->>User: Authentication Success
    else Membership not confirmed
        GitHubAPI-->>OAuthProvider: Membership denied
        OAuthProvider->>User: Raise AuthenticationException (5122)
    end

Poem

Hopping in code with joyful glee,
I’ve added fields for orgs, you see.
API calls dance and errors flee,
With GitHub checks, we’re bug-free!
Carrots and commits — a rabbit’s jubilee!

✨ Finishing Touches
  • 📝 Generate Docstrings

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 generate docstrings to generate docstrings for this 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
admin/app/authentication/github/form.tsx (1)

97-109: Improve description for GitHub Organization ID field.

The field is correctly added and marked as optional, but the description could be more helpful for users.

Consider updating the description to provide more context about what this field is for and how to obtain the organization ID:

      description: (
        <>
-          The organization github ID.
+          Optional: Enter your GitHub Organization ID to restrict login to members of this organization. 
+          When provided, only users who belong to this organization will be allowed to sign in. 
+          You can find your Organization ID in your GitHub organization settings or via the GitHub API.
        </>
      ),
apiserver/plane/authentication/provider/oauth/github.py (1)

21-21: Remove extraneous f-string prefix.

The org_membership_url doesn't contain any placeholders but is defined as an f-string.

-    org_membership_url = f"https://api.github.com/orgs"
+    org_membership_url = "https://api.github.com/orgs"
🧰 Tools
🪛 Ruff (0.8.2)

21-21: f-string without any placeholders

Remove extraneous f prefix

(F541)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80198f5 and c8d962e.

📒 Files selected for processing (4)
  • admin/app/authentication/github/form.tsx (3 hunks)
  • apiserver/plane/authentication/adapter/error.py (1 hunks)
  • apiserver/plane/authentication/provider/oauth/github.py (4 hunks)
  • apiserver/plane/license/management/commands/configure_instance.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
apiserver/plane/authentication/provider/oauth/github.py

21-21: f-string without any placeholders

Remove extraneous f prefix

(F541)


30-30: Line too long (97 > 88)

(E501)


131-131: Line too long (131 > 88)

(E501)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)
🔇 Additional comments (9)
apiserver/plane/authentication/adapter/error.py (1)

39-39: New error code added for GitHub organization membership checks.

This error code will be used when a GitHub user tries to authenticate but doesn't belong to the configured organization.

apiserver/plane/license/management/commands/configure_instance.py (1)

74-79: Configuration option added for GitHub organization validation.

The GitHub organization ID configuration is correctly added to the configuration keys, consistent with other GitHub settings. The value is properly marked as non-encrypted.

admin/app/authentication/github/form.tsx (2)

46-46: Default value added for GitHub organization ID.

This field correctly retrieves the GitHub organization ID from the existing configuration.


167-167: Reset function updated to include GitHub organization ID.

The form reset is correctly handling the new field.

apiserver/plane/authentication/provider/oauth/github.py (5)

26-26: Scope defined for organization membership checks.

Appropriate GitHub API scope added to access organization data.


30-43: GitHub organization ID added to provider configuration.

The configuration is properly retrieved and now includes the organization ID value. The line is slightly over the recommended length limit but remains readable.

🧰 Tools
🪛 Ruff (0.8.2)

30-30: Line too long (97 > 88)

(E501)


55-58: Conditional scope expansion for organization membership checks.

This implementation correctly adds the organization scope only when an organization ID is provided, following the principle of least privilege.


129-133:

✅ Verification successful

GitHub organization membership verification implemented.

The method uses the GitHub API to check if a user belongs to the specified organization. This correctly implements the feature requirement.

However, there's a line length issue and we should validate if the GitHub API endpoint works as expected.


🏁 Script executed:

#!/bin/bash
# Check if the GitHub API endpoint format is correct for org membership
curl -s "https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28" | grep -i "/orgs/{org}/memberships/{username}"

Length of output: 131070


GitHub membership check implementation verified and approved

  • The GitHub API endpoint used—/orgs/{org}/memberships/{username}—matches the documented format as confirmed by the curl/grep output.
  • The method correctly returns a 200 status for valid memberships.
  • There is a minor style concern regarding line length; please refactor or adjust lint settings to resolve the line length warning.
🧰 Tools
🪛 Ruff (0.8.2)

131-131: Line too long (131 > 88)

(E501)


141-147:

✅ Verification successful

Organization membership validation added to authentication flow.

This implementation correctly checks if the user belongs to the specified organization before allowing authentication, raising the appropriate exception if not.

Can you verify that the GitHub API responses are properly handled? Let's check the documentation for the membership API:


🌐 Web query:

What HTTP status codes are returned by GitHub API for organization membership checks?

💡 Result:

The GitHub API returns specific HTTP status codes for organization membership checks, depending on the type of membership being verified. Here's a breakdown of the key endpoints and their responses:

Organization Membership Status Codes

1. General Membership Check
Endpoint: GET /orgs/{org}/memberships/{username}
Status codes:

  • 200 OK: User has an active membership
  • 403 Forbidden: Request lacks proper authorization
  • 404 Not Found: User has no membership record [1]

2. Public Membership Check
Endpoint: GET /orgs/{org}/public_members/{username}
Status codes:

  • 204 No Content: User is a public member
  • 404 Not Found: User isn't a public member [1]

3. Membership State Transitions
When modifying memberships (PUT/PATCH endpoints), additional codes appear:

  • 422 Unprocessable Entity: Invalid request parameters or spam detection
  • 200 OK: Successful membership update [1]
Endpoint Success Code Error Codes
Standard Check GET /memberships 200 403, 404
Public Check GET /public_members 204 404
Modification PUT/PATCH 200 403, 422

These responses help developers handle different scenarios:

  • Handle 404s for missing memberships
  • Use 403 to detect authorization issues
  • Leverage 204's empty body for public member verification

Citations:


GitHub API membership responses are correctly handled.
The implementation correctly interprets GitHub’s HTTP status codes based on the official documentation (e.g., 200/204 for valid membership versus 403/404 for non-membership). The membership check via is_user_in_organization appropriately raises an AuthenticationException when the user isn’t part of the organization, so no additional changes are required.

@sriramveeraghanta sriramveeraghanta changed the title Feat/validate org GitHub feat: validate github organization during OAuth login Mar 5, 2025
@sriramveeraghanta
Copy link
Contributor

Hey @SamuelTR20

Your changes looks good to us, we will be testing it internally. We will merging these changes as a part of the next minor release.

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.

3 participants