feat: oidc domain registration and verification #7745
Conversation
Summary of ChangesHello @n1ru4l, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant feature for OIDC integrations, enabling organizations to register and verify domains. This enhancement aims to improve the user experience by allowing automatic user provisioning and bypassing email verification for users from verified domains. It involves comprehensive changes across the backend, including database schema updates, new API endpoints, and a dedicated data store, as well as a complete overhaul of the frontend SSO settings interface to expose these new capabilities. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
💻 Website PreviewThe latest changes are available as preview in: https://pr-7745.hive-landing-page.pages.dev |
There was a problem hiding this comment.
Code Review
This pull request introduces OIDC domain registration and verification, a significant new feature. However, critical flaws exist in the authorization logic, where OIDC integration IDs are incorrectly used instead of organization IDs for permission checks, potentially breaking the feature for legitimate users. Additionally, a database integrity issue was identified in the domain creation logic due to a missing required column in an INSERT statement. Other issues include a broken GraphQL query, typos, and a faulty regex for domain validation. Please review the detailed comments for suggestions on how to fix these issues.
packages/web/app/src/components/organization/settings/single-sign-on/single-sign-on-subpage.tsx
Show resolved
Hide resolved
...b/app/src/components/organization/settings/single-sign-on/oidc-integration-configuration.tsx
Outdated
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts
Outdated
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts
Outdated
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts
Outdated
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integration.store.ts
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integration.store.ts
Outdated
Show resolved
Hide resolved
packages/services/api/src/modules/oidc-integrations/providers/oidc-integrations.provider.ts
Outdated
Show resolved
Hide resolved
|
🐋 This PR was built and pushed to the following Docker images: Targets: Platforms: Image Tag: |
aa30811 to
b8eda49
Compare
c2835ae to
65286f5
Compare
310c1c9 to
b36594d
Compare
fc23191 to
427e602
Compare
39a2e0c to
b142cae
Compare
| - name: disable rate limiting | ||
| uses: mikefarah/yq@4839dbbf80445070a31c7a9c1055da527db2d5ee # v4.44.6 | ||
| with: | ||
| cmd: | ||
| yq -i '.services.server.environment.SUPERTOKENS_RATE_LIMIT = "0"' | ||
| docker/docker-compose.community.yml | ||
|
|
There was a problem hiding this comment.
This value now provided via docker/docker-compose.end2end.yml
|
|
||
| cy.get('div[role="dialog"]').find('button[type="submit"]').last().click(); | ||
| Cypress.Commands.add('createOIDCIntegration', () => { | ||
| const isLocal = Cypress.env('RUN_AGAINST_LOCAL_SERVICES') == '1'; |
There was a problem hiding this comment.
This now works correctly on both CI and local
| cy.contains('Create Organization'); | ||
| cy.contains('Verify your email address'); | ||
|
|
||
| const email = user.email; | ||
| return cy.task('getEmailConfirmationLink', email).then((url: string) => { | ||
| cy.visit(url); | ||
| cy.contains('Success!'); | ||
| cy.get('[data-button-verify-email-continue]').click(); | ||
| cy.contains('Create Organization'); | ||
| }); |
There was a problem hiding this comment.
The end2end tests now include email verification (when needed).
| }, | ||
| { | ||
| "SubjectId": "3", | ||
| "Username": "test-user-3", | ||
| "Password": "password", | ||
| "Claims": [ | ||
| { | ||
| "Type": "name", | ||
| "Value": "Hive Bro", | ||
| "ValueType": "string" | ||
| }, | ||
| { | ||
| "Type": "email", | ||
| "Value": "hive.bro@buzzcheck.dev", | ||
| "ValueType": "string" | ||
| } | ||
| ] |
There was a problem hiding this comment.
I added a user with the @buzzcheck.dev email, so we can test the full flow including DNS querying from our dev environment in a e2e test
| workflows: | ||
| ports: | ||
| - '3014:3014' | ||
| environment: | ||
| EMAIL_PROVIDER: mock | ||
|
|
||
| redis: | ||
| ports: | ||
| - '6379:6379' | ||
|
|
||
| server: | ||
| environment: | ||
| SUPERTOKENS_RATE_LIMIT: '0' | ||
| AUTH_REQUIRE_EMAIL_VERIFICATION: '1' |
There was a problem hiding this comment.
these are needed for e2e tests and fixtures/tasks to work.
| } | ||
|
|
||
| return { | ||
| async purgeOIDCDomains() { |
There was a problem hiding this comment.
simple cleanup helper to run before specific test cases
| TRUNCATE "oidc_integration_domains" | ||
| `); | ||
| }, | ||
| async forgeOIDCDNSChallenge(orgSlug: string) { |
There was a problem hiding this comment.
This one overwrites a DNS challenge record to a fixed value, so we can test the verification flow.
| """ | ||
| List of domains registered with this OIDC integration. | ||
| """ | ||
| registeredDomains: [OIDCIntegrationDomain!]! |
There was a problem hiding this comment.
Did not make this a Connection as the list will be 1 domain per org in 99.999999% of cases.
There was a problem hiding this comment.
Makes sense.
Should we make the OIDCIntegrationDomain nullable to support partial query resolution in case of error?
| }); | ||
|
|
||
| if (oidcConfig?.requireInvitation) { | ||
| if (oidcConfig) { |
There was a problem hiding this comment.
This previously was ONLY assigning the invitation role, if the requireInvitation flag was set. I think that is a bit confusing, so I changed it to always assign the invitation role if it exists.
There was a problem hiding this comment.
I added a way to filter the emails by date, so it is easier to only get the emails of the current test run (e2e)
There was a problem hiding this comment.
Here I exposed the seed functions to the cypress test as tasks. The API is cumbersome, but it works...
There was a problem hiding this comment.
A lot of noise in these files...
Most important things:
- We use the seed to speed up tests a bit and not do a type/button click sign up every time
- Added a new test for verifying the domain registration flow.
jdolle
left a comment
There was a problem hiding this comment.
Just minor comments on this functionality.
We discussed possible future improvements already via slack so I've not included those comments again here.
| if (rawChallenge === null) { | ||
| return null; | ||
| } | ||
| return ChallengePayloadModel.parse(JSON.parse(rawChallenge)); |
There was a problem hiding this comment.
Minor: Consider handling the unlikely case of if the rawChallenge is corrupt and isnt valid JSON
|
|
||
| const key = `hive:oidcDomainChallenge:${domainId}`; | ||
| await this.redis.set(key, JSON.stringify(challenge)); | ||
| await this.redis.expire(key, 60 * 60 * 24); |
There was a problem hiding this comment.
You can use the ex option on set to combine these two commands.
await redis.set(key, JSON.stringify(challenge), 'EX', 60 * 60 * 24);
| """ | ||
| List of domains registered with this OIDC integration. | ||
| """ | ||
| registeredDomains: [OIDCIntegrationDomain!]! |
There was a problem hiding this comment.
Makes sense.
Should we make the OIDCIntegrationDomain nullable to support partial query resolution in case of error?
| )} | ||
| {stepper.switch({ | ||
| 'step-1-general': () => ( | ||
| <Form {...form}> |
There was a problem hiding this comment.
minor -- to help keep the component logic easy to follow, it'd be helpful to move each step into its own component.
Background
Closes #7735
Description
This PR addresses the following things:
buzzcheck.devA full run through of the PR can be found on on this internal Slack video: https://guild-oss.slack.com/archives/CAY2119MX/p1772221874651489?thread_ts=1772218438.245559&cid=CAY2119MX
Originally I wanted to have #7763 as part of the scope of this PR. But it got a bit bigger, so I will do that in a follow up PR.
Here are some screenshots of the functionality, but I recommend to watch the video instead.
Rollout Strategy
This change is fully backwards-compatible. I will probably manually create records for our known and trusted enterprise users to spare them some time running through the DNS challenge. In case we would need to rollback the pre-existing functionality continues to work. The only regression would be that some people need to verify their email again.
Checklist