diff --git a/gateway/api.go b/gateway/api.go index 99636281b011..f9ba912eee9b 100644 --- a/gateway/api.go +++ b/gateway/api.go @@ -262,11 +262,8 @@ func (gw *Gateway) applyPoliciesAndSave(keyName string, session *user.SessionSta // calculate lifetime considering access rights lifetime := gw.ApplyLifetime(session, spec) - if err := gw.GlobalSessionManager.UpdateSession(keyName, session, lifetime, isHashed); err != nil { - return err - } - return nil + return gw.GlobalSessionManager.UpdateSession(keyName, session, lifetime, isHashed) } // GetApiSpecsFromAccessRights from the session.AccessRights returns the collection of api specs @@ -322,48 +319,54 @@ func (gw *Gateway) doAddOrUpdate(keyName string, newSession *user.SessionState, newSession.LastUpdated = strconv.Itoa(int(time.Now().Unix())) } + logger := log.WithFields(logrus.Fields{ + "prefix": "api", + "key": gw.obfuscateKey(keyName), + "org_id": newSession.OrgID, + "expires": newSession.Expires, + "api_id": "--", + "user_id": "system", + "user_ip": "--", + "path": "--", + "server_name": "system", + }) + if len(newSession.AccessRights) > 0 { // reset API-level limit to empty APILimit if any has a zero-value resetAPILimits(newSession.AccessRights) + // We have a specific list of access rules, only add / update those for apiId := range newSession.AccessRights { apiSpec := gw.getApiSpec(apiId) if apiSpec == nil { - log.WithFields(logrus.Fields{ - "prefix": "api", - "key": keyName, - "org_id": newSession.OrgID, - "api_id": apiId, - "user_id": "system", - "user_ip": "--", - "path": "--", - "server_name": "system", - }).Error("Could not add key for this API ID, API doesn't exist.") - return errors.New("API must be active to add keys") + logger.WithField("api_id", apiId).Warn("Can't find active API, storing anyway") + } + + if apiSpec != nil { + gw.checkAndApplyTrialPeriod(keyName, newSession, isHashed) } - gw.checkAndApplyTrialPeriod(keyName, newSession, isHashed) // Lets reset keys if they are edited by admin - if !apiSpec.DontSetQuotasOnCreate { + if apiSpec == nil || !apiSpec.DontSetQuotasOnCreate { // Reset quote by default if !dontReset { gw.GlobalSessionManager.ResetQuota(keyName, newSession, isHashed) newSession.QuotaRenews = time.Now().Unix() + newSession.QuotaRenewalRate } + } - // apply polices (if any) and save key - if err := gw.applyPoliciesAndSave(keyName, newSession, apiSpec, isHashed); err != nil { - return err - } + // apply polices (if any) and save key + if err := gw.applyPoliciesAndSave(keyName, newSession, apiSpec, isHashed); err != nil { + return err } } } else { // nothing defined, add key to ALL if !gw.GetConfig().AllowMasterKeys { - log.Error("Master keys disallowed in configuration, key not added.") + logger.Error("Master keys disallowed in configuration, key not added.") return errors.New("Master keys not allowed") } - log.Warning("No API Access Rights set, adding key to ALL.") + logger.Warning("No API Access Rights set, adding key to ALL.") gw.apisMu.RLock() defer gw.apisMu.RUnlock() @@ -380,17 +383,7 @@ func (gw *Gateway) doAddOrUpdate(keyName string, newSession *user.SessionState, } } - log.WithFields(logrus.Fields{ - "prefix": "api", - "key": gw.obfuscateKey(keyName), - "expires": newSession.Expires, - "org_id": newSession.OrgID, - "api_id": "--", - "user_id": "system", - "user_ip": "--", - "path": "--", - "server_name": "system", - }).Info("Key added or updated.") + logger.Info("Key added or updated.") return nil } @@ -1979,9 +1972,13 @@ func (gw *Gateway) createKeyHandler(w http.ResponseWriter, r *http.Request) { newSession.LastUpdated = strconv.Itoa(int(time.Now().Unix())) newSession.DateCreated = time.Now() + sessionManager := gw.GlobalSessionManager + mw := BaseMiddleware{Gw: gw} - // TODO: handle apply policies error - mw.ApplyPolicies(newSession) + if err := mw.ApplyPolicies(newSession); err != nil { + doJSONWrite(w, http.StatusInternalServerError, apiError("Failed to create key - "+err.Error())) + return + } if len(newSession.AccessRights) > 0 { // reset API-level limit to nil if any has a zero-value @@ -1990,28 +1987,18 @@ func (gw *Gateway) createKeyHandler(w http.ResponseWriter, r *http.Request) { apiSpec := gw.getApiSpec(apiID) if apiSpec != nil { gw.checkAndApplyTrialPeriod(newKey, newSession, false) - // If we have enabled HMAC checking for keys, we need to generate a secret for the client to use - if !apiSpec.DontSetQuotasOnCreate { - // Reset quota by default - gw.GlobalSessionManager.ResetQuota(newKey, newSession, false) - newSession.QuotaRenews = time.Now().Unix() + newSession.QuotaRenewalRate - } - // apply polices (if any) and save key - if err := gw.applyPoliciesAndSave(newKey, newSession, apiSpec, false); err != nil { - doJSONWrite(w, http.StatusInternalServerError, apiError("Failed to create key - "+err.Error())) - return - } - } else { - // Use fallback - sessionManager := gw.GlobalSessionManager + } + + if apiSpec == nil || !apiSpec.DontSetQuotasOnCreate { + // Reset quota by default newSession.QuotaRenews = time.Now().Unix() + newSession.QuotaRenewalRate sessionManager.ResetQuota(newKey, newSession, false) - // apply polices (if any) and save key - err := sessionManager.UpdateSession(newKey, newSession, -1, false) - if err != nil { - doJSONWrite(w, http.StatusInternalServerError, apiError("Failed to create key - "+err.Error())) - return - } + } + + // apply polices (if any) and save key + if err := gw.applyPoliciesAndSave(newKey, newSession, apiSpec, false); err != nil { + doJSONWrite(w, http.StatusInternalServerError, apiError("Failed to create key - "+err.Error())) + return } } } else { @@ -2033,8 +2020,8 @@ func (gw *Gateway) createKeyHandler(w http.ResponseWriter, r *http.Request) { for _, spec := range gw.apisByID { gw.checkAndApplyTrialPeriod(newKey, newSession, false) if !spec.DontSetQuotasOnCreate { - // Reset quote by default - gw.GlobalSessionManager.ResetQuota(newKey, newSession, false) + // Reset quota by default + sessionManager.ResetQuota(newKey, newSession, false) newSession.QuotaRenews = time.Now().Unix() + newSession.QuotaRenewalRate } if err := gw.applyPoliciesAndSave(newKey, newSession, spec, false); err != nil { diff --git a/gateway/api_test.go b/gateway/api_test.go index e0f1f2396187..c9c96220c0d5 100644 --- a/gateway/api_test.go +++ b/gateway/api_test.go @@ -269,6 +269,12 @@ func TestKeyHandler(t *testing.T) { } withBadPolicyJSON := test.MarshalJSON(t)(withBadPolicy) + withUnknownAPI := CreateStandardSession() + withUnknownAPI.AccessRights = map[string]user.AccessDefinition{"unknown": { + APIID: "unknown", Versions: []string{"v1"}, + }} + withUnknownAPIJSON := test.MarshalJSON(t)(withUnknownAPI) + t.Run("Create key", func(t *testing.T) { _, _ = ts.Run(t, []test.TestCase{ // Master keys should be disabled by default @@ -405,6 +411,7 @@ func TestKeyHandler(t *testing.T) { // Without data {Method: "PUT", Path: "/tyk/keys/" + knownKey, AdminAuth: true, Code: 400}, {Method: "PUT", Path: "/tyk/keys/" + knownKey, Data: string(withAccessJSON), AdminAuth: true, Code: 200}, + {Method: "PUT", Path: "/tyk/keys/" + knownKey, Data: string(withUnknownAPIJSON), AdminAuth: true, Code: 200}, {Method: "PUT", Path: "/tyk/keys/" + knownKey + "?api_id=test", Data: string(withAccessJSON), AdminAuth: true, Code: 200}, {Method: "PUT", Path: "/tyk/keys/" + knownKey + "?api_id=none", Data: string(withAccessJSON), AdminAuth: true, Code: 200}, }...)