[XAPID-1037] refactor and add tests
diff --git a/api.go b/api.go
index 57aae9b..d8cbe34 100644
--- a/api.go
+++ b/api.go
@@ -63,8 +63,6 @@
} else {
w.WriteHeader(respStatusCode)
}
- // TODO : discuss and finalize on error codes.
- w.WriteHeader(http.StatusBadRequest)
}
log.Debugf("handleVerifyAPIKey result %s", b)
@@ -117,7 +115,7 @@
case err == sql.ErrNoRows:
reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
errorCode := "oauth.v2.InvalidApiKey"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusBadRequest))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
case err != nil:
reason := err.Error()
@@ -125,6 +123,8 @@
return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusInternalServerError))
}
+ apiProduct := shortListApiProduct(dataWrapper.apiProducts, verifyApiKeyReq)
+ dataWrapper.verifyApiKeySuccessResponse.ApiProduct = apiProduct
/*
* Perform all validations
*/
@@ -135,26 +135,67 @@
apiM.enrichAttributes(&dataWrapper)
- if dataWrapper.ctype == "developer" {
- dataWrapper.verifyApiKeySuccessResponse.Developer = dataWrapper.tempDeveloperDetails
- } else {
- dataWrapper.verifyApiKeySuccessResponse.Company = CompanyDetails{
- Id: dataWrapper.tempDeveloperDetails.Id,
- DisplayName: dataWrapper.tempDeveloperDetails.UserName,
- Status: dataWrapper.tempDeveloperDetails.Status,
- CreatedAt: dataWrapper.tempDeveloperDetails.CreatedAt,
- CreatedBy: dataWrapper.tempDeveloperDetails.CreatedBy,
- LastmodifiedAt: dataWrapper.tempDeveloperDetails.LastmodifiedAt,
- LastmodifiedBy: dataWrapper.tempDeveloperDetails.LastmodifiedBy,
- Attributes: dataWrapper.tempDeveloperDetails.Attributes,
- }
- }
+ setDevOrCompanyInResponseBasedOnCtype(dataWrapper.ctype, dataWrapper.tempDeveloperDetails, &dataWrapper.verifyApiKeySuccessResponse)
resp := dataWrapper.verifyApiKeySuccessResponse
return json.Marshal(resp)
}
+func setDevOrCompanyInResponseBasedOnCtype(ctype string, tempDeveloperDetails DeveloperDetails, response *VerifyApiKeySuccessResponse) {
+ if ctype == "developer" {
+ response.Developer = tempDeveloperDetails
+ } else {
+ response.Company = CompanyDetails{
+ Id: tempDeveloperDetails.Id,
+ DisplayName: tempDeveloperDetails.UserName,
+ Status: tempDeveloperDetails.Status,
+ CreatedAt: tempDeveloperDetails.CreatedAt,
+ CreatedBy: tempDeveloperDetails.CreatedBy,
+ LastmodifiedAt: tempDeveloperDetails.LastmodifiedAt,
+ LastmodifiedBy: tempDeveloperDetails.LastmodifiedBy,
+ Attributes: tempDeveloperDetails.Attributes,
+ }
+ }
+}
+
+func shortListApiProduct(details []ApiProductDetails, verifyApiKeyReq VerifyApiKeyRequest) ApiProductDetails {
+ var bestMathcedProduct ApiProductDetails
+ rankedProducts := make(map[int][]ApiProductDetails)
+ rankedProducts[2] = []ApiProductDetails{}
+ rankedProducts[3] = []ApiProductDetails{}
+
+ for _, apiProd := range details {
+ if len(apiProd.Resources) == 0 || validatePath(apiProd.Resources, verifyApiKeyReq.UriPath) {
+ if len(apiProd.Apiproxies) == 0 || contains(apiProd.Apiproxies, verifyApiKeyReq.ApiProxyName) {
+ if len(apiProd.Environments) == 0 || contains(apiProd.Environments, verifyApiKeyReq.EnvironmentName) {
+ bestMathcedProduct = apiProd
+ return bestMathcedProduct
+ // set rank 1 or just return
+ } else {
+ // set rank to 2
+ rankedProducts[2] = append(rankedProducts[2], apiProd)
+ }
+ } else {
+ // set rank to 3,
+ rankedProducts[3] = append(rankedProducts[3], apiProd)
+ }
+ }
+ }
+
+ // TODO : remove this check from here and let performValidations take care of checking this
+ if !verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs {
+ if len(rankedProducts[2]) > 0 {
+ return rankedProducts[2][0]
+ } else if len(rankedProducts[3]) > 0 {
+ return rankedProducts[3][0]
+ }
+ }
+
+ return bestMathcedProduct
+
+}
+
func (apiM apiManager) performValidations(dataWrapper VerifyApiKeyRequestResponseDataWrapper) ([]byte, error) {
clientIdDetails := dataWrapper.verifyApiKeySuccessResponse.ClientId
verifyApiKeyReq := dataWrapper.verifyApiKeyRequest
@@ -166,13 +207,13 @@
if !strings.EqualFold("APPROVED", clientIdDetails.Status) {
reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
errorCode := "oauth.v2.ApiKeyNotApproved"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
}
if !strings.EqualFold("APPROVED", appDetails.Status) {
reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
errorCode := "keymanagement.service.invalid_client-app_not_approved"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
}
if !strings.EqualFold("ACTIVE", tempDeveloperDetails.Status) {
@@ -181,47 +222,46 @@
if cType == "company" {
errorCode = "keymanagement.service.CompanyStatusNotActive"
}
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
+ }
+
+ if dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id == "" {
+ reason := "Path Validation Failed. Product not resolved"
+ errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
}
result := validatePath(apiProductDetails.Resources, verifyApiKeyReq.UriPath)
if result == false {
reason := "Path Validation Failed (" + strings.Join(apiProductDetails.Resources, ", ") + " vs " + verifyApiKeyReq.UriPath + ")"
errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
}
+ // TODO : empty check
+ if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && !contains(apiProductDetails.Apiproxies, verifyApiKeyReq.ApiProxyName) {
+ reason := "Proxy Validation Failed (" + strings.Join(apiProductDetails.Apiproxies, ", ") + " vs " + verifyApiKeyReq.ApiProxyName + ")"
+ errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
+ }
/* Verify if the ENV matches */
if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && !contains(apiProductDetails.Environments, verifyApiKeyReq.EnvironmentName) {
reason := "ENV Validation Failed (" + strings.Join(apiProductDetails.Environments, ", ") + " vs " + verifyApiKeyReq.EnvironmentName + ")"
errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
- }
-
- if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && !contains(apiProductDetails.Apiproxies, verifyApiKeyReq.ApiProxyName) {
- reason := "Proxy Validation Failed (" + strings.Join(apiProductDetails.Apiproxies, ", ") + " vs " + verifyApiKeyReq.ApiProxyName + ")"
- errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
- return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
+ return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusOK))
}
return nil, nil
}
-func contains(givenArray []string, searchString string) bool {
- for _, element := range givenArray {
- if element == searchString {
- return true
- }
- }
- return false
-}
-
func (a *apiManager) enrichAttributes(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) {
- clientIdAttributes := a.dbMan.getKmsAttributes(dataWrapper.tenant_id, dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId)
- developerAttributes := a.dbMan.getKmsAttributes(dataWrapper.tenant_id, dataWrapper.tempDeveloperDetails.Id)
- appAttributes := a.dbMan.getKmsAttributes(dataWrapper.tenant_id, dataWrapper.verifyApiKeySuccessResponse.App.Id)
- apiProductAttributes := a.dbMan.getKmsAttributes(dataWrapper.tenant_id, dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id)
+ attributeMap := a.dbMan.getKmsAttributes(dataWrapper.tenant_id, dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId, dataWrapper.tempDeveloperDetails.Id, dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id, dataWrapper.verifyApiKeySuccessResponse.App.Id)
+
+ clientIdAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId]
+ developerAttributes := attributeMap[dataWrapper.tempDeveloperDetails.Id]
+ appAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.App.Id]
+ apiProductAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id]
dataWrapper.verifyApiKeySuccessResponse.ClientId.Attributes = clientIdAttributes
dataWrapper.verifyApiKeySuccessResponse.App.Attributes = appAttributes
diff --git a/api_ShortListApiProduct_test.go b/api_ShortListApiProduct_test.go
new file mode 100644
index 0000000..f604b83
--- /dev/null
+++ b/api_ShortListApiProduct_test.go
@@ -0,0 +1,142 @@
+// Copyright 2017 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package apidVerifyApiKey
+
+import "testing"
+
+var shortListApiProductTestData = []struct {
+ testDesc string
+ req VerifyApiKeyRequest
+ dbData []ApiProductDetails
+ expectedResult string
+ expectedWhenValidateProxyEnvIsTrue string
+}{
+ {
+ testDesc: "single-product-happy-path",
+ req: VerifyApiKeyRequest{EnvironmentName: "test", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}}},
+ expectedResult: "api-product-1",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-1",
+ },
+ {
+ testDesc: "multi-product-custom-resource-happy-path",
+ req: VerifyApiKeyRequest{EnvironmentName: "test", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+ expectedResult: "api-product-2",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-2",
+ }, {
+ testDesc: "multi-product-only-one-matches-env",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{"test", "prod", "stage"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+ expectedResult: "api-product-3",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-3",
+ },
+ {
+ testDesc: "multi-product-match-with-no-env",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+ expectedResult: "api-product-3",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-3",
+ },
+ {
+ testDesc: "multi-product-match-env",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod", "stage"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/this-is-my-path"}},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+
+ expectedResult: "api-product-2",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-2",
+ },
+
+ {
+ testDesc: "multi-product-match-empty-res-env-proxy",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1"},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod", "stage"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/this-is-my-path"}},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+
+ expectedResult: "api-product-1",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-1",
+ },
+
+ {
+ testDesc: "multi-product-match-empty-res-env-proxy-second-indexed",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2"},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ },
+ expectedResult: "api-product-2",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-2",
+ },
+ {
+ testDesc: "multi-product-with-no-resource-match",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2"},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/b/**"}},
+ },
+ expectedResult: "api-product-2",
+ expectedWhenValidateProxyEnvIsTrue: "api-product-2",
+ },
+ {
+ testDesc: "multi-product-non-existent-proxy",
+ req: VerifyApiKeyRequest{EnvironmentName: "stage", ApiProxyName: "test-non-exisitent-proxy", UriPath: "/this-is-my-path"},
+ dbData: []ApiProductDetails{
+ ApiProductDetails{Id: "api-product-1", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/a/**"}},
+ ApiProductDetails{Id: "api-product-2", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/**"}},
+ ApiProductDetails{Id: "api-product-3", Environments: []string{"test", "prod"}, Apiproxies: []string{"test-proxy"}, Resources: []string{"/b/**"}},
+ },
+ expectedResult: "api-product-2",
+ expectedWhenValidateProxyEnvIsTrue: "",
+ },
+}
+
+func TestShortListApiProduct(t *testing.T) {
+ for _, td := range shortListApiProductTestData {
+ actual := shortListApiProduct(td.dbData, td.req)
+ if actual.Id != td.expectedResult {
+ t.Errorf("TestData (%s) ValidateProxyEnv (%t) : expected (%s), actual (%s)", td.testDesc, td.req.ValidateAgainstApiProxiesAndEnvs, td.expectedResult, actual.Id)
+ }
+ }
+}
+
+func TestShortListApiProductValidateProxyEnv(t *testing.T) {
+ for _, td := range shortListApiProductTestData {
+ td.req.ValidateAgainstApiProxiesAndEnvs = true
+ actual := shortListApiProduct(td.dbData, td.req)
+ if actual.Id != td.expectedWhenValidateProxyEnvIsTrue {
+ t.Errorf("TestData (%s) ValidateProxyEnv (%t) : expected (%s), actual (%s)", td.testDesc, td.req.ValidateAgainstApiProxiesAndEnvs, td.expectedResult, actual.Id)
+ }
+ }
+}
diff --git a/api_performValidations_test.go b/api_performValidations_test.go
new file mode 100644
index 0000000..1054308
--- /dev/null
+++ b/api_performValidations_test.go
@@ -0,0 +1,250 @@
+// Copyright 2017 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package apidVerifyApiKey
+
+import (
+ "github.com/30x/apid-core"
+ "github.com/30x/apid-core/factory"
+ "testing"
+)
+
+var performValidationsTestData = []struct {
+ testDesc string
+ dataWrapper VerifyApiKeyRequestResponseDataWrapper
+ expectedResult string
+ expectedWhenValidateProxyEnvIsTrue string
+}{
+ {
+ testDesc: "happy-path",
+ expectedResult: "",
+ expectedWhenValidateProxyEnvIsTrue: "",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "ACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{
+ Id: "test-api-product",
+ Resources: []string{"/**"},
+ Apiproxies: []string{"test-proxy-name"},
+ Environments: []string{"test-env-name"},
+ Status: "APPROVED",
+ },
+ App: AppDetails{
+ Status: "APPROVED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "APPROVED",
+ },
+ },
+ },
+ }, {
+ testDesc: "Inactive Developer",
+ expectedResult: "{\"response_code\":\"keymanagement.service.DeveloperStatusNotActive\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ expectedWhenValidateProxyEnvIsTrue: "{\"response_code\":\"keymanagement.service.DeveloperStatusNotActive\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "INACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{
+ Id: "test-api-product",
+ Resources: []string{"/**"},
+ Apiproxies: []string{"test-proxy-name"},
+ Environments: []string{"test-env-name"},
+ Status: "APPROVED",
+ },
+ App: AppDetails{
+ Status: "APPROVED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "APPROVED",
+ },
+ },
+ },
+ },
+ {
+ testDesc: "Revoked Client Id",
+ expectedResult: "{\"response_code\":\"oauth.v2.ApiKeyNotApproved\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ expectedWhenValidateProxyEnvIsTrue: "{\"response_code\":\"oauth.v2.ApiKeyNotApproved\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "ACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{
+ Id: "test-api-product",
+ Resources: []string{"/**"},
+ Apiproxies: []string{"test-proxy-name"},
+ Environments: []string{"test-env-name"},
+ Status: "APPROVED",
+ },
+ App: AppDetails{
+ Status: "APPROVED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "REVOKED",
+ },
+ },
+ },
+ },
+ {
+ testDesc: "Revoked App",
+ expectedResult: "{\"response_code\":\"keymanagement.service.invalid_client-app_not_approved\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ expectedWhenValidateProxyEnvIsTrue: "{\"response_code\":\"keymanagement.service.invalid_client-app_not_approved\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "ACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{
+ Id: "test-api-product",
+ Resources: []string{"/**"},
+ Apiproxies: []string{"test-proxy-name"},
+ Environments: []string{"test-env-name"},
+ Status: "APPROVED",
+ },
+ App: AppDetails{
+ Status: "REVOKED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "APPROVED",
+ },
+ },
+ },
+ },
+ {
+ testDesc: "Company Inactive",
+ expectedResult: "{\"response_code\":\"keymanagement.service.CompanyStatusNotActive\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ expectedWhenValidateProxyEnvIsTrue: "{\"response_code\":\"keymanagement.service.CompanyStatusNotActive\",\"response_message\":\"API Key verify failed for (test-key, test-org)\"}",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ ctype: "company",
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "INACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{
+ Id: "test-api-product",
+ Resources: []string{"/**"},
+ Apiproxies: []string{"test-proxy-name"},
+ Environments: []string{"test-env-name"},
+ Status: "APPROVED",
+ },
+ App: AppDetails{
+ Status: "APPROVED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "APPROVED",
+ },
+ },
+ },
+ },
+ {
+ testDesc: "Product not resolved",
+ expectedResult: "{\"response_code\":\"oauth.v2.InvalidApiKeyForGivenResource\",\"response_message\":\"Path Validation Failed. Product not resolved\"}",
+ expectedWhenValidateProxyEnvIsTrue: "{\"response_code\":\"oauth.v2.InvalidApiKeyForGivenResource\",\"response_message\":\"Path Validation Failed. Product not resolved\"}",
+ dataWrapper: VerifyApiKeyRequestResponseDataWrapper{
+ verifyApiKeyRequest: VerifyApiKeyRequest{
+ Key: "test-key",
+ OrganizationName: "test-org",
+ UriPath: "/test",
+ ApiProxyName: "test-proxy-name",
+ EnvironmentName: "test-env-name",
+ },
+ tempDeveloperDetails: DeveloperDetails{
+ Status: "ACTIVE",
+ },
+ verifyApiKeySuccessResponse: VerifyApiKeySuccessResponse{
+ ApiProduct: ApiProductDetails{},
+ App: AppDetails{
+ Status: "APPROVED",
+ },
+ ClientId: ClientIdDetails{
+ Status: "APPROVED",
+ },
+ },
+ },
+ },
+}
+
+func TestPerformValidation(t *testing.T) {
+
+ // tODO : what is the right way to get this ?
+ apid.Initialize(factory.DefaultServicesFactory())
+ log = factory.DefaultServicesFactory().Log()
+ a := apiManager{}
+ for _, td := range performValidationsTestData {
+ actual, err := a.performValidations(td.dataWrapper)
+ if string(actual) != td.expectedResult {
+ t.Errorf("TestData (%s) ValidateProxyEnv (%t) : expected (%s), actual (%s)", td.testDesc, td.dataWrapper.verifyApiKeyRequest.ValidateAgainstApiProxiesAndEnvs, td.expectedResult, string(actual))
+ }
+ if err != nil && err.Error() != "200" {
+ t.Error("Expected to return 200 status code")
+ }
+ }
+}
+
+func TestPerformValidationValidateProxyEnv(t *testing.T) {
+
+ // tODO : what is the right way to get this ?
+ apid.Initialize(factory.DefaultServicesFactory())
+ log = factory.DefaultServicesFactory().Log()
+ a := apiManager{}
+ for _, td := range performValidationsTestData {
+ td.dataWrapper.verifyApiKeyRequest.ValidateAgainstApiProxiesAndEnvs = true
+ actual, err := a.performValidations(td.dataWrapper)
+ if string(actual) != td.expectedWhenValidateProxyEnvIsTrue {
+ t.Errorf("TestData (%s) ValidateProxyEnv (%t) : expected (%s), actual (%s)", td.testDesc, td.dataWrapper.verifyApiKeyRequest.ValidateAgainstApiProxiesAndEnvs, td.expectedWhenValidateProxyEnvIsTrue, string(actual))
+ }
+ if err != nil && err.Error() != "200" {
+ t.Error("Expected to return 200 status code")
+ }
+ }
+}
diff --git a/api_test.go b/api_test.go
deleted file mode 100644
index f9b611c..0000000
--- a/api_test.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2017 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package apidVerifyApiKey
-
-import (
- "encoding/json"
- "github.com/30x/apid-core"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
- "io/ioutil"
- "net/http"
- "net/url"
- "strconv"
- "strings"
-)
-
-var _ = Describe("api", func() {
-
- Context("DB Inserts/Deletes verification", func() {
-
- It("should reject a bad key", func() {
- v := url.Values{
- "key": []string{"credential_x"},
- "uriPath": []string{"/test"},
- "scopeuuid": []string{"ABCDE"},
- "action": []string{"verify"},
- }
- rsp, err := verifyAPIKey(v)
- Expect(err).ShouldNot(HaveOccurred())
-
- var respj kmsResponseFail
- json.Unmarshal(rsp, &respj)
- Expect(respj.Type).Should(Equal("ErrorResult"))
- Expect(respj.ErrInfo.ErrorCode).Should(Equal("REQ_ENTRY_NOT_FOUND"))
-
- })
-
- It("should successfully verify good Developer keys", func() {
- for i := 1; i < 10; i++ {
- resulti := strconv.FormatInt(int64(i), 10)
- v := url.Values{
- "key": []string{"app_credential_" + resulti},
- "uriPath": []string{"/test"},
- "scopeuuid": []string{"ABCDE"},
- "action": []string{"verify"},
- }
- rsp, err := verifyAPIKey(v)
- Expect(err).ShouldNot(HaveOccurred())
-
- var respj kmsResponseSuccess
- json.Unmarshal(rsp, &respj)
- Expect(respj.Type).Should(Equal("APIKeyContext"))
- Expect(respj.RspInfo.Type).Should(Equal("developer"))
- Expect(respj.RspInfo.Key).Should(Equal("app_credential_" + resulti))
- }
- })
-
- It("should successfully verify good Company keys", func() {
- for i := 100; i < 110; i++ {
- resulti := strconv.FormatInt(int64(i), 10)
- v := url.Values{
- "key": []string{"app_credential_" + resulti},
- "uriPath": []string{"/test"},
- "scopeuuid": []string{"ABCDE"},
- "action": []string{"verify"},
- }
- rsp, err := verifyAPIKey(v)
- Expect(err).ShouldNot(HaveOccurred())
-
- var respj kmsResponseSuccess
- json.Unmarshal(rsp, &respj)
- Expect(respj.Type).Should(Equal("APIKeyContext"))
- Expect(respj.RspInfo.Type).Should(Equal("company"))
- Expect(respj.RspInfo.Key).Should(Equal("app_credential_" + resulti))
- }
- })
-
- It("should reject a bad key", func() {
-
- uri, err := url.Parse(testServer.URL)
- uri.Path = apiPath
-
- v := url.Values{}
- v.Add("key", "credential_x")
- v.Add("scopeuuid", "ABCDE")
- v.Add("uriPath", "/test")
- v.Add("action", "verify")
-
- client := &http.Client{}
- req, err := http.NewRequest("POST", uri.String(), strings.NewReader(v.Encode()))
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
-
- res, err := client.Do(req)
- defer res.Body.Close()
- Expect(err).ShouldNot(HaveOccurred())
-
- var respj kmsResponseFail
- body, err := ioutil.ReadAll(res.Body)
- Expect(err).ShouldNot(HaveOccurred())
- json.Unmarshal(body, &respj)
- Expect(respj.Type).Should(Equal("ErrorResult"))
- Expect(respj.ErrInfo.ErrorCode).Should(Equal("REQ_ENTRY_NOT_FOUND"))
- })
-
- It("should report error for no scopes", func() {
- v := url.Values{
- "key": []string{"credential_x"},
- "uriPath": []string{"/test"},
- "scopeuuid": []string{"ABCDE"},
- "action": []string{"verify"},
- }
-
- clearDataScopeTable(getDB())
- rsp, err := verifyAPIKey(v)
- Expect(err).ShouldNot(HaveOccurred())
-
- var respj kmsResponseFail
- json.Unmarshal(rsp, &respj)
- Expect(respj.Type).Should(Equal("ErrorResult"))
- Expect(respj.ErrInfo.ErrorCode).Should(Equal("ENV_VALIDATION_FAILED"))
-
- })
-
- It("should report error for invalid requests", func() {
- v := url.Values{
- "key": []string{"credential_x"},
- "uriPath": []string{"/test"},
- "scopeuuid": []string{"ABCDE"},
- "action": []string{"verify"},
- }
-
- fields := []string{"key", "uriPath", "scopeuuid", "action"}
- for _, field := range fields {
- tmp := v.Get(field)
- v.Del(field)
-
- rsp, err := verifyAPIKey(v)
- Expect(err).ShouldNot(HaveOccurred())
- var respj kmsResponseFail
- json.Unmarshal(rsp, &respj)
- Expect(respj.Type).Should(Equal("ErrorResult"))
- Expect(respj.ErrInfo.ErrorCode).Should(Equal("INCORRECT_USER_INPUT"))
-
- v.Set(field, tmp)
- }
- })
- })
-})
-
-func clearDataScopeTable(db apid.DB) {
- txn, _ := db.Begin()
- txn.Exec("DELETE FROM EDGEX_DATA_SCOPE")
- log.Info("clear EDGEX_DATA_SCOPE for test")
- txn.Commit()
-}
diff --git a/data.go b/data.go
index ffb5811..2674a92 100644
--- a/data.go
+++ b/data.go
@@ -17,6 +17,7 @@
"database/sql"
"errors"
"github.com/30x/apid-core"
+ "strings"
"sync"
)
@@ -54,11 +55,11 @@
setDbVersion(string)
initDb() error
getDb() apid.DB
- getKmsAttributes(tenantId string, entityId string) []Attribute
+ getKmsAttributes(tenantId string, entities ...string) map[string][]Attribute
getApiKeyDetails(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) error
}
-func (dbc *dbManager) getKmsAttributes(tenantId string, entityId string) []Attribute {
+func (dbc *dbManager) getKmsAttributesOld(tenantId, entityId string) []Attribute {
db := dbc.db
var attName, attValue sql.NullString
@@ -87,10 +88,40 @@
return attributesForQuery
}
+func (dbc *dbManager) getKmsAttributes(tenantId string, entities ...string) map[string][]Attribute {
+
+ db := dbc.db
+ var attName, attValue sql.NullString
+ var entity_id string
+ // TODO : is there no other better way to do in caluse???
+ sql := `select entity_id, name, value from kms_attributes where tenant_id = $1 and entity_id in ('` + strings.Join(entities, `','`) + `')`
+ mapOfAttributes := make(map[string][]Attribute)
+ attributes, err := db.Query(sql, tenantId)
+ if err != nil {
+ log.Error("Error while fetching attributes for tenant id : %s and entityId : %s", tenantId, err)
+ return mapOfAttributes
+ }
+ for attributes.Next() {
+ err := attributes.Scan(
+ &entity_id,
+ &attName,
+ &attValue,
+ )
+ if err != nil {
+ log.Error("error fetching attributes for entityid ", entities, err)
+ }
+ if attName.String != "" {
+ att := Attribute{Name: attName.String, Value: attValue.String}
+ mapOfAttributes[entity_id] = append(mapOfAttributes[entity_id], att)
+ }
+ }
+ log.Debug("attributes returned for query ", sql, " are ", mapOfAttributes)
+ return mapOfAttributes
+}
+
func (dbc dbManager) getApiKeyDetails(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) error {
db := dbc.db
- var proxies, environments, resources string
sSql := `
SELECT
COALESCE("developer","") as ctype,
@@ -121,21 +152,8 @@
COALESCE(a.created_at,"") as app_created_at,
COALESCE(a.created_by,"") as app_created_by,
COALESCE(a.updated_at,"") as app_updated_at,
- COALESCE(a.updated_by,"") as app_updated_by,
+ COALESCE(a.updated_by,"") as app_updated_by
- COALESCE(ap.id,"") as prod_id,
- COALESCE(ap.name,"") as prod_name,
- COALESCE(ap.display_name,"") as prod_display_name,
- COALESCE(ap.quota,"") as prod_quota,
- COALESCE(ap.quota_interval, 0) as prod_quota_interval,
- COALESCE(ap.quota_time_unit,"") as prod_quota_time_unit,
- COALESCE(ap.created_at,"") as prod_created_at,
- COALESCE(ap.created_by,"") as prod_created_by,
- COALESCE(ap.updated_at,"") as prod_updated_at,
- COALESCE(ap.updated_by,"") as prod_updated_by,
- COALESCE(ap.proxies,"") as prod_proxies,
- COALESCE(ap.environments,"") as prod_environments,
- COALESCE(ap.api_resources,"") as prod_resources
FROM
KMS_APP_CREDENTIAL AS c
INNER JOIN KMS_APP AS a
@@ -144,12 +162,10 @@
ON ad.id = a.developer_id
INNER JOIN KMS_APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
ON mp.appcred_id = c.id
- INNER JOIN KMS_API_PRODUCT as ap
- ON ap.id = mp.apiprdt_id
INNER JOIN KMS_ORGANIZATION AS o
ON o.tenant_id = c.tenant_id
- WHERE (mp.apiprdt_id = ap.id
- AND mp.app_id = a.id
+ WHERE (
+ mp.app_id = a.id
AND mp.appcred_id = c.id
AND c.id = $1
AND o.name = $2)
@@ -183,21 +199,7 @@
COALESCE(a.created_at,"") as app_created_at,
COALESCE(a.created_by,"") as app_created_by,
COALESCE(a.updated_at,"") as app_updated_at,
- COALESCE(a.updated_by,"") as app_updated_by,
-
- COALESCE(ap.id,"") as prod_id,
- COALESCE(ap.name,"") as prod_name,
- COALESCE(ap.display_name,"") as prod_display_name,
- COALESCE(ap.quota,"") as prod_quota,
- COALESCE(ap.quota_interval,0) as prod_quota_interval,
- COALESCE(ap.quota_time_unit,"") as prod_quota_time_unit,
- COALESCE(ap.created_at,"") as prod_created_at,
- COALESCE(ap.created_by,"") as prod_created_by,
- COALESCE(ap.updated_at,"") as prod_updated_at,
- COALESCE(ap.updated_by,"") as prod_updated_by,
- COALESCE(ap.proxies,"") as prod_proxies,
- COALESCE(ap.environments,"") as prod_environments,
- COALESCE(ap.api_resources,"") as prod_resources
+ COALESCE(a.updated_by,"") as app_updated_by
FROM
KMS_APP_CREDENTIAL AS c
@@ -207,12 +209,10 @@
ON ad.id = a.company_id
INNER JOIN KMS_APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
ON mp.appcred_id = c.id
- INNER JOIN KMS_API_PRODUCT as ap
- ON ap.id = mp.apiprdt_id
INNER JOIN KMS_ORGANIZATION AS o
ON o.tenant_id = c.tenant_id
- WHERE (mp.apiprdt_id = ap.id
- AND mp.app_id = a.id
+ WHERE (
+ mp.app_id = a.id
AND mp.appcred_id = c.id
AND c.id = $1
AND o.name = $2)
@@ -250,36 +250,90 @@
&dataWrapper.verifyApiKeySuccessResponse.App.CreatedBy,
&dataWrapper.verifyApiKeySuccessResponse.App.LastmodifiedAt,
&dataWrapper.verifyApiKeySuccessResponse.App.LastmodifiedBy,
-
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Name,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.DisplayName,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.QuotaLimit,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.QuotaInterval,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.QuotaTimeunit,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.CreatedAt,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.CreatedBy,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.LastmodifiedAt,
- &dataWrapper.verifyApiKeySuccessResponse.ApiProduct.LastmodifiedBy,
- &proxies,
- &environments,
- &resources,
)
if err != nil {
- log.Error("error fetching verify apikey details", err)
+ log.Error("error fetching verify apikey details ", err)
return err
}
- dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Apiproxies = jsonToStringArray(proxies)
- dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Environments = jsonToStringArray(environments)
- dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Resources = jsonToStringArray(resources)
-
if dataWrapper.verifyApiKeySuccessResponse.App.CallbackUrl != "" {
dataWrapper.verifyApiKeySuccessResponse.ClientId.RedirectURIs = []string{dataWrapper.verifyApiKeySuccessResponse.App.CallbackUrl}
}
+ dataWrapper.apiProducts = dbc.getApiProductsForApiKey(dataWrapper.verifyApiKeyRequest.Key, dataWrapper.tenant_id)
+
log.Debug("dataWrapper : ", dataWrapper)
return err
}
+
+func (dbc dbManager) getApiProductsForApiKey(key, tenantId string) []ApiProductDetails {
+
+ db := dbc.db
+ allProducts := []ApiProductDetails{}
+ var proxies, environments, resources string
+ sSql := `
+ SELECT
+ COALESCE(ap.id,"") as prod_id,
+ COALESCE(ap.name,"") as prod_name,
+ COALESCE(ap.display_name,"") as prod_display_name,
+ COALESCE(ap.quota,"") as prod_quota,
+ COALESCE(ap.quota_interval, 0) as prod_quota_interval,
+ COALESCE(ap.quota_time_unit,"") as prod_quota_time_unit,
+ COALESCE(ap.created_at,"") as prod_created_at,
+ COALESCE(ap.created_by,"") as prod_created_by,
+ COALESCE(ap.updated_at,"") as prod_updated_at,
+ COALESCE(ap.updated_by,"") as prod_updated_by,
+ COALESCE(ap.proxies,"") as prod_proxies,
+ COALESCE(ap.environments,"") as prod_environments,
+ COALESCE(ap.api_resources,"") as prod_resources
+ FROM
+ KMS_APP_CREDENTIAL AS c
+ INNER JOIN KMS_APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
+ ON mp.appcred_id = c.id
+ INNER JOIN KMS_API_PRODUCT as ap
+ ON ap.id = mp.apiprdt_id
+ WHERE (mp.apiprdt_id = ap.id
+ AND mp.appcred_id = c.id
+ AND c.id = $1
+ AND ap.tenant_id = $2)
+ ;`
+
+ //cid,csecret,did,dusername,dfirstname,dlastname,demail,dstatus,dcreated_at,dcreated_by,dlast_modified_at,dlast_modified_by, aid,aname,aaccesstype,acallbackurl,adisplay_name,astatus,aappfamily, acompany,acreated_at,acreated_by,alast_modified_at,alast_modified_by,pid,pname,pdisplayname,pquota_limit,pqutoainterval,pquotatimeout,pcreated_at,pcreated_by,plast_modified_at,plast_modified_by sql.NullString
+
+ rows, err := db.Query(sSql, key, tenantId)
+
+ if err != nil {
+ log.Error("error fetching apiProduct details", err)
+ return allProducts
+ }
+
+ for rows.Next() {
+ apiProductDetais := ApiProductDetails{}
+ rows.Scan(
+ &apiProductDetais.Id,
+ &apiProductDetais.Name,
+ &apiProductDetais.DisplayName,
+ &apiProductDetais.QuotaLimit,
+ &apiProductDetais.QuotaInterval,
+ &apiProductDetais.QuotaTimeunit,
+ &apiProductDetais.CreatedAt,
+ &apiProductDetais.CreatedBy,
+ &apiProductDetais.LastmodifiedAt,
+ &apiProductDetais.LastmodifiedBy,
+ &proxies,
+ &environments,
+ &resources,
+ )
+ apiProductDetais.Apiproxies = jsonToStringArray(proxies)
+ apiProductDetais.Environments = jsonToStringArray(environments)
+ apiProductDetais.Resources = jsonToStringArray(resources)
+
+ allProducts = append(allProducts, apiProductDetais)
+ }
+
+ log.Debug("Api products retrieved for key : [%s] , tenantId : [%s] is ", key, tenantId, allProducts)
+
+ return allProducts
+}
diff --git a/init.go b/init.go
index 5251cd1..a60b40e 100644
--- a/init.go
+++ b/init.go
@@ -61,155 +61,3 @@
return pluginData, nil
}
-
-func createTables(db apid.DB) {
- _, err := db.Exec(`
-CREATE TABLE IF NOT EXISTS kms_api_product (
- id text,
- tenant_id text,
- name text,
- display_name text,
- description text,
- api_resources text[],
- approval_type text,
- _change_selector text,
- proxies text[],
- environments text[],
- quota text,
- quota_time_unit text,
- quota_interval int,
- created_at int64,
- created_by text,
- updated_at int64,
- updated_by text,
- PRIMARY KEY (tenant_id, id));
-CREATE TABLE IF NOT EXISTS kms_developer (
- id text,
- tenant_id text,
- username text,
- first_name text,
- last_name text,
- password text,
- email text,
- status text,
- encrypted_password text,
- salt text,
- _change_selector text,
- created_at int64,
- created_by text,
- updated_at int64,
- updated_by text,
- PRIMARY KEY (tenant_id, id)
-);
-CREATE TABLE IF NOT EXISTS kms_company (
- id text,
- tenant_id text,
- name text,
- display_name text,
- status text,
- created_at int64,
- created_by text,
- updated_at int64,
- updated_by text,
- _change_selector text,
- PRIMARY KEY (tenant_id, id)
-);
-CREATE TABLE IF NOT EXISTS kms_company_developer (
- tenant_id text,
- company_id text,
- developer_id text,
- roles text[],
- created_at int64,
- created_by text,
- updated_at int64,
- updated_by text,
- _change_selector text,
- PRIMARY KEY (tenant_id, company_id,developer_id)
-);
-CREATE TABLE IF NOT EXISTS kms_app (
- id text,
- tenant_id text,
- name text,
- display_name text,
- access_type text,
- callback_url text,
- status text,
- app_family text,
- company_id text,
- parent_id text,
- developer_id text,
- type int,
- created_at int64,
- created_by text,
- updated_at int64,
- updated_by text,
- _change_selector text,
- PRIMARY KEY (tenant_id, id)
-);
-CREATE TABLE IF NOT EXISTS kms_app_credential (
- id text,
- tenant_id text,
- consumer_secret text,
- app_id text,
- method_type text,
- status text,
- issued_at int64,
- expires_at int64,
- app_status text,
- _change_selector text,
- PRIMARY KEY (tenant_id, id)
-);
-CREATE TABLE IF NOT EXISTS kms_app_credential_apiproduct_mapper (
- tenant_id text,
- appcred_id text,
- app_id text,
- apiprdt_id text,
- _change_selector text,
- status text,
- PRIMARY KEY (appcred_id, app_id, apiprdt_id,tenant_id)
-);
-CREATE INDEX IF NOT EXISTS company_id ON kms_company (id);
-CREATE INDEX IF NOT EXISTS developer_id ON kms_developer (id);
-CREATE INDEX IF NOT EXISTS api_product_id ON kms_api_product (id);
-CREATE INDEX IF NOT EXISTS app_id ON kms_app (id);
-`)
- if err != nil {
- log.Panic("Unable to initialize DB", err)
- }
-}
-
-func createApidClusterTables(db apid.DB) {
- _, err := db.Exec(`
-CREATE TABLE edgex_apid_cluster (
- id text,
- instance_id text,
- name text,
- description text,
- umbrella_org_app_name text,
- created int64,
- created_by text,
- updated int64,
- updated_by text,
- _change_selector text,
- snapshotInfo text,
- lastSequence text,
- PRIMARY KEY (id)
-);
-CREATE TABLE edgex_data_scope (
- id text,
- apid_cluster_id text,
- scope text,
- org text,
- env text,
- created int64,
- created_by text,
- updated int64,
- updated_by text,
- _change_selector text,
- PRIMARY KEY (id)
-);
-`)
- if err != nil {
- log.Panic("Unable to initialize DB", err)
- }
-}
diff --git a/listener.go b/listener.go
index 19ff9cc..416c557 100644
--- a/listener.go
+++ b/listener.go
@@ -49,6 +49,6 @@
if snapData, ok := e.(*common.Snapshot); ok {
h.processSnapshot(snapData)
} else {
- log.Debugf("Received invalid event. Ignoring. %v", e)
+ log.Debugf("Received event. No action required for verifyApiKey plugin. Ignoring. %v", e)
}
}
diff --git a/listener_test.go b/listener_test.go
index 0645677..dc3cd34 100644
--- a/listener_test.go
+++ b/listener_test.go
@@ -18,18 +18,19 @@
"github.com/30x/apid-core"
"github.com/apigee-labs/transicator/common"
. "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
+ //. "github.com/onsi/gomega"
+ //"github.com/30x/apid-core/data"
)
var _ = Describe("listener", func() {
Context("KMS create/updates verification via changes for Developer", func() {
- handler := handler{}
+ handler := apigeeSyncHandler{}
It("should set DB to appropriate version", func() {
- saveDb := getDB()
+ //saveDb := handler.dbMan.getDb()
s := &common.Snapshot{
SnapshotInfo: "test_snapshot",
@@ -38,13 +39,13 @@
handler.Handle(s)
- expectedDB, err := data.DBVersion(s.SnapshotInfo)
- Expect(err).NotTo(HaveOccurred())
-
- Expect(getDB() == expectedDB).Should(BeTrue())
-
- //restore the db to the valid one
- setDB(saveDb)
+ //expectedDB, err := handler.dbMan.data.DBVersion(s.SnapshotInfo)
+ //Expect(err).NotTo(HaveOccurred())
+ //
+ //Expect(getDB() == expectedDB).Should(BeTrue())
+ //
+ ////restore the db to the valid one
+ //setDB(saveDb)
})
})
diff --git a/test_helper.go b/test_helper.go
index 12e135b..de2db79 100644
--- a/test_helper.go
+++ b/test_helper.go
@@ -16,6 +16,7 @@
import (
"database/sql"
+ "github.com/30x/apid-core"
"strconv"
)
@@ -99,3 +100,155 @@
s.Exec("api_product_"+convertSuffix(suffix), "Approved", "application_id_"+convertSuffix(suffix),
"app_credential_"+convertSuffix(suffix), "tenant_id_xxxx", "Org_0")
}
+
+func createTables(db apid.DB) {
+ _, err := db.Exec(`
+CREATE TABLE IF NOT EXISTS kms_api_product (
+ id text,
+ tenant_id text,
+ name text,
+ display_name text,
+ description text,
+ api_resources text[],
+ approval_type text,
+ _change_selector text,
+ proxies text[],
+ environments text[],
+ quota text,
+ quota_time_unit text,
+ quota_interval int,
+ created_at int64,
+ created_by text,
+ updated_at int64,
+ updated_by text,
+ PRIMARY KEY (tenant_id, id));
+CREATE TABLE IF NOT EXISTS kms_developer (
+ id text,
+ tenant_id text,
+ username text,
+ first_name text,
+ last_name text,
+ password text,
+ email text,
+ status text,
+ encrypted_password text,
+ salt text,
+ _change_selector text,
+ created_at int64,
+ created_by text,
+ updated_at int64,
+ updated_by text,
+ PRIMARY KEY (tenant_id, id)
+);
+CREATE TABLE IF NOT EXISTS kms_company (
+ id text,
+ tenant_id text,
+ name text,
+ display_name text,
+ status text,
+ created_at int64,
+ created_by text,
+ updated_at int64,
+ updated_by text,
+ _change_selector text,
+ PRIMARY KEY (tenant_id, id)
+);
+CREATE TABLE IF NOT EXISTS kms_company_developer (
+ tenant_id text,
+ company_id text,
+ developer_id text,
+ roles text[],
+ created_at int64,
+ created_by text,
+ updated_at int64,
+ updated_by text,
+ _change_selector text,
+ PRIMARY KEY (tenant_id, company_id,developer_id)
+);
+CREATE TABLE IF NOT EXISTS kms_app (
+ id text,
+ tenant_id text,
+ name text,
+ display_name text,
+ access_type text,
+ callback_url text,
+ status text,
+ app_family text,
+ company_id text,
+ parent_id text,
+ developer_id text,
+ type int,
+ created_at int64,
+ created_by text,
+ updated_at int64,
+ updated_by text,
+ _change_selector text,
+ PRIMARY KEY (tenant_id, id)
+);
+CREATE TABLE IF NOT EXISTS kms_app_credential (
+ id text,
+ tenant_id text,
+ consumer_secret text,
+ app_id text,
+ method_type text,
+ status text,
+ issued_at int64,
+ expires_at int64,
+ app_status text,
+ _change_selector text,
+ PRIMARY KEY (tenant_id, id)
+);
+CREATE TABLE IF NOT EXISTS kms_app_credential_apiproduct_mapper (
+ tenant_id text,
+ appcred_id text,
+ app_id text,
+ apiprdt_id text,
+ _change_selector text,
+ status text,
+ PRIMARY KEY (appcred_id, app_id, apiprdt_id,tenant_id)
+);
+CREATE INDEX IF NOT EXISTS company_id ON kms_company (id);
+CREATE INDEX IF NOT EXISTS developer_id ON kms_developer (id);
+CREATE INDEX IF NOT EXISTS api_product_id ON kms_api_product (id);
+CREATE INDEX IF NOT EXISTS app_id ON kms_app (id);
+`)
+ if err != nil {
+ log.Panic("Unable to initialize DB", err)
+ }
+}
+
+func createApidClusterTables(db apid.DB) {
+ _, err := db.Exec(`
+CREATE TABLE edgex_apid_cluster (
+ id text,
+ instance_id text,
+ name text,
+ description text,
+ umbrella_org_app_name text,
+ created int64,
+ created_by text,
+ updated int64,
+ updated_by text,
+ _change_selector text,
+ snapshotInfo text,
+ lastSequence text,
+ PRIMARY KEY (id)
+);
+CREATE TABLE edgex_data_scope (
+ id text,
+ apid_cluster_id text,
+ scope text,
+ org text,
+ env text,
+ created int64,
+ created_by text,
+ updated int64,
+ updated_by text,
+ _change_selector text,
+ PRIMARY KEY (id)
+);
+`)
+ if err != nil {
+ log.Panic("Unable to initialize DB", err)
+ }
+}
diff --git a/validate_env_test.go b/validate_env_test.go
index e07e240..024e26b 100644
--- a/validate_env_test.go
+++ b/validate_env_test.go
@@ -22,19 +22,19 @@
var _ = Describe("Validate Env", func() {
It("validation1", func() {
- s := validateEnv("{foo,bar}", "foo")
+ s := contains([]string{"foo", "bar"}, "foo")
Expect(s).Should(BeTrue())
})
It("validation2", func() {
- s := validateEnv("{foo,bar}", "bar")
+ s := contains([]string{"foo", "bar"}, "bar")
Expect(s).Should(BeTrue())
})
It("validation3", func() {
- s := validateEnv("{foo,bar}", "xxx")
+ s := contains([]string{"foo", "bar"}, "xxx")
Expect(s).Should(BeFalse())
})
It("validation4", func() {
- s := validateEnv("{}", "xxx")
+ s := contains([]string{}, "xxx")
Expect(s).Should(BeFalse())
})
})
diff --git a/validate_path_test.go b/validate_path_test.go
index 02fc0eb..563b52c 100644
--- a/validate_path_test.go
+++ b/validate_path_test.go
@@ -22,87 +22,87 @@
var _ = Describe("Validate Path", func() {
It("validation1", func() {
- s := validatePath("", "/foo")
+ s := validatePath([]string{}, "/foo")
Expect(s).Should(BeTrue())
})
It("validation2", func() {
- s := validatePath("", "foo")
+ s := validatePath([]string{}, "foo")
Expect(s).Should(BeTrue())
})
It("validation3", func() {
- s := validatePath("{}", "foo")
+ s := validatePath([]string{}, "foo")
Expect(s).Should(BeTrue())
})
It("validation4", func() {
- s := validatePath("{/**}", "/foo")
+ s := validatePath([]string{"/**"}, "/foo")
Expect(s).Should(BeTrue())
})
It("validation5", func() {
- s := validatePath("{/**}", "foo")
+ s := validatePath([]string{"/**"}, "foo")
Expect(s).Should(BeFalse())
})
It("validation6", func() {
- s := validatePath("{/**}", "/")
+ s := validatePath([]string{"/**"}, "/")
Expect(s).Should(BeTrue())
})
It("validation7", func() {
- s := validatePath("{/foo/**}", "/")
+ s := validatePath([]string{"/foo/**"}, "/")
Expect(s).Should(BeFalse())
})
It("validation8", func() {
- s := validatePath("{/foo/**}", "/foo/")
+ s := validatePath([]string{"/foo/**"}, "/foo/")
Expect(s).Should(BeTrue())
})
It("validation9", func() {
- s := validatePath("{/foo/**}", "/foo/bar")
+ s := validatePath([]string{"{/foo/**"}, "/foo/bar")
Expect(s).Should(BeTrue())
})
It("validation10", func() {
- s := validatePath("{/foo/**}", "foo")
+ s := validatePath([]string{"/foo/**"}, "foo")
Expect(s).Should(BeFalse())
})
It("validation11", func() {
- s := validatePath("{/foo/bar/**}", "/foo/bar/xx/yy")
+ s := validatePath([]string{"{/foo/bar/**"}, "/foo/bar/xx/yy")
Expect(s).Should(BeTrue())
})
It("validation12", func() {
- s := validatePath("/foo/bar/*}", "/foo/bar/xxx")
+ s := validatePath([]string{"/foo/bar/*"}, "/foo/bar/xxx")
Expect(s).Should(BeTrue())
})
It("validation13", func() {
- s := validatePath("{/foo/bar/*/}", "/foo/bar/xxx")
+ s := validatePath([]string{"{/foo/bar/*/"}, "/foo/bar/xxx")
Expect(s).Should(BeFalse())
})
It("validation14", func() {
- s := validatePath("{/foo/bar/**}", "/foo/bar/xx/yy")
+ s := validatePath([]string{"{/foo/bar/**"}, "/foo/bar/xx/yy")
Expect(s).Should(BeTrue())
})
It("validation15", func() {
- s := validatePath("{/foo/*/**/}", "/foo/bar")
+ s := validatePath([]string{"{/foo/*/**/"}, "/foo/bar")
Expect(s).Should(BeFalse())
})
It("validation16", func() {
- s := validatePath("{/foo/bar/*/xxx}", "/foo/bar/yyy/xxx")
+ s := validatePath([]string{"{/foo/bar/*/xxx"}, "/foo/bar/yyy/xxx")
Expect(s).Should(BeTrue())
})
It("validation17", func() {
- s := validatePath("{/foo/bar/*/xxx/}", "/foo/bar/yyy/xxx")
+ s := validatePath([]string{"{/foo/bar/*/xxx/"}, "/foo/bar/yyy/xxx")
Expect(s).Should(BeFalse())
})
It("validation18", func() {
- s := validatePath("{/foo/bar/**/xxx/}", "/foo/bar/aaa/bbb/xxx/")
+ s := validatePath([]string{"{/foo/bar/**/xxx/"}, "/foo/bar/aaa/bbb/xxx/")
Expect(s).Should(BeTrue())
})
It("validation19", func() {
- s := validatePath("{/foo/bar/***/xxx/}", "/foo/bar/aaa/bbb/xxx/")
+ s := validatePath([]string{"{/foo/bar/***/xxx/"}, "/foo/bar/aaa/bbb/xxx/")
Expect(s).Should(BeTrue())
})
It("validation20", func() {
- s := validatePath("{/foo/, /bar/}", "/foo/")
+ s := validatePath([]string{"{/foo/, /bar/"}, "/foo/")
Expect(s).Should(BeTrue())
})
It("validation21", func() {
- s := validatePath("{/foo/bar/yy*/xxx}", "/foo/bar/yyy/xxx")
+ s := validatePath([]string{"{/foo/bar/yy*/xxx"}, "/foo/bar/yyy/xxx")
Expect(s).Should(BeTrue())
})
})
diff --git a/verifyAPIKey_suite_test.go b/verifyAPIKey_suite_test_old.go.bak
similarity index 90%
rename from verifyAPIKey_suite_test.go
rename to verifyAPIKey_suite_test_old.go.bak
index 7a62357..ff656a3 100644
--- a/verifyAPIKey_suite_test.go
+++ b/verifyAPIKey_suite_test_old.go.bak
@@ -21,7 +21,7 @@
"github.com/30x/apid-core"
"github.com/30x/apid-core/factory"
"io/ioutil"
- "net/http"
+ //"net/http"
"net/http/httptest"
"os"
"testing"
@@ -47,15 +47,15 @@
db, err := apid.Data().DB()
Expect(err).NotTo(HaveOccurred())
- setDB(db)
- createTables(db)
- createApidClusterTables(db)
- addScopes(db)
- testServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- if req.URL.Path == apiPath {
- handleRequest(w, req)
- }
- }))
+ //setDB(db)
+ //createTables(db)
+ //createApidClusterTables(db)
+ //addScopes(db)
+ //testServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ // if req.URL.Path == apiPath {
+ // handleRequest(w, req)
+ // }
+ //}))
createTestData(db)
})
diff --git a/verifyApiKeyStructs.go b/verifyApiKeyStructs.go
index c5656ac..49a4b15 100644
--- a/verifyApiKeyStructs.go
+++ b/verifyApiKeyStructs.go
@@ -121,6 +121,7 @@
verifyApiKeyRequest VerifyApiKeyRequest
verifyApiKeySuccessResponse VerifyApiKeySuccessResponse
tempDeveloperDetails DeveloperDetails
+ apiProducts []ApiProductDetails
ctype string
tenant_id string
}
diff --git a/verifyApiKeyUtil.go b/verifyApiKeyUtil.go
index 33ec5aa..16d0936 100644
--- a/verifyApiKeyUtil.go
+++ b/verifyApiKeyUtil.go
@@ -21,21 +21,6 @@
"unicode/utf8"
)
-func validateEnv(envLocal string, envInPath string) bool {
- if envInPath == "" {
- return false
- }
- s := strings.TrimPrefix(envLocal, "{")
- s = strings.TrimSuffix(s, "}")
- fs := strings.Split(s, ",")
- for _, a := range fs {
- if a == envInPath {
- return true
- }
- }
- return false
-}
-
/*
* Check for the base path (API_Product) match with the path
* received in the Request, via the customized regex, where
@@ -76,11 +61,20 @@
if err := json.Unmarshal([]byte(fjson), array); err == nil {
return array
}
- log.Debug("unmarshall error for string, performing custom unmarshal ", fjson)
s := strings.TrimPrefix(fjson, "{")
s = strings.TrimSuffix(s, "}")
if utf8.RuneCountInString(s) > 0 {
array = strings.Split(s, ",")
}
+ log.Debug("unmarshall error for string, performing custom unmarshal ", fjson, " and result is : ", array)
return array
}
+
+func contains(givenArray []string, searchString string) bool {
+ for _, element := range givenArray {
+ if element == searchString {
+ return true
+ }
+ }
+ return false
+}