Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,25 @@ che.auth.access_denied_error_page=/error-oauth
che.auth.reserved_user_names=

# Configuration of the Azure DevOps Service OAuth2 client. Used to obtain personal access tokens.
# Location of the file with Azure DevOps Service Application ID.
# Location of the file with Microsoft OIDC Directory (tenant) ID.
che.oauth2.azure.devops.tenantid_filepath=NULL

# Location of the file with Microsoft OIDC Application (client) ID.
che.oauth2.azure.devops.clientid_filepath=NULL

# Location of the file with Azure DevOps Service Client Secret.
# Location of the file with Microsoft OIDC Application (client) secret.
che.oauth2.azure.devops.clientsecret_filepath=NULL

# Azure DevOps Service OAuth2 scopes.
# Separate multiple values with comma, for example: scope,scope,scope
# The full list of scopes: https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops#scopes
che.integration.azure.devops.application_scopes=vso.code_write
che.integration.azure.devops.application_scopes=499b84ac-1321-427f-aa17-267ca6975798/vso.code_write

# Azure DevOps Service OAuth2 authorization URI.
che.oauth.azure.devops.authuri=https://app.vssps.visualstudio.com/oauth2/authorize
# Azure DevOps Service OAuth2 authorization URI template. Tenant-id must be injected.
che.oauth.azure.devops.authuri.template=https://login.microsoftonline.com/%s/oauth2/v2.0/authorize

# Azure DevOps OAuth Service token URI.
che.oauth.azure.devops.tokenuri=https://app.vssps.visualstudio.com/oauth2/token
# Azure DevOps OAuth Service token URI template. Tenant-id must be injected.
che.oauth.azure.devops.tokenuri.template=https://login.microsoftonline.com/%s/oauth2/v2.0/token

# Azure DevOps Service API server address.
che.integration.azure.devops.api_endpoint=https://vssps.dev.azure.com
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2024 Red Hat, Inc.
* Copyright (c) 2012-2026 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
Expand All @@ -22,13 +22,15 @@
import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl;
import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.util.store.MemoryDataStoreFactory;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
Expand All @@ -51,6 +53,7 @@ public class AzureDevOpsOAuthAuthenticator extends OAuthAuthenticator {
private final String[] redirectUris;
private final String API_VERSION = "7.0";
private final String PROVIDER_NAME = "azure-devops";
private final String clientId;
private final String clientSecret;

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
Expand All @@ -66,6 +69,7 @@ public AzureDevOpsOAuthAuthenticator(
String[] redirectUris)
throws IOException {
this.cheApiEndpoint = cheApiEndpoint;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.azureDevOpsScmApiEndpoint = trimEnd(azureDevOpsScmApiEndpoint, '/');
this.azureDevOpsUserProfileDataApiUrl =
Expand All @@ -87,7 +91,7 @@ public AzureDevOpsOAuthAuthenticator(
@Override
public String getAuthenticateUrl(URL requestUrl, List<String> scopes) {
AuthorizationCodeRequestUrl url = flow.newAuthorizationUrl().setScopes(scopes);
url.set("response_type", "Assertion");
url.set("response_type", "code");
url.set("redirect_uri", format("%s/oauth/callback", cheApiEndpoint));
url.setState(prepareState(requestUrl));
return url.build();
Expand Down Expand Up @@ -200,11 +204,10 @@ protected AuthorizationCodeTokenRequest getAuthorizationCodeTokenRequest(
URL requestUrl, List<String> scopes, String code) {
AuthorizationCodeTokenRequest request =
super.getAuthorizationCodeTokenRequest(requestUrl, scopes, code);
request.set("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
request.set("assertion", code);
request.set("client_assertion", clientSecret);
request.set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
request.setResponseClass(AzureDevOpsTokenResponse.class);
request.set("client_id", clientId);
request.set("grant_type", "authorization_code");
request.set("client_secret", URLEncoder.encode(clientSecret));
request.setResponseClass(TokenResponse.class);
return request;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2023 Red Hat, Inc.
* Copyright (c) 2012-2026 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
Expand Down Expand Up @@ -38,18 +38,20 @@ public class AzureDevOpsOAuthAuthenticatorProvider implements Provider<OAuthAuth
@Inject
public AzureDevOpsOAuthAuthenticatorProvider(
@Named("che.api") String cheApiEndpoint,
@Nullable @Named("che.oauth2.azure.devops.tenantid_filepath") String azureDevOpsTennantIdPath,
@Nullable @Named("che.oauth2.azure.devops.clientid_filepath") String azureDevOpsClientIdPath,
@Nullable @Named("che.oauth2.azure.devops.clientsecret_filepath")
String azureDevOpsClientSecretPath,
@Named("che.integration.azure.devops.api_endpoint") String azureDevOpsApiEndpoint,
@Named("che.integration.azure.devops.scm.api_endpoint") String azureDevOpsScmApiEndpoint,
@Named("che.oauth.azure.devops.authuri") String authUri,
@Named("che.oauth.azure.devops.tokenuri") String tokenUri,
@Named("che.oauth.azure.devops.authuri.template") String authUri,
@Named("che.oauth.azure.devops.tokenuri.template") String tokenUri,
@Named("che.oauth.azure.devops.redirecturis") String[] redirectUris)
throws IOException {
authenticator =
getOAuthAuthenticator(
cheApiEndpoint,
azureDevOpsTennantIdPath,
azureDevOpsClientIdPath,
azureDevOpsClientSecretPath,
azureDevOpsApiEndpoint,
Expand All @@ -67,27 +69,31 @@ public OAuthAuthenticator get() {

private OAuthAuthenticator getOAuthAuthenticator(
String cheApiEndpoint,
String tenantIdPath,
String clientIdPath,
String clientSecretPath,
String azureDevOpsApiEndpoint,
String azureDevOpsScmApiEndpoint,
String authUri,
String tokenUri,
String authUriTemplate,
String tokenUriTemplate,
String[] redirectUris)
throws IOException {

if (!isNullOrEmpty(clientIdPath) && !isNullOrEmpty(clientSecretPath)) {
if (!isNullOrEmpty(clientIdPath)
&& !isNullOrEmpty(clientSecretPath)
&& !isNullOrEmpty(tenantIdPath)) {
final String tenantId = Files.readString(Path.of(tenantIdPath)).trim();
final String clientId = Files.readString(Path.of(clientIdPath)).trim();
final String clientSecret = Files.readString(Path.of(clientSecretPath)).trim();
if (!isNullOrEmpty(clientId) && !isNullOrEmpty(clientSecret)) {
if (!isNullOrEmpty(clientId) && !isNullOrEmpty(clientSecret) && !isNullOrEmpty(tenantId)) {
return new AzureDevOpsOAuthAuthenticator(
cheApiEndpoint,
clientId,
clientSecret,
azureDevOpsApiEndpoint,
azureDevOpsScmApiEndpoint,
authUri,
tokenUri,
String.format(authUriTemplate, tenantId),
String.format(tokenUriTemplate, tenantId),
redirectUris);
}
}
Expand Down

This file was deleted.

Loading