Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: vinokurig The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
fb69994 to
7a2aa30
Compare
Persist OAuth refresh tokens and expiration times in Kubernetes secrets alongside access tokens, enabling token refresh without re-authorization after server restarts. Adds a POST /oauth/refresh endpoint, updates the OAuthToken DTO, PersonalAccessToken, and PersonalAccessTokenParams with refreshToken/expiresIn fields, and restores in-memory credentials from persisted secrets when the credential store is empty. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
| public static final String REFRESH_TOKEN_DATA_FIELD = "refresh-token"; | ||
|
|
||
| /** Kubernetes secret data field key for the token expiration time in seconds. */ | ||
| public static final String EXPIRES_IN_DATA_FIELD = "expires-in"; |
There was a problem hiding this comment.
Is it better to move to annotation?
| */ | ||
| @POST | ||
| @Path("refresh") | ||
| public void refresh(@Required @QueryParam("oauth_provider") String oauthProvider) |
There was a problem hiding this comment.
I can see that provider url is not considered.
What if we have different urls for a single provider, like GitHub
There was a problem hiding this comment.
done, switched to provider_url parameter
| token.getRefreshToken(), | ||
| token.getExpiresIn()); | ||
| personalAccessTokenManager.store(personalAccessToken); | ||
| gitCredentialManager.createOrReplace(personalAccessToken); |
There was a problem hiding this comment.
I think removePreviousTokenSecretsIfPresent is missed.
BTW, can we resue forceRefreshPersonalAccessToken(String scmServerUrl) ?
There was a problem hiding this comment.
nice catch, switched to forceRefreshPersonalAccessToken(String scmServerUrl)
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
…en flow Handle providers that omit `expires_in` and issue no refresh token: * `OAuthAuthenticator`: extract `newOAuthToken(Credential)` and set the expiration only when the credential provides one, since `OAuthToken#withExpiresIn` takes a primitive. * `EmbeddedOAuthAPI`: fall back to 0 when the token response has no `expires_in`. * `KubernetesPersonalAccessTokenManager`: only write the `refresh-token` secret field when a refresh token is present. Add tests for each case, including a new `OAuthAuthenticatorTest` for the OAuth2 authenticator. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Docker image build succeeded: quay.io/eclipse/che-server:pr-1047 kubectl patch commandkubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/cheServer/deployment", "value": {containers: [{image: "quay.io/eclipse/che-server:pr-1047", name: che}]}}]" |
|
/retest |
| * Refreshes the OAuth token for the given provider and persists the updated token as a Kubernetes | ||
| * secret and git credential, so that subsequent SCM operations use the new access token. | ||
| * | ||
| * @param providerUrl URL of the OAuth provider instance the token belongs to. Optional, if not |
There was a problem hiding this comment.
providerUrl has @Required annotation
| personalAccessToken.getScmTokenName()) | ||
| .put( | ||
| ANNOTATION_SCM_TOKEN_EXPIRES_IN, | ||
| String.valueOf(personalAccessToken.getExpiresIn())) |
There was a problem hiding this comment.
I think it updates every PAT and most all of them will have 0
It misleads since 0 means expires immediately.
Should we check if personalAccessToken.getExpiresIn()) > 0 before adding annotation?
| } else { | ||
| throw new UnauthorizedException( | ||
| "OAuth token for user " + subject.getUserId() + " was not found"); | ||
| // Credential was not found in the in-memory store (e.g. after server restart). |
There was a problem hiding this comment.
I think it is a new workflow, can we have validation steps in the description of the issue?
| new TokenResponse() | ||
| .setAccessToken(token.getToken()) | ||
| .setRefreshToken(token.getRefreshToken()) | ||
| .setExpiresInSeconds(token.getExpiresIn()); |
There was a problem hiding this comment.
I wouldn't put 0 which is a default value.
Instead it is better to check if value > 0
|
@vinokurig: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
What does this PR do?
Persist OAuth refresh tokens and expiration times in Kubernetes secrets alongside access tokens, enabling token refresh without re-authorization after server restarts.
Adds a POST
/oauth/refreshendpoint, updates the OAuthToken DTO, PersonalAccessToken, and PersonalAccessTokenParams with refreshToken/expiresIn fields, and restores in-memory credentials from persisted secrets when the credential store is empty.Screenshot/screencast of this PR
What issues does this PR fix or reference?
https://redhat.atlassian.net/browse/CRW-4121
How to test this PR?
quay.io/eclipse/che-server:pr-1047che-serverpod to clear the oauth data from theche-serverpod memory.<che host url>/api/oauth/refresh?oauth_provider=gitlab&provider_url=https://gitlab.comtokenand therefresh-tokendata must be refreshed.PR Checklist
As the author of this Pull Request I made sure that:
What issues does this PR fix or referenceandHow to test this PRcompletedRelease Notes
Reviewers
Reviewers, please comment how you tested the PR when approving it.