| /* |
| 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 adapter |
| |
| import ( |
| "fmt" |
| "net/url" |
| |
| "github.com/apid/istioApigeeAdapter/adapter/config" |
| "istio.io/mixer/pkg/adapter" |
| ) |
| |
| const ( |
| checkName = "apigeeKeyChecker" |
| checkDesc = "Verify an API key from a parameter" |
| verifyKeyPath = "/verifyApiKey" |
| productsPath = "/products" |
| defaultVerifyURL = "https://%s-%s.apigee.net/edgemicro-auth" |
| ) |
| |
| var checkConf = &config.VerifyKeyParams{} |
| |
| type keyCheckBuilder struct { |
| adapter.DefaultBuilder |
| } |
| |
| type keyChecker struct { |
| env adapter.Env |
| application *applicationManager |
| } |
| |
| func newKeyCheckBuilder() adapter.ListsBuilder { |
| return keyCheckBuilder{ |
| adapter.NewDefaultBuilder(checkName, checkDesc, checkConf), |
| } |
| } |
| |
| func (b keyCheckBuilder) ValidateConfig(c adapter.Config) *adapter.ConfigErrors { |
| return validateKeyParams(c) |
| } |
| |
| func validateKeyParams(c adapter.Config) (ce *adapter.ConfigErrors) { |
| cfg := c.(*config.VerifyKeyParams) |
| if cfg.Organization == "" { |
| ce = ce.Appendf("organization", "Organization parameter must be specified") |
| } |
| if cfg.Environment == "" { |
| ce = ce.Appendf("environment", "Environment parameter must be specified") |
| } |
| if cfg.VerificationURL != "" { |
| _, err := url.Parse(cfg.VerificationURL) |
| if err != nil { |
| ce = ce.Appendf("verificationURL", "Invalid verification URL: %s", err) |
| } |
| } |
| return |
| } |
| |
| func (b keyCheckBuilder) NewListsAspect(env adapter.Env, c adapter.Config) (adapter.ListsAspect, error) { |
| cfg := c.(*config.VerifyKeyParams) |
| verifyPath, _ := getPaths(cfg) |
| kc := &keyChecker{ |
| env: env, |
| application: newApplicationManager(env, defaultAppLifetime, verifyPath), |
| } |
| env.Logger().Infof("Created Apigee Key Checker to invoke \"%s\"", kc.application.checkURL) |
| |
| return kc, nil |
| } |
| |
| func getPaths(cfg *config.VerifyKeyParams) (string, string) { |
| var basePath string |
| |
| if cfg.VerificationURL == "" { |
| basePath = fmt.Sprintf(defaultVerifyURL, cfg.Organization, cfg.Environment) |
| } else { |
| basePath = cfg.VerificationURL |
| } |
| return basePath + verifyKeyPath, basePath + productsPath |
| } |
| |
| func (l *keyChecker) Close() error { |
| return nil |
| } |
| |
| // CheckList is part of the interface for a "list checker" adapter. It's the part that |
| // gets whatever the value is (we want it to be the API key in our case) and checks it. |
| |
| // Test command ./bazel-bin/cmd/client/mixc check -a target.service=f.default.svc.cluster.local --stringmap_attributes request.headers=x-api-key:1tu9pl04Srua2MtsAGtu6ViPxSYSSX2I |
| |
| func (l *keyChecker) CheckList(symbol string) (bool, error) { |
| app, err := l.application.get(symbol) |
| if err != nil { |
| l.env.Logger().Errorf("Error verifying API key: %s", err) |
| return false, err |
| } |
| return app.valid, nil |
| } |