Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
FR: gen bundle from oas - part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
srinandan committed Jan 30, 2022
1 parent 5e33d50 commit 3130010
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 56 deletions.
133 changes: 91 additions & 42 deletions bundlegen/generateapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,34 @@ import (
)

type pathDetailDef struct {
OperationID string
Description string
OAuthPolicy bool
APIKeyPoicy bool
OperationID string
Description string
SecurityScheme securitySchemesDef
}

var generateOAuthPolicy, generateAPIKeyPolicy, generateSetTarget bool
type oAuthPolicyDef struct {
OAuthPolicyEnabled bool
}

type securitySchemesListDef struct {
SecuritySchemes []securitySchemesDef
}

type securitySchemesDef struct {
SchemeName string
OAuthPolicy oAuthPolicyDef
APIKeyPolicy apiKeyPolicyDef
}

type apiKeyPolicyDef struct {
APIKeyPolicyEnabled bool
APIKeyLocation string
APIKeyName string
}

var generateSetTarget bool

var securitySchemesList = securitySchemesListDef{}

var doc *openapi3.T

Expand Down Expand Up @@ -126,6 +147,9 @@ func GenerateAPIProxyDefFromOAS(name string, oasDocName string, skipPolicy bool,
return fmt.Errorf("Open API document not loaded")
}

//load security schemes
loadSecurityRequirements(doc.Components.SecuritySchemes)

apiproxy.SetDisplayName(name)
if doc.Info != nil {
if doc.Info.Description != "" {
Expand Down Expand Up @@ -166,6 +190,15 @@ func GenerateAPIProxyDefFromOAS(name string, oasDocName string, skipPolicy bool,

proxies.NewProxyEndpoint(u.Path)

//add any preflow security schemes
if securityScheme := getSecurityRequirements(doc.Security); securityScheme.SchemeName != "" {
if securityScheme.APIKeyPolicy.APIKeyPolicyEnabled {
proxies.AddStepToPreFlowRequest("Verify-API-Key-" + securityScheme.SchemeName)
} else if securityScheme.OAuthPolicy.OAuthPolicyEnabled {
apiproxy.AddPolicy("OAuth-v20-1")
}
}

if addCORS {
proxies.AddStepToPreFlowRequest("Add-CORS")
apiproxy.AddPolicy("Add-CORS")
Expand All @@ -179,12 +212,12 @@ func GenerateAPIProxyDefFromOAS(name string, oasDocName string, skipPolicy bool,
return err
}

if GenerateAPIKeyPolicy() {
apiproxy.AddPolicy("Verify-API-Key-1")
}

if GenerateOAuthPolicy() {
apiproxy.AddPolicy("OAuth-v20-1")
for _, securityScheme := range securitySchemesList.SecuritySchemes {
if securityScheme.APIKeyPolicy.APIKeyPolicyEnabled {
apiproxy.AddPolicy("Verify-API-Key-" + securityScheme.SchemeName)
} else if securityScheme.OAuthPolicy.OAuthPolicyEnabled {
apiproxy.AddPolicy("OAuth-v20-1")
}
}

return nil
Expand Down Expand Up @@ -215,7 +248,7 @@ func GetHTTPMethod(pathItem *openapi3.PathItem, keyPath string) map[string]pathD
}
if pathItem.Get.Security != nil {
securityRequirements := []openapi3.SecurityRequirement(*pathItem.Get.Security)
getPathDetail.OAuthPolicy, getPathDetail.APIKeyPoicy = getSecurityRequirements(securityRequirements)
getPathDetail.SecurityScheme = getSecurityRequirements(securityRequirements)
}
pathMap["get"] = getPathDetail
}
Expand All @@ -232,7 +265,7 @@ func GetHTTPMethod(pathItem *openapi3.PathItem, keyPath string) map[string]pathD
}
if pathItem.Post.Security != nil {
securityRequirements := []openapi3.SecurityRequirement(*pathItem.Post.Security)
postPathDetail.OAuthPolicy, postPathDetail.APIKeyPoicy = getSecurityRequirements(securityRequirements)
postPathDetail.SecurityScheme = getSecurityRequirements(securityRequirements)
}
pathMap["post"] = postPathDetail
}
Expand All @@ -249,7 +282,7 @@ func GetHTTPMethod(pathItem *openapi3.PathItem, keyPath string) map[string]pathD
}
if pathItem.Put.Security != nil {
securityRequirements := []openapi3.SecurityRequirement(*pathItem.Put.Security)
putPathDetail.OAuthPolicy, putPathDetail.APIKeyPoicy = getSecurityRequirements(securityRequirements)
putPathDetail.SecurityScheme = getSecurityRequirements(securityRequirements)
}
pathMap["put"] = putPathDetail
}
Expand All @@ -266,7 +299,7 @@ func GetHTTPMethod(pathItem *openapi3.PathItem, keyPath string) map[string]pathD
}
if pathItem.Patch.Security != nil {
securityRequirements := []openapi3.SecurityRequirement(*pathItem.Patch.Security)
patchPathDetail.OAuthPolicy, patchPathDetail.APIKeyPoicy = getSecurityRequirements(securityRequirements)
patchPathDetail.SecurityScheme = getSecurityRequirements(securityRequirements)
}
pathMap["patch"] = patchPathDetail
}
Expand All @@ -283,7 +316,7 @@ func GetHTTPMethod(pathItem *openapi3.PathItem, keyPath string) map[string]pathD
}
if pathItem.Delete.Security != nil {
securityRequirements := []openapi3.SecurityRequirement(*pathItem.Delete.Security)
deletePathDetail.OAuthPolicy, deletePathDetail.APIKeyPoicy = getSecurityRequirements(securityRequirements)
deletePathDetail.SecurityScheme = getSecurityRequirements(securityRequirements)
}
pathMap["delete"] = deletePathDetail
}
Expand Down Expand Up @@ -335,13 +368,12 @@ func GenerateFlows(paths openapi3.Paths) (err error) {
pathMap := GetHTTPMethod(paths[keyPath], keyPath)
for method, pathDetail := range pathMap {
proxies.AddFlow(pathDetail.OperationID, replacePathWithWildCard(keyPath), method, pathDetail.Description)
if pathDetail.OAuthPolicy {
if pathDetail.SecurityScheme.OAuthPolicy.OAuthPolicyEnabled {
if err = proxies.AddStepToFlowRequest("OAuth-v20-1", pathDetail.OperationID); err != nil {
return err
}
}
if pathDetail.APIKeyPoicy {
if err = proxies.AddStepToFlowRequest("Verify-API-Key-1", pathDetail.OperationID); err != nil {
} else if pathDetail.SecurityScheme.APIKeyPolicy.APIKeyPolicyEnabled {
if err = proxies.AddStepToFlowRequest("Verify-API-Key-"+pathDetail.SecurityScheme.SchemeName, pathDetail.OperationID); err != nil {
return err
}
}
Expand All @@ -350,14 +382,6 @@ func GenerateFlows(paths openapi3.Paths) (err error) {
return nil
}

func GenerateOAuthPolicy() bool {
return generateOAuthPolicy
}

func GenerateAPIKeyPolicy() bool {
return generateAPIKeyPolicy
}

func GenerateSetTargetPolicy() bool {
return generateSetTarget
}
Expand All @@ -371,27 +395,52 @@ func replacePathWithWildCard(keyPath string) string {
}
}

func getSecurityType(name string) (oauth bool, apikey bool) {
for schemeName, securityScheme := range doc.Components.SecuritySchemes {
if schemeName == name {
if securityScheme.Value.Type == "oauth2" {
generateOAuthPolicy = true
return true, false
}
if securityScheme.Value.Type == "apiKey" {
generateAPIKeyPolicy = true
return false, true
}
func loadSecurityType(secSchemeName string, securityScheme openapi3.SecuritySchemeRef) (secScheme securitySchemesDef) {
secScheme = securitySchemesDef{}
apiKeyPolicy := apiKeyPolicyDef{}
oAuthPolicy := oAuthPolicyDef{}

if securityScheme.Value.Type == "oauth2" {
secScheme.SchemeName = secSchemeName
oAuthPolicy.OAuthPolicyEnabled = true
apiKeyPolicy.APIKeyPolicyEnabled = false
secScheme.OAuthPolicy = oAuthPolicy
} else if securityScheme.Value.Type == "apiKey" {
secScheme.SchemeName = secSchemeName
apiKeyPolicy.APIKeyPolicyEnabled = true
oAuthPolicy.OAuthPolicyEnabled = false
apiKeyPolicy.APIKeyLocation = securityScheme.Value.In
apiKeyPolicy.APIKeyName = securityScheme.Value.Name
secScheme.APIKeyPolicy = apiKeyPolicy
}

return secScheme
}

func getSecurityType(secName string) securitySchemesDef {
for _, securityScheme := range securitySchemesList.SecuritySchemes {
if securityScheme.SchemeName == secName {
return securityScheme
}
}
return false, false
return securitySchemesDef{}
}

func getSecurityRequirements(securityRequirements []openapi3.SecurityRequirement) (oauth bool, apikey bool) {
func getSecurityRequirements(securityRequirements []openapi3.SecurityRequirement) securitySchemesDef {
for _, secReq := range securityRequirements {
for secReqName := range secReq {
return getSecurityType(secReqName)
}
}
return false, false
return securitySchemesDef{}
}

func loadSecurityRequirements(securitySchemes openapi3.SecuritySchemes) {
for secSchemeName, secScheme := range securitySchemes {
securitySchemesList.SecuritySchemes = append(securitySchemesList.SecuritySchemes, loadSecurityType(secSchemeName, *secScheme))
}
}

func GetSecuritySchemesList() []securitySchemesDef {
return securitySchemesList.SecuritySchemes
}
13 changes: 10 additions & 3 deletions bundlegen/policies/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var oasPolicyTemplate = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

var verifyApiKeyPolicy = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1">
<DisplayName>Verify API Key-1</DisplayName>
<DisplayName>Verify-API-Key-1</DisplayName>
<Properties/>
<APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>`
Expand Down Expand Up @@ -72,8 +72,15 @@ func AddOpenAPIValidatePolicy(name string) string {
return replaceTemplateWithPolicy(name)
}

func AddVerifyApiKeyPolicy() string {
return verifyApiKeyPolicy
func AddVerifyApiKeyPolicy(location string, policyName string, keyName string) string {
var apiKeyLocation string
if location == "query" {
apiKeyLocation = "request.queryparam." + keyName
} else {
apiKeyLocation = "request.header." + keyName
}
tmp := strings.Replace(verifyApiKeyPolicy, "request.queryparam.apikey", apiKeyLocation, -1)
return strings.Replace(tmp, "Verify-API-Key-1", "Verify-API-Key-"+policyName, -1)
}

func AddOAuth2Policy() string {
Expand Down
20 changes: 10 additions & 10 deletions bundlegen/proxybundle/proxybundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,17 @@ func GenerateAPIProxyBundle(name string, content string, fileName string, resour
}
}

//add oauth policy
if genapi.GenerateOAuthPolicy() {
if err = writeXMLData(policiesDirPath+string(os.PathSeparator)+"OAuth-v20-1.xml", policies.AddOAuth2Policy()); err != nil {
return err
//add security policies
for _, securityScheme := range genapi.GetSecuritySchemesList() {
if securityScheme.APIKeyPolicy.APIKeyPolicyEnabled {
if err = writeXMLData(policiesDirPath+string(os.PathSeparator)+"Verify-API-Key-"+securityScheme.SchemeName+".xml", policies.AddVerifyApiKeyPolicy(securityScheme.APIKeyPolicy.APIKeyLocation, securityScheme.SchemeName, securityScheme.APIKeyPolicy.APIKeyName)); err != nil {
return err
}
}
}

//add api key policy
if genapi.GenerateAPIKeyPolicy() {
if err = writeXMLData(policiesDirPath+string(os.PathSeparator)+"Verify-API-Key-1.xml", policies.AddVerifyApiKeyPolicy()); err != nil {
return err
if securityScheme.OAuthPolicy.OAuthPolicyEnabled {
if err = writeXMLData(policiesDirPath+string(os.PathSeparator)+"OAuth-v20-1.xml", policies.AddOAuth2Policy()); err != nil {
return err
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/apis/crtapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ var CreateCmd = &cobra.Command{
return err
}

//Generate the apiproxy struct
err = bundle.GenerateAPIProxyDefFromOAS(name,
oasDocName,
skipPolicy,
Expand All @@ -108,10 +109,12 @@ var CreateCmd = &cobra.Command{
oasGoogleIdTokenAudLiteral,
oasGoogleIdTokenAudRef,
oasTargetUrlRef)

if err != nil {
return err
}

//Create the API proxy bundle
err = proxybundle.GenerateAPIProxyBundle(name,
string(content),
oasDocName,
Expand All @@ -122,6 +125,7 @@ var CreateCmd = &cobra.Command{
oasGoogleIdTokenAudLiteral,
oasGoogleIdTokenAudRef,
oasTargetUrlRef)

if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/srinandan/apigeecli
go 1.16

require (
github.com/getkin/kin-openapi v0.83.0
github.com/getkin/kin-openapi v0.88.0
github.com/ghodss/yaml v1.0.0
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getkin/kin-openapi v0.83.0 h1:qQbfSsapSPuRS73xhElJ85bWFo2REHNXBXAQ1kqqlCE=
github.com/getkin/kin-openapi v0.83.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/getkin/kin-openapi v0.88.0 h1:BjJ2JERWJbYE1o1RGEj/5LmR5qw7ecfl3O3su4ImR+0=
github.com/getkin/kin-openapi v0.88.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
Expand Down

0 comments on commit 3130010

Please sign in to comment.