OpenAPI.NET.OData/src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiSecuritySchemeGenerator.cs
2019-06-27 17:06:02 -07:00

175 lines
6.4 KiB
C#

// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
namespace Microsoft.OpenApi.OData.Generator
{
/// <summary>
/// Extension methods to create <see cref="OpenApiSecurityScheme"/> by <see cref="ODataContext"/>.
/// </summary>
internal static class OpenApiSecuritySchemeGenerator
{
/// <summary>
/// Create the dictionary of <see cref="OpenApiSecurityScheme"/> object.
/// The name of each pair is the name of authorization. The value of each pair is a <see cref="OpenApiSecurityScheme"/>.
/// </summary>
/// <param name="context">The OData to Open API context.</param>
/// <returns>The string/security scheme dictionary.</returns>
public static IDictionary<string, OpenApiSecurityScheme> CreateSecuritySchemes(this ODataContext context)
{
Utils.CheckArgumentNull(context, nameof(context));
if (context.Model == null || context.Model.EntityContainer == null)
{
return null;
}
IDictionary<string, OpenApiSecurityScheme> securitySchemes = new Dictionary<string, OpenApiSecurityScheme>();
var authorizations = context.Model.GetAuthorizations(context.EntityContainer);
if (authorizations == null)
{
return securitySchemes;
}
foreach (var authorization in authorizations)
{
OpenApiSecurityScheme scheme = new OpenApiSecurityScheme
{
Type = authorization.SchemeType,
Description = authorization.Description
};
switch (authorization.SchemeType)
{
case SecuritySchemeType.ApiKey: // ApiKey
AppendApiKey(scheme, (ApiKey)authorization);
break;
case SecuritySchemeType.Http: // Http
AppendHttp(scheme, (Http)authorization);
break;
case SecuritySchemeType.OpenIdConnect: // OpenIdConnect
AppendOpenIdConnect(scheme, (OpenIDConnect)authorization);
break;
case SecuritySchemeType.OAuth2: // OAuth2
AppendOAuth2(scheme, (OAuthAuthorization)authorization);
break;
}
securitySchemes[authorization.Name] = scheme;
}
return securitySchemes;
}
private static void AppendApiKey(OpenApiSecurityScheme scheme, ApiKey apiKey)
{
Debug.Assert(scheme != null);
Debug.Assert(apiKey != null);
scheme.Name = apiKey.KeyName;
Debug.Assert(apiKey.Location != null);
switch(apiKey.Location.Value)
{
case KeyLocation.Cookie:
scheme.In = ParameterLocation.Cookie;
break;
case KeyLocation.Header:
scheme.In = ParameterLocation.Header;
break;
case KeyLocation.QueryOption:
scheme.In = ParameterLocation.Query;
break;
}
}
private static void AppendHttp(OpenApiSecurityScheme scheme, Http http)
{
Debug.Assert(scheme != null);
Debug.Assert(http != null);
scheme.Scheme = http.Scheme;
scheme.BearerFormat = http.BearerFormat;
}
private static void AppendOpenIdConnect(OpenApiSecurityScheme scheme, OpenIDConnect openIdConnect)
{
Debug.Assert(scheme != null);
Debug.Assert(openIdConnect != null);
scheme.OpenIdConnectUrl = new Uri(openIdConnect.IssuerUrl);
}
private static void AppendOAuth2(OpenApiSecurityScheme scheme, OAuthAuthorization oAuth2)
{
Debug.Assert(scheme != null);
Debug.Assert(oAuth2 != null);
scheme.Flows = new OpenApiOAuthFlows();
OpenApiOAuthFlow flow = null;
switch (oAuth2.OAuth2Type)
{
case OAuth2Type.AuthCode: // AuthCode
OAuth2AuthCode authCode = (OAuth2AuthCode)oAuth2;
flow = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(authCode.AuthorizationUrl),
TokenUrl = new Uri(authCode.TokenUrl)
};
scheme.Flows.AuthorizationCode = flow;
break;
case OAuth2Type.Pasword: // Password
OAuth2Password password = (OAuth2Password)oAuth2;
flow = new OpenApiOAuthFlow
{
TokenUrl = new Uri(password.TokenUrl)
};
scheme.Flows.Password = flow;
break;
case OAuth2Type.Implicit: // Implicit
OAuth2Implicit @implicit = (OAuth2Implicit)oAuth2;
flow = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(@implicit.AuthorizationUrl)
};
scheme.Flows.Implicit = flow;
break;
case OAuth2Type.ClientCredentials: // ClientCredentials
OAuth2ClientCredentials credentials = (OAuth2ClientCredentials)oAuth2;
flow = new OpenApiOAuthFlow
{
TokenUrl = new Uri(credentials.TokenUrl)
};
scheme.Flows.ClientCredentials = flow;
break;
}
Debug.Assert(flow != null);
flow.RefreshUrl = new Uri(oAuth2.RefreshUrl);
if (oAuth2.Scopes != null)
{
flow.Scopes = oAuth2.Scopes.ToDictionary(s => s.Scope, s => s.Description);
}
}
}
}