-
Notifications
You must be signed in to change notification settings - Fork 3
Add AuthClient for updating login user details and generate proto files #109
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
Conversation
WalkthroughAdds an AuthClient and exposes it on ScalekitClient; introduces new generated protobuf/gRPC modules for WebAuthn, Interceptors, Secrets and related messages; updates multiple protobuf message schemas (user profile renames, connection WebAuthn config, session/device refactor), adjusts RPC signatures and many descriptor option bytes. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ScalekitClient
participant AuthClient
participant CoreClient
participant AuthService as AuthService(gRPC)
Client->>ScalekitClient: instantiate
ScalekitClient->>CoreClient: create core_client
ScalekitClient->>AuthClient: AuthClient(core_client)
Client->>AuthClient: update_login_user_details(conn_id, login_req_id, user)
AuthClient->>AuthClient: validate user Mapping
AuthClient->>AuthClient: ParseDict -> User proto
AuthClient->>CoreClient: grpc_exec(AuthServiceStub.UpdateLoginUserDetails, request)
AuthService-->>CoreClient: Empty response
CoreClient-->>AuthClient: return result
AuthClient-->>Client: return result
sequenceDiagram
participant User
participant WebAuthnClient as WebAuthnService(gRPC)
participant Server
User->>WebAuthnClient: BeginRegistration(req)
WebAuthnClient-->>User: BeginRegistrationResponse (challenge)
User->>WebAuthnClient: FinishRegistration(resp)
WebAuthnClient->>Server: FinishRegistration(request) via gRPC
Server-->>WebAuthnClient: FinishRegistrationResponse
WebAuthnClient-->>User: registration success
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas needing extra attention:
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-11-13T11:57:12.824ZApplied to files:
🔇 Additional comments (3)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
scalekit/v1/sessions/sessions_pb2.pyi (1)
81-108: Do not reuse deprecated field numbers for new wire types.
devicenow occupies tag 12 andlast_active_attag 13, but onmainthose tags belonged to the removedinitial_*/latest_*string fields (e.g.,INITIAL_USER_AGENT_FIELD_NUMBER = 12). Reusing the same numbers with a different type/name is a wire-format breaking change: old envelopes encoded with tag 12 as a string will fail to parse as aDeviceDetailsmessage. Please reserve the retired field numbers (e.g.,reserved 12 to 27;) and allocate fresh tags for the new fields (e.g., 40, 41) in the.proto, then regenerate these stubs.scalekit/v1/environments/environments_pb2.py (1)
168-185: Restore legacy GET portal customization bindingThe new HTTP annotation now exposes
GetPortalCustomizationonly via/api/v1/portal_customizations(plus the literal/-/variant). The previous binding/api/v1/environments/{id}/portal_customizationsis gone, so existing clients will start receiving 404s once this ships. Please keep the original{id}route (either as the primary rule or anadditional_bindings) so we do not break deployed integrations that still call the environment-scoped URL.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (37)
scalekit/auth.py(1 hunks)scalekit/client.py(2 hunks)scalekit/v1/auditlogs/auditlogs_pb2.py(2 hunks)scalekit/v1/auditlogs/auditlogs_pb2.pyi(4 hunks)scalekit/v1/auth/auth_pb2.py(3 hunks)scalekit/v1/auth/auth_pb2.pyi(4 hunks)scalekit/v1/auth/auth_pb2_grpc.py(6 hunks)scalekit/v1/auth/passwordless_pb2.py(3 hunks)scalekit/v1/auth/webauthn_pb2.py(1 hunks)scalekit/v1/auth/webauthn_pb2.pyi(1 hunks)scalekit/v1/auth/webauthn_pb2_grpc.py(1 hunks)scalekit/v1/clients/clients_pb2.pyi(1 hunks)scalekit/v1/commons/commons_pb2.py(4 hunks)scalekit/v1/commons/commons_pb2.pyi(2 hunks)scalekit/v1/connected_accounts/connected_accounts_pb2.py(3 hunks)scalekit/v1/connected_accounts/connected_accounts_pb2.pyi(0 hunks)scalekit/v1/connected_accounts/connected_accounts_pb2_grpc.py(0 hunks)scalekit/v1/connections/connections_pb2.pyi(11 hunks)scalekit/v1/connections/connections_pb2_grpc.py(4 hunks)scalekit/v1/domains/domains_pb2.py(3 hunks)scalekit/v1/environments/environments_pb2.py(5 hunks)scalekit/v1/environments/environments_pb2.pyi(4 hunks)scalekit/v1/events/events_pb2.py(3 hunks)scalekit/v1/events/events_pb2.pyi(5 hunks)scalekit/v1/interceptors/interceptors_pb2.py(1 hunks)scalekit/v1/interceptors/interceptors_pb2.pyi(1 hunks)scalekit/v1/interceptors/interceptors_pb2_grpc.py(1 hunks)scalekit/v1/members/members_pb2.py(4 hunks)scalekit/v1/members/members_pb2.pyi(1 hunks)scalekit/v1/secrets/secrets_pb2.py(1 hunks)scalekit/v1/secrets/secrets_pb2.pyi(1 hunks)scalekit/v1/secrets/secrets_pb2_grpc.py(1 hunks)scalekit/v1/sessions/sessions_pb2.py(2 hunks)scalekit/v1/sessions/sessions_pb2.pyi(6 hunks)scalekit/v1/users/users_pb2.pyi(4 hunks)scalekit/v1/workspaces/workspaces_pb2.py(4 hunks)tests/.env.example(0 hunks)
💤 Files with no reviewable changes (3)
- scalekit/v1/connected_accounts/connected_accounts_pb2.pyi
- tests/.env.example
- scalekit/v1/connected_accounts/connected_accounts_pb2_grpc.py
🧰 Additional context used
🧬 Code graph analysis (13)
scalekit/v1/connections/connections_pb2_grpc.py (1)
scalekit/v1/connections/connections_pb2.pyi (2)
UpdateConnectionUserManagementSettingsRequest(193-199)UpdateConnectionUserManagementSettingsResponse(207-211)
scalekit/client.py (1)
scalekit/auth.py (1)
AuthClient(10-80)
scalekit/v1/auth/auth_pb2.pyi (1)
scalekit/v1/connections/connections_pb2.pyi (2)
ConnectionType(86-97)PasswordlessType(43-48)
scalekit/v1/secrets/secrets_pb2_grpc.py (1)
scalekit/v1/secrets/secrets_pb2.pyi (10)
CreateSecret(44-50)CreateSecretRequest(38-42)CreateSecretResponse(52-56)RotateSecretRequest(58-62)RotateSecretResponse(64-68)GetSecretRequest(70-76)GetSecretResponse(78-82)ListSecretsRequest(84-88)ListSecretsResponse(96-100)DeleteSecretRequest(90-94)
scalekit/v1/auth/webauthn_pb2_grpc.py (1)
scalekit/v1/auth/webauthn_pb2.pyi (16)
BeginRegistrationRequest(17-19)BeginRegistrationResponse(21-25)FinishRegistrationRequest(27-43)FinishRegistrationResponse(45-49)BeginAuthenticationRequest(51-55)BeginAuthenticationResponse(57-63)FinishAuthenticationRequest(65-79)FinishAuthenticationResponse(93-101)ListCredentialsRequest(121-125)ListCredentialsResponse(127-133)DeleteCredentialRequest(135-139)DeleteCredentialResponse(141-147)UpdateCredentialRequest(167-173)UpdateCredentialResponse(175-179)GetRelatedOriginsRequest(263-265)GetRelatedOriginsResponse(267-271)
scalekit/auth.py (3)
scalekit/core.py (2)
CoreClient(26-175)grpc_exec(151-175)scalekit/v1/auth/auth_pb2_grpc.py (1)
AuthServiceStub(9-77)scalekit/v1/auth/auth_pb2.pyi (1)
UpdateLoginUserDetailsRequest(210-218)
scalekit/v1/interceptors/interceptors_pb2_grpc.py (1)
scalekit/v1/interceptors/interceptors_pb2.pyi (15)
CreateInterceptor(71-93)CreateInterceptorRequest(169-173)CreateInterceptorResponse(175-179)GetInterceptorRequest(181-185)GetInterceptorResponse(187-191)ListInterceptorsRequest(205-215)ListInterceptorsResponse(217-227)UpdateInterceptor(237-257)UpdateInterceptorRequest(229-235)UpdateInterceptorResponse(259-263)DeleteInterceptorRequest(265-269)EnableInterceptorRequest(193-197)DisableInterceptorRequest(199-203)TestInterceptorRequest(279-285)TestInterceptorResponse(287-295)
scalekit/v1/secrets/secrets_pb2.pyi (1)
scalekit/v1/secrets/secrets_pb2_grpc.py (2)
CreateSecret(48-52)CreateSecret(117-131)
scalekit/v1/auth/auth_pb2_grpc.py (1)
scalekit/v1/auth/auth_pb2.pyi (2)
GetAuthErrorRequest(258-262)GetAuthErrorResponse(264-270)
scalekit/v1/events/events_pb2.pyi (2)
scalekit/v1/users/users_pb2.pyi (1)
Permission(489-499)scalekit/v1/roles/roles_pb2.pyi (1)
Permission(284-296)
scalekit/v1/members/members_pb2.pyi (1)
scalekit/v1/users/users_pb2.pyi (8)
MetadataEntry(20-26)MetadataEntry(67-73)MetadataEntry(230-236)MetadataEntry(245-251)MetadataEntry(292-298)MetadataEntry(313-319)MetadataEntry(357-363)UpdateUserProfile(355-397)
scalekit/v1/connections/connections_pb2.pyi (1)
scalekit/v1/domains/domains_pb2.pyi (1)
Domain(168-190)
scalekit/v1/interceptors/interceptors_pb2.pyi (2)
scalekit/v1/interceptors/interceptors_pb2_grpc.py (4)
CreateInterceptor(63-67)CreateInterceptor(165-179)UpdateInterceptor(81-85)UpdateInterceptor(216-230)scalekit/v1/errdetails/errdetails_pb2.pyi (1)
ValidationErrorInfo(37-50)
🪛 Ruff (0.14.4)
scalekit/v1/connections/connections_pb2_grpc.py
226-226: Unused method argument: request
(ARG002)
scalekit/v1/secrets/secrets_pb2_grpc.py
48-48: Unused method argument: request
(ARG002)
54-54: Unused method argument: request
(ARG002)
60-60: Unused method argument: request
(ARG002)
66-66: Unused method argument: request
(ARG002)
72-72: Unused method argument: request
(ARG002)
scalekit/v1/auth/webauthn_pb2_grpc.py
62-62: Unused method argument: request
(ARG002)
68-68: Unused method argument: request
(ARG002)
74-74: Unused method argument: request
(ARG002)
80-80: Unused method argument: request
(ARG002)
86-86: Unused method argument: request
(ARG002)
92-92: Unused method argument: request
(ARG002)
98-98: Unused method argument: request
(ARG002)
104-104: Unused method argument: request
(ARG002)
scalekit/auth.py
66-66: Avoid specifying long messages outside the exception class
(TRY003)
scalekit/v1/interceptors/interceptors_pb2_grpc.py
63-63: Unused method argument: request
(ARG002)
69-69: Unused method argument: request
(ARG002)
75-75: Unused method argument: request
(ARG002)
81-81: Unused method argument: request
(ARG002)
87-87: Unused method argument: request
(ARG002)
93-93: Unused method argument: request
(ARG002)
99-99: Unused method argument: request
(ARG002)
105-105: Unused method argument: request
(ARG002)
scalekit/v1/auth/auth_pb2_grpc.py
125-125: Unused method argument: request
(ARG002)
131-131: Unused method argument: request
(ARG002)
🔇 Additional comments (3)
scalekit/v1/workspaces/workspaces_pb2.py (1)
1-196: LGTM! Protobuf code properly regenerated.This file is correctly auto-generated by the protocol buffer compiler. The changes reflect updates to the underlying
.protofile, primarily adding validation options to theCatalogProduct.metadatafield and adjusting serialization boundaries accordingly. The generation appears clean and consistent.scalekit/v1/connected_accounts/connected_accounts_pb2.py (1)
1-209: Based on my investigation, this is a protocol buffer generated file that should not be manually edited. The file header correctly states "DO NOT EDIT!" and all changes are properly generated binary serialized data and offset calculations—no manual code modifications are present.The actual review should focus on the
.protosource file, which could not be located at the expected pathscalekit/v1/connected_accounts/connected_accounts.proto. Since the Python file was regenerated from the proto schema, verifying the proto file changes and confirming the regeneration process used the correct protobuf compiler (version 5.26.1 matches the file header) is important.Auto-generated file: verify the .proto source and generation process.
This is a protocol buffer generated file (
_pb2.pysuffix indicates protobuf version 2). All changes consist of auto-generated binary serialized descriptors and offset integers—no manual code modifications were made to this file.Since this file is machine-generated:
- Manual review of binary data is not meaningful
- The actual changes belong in the source
.protofile- Verify the
.protofile was modified appropriately and this file was regenerated usingprotocwith Protobuf Python Version 5.26.1Before approving, confirm:
- The
.protosource file (located elsewhere, not atscalekit/v1/connected_accounts/connected_accounts.proto) has reviewed changes- This file was regenerated using the correct protoc command with compatible plugins
- Codebase is in a consistent state with all related
_pb2.pyfiles regeneratedscalekit/v1/auth/passwordless_pb2.py (1)
1-98: Auto-generated proto files regenerated correctly via buf.build.This file is properly auto-generated by the protocol buffer compiler using buf.build configuration. The modifications across all lines are consistent with the batch regeneration workflow:
- Protobuf version in header (5.26.1) matches setup.py requirement constraint (>=5.26.1,<6.0.0)
- buf.gen.yaml is configured with matching protoc v26.1 plugins
- All related pb2.py files across the codebase were regenerated together
- Git history confirms intentional regeneration ("Generate proto files" commit)
The proto source files are managed externally via buf.build, and all changes here are legitimate serialization output from that regeneration process.
There was a problem hiding this 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
♻️ Duplicate comments (2)
scalekit/auth.py (2)
77-80: This issue was already identified in a previous review.The past review correctly identified that
.with_callreturns a tuple instead of the documentedEmptyreturn type. Please apply the suggested fix from the previous review comment.
27-59: Fix return type inconsistency: annotation vs docstring vs implementation.The return type annotation states
-> Empty, but the docstring (lines 57-58) claims this returns "Tuple of (Empty response, grpc.Call metadata)". This inconsistency stems from the use of.with_callon line 78, which the past review already flagged as a critical issue. Once.with_callis removed (per the existing review comment on lines 77-80), update the docstring to reflect that onlyEmptyis returned, not a tuple.Apply this diff to fix the docstring:
- :returns: - Tuple of (Empty response, grpc.Call metadata) + :returns: + Empty
🧹 Nitpick comments (1)
scalekit/auth.py (1)
62-66: Consider extracting exception message to a custom exception class.The exception message is inline, which Ruff flags as TRY003. While not critical, defining a custom exception class with the message improves consistency and testability.
Based on static analysis hints.
Example refactor:
class InvalidUserDataError(TypeError): """Raised when user data is not a mapping-compatible object.""" def __init__(self): super().__init__("user must be a mapping-compatible object")Then on line 66:
- raise TypeError("user must be a mapping-compatible object") + raise InvalidUserDataError()
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
scalekit/auth.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
scalekit/auth.py (3)
scalekit/core.py (2)
CoreClient(26-175)grpc_exec(151-175)scalekit/v1/auth/auth_pb2_grpc.py (1)
AuthServiceStub(9-77)scalekit/v1/auth/auth_pb2.pyi (1)
UpdateLoginUserDetailsRequest(210-218)
🪛 Ruff (0.14.4)
scalekit/auth.py
66-66: Avoid specifying long messages outside the exception class
(TRY003)
🔇 Additional comments (3)
scalekit/auth.py (3)
1-8: LGTM!The imports are well-organized and all are utilized in the implementation.
10-26: LGTM!The constructor correctly initializes the AuthServiceStub with the secure gRPC channel from CoreClient, following the SDK's established pattern.
68-75: LGTM!The use of
ParseDictcorrectly transforms the dictionary into a protobufUsermessage, and the request is properly constructed with all required fields.
Summary by CodeRabbit
New Features
Updates