refactor: use host instead of url for SCM authentication

Signed-off-by: Benjamin Janssens <benji.janssens@gmail.com>
This commit is contained in:
Benjamin Janssens
2024-06-06 13:20:55 +02:00
parent 1ea76795a0
commit 0a3f1bb2e0
3 changed files with 12 additions and 21 deletions
@@ -49,11 +49,11 @@ class ScmAuthMux implements ScmAuthApi {
async getCredentials(
options: ScmAuthTokenOptions,
): Promise<ScmAuthTokenResponse> {
const url = new URL(options.url);
const provider = this.#providers.find(p => p.isUrlSupported(url));
const { host } = options;
const provider = this.#providers.find(p => p.isHostSupported(host));
if (!provider) {
throw new Error(
`No auth provider available for '${options.url}', see https://backstage.io/link?scm-auth`,
`No auth provider available for '${host}', see https://backstage.io/link?scm-auth`,
);
}
@@ -261,10 +261,10 @@ export class ScmAuth implements ScmAuthApi {
}
/**
* Checks whether the implementation is able to provide authentication for the given URL.
* Checks whether the implementation is able to provide authentication for the given host.
*/
isUrlSupported(url: URL): boolean {
return url.host === this.#host;
isHostSupported(host: string): boolean {
return host === this.#host;
}
private getAdditionalScopesForProvider(
@@ -283,7 +283,7 @@ export class ScmAuth implements ScmAuthApi {
async getCredentials(
options: ScmAuthTokenOptions,
): Promise<ScmAuthTokenResponse> {
const { url, additionalScope, ...restOptions } = options;
const { host, additionalScope, ...restOptions } = options;
const scopes = this.#scopeMapping.default.slice();
if (additionalScope?.repoWrite) {
@@ -27,11 +27,11 @@ import {
*/
export interface ScmAuthTokenOptions extends AuthRequestOptions {
/**
* The URL of the SCM resource to be accessed.
* The host of the SCM resource to be accessed.
*
* @example https://github.com/backstage/backstage
* @example github.com
*/
url: string;
host: string;
/**
* Whether to request additional access scope.
@@ -124,8 +124,7 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => {
async () => {
const { requestUserCredentials } = uiSchema?.['ui:options'] ?? {};
const workspace = state.owner ? state.owner : state.project;
if (!requestUserCredentials) {
if (!requestUserCredentials || !state.host) {
return;
}
@@ -134,19 +133,11 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => {
return;
}
// previously, we were encodeURI for state.host, workspace and state.repoName separately.
// That created an issue where GitLab workspace can be nested like groupA/subgroupB
// when we encodeURi separately and then join, the URL will be malformed and
// resulting in 400 request error from GitLab API
const [encodedHost, encodedRepoName] = [state.host, state.repoName].map(
encodeURIComponent,
);
// user has requested that we use the users credentials
// so lets grab them using the scmAuthApi and pass through
// any additional scopes from the ui:options
const { token } = await scmAuthApi.getCredentials({
url: `https://${encodedHost}/${workspace}/${encodedRepoName}`,
host: state.host,
additionalScope: {
repoWrite: true,
customScopes: requestUserCredentials.additionalScopes,