Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
oauth2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
rathnapandi committed Apr 13, 2023
1 parent 1d8361c commit 93aefcd
Show file tree
Hide file tree
Showing 5 changed files with 586 additions and 10 deletions.
70 changes: 64 additions & 6 deletions pkg/cmd/discovery/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package discovery

import (
"github.com/Axway/agent-sdk/pkg/agent"
"github.com/Axway/agent-sdk/pkg/apic/provisioning"
"github.com/sirupsen/logrus"

subs "git.ecd.axway.org/apigov/agents-webmethods/pkg/subscription"
"git.ecd.axway.org/apigov/agents-webmethods/pkg/webmethods"
coreagent "github.com/Axway/agent-sdk/pkg/agent"
coreapi "github.com/Axway/agent-sdk/pkg/api"
corecmd "github.com/Axway/agent-sdk/pkg/cmd"

"github.com/Axway/agent-sdk/pkg/cmd/service"
corecfg "github.com/Axway/agent-sdk/pkg/config"

Expand Down Expand Up @@ -57,19 +60,74 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) {
})
client := coreapi.NewClient(conf.WebMethodConfig.TLS, conf.WebMethodConfig.ProxyURL)
gatewayClient, err := webmethods.NewClient(conf.WebMethodConfig, client)
if err != nil {
return nil, err
}

oauthServersResponse, err := gatewayClient.ListOauth2Servers()

if err != nil {
return nil, err
}
servers := []string{}

if centralConfig.IsMarketplaceSubsEnabled() {
agent.RegisterProvisioner(subs.NewProvisioner(gatewayClient, logger))
agent.NewAPIKeyAccessRequestBuilder().Register()
agent.NewAPIKeyCredentialRequestBuilder().IsRenewable().Register()
agent.NewOAuthCredentialRequestBuilder().IsRenewable().Register()
for _, server := range oauthServersResponse.Alias {
servers = append(servers, server.Name)
}

discoveryAgent = discovery.NewAgent(conf, gatewayClient)
scopes := []string{}

for _, server := range oauthServersResponse.Alias {
for _, scope := range server.Scopes {
serverPlusScope := server.Name + "-" + scope.Name
scopes = append(scopes, serverPlusScope)
}
}

corsProp := getCorsSchemaPropertyBuilder()

agent.RegisterProvisioner(subs.NewProvisioner(gatewayClient, logger))
agent.NewAPIKeyAccessRequestBuilder().Register()
agent.NewAPIKeyCredentialRequestBuilder(coreagent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register()
oAuthRedirects := getAuthRedirectSchemaPropertyBuilder()

oAuthServers := provisioning.NewSchemaPropertyBuilder().
SetName("oauthServer").
SetRequired().
SetLabel("Oauth Server").
IsString().
SetEnumValues(servers)

agent.NewOAuthCredentialRequestBuilder(
//coreagent.WithCRDSco
coreagent.WithCRDOAuthSecret(),
coreagent.WithCRDRequestSchemaProperty(oAuthRedirects),
coreagent.WithCRDRequestSchemaProperty(oAuthServers),
coreagent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register()

discoveryAgent = discovery.NewAgent(conf, gatewayClient)
return conf, nil
}

func getCorsSchemaPropertyBuilder() provisioning.PropertyBuilder {
// register the supported credential request defs
return provisioning.NewSchemaPropertyBuilder().
SetName("cors").
SetLabel("Javascript Origins").
IsArray().
AddItem(
provisioning.NewSchemaPropertyBuilder().
SetName("Origins").
IsString())
}

func getAuthRedirectSchemaPropertyBuilder() provisioning.PropertyBuilder {
return provisioning.NewSchemaPropertyBuilder().
SetName("redirectURLs").
SetLabel("Redirect URLs").
IsArray().
AddItem(
provisioning.NewSchemaPropertyBuilder().
SetName("URL").
IsString())
}
35 changes: 31 additions & 4 deletions pkg/subscription/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func (p provisioner) ApplicationRequestProvision(req prov.ApplicationRequest) pr
if appName == "" {
return p.failed(rs, notFound("managed application name"))
}

// process application create
var application webmethods.Application
application.Name = appName
Expand Down Expand Up @@ -178,17 +179,43 @@ func (p provisioner) CredentialProvision(req prov.CredentialRequest) (prov.Reque

log.Infof("Credential Type %s", req.GetCredentialType())
applicationsResponse, err := p.client.GetApplication(webmethodsApplicationId)
if err != nil {
return p.failed(rs, notFound("Unable to get application from Webmethods")), nil
}
var credential prov.Credential

switch req.GetCredentialType() {
case prov.APIKeyCRD:
credential = prov.NewCredentialBuilder().SetAPIKey(applicationsResponse.Applications[0].AccessTokens.ApiAccessKeyCredentials.ApiAccessKey)
case prov.OAuthIDPCRD:
credential = prov.NewCredentialBuilder().SetOAuthIDAndSecret("", "")
}
if err != nil {
return p.failed(rs, notFound("Unable to get application from Webmethods")), nil
dcrconfig := webmethods.DcrConfig{}
strategy := &webmethods.Strategy{
Name: "test",
Description: "test",
AuthServerAlias: "",
Audience: "",
Type: "OAUTH2",
DcrConfig: dcrconfig,
}

strategyResponse, err := p.client.CreateOauth2Strategy(strategy)
if err != nil {
return p.failed(rs, notFound("Unable to get application from Webmethods")), nil

}

application := applicationsResponse.Applications[0]
application.AuthStrategyIds = []string{strategyResponse.Strategy.Id}
applicationsResponse, err := p.client.UpdateApplication(&application)
if err != nil {
return p.failed(rs, notFound("Unable to get update Webmethods applicaiton")), nil
}
if applicationsResponse == nil {
return p.failed(rs, notFound("Unable to get update Webmethods applicaiton")), nil
}
credential = prov.NewCredentialBuilder().SetOAuthIDAndSecret(strategyResponse.Strategy.ClientRegistration.ClientId, strategyResponse.Strategy.ClientRegistration.ClientSecret)
}

rs.AddProperty(common.AttrAppID, webmethodsApplicationId)
p.log.Info("created credentials")
return rs.Success(), credential
Expand Down
169 changes: 169 additions & 0 deletions pkg/webmethods/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ type Client interface {
IsAllowedTags(tags []Tag) bool
GetApiSpec(id string) ([]byte, error)
GetWsdl(gatewayEndpoint string) ([]byte, error)
FindApplicationByName(applicationName string) (*SearchApplicationResponse, error)
CreateApplication(application *Application) (*Application, error)
UpdateApplication(application *Application) (*Application, error)
SubscribeApplication(applicationId string, ApplicationApiSubscription *ApplicationApiSubscription) error
GetApplication(applicationId string) (*ApplicationResponse, error)
RotateApplicationApikey(applicationId string) error
CreateOauth2Strategy(strategy *Strategy) (*StrategyResponse, error)
GetStrategy(strategyId string) (*StrategyResponse, error)
DeleteApplication(applicationId string) error
OnConfigChange(webMethodConfig *config.WebMethodConfig) error
DeleteApplicationAccessTokens(applicationId string) error
UnsubscribeApplication(applicationId string, apiId string) error
ListOauth2Servers() (*OauthServers, error)
}

// WebMethodClient is the client for interacting with Webmethods APIM.
Expand Down Expand Up @@ -217,6 +222,42 @@ func (c *WebMethodClient) GetWsdl(gatewayEndpoint string) ([]byte, error) {
return response.Body, nil
}

func (c *WebMethodClient) FindApplicationByName(applicationName string) (*SearchApplicationResponse, error) {
searchRequest := &Search{}
searchRequest.Types = []string{"APPLICATION"}
searchRequest.ResponseFields = []string{"applicationID", "name"}
applicationResponse := &SearchApplicationResponse{}
scope := Scope{}
scope.AttributeName = "name"
scope.Keyword = applicationName
searchRequest.Scope = []Scope{scope}
url := fmt.Sprintf("%s/rest/apigateway/search", c.url)
headers := map[string]string{
"Authorization": c.createAuthToken(),
"Content-Type": "application/json",
}
buffer, err := json.Marshal(searchRequest)
if err != nil {
return nil, agenterrors.Newf(2000, err.Error())
}
request := coreapi.Request{
Method: coreapi.POST,
URL: url,
Headers: headers,
Body: buffer,
}
response, err := c.httpClient.Send(request)
if err != nil {
return nil, err
}

err = json.Unmarshal(response.Body, applicationResponse)
if err != nil {
return nil, err
}
return applicationResponse, nil
}

func (c *WebMethodClient) GetApplication(applicationId string) (*ApplicationResponse, error) {
applicationResponse := &ApplicationResponse{}
url := fmt.Sprintf("%s/rest/apigateway/applications/%s", c.url, applicationId)
Expand Down Expand Up @@ -268,6 +309,89 @@ func (c *WebMethodClient) CreateApplication(application *Application) (*Applicat
return responseApplication, nil
}

func (c *WebMethodClient) UpdateApplication(application *Application) (*Application, error) {
responseApplication := &Application{}
url := fmt.Sprintf("%s/rest/apigateway/applications/%s", c.url, application.Id)
headers := map[string]string{
"Authorization": c.createAuthToken(),
"Content-Type": "application/json",
}
buffer, err := json.Marshal(application)
if err != nil {
return nil, agenterrors.Newf(2000, err.Error())
}
request := coreapi.Request{
Method: coreapi.PUT,
URL: url,
Headers: headers,
Body: buffer,
}

response, err := c.httpClient.Send(request)
if err != nil {
return nil, err
}

err = json.Unmarshal(response.Body, responseApplication)
return responseApplication, nil
}

func (c *WebMethodClient) CreateOauth2Strategy(strategy *Strategy) (*StrategyResponse, error) {
strategyResponse := &StrategyResponse{}

url := fmt.Sprintf("%s/rest/apigateway/strategies", c.url)
headers := map[string]string{
"Authorization": c.createAuthToken(),
"Content-Type": "application/json",
}
buffer, err := json.Marshal(strategy)
if err != nil {
return nil, agenterrors.Newf(2000, err.Error())
}
request := coreapi.Request{
Method: coreapi.POST,
URL: url,
Headers: headers,
Body: buffer,
}

response, err := c.httpClient.Send(request)
if err != nil {
return nil, err
}

if response.Code == 201 {
err = json.Unmarshal(response.Body, strategyResponse)
return strategyResponse, nil
}

return nil, agenterrors.Newf(2000, "Unable to create strategy")
}

func (c *WebMethodClient) GetStrategy(strategyId string) (*StrategyResponse, error) {
strategyResponse := &StrategyResponse{}
url := fmt.Sprintf("%s/rest/apigateway/strategies/%s", c.url, strategyId)
headers := map[string]string{
"Authorization": c.createAuthToken(),
"Accept": "application/json",
}
request := coreapi.Request{
Method: coreapi.GET,
URL: url,
Headers: headers,
}
response, err := c.httpClient.Send(request)
if err != nil {
return nil, err
}

err = json.Unmarshal(response.Body, strategyResponse)
if err != nil {
return nil, err
}
return strategyResponse, nil
}

func (c *WebMethodClient) SubscribeApplication(applicationId string, ApplicationApiSubscription *ApplicationApiSubscription) error {
url := fmt.Sprintf("%s/rest/apigateway/applications/%s/apis", c.url, applicationId)
headers := map[string]string{
Expand Down Expand Up @@ -392,6 +516,51 @@ func (c *WebMethodClient) UnsubscribeApplication(applicationId string, apiId str
return nil
}

func (c *WebMethodClient) ListOauth2Servers() (*OauthServers, error) {
requestStr := `{
"types": [
"alias"
],
"scope": [
{
"attributeName": "type",
"keyword": "authServerAlias"
}
],
"responseFields": [
"id",
"name",
"type",
"description"
],
"condition": "or",
"sortByField": "name"
}`
oauthServers := &OauthServers{}
url := fmt.Sprintf("%s/rest/apigateway/search", c.url)
headers := map[string]string{
"Authorization": c.createAuthToken(),
"Content-Type": "application/json",
}

request := coreapi.Request{
Method: coreapi.POST,
URL: url,
Headers: headers,
Body: []byte(requestStr),
}
response, err := c.httpClient.Send(request)
if err != nil {
return nil, err
}

err = json.Unmarshal(response.Body, oauthServers)
if err != nil {
return nil, err
}
return oauthServers, nil
}

func (c *WebMethodClient) createAuthToken() string {
credential := c.username + ":" + c.password
return "Basic :" + base64.StdEncoding.EncodeToString([]byte(credential))
Expand Down
Loading

0 comments on commit 93aefcd

Please sign in to comment.