Skip to content

Commit

Permalink
Make the deprecated PAT name annotation optional
Browse files Browse the repository at this point in the history
Signed-off-by: ivinokur <ivinokur@redhat.com>
  • Loading branch information
vinokurig committed Aug 5, 2024
1 parent 370c40f commit 14e5574
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ public void store(PersonalAccessToken personalAccessToken)
.put(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID,
personalAccessToken.getScmTokenId())
.put(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
personalAccessToken.getScmTokenName())
.build())
.withLabels(SECRET_LABELS)
.build();
Expand Down Expand Up @@ -226,7 +223,9 @@ private List<PersonalAccessToken> doGetPersonalAccessTokens(
PersonalAccessToken personalAccessToken =
new PersonalAccessToken(
personalAccessTokenParams.getScmProviderUrl(),
getScmProviderName(personalAccessTokenParams),
getScmProviderName(
personalAccessTokenParams.getScmProviderName(),
personalAccessTokenParams.getScmTokenName()),
secretAnnotations.get(ANNOTATION_CHE_USERID),
personalAccessTokenParams.getOrganization(),
scmUsername.get(),
Expand Down Expand Up @@ -262,13 +261,12 @@ private List<PersonalAccessToken> doGetPersonalAccessTokens(
* This is used to support back compatibility with the old token secrets, which do not have the
* 'che.eclipse.org/scm-provider-name' annotation.
*
* @param params the parameters of the personal access token
* @param providerName the name of the SCM provider
* @param tokenName the name of the token
* @return the name of the SCM provider
*/
private String getScmProviderName(PersonalAccessTokenParams params) {
return isNullOrEmpty(params.getScmProviderName())
? params.getScmTokenName()
: params.getScmProviderName();
private String getScmProviderName(@Nullable String providerName, String tokenName) {
return isNullOrEmpty(providerName) ? tokenName : providerName;
}

private boolean deleteSecretIfMisconfigured(Secret secret) throws InfrastructureException {
Expand All @@ -278,8 +276,8 @@ private boolean deleteSecretIfMisconfigured(Secret secret) throws Infrastructure
LOG.debug("SCM server URL: {}", configuredScmServerUrl);
String configuredCheUserId = secretAnnotations.get(ANNOTATION_CHE_USERID);
LOG.debug("Che user ID: {}", configuredCheUserId);
String configuredOAuthProviderName =
secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME);
String providerName = secretAnnotations.get(ANNOTATION_SCM_PROVIDER_NAME);
String configuredOAuthProviderName = getScmProviderName(providerName, getTokenName(secret));
LOG.debug("OAuth provider name: {}", configuredOAuthProviderName);

// if any of the required annotations is missing, the secret is not valid
Expand All @@ -298,12 +296,15 @@ private boolean deleteSecretIfMisconfigured(Secret secret) throws Infrastructure
return false;
}

private String getTokenName(Secret secret) {
String name = secret.getMetadata().getName();
return name.substring(name.lastIndexOf("-") + 1);
}

private PersonalAccessTokenParams secret2PersonalAccessTokenParams(Secret secret) {
Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations();

String token = new String(Base64.getDecoder().decode(secret.getData().get("token"))).trim();
String configuredOAuthTokenName =
secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME);
String configuredTokenId = secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID);
String configuredScmOrganization = secretAnnotations.get(ANNOTATION_SCM_ORGANIZATION);
String configuredScmServerUrl = secretAnnotations.get(ANNOTATION_SCM_URL);
Expand All @@ -312,7 +313,7 @@ private PersonalAccessTokenParams secret2PersonalAccessTokenParams(Secret secret
return new PersonalAccessTokenParams(
trimEnd(configuredScmServerUrl, '/'),
configuredScmProviderName,
configuredOAuthTokenName,
getTokenName(secret),
configuredTokenId,
token,
configuredScmOrganization);
Expand All @@ -330,7 +331,9 @@ private boolean isSecretMatchesSearchCriteria(
secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME);

return (configuredCheUserId.equals(cheUser.getUserId()))
&& (oAuthProviderName == null || oAuthProviderName.equals(configuredOAuthProviderName))
&& (oAuthProviderName == null
|| oAuthProviderName.equals(configuredOAuthProviderName)
|| oAuthProviderName.equals(getTokenName(secret)))
&& (scmServerUrl == null
|| trimEnd(configuredScmServerUrl, '/').equals(trimEnd(scmServerUrl, '/')));
}
Expand Down Expand Up @@ -381,8 +384,7 @@ private void removePreviousTokensIfPresent(Subject subject, String scmServerUrl)

@Override
public void storeGitCredentials(String scmServerUrl)
throws UnsatisfiedScmPreconditionException, ScmConfigurationPersistenceException,
ScmCommunicationException, ScmUnauthorizedException {
throws UnsatisfiedScmPreconditionException, ScmConfigurationPersistenceException {
Subject subject = EnvironmentContext.getCurrent().getSubject();
Optional<PersonalAccessToken> tokenOptional = get(subject, scmServerUrl);
if (tokenOptional.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ public void shouldTrimBlankCharsInToken() throws Exception {

ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withCreationTimestamp("2021-07-01T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user",
Expand Down Expand Up @@ -186,10 +187,11 @@ public void testGetTokenFromNamespace() throws Exception {

ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_1")
.withCreationTimestamp("2021-07-01T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand All @@ -198,10 +200,11 @@ public void testGetTokenFromNamespace() throws Exception {
.build();
ObjectMeta meta2 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_2")
.withCreationTimestamp("2021-07-02T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand All @@ -210,10 +213,11 @@ public void testGetTokenFromNamespace() throws Exception {
.build();
ObjectMeta meta3 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_3")
.withCreationTimestamp("2021-07-03T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user2",
Expand Down Expand Up @@ -257,9 +261,10 @@ public void shouldGetTokenFromASecretWithSCMUsername() throws Exception {

ObjectMeta metaData =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand Down Expand Up @@ -302,6 +307,52 @@ public void shouldGetTokenFromASecretWithoutSCMUsername() throws Exception {

ObjectMeta metaData =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
ANNOTATION_SCM_URL,
"http://host1"))
.build();

Secret secret = new SecretBuilder().withMetadata(metaData).withData(data).build();

when(secrets.get(any(LabelSelector.class))).thenReturn(singletonList(secret));

// when
Optional<PersonalAccessToken> tokenOptional =
personalAccessTokenManager.get(
new SubjectImpl("user", "user1", "t1", false), "http://host1");

// then
assertTrue(tokenOptional.isPresent());
assertEquals(tokenOptional.get().getCheUserId(), "user1");
assertEquals(tokenOptional.get().getScmProviderUrl(), "http://host1");
assertEquals(tokenOptional.get().getToken(), "token1");
}

// TODO remove this test after removing the deprecated scm-personal-access-token-name annotation
@Test
public void shouldGetTokenFromASecretWithTokenNameButWithoutProviderAnnotation() throws Exception {

KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test");
when(namespaceFactory.list()).thenReturn(singletonList(meta));
KubernetesNamespace kubernetesnamespace = Mockito.mock(KubernetesNamespace.class);
KubernetesSecrets secrets = Mockito.mock(KubernetesSecrets.class);
when(namespaceFactory.access(eq(null), eq(meta.getName()))).thenReturn(kubernetesnamespace);
when(kubernetesnamespace.secrets()).thenReturn(secrets);
when(scmPersonalAccessTokenFetcher.getScmUsername(any(PersonalAccessTokenParams.class)))
.thenReturn(Optional.of("user"));

Map<String, String> data =
Map.of("token", Base64.getEncoder().encodeToString("token1".getBytes(UTF_8)));

ObjectMeta metaData =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
Expand Down Expand Up @@ -347,10 +398,11 @@ public void testGetTokenFromNamespaceWithTrailingSlashMismatch() throws Exceptio

ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_1")
.withCreationTimestamp("2021-07-01T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand All @@ -359,10 +411,11 @@ public void testGetTokenFromNamespaceWithTrailingSlashMismatch() throws Exceptio
.build();
ObjectMeta meta2 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_2")
.withCreationTimestamp("2021-08-01T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand Down Expand Up @@ -406,10 +459,11 @@ public void shouldDeleteMisconfiguredTokensOnGet() throws Exception {
Map.of("token", Base64.getEncoder().encodeToString("token1".getBytes(UTF_8)));
ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withNamespace("test")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1"))
Expand Down Expand Up @@ -443,9 +497,10 @@ public void shouldDeleteInvalidTokensOnGet() throws Exception {
Map.of("token", Base64.getEncoder().encodeToString("token1".getBytes(UTF_8)));
ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand Down Expand Up @@ -491,10 +546,11 @@ public void shouldReturnFirstValidTokenAndDeleteTheOlderOne() throws Exception {
Map.of("token", Base64.getEncoder().encodeToString("token2".getBytes(UTF_8)));
ObjectMeta meta1 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_1")
.withCreationTimestamp("2021-07-01T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand All @@ -505,10 +561,11 @@ public void shouldReturnFirstValidTokenAndDeleteTheOlderOne() throws Exception {
.build();
ObjectMeta meta2 =
new ObjectMetaBuilder()
.withName(NAME_PATTERN + "token_name_2")
.withCreationTimestamp("2021-07-02T12:00:00Z")
.withAnnotations(
Map.of(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME,
ANNOTATION_SCM_PROVIDER_NAME,
"github",
ANNOTATION_CHE_USERID,
"user1",
Expand Down

0 comments on commit 14e5574

Please sign in to comment.