Skip to content
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

Use Auth shcemes #4863

Merged
merged 5 commits into from
Jan 23, 2024
Merged
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
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@autorest/openapi-to-typespec",
"comment": "Support Auth",
"type": "minor"
}
],
"packageName": "@autorest/openapi-to-typespec"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TypespecProgram, EndpointParameter } from "../interfaces";
import { TypespecProgram, EndpointParameter, Auth } from "../interfaces";
import { getOptions } from "../options";
import { generateDocs } from "../utils/docs";
import { getNamespace } from "../utils/namespace";
Expand All @@ -13,6 +13,7 @@ export function generateServiceInformation(program: TypespecProgram) {
definitions.push(`@armProviderNamespace`);
}

generateUseAuth(serviceInformation.authentication, definitions);
definitions.push(`@service({
title: "${serviceInformation.name}"
})`);
Expand Down Expand Up @@ -91,3 +92,30 @@ function getEndpointParameters(endpoint: string) {

return params;
}

function generateUseAuth(authDefinitions: Auth[] | undefined, statements: string[]): void {
if (!authDefinitions) {
return;
}

const authFlows: string[] = [];

for (const auth of authDefinitions) {
if (auth.kind === "AadOauth2Auth") {
const scopes = `[${auth.scopes.map((s) => `"${s}"`).join()}]`;
authFlows.push(`AadOauth2Auth<${scopes}>`);
}

if (auth.kind === "ApiKeyAuth") {
authFlows.push(`ApiKeyAuth<ApiKeyLocation.${auth.location}, "${auth.name}">`);
}
}

if (!authFlows.length) {
return;
}

statements.push(`@useAuth(${authFlows.join(" | ")})`);

return;
}
19 changes: 19 additions & 0 deletions packages/extensions/openapi-to-typespec/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,32 @@ export interface TypespecResource {
response: TypespecDataType;
}

export interface AadOauth2AuthFlow {
kind: "AadOauth2Auth";
scopes: string[];
}

export interface AadTokenAuthFlow {
kind: "AadTokenAuthFlow";
scopes: string[];
}

export interface ApiKeyAuthentication {
kind: "ApiKeyAuth";
location: "header" | "query" | "cookie";
name: string;
}

export type Auth = ApiKeyAuthentication | AadOauth2AuthFlow | AadTokenAuthFlow;

export interface ServiceInformation extends WithDoc {
name: string;
versions?: string[];
endpoint?: string;
endpointParameters?: EndpointParameter[];
produces?: string[];
consumes?: string[];
authentication?: Auth[];
armCommonTypeVersion?: string;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { CodeModel, ImplementationLocation, ParameterLocation } from "@autorest/codemodel";
import {
CodeModel,
ImplementationLocation,
KeySecurityScheme,
OAuth2SecurityScheme,
ParameterLocation,
SecurityScheme,
codeModelSchema,
} from "@autorest/codemodel";
import { getArmCommonTypeVersion } from "../autorest-session";
import { EndpointParameter, ServiceInformation } from "../interfaces";
import { AadOauth2AuthFlow, ApiKeyAuthentication, Auth, EndpointParameter, ServiceInformation } from "../interfaces";
import { getOptions } from "../options";
import { getFirstEndpoint } from "../utils/get-endpoint";
import { isConstantSchema } from "../utils/schemas";
Expand All @@ -14,9 +22,54 @@ export function transformServiceInformation(model: CodeModel): ServiceInformatio
endpointParameters: transformEndpointParameters(model),
versions: getApiVersions(model),
armCommonTypeVersion: isArm ? getArmCommonTypeVersion() : undefined,
authentication: getAuth(model),
};
}

function getAuth(model: CodeModel): Auth[] | undefined {
if (!model.security.schemes?.length) {
return undefined;
}

const distinctSchemes = getDistinctAuthSchemes(model);
const auths: Auth[] = [];
for (const scheme of distinctSchemes) {
if (isAadOauth2Auth(scheme)) {
const aadOauth: AadOauth2AuthFlow = {
kind: "AadOauth2Auth",
scopes: scheme.scopes,
};

auths.push(aadOauth);
}

if (isKeyAuth(scheme)) {
const azureApiKeyAuthentication: ApiKeyAuthentication = {
kind: "ApiKeyAuth",
location: scheme.in,
name: scheme.name,
};

auths.push(azureApiKeyAuthentication);
}
}

return auths;
}

function getDistinctAuthSchemes(model: CodeModel): SecurityScheme[] {
const distinct = Array.from(new Set(model.security.schemes?.map((s) => JSON.stringify(s)) ?? []));
return distinct.map((s) => JSON.parse(s));
}

function isAadOauth2Auth(scheme: SecurityScheme): scheme is OAuth2SecurityScheme {
return scheme.type === "OAuth2";
}

function isKeyAuth(scheme: SecurityScheme): scheme is KeySecurityScheme {
return scheme.type === "Key";
}

export function transformEndpointParameters(model: CodeModel): EndpointParameter[] {
const globalParameters = (model.globalParameters ?? []).filter(
(p) => p.implementation === "Client" && p.protocol?.http?.in === "uri",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ using TypeSpec.Http;
* documentation can be found in <a
* href="https://docs.microsoft.com/en-us/azure/cognitive-services/language-service/overview">https://docs.microsoft.com/en-us/azure/cognitive-services/language-service/overview</a>.
*/
@useAuth(ApiKeyAuth<ApiKeyLocation.header, "Ocp-Apim-Subscription-Key">)
@service({
title: "Microsoft Cognitive Language Service - Analyze Text Authoring",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ using TypeSpec.Http;
* a set of time series. By using anomaly detector service, business customers can
* discover incidents and establish a logic flow for root cause analysis.
*/
@useAuth(ApiKeyAuth<ApiKeyLocation.header, "Ocp-Apim-Subscription-Key">)
@service({
title: "Anomaly Detector Client",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using TypeSpec.Versioning;
* APIs documentation for Microsoft Azure Data Manager for Agriculture Service.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure AgFoodPlatform RP Service",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using TypeSpec.Versioning;
* The Azure Analysis Services Web API provides a RESTful set of web services that enables users to create, retrieve, update, and delete Analysis Services servers
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "AzureAnalysisServices",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ using TypeSpec.Versioning;
* ApiManagement Client
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "ApiManagementClient",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ using TypeSpec.Versioning;
* Role based access control provides you a way to apply granular level policy administration down to individual resources or resource groups. These operations enable you to manage role definitions and role assignments. A role definition describes the set of actions that can be performed on resources. A role assignment grants access to Azure Active Directory users.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "AuthorizationManagementClient",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ using TypeSpec.Versioning;
* The azure integration spaces resource provider.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Integration Spaces resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ using TypeSpec.Versioning;
* Compute Client
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Compute resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ using TypeSpec.Versioning;
* These APIs allow end users to operate on Azure Machine Learning Workspace resources.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Machine Learning Services",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ using TypeSpec.Versioning;
* // FIXME: (missing-service-description) Add service description
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Network Analytics resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ using TypeSpec.Versioning;
* Azure Playwright testing management service
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Microsoft AzurePlaywrightService Management API",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ using TypeSpec.Versioning;
* Traffic Controller Provider management API.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Traffic Controller Provider management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ using TypeSpec.Versioning;
* Azure Sphere resource management API.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Sphere resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ using TypeSpec.Versioning;
* The Azure Storage Management API.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Storage resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ using TypeSpec.Versioning;
* For test.
*/
@armProviderNamespace
@useAuth(AadOauth2Auth<["user_impersonation"]>)
@service({
title: "Azure Test resource management API.",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "./routes.tsp";

using TypeSpec.Rest;
using TypeSpec.Http;
@useAuth(AadOauth2Auth<["user_impersonation"]> | ApiKeyAuth<ApiKeyLocation.header, "Authorization">)
@service({
title: "Azure Batch Service"
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ using TypeSpec.Http;
* These APIs allow end users to create, view and run load tests using Azure Load
* Test Service.
*/
@useAuth(AadOauth2Auth<["https://cnt-prod.loadtesting.azure.com/.default"]>)
@service({
title: "Load Testing Service",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ using TypeSpec.Http;
/**
* Azure OpenAI APIs for completions and search
*/
@useAuth(
AadOauth2Auth<["api.read"]> | ApiKeyAuth<ApiKeyLocation.header, "api-key">
)
@service({
title: "OpenAI",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ using TypeSpec.Http;
* documentation can be found in <a
* href="https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview">https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview</a>.
*/
@useAuth(
AadOauth2Auth<["https://cognitiveservices.azure.com/.default"]> | ApiKeyAuth<
ApiKeyLocation.header,
"Ocp-Apim-Subscription-Key"
>
)
@service({
title: "QnA Maker",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ using TypeSpec.Http;
* documentation can be found in <a
* href="https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview">https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview</a>.
*/
@useAuth(
AadOauth2Auth<["https://cognitiveservices.azure.com/.default"]> | ApiKeyAuth<
ApiKeyLocation.header,
"Ocp-Apim-Subscription-Key"
>
)
@service({
title: "Microsoft Cognitive Language Service - Question Answering - Authoring",
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ using TypeSpec.Http;
/**
* An API for QnAMaker runtime
*/
@useAuth(ApiKeyAuth<ApiKeyLocation.header, "Authorization">)
@service({
title: "QnAMaker Runtime Client",
})
Expand Down
Loading