Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TT-5988] Use defaults APISpec if no API ID found (inactive or deleted) #5423

Merged
merged 6 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 45 additions & 58 deletions gateway/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,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
Expand Down Expand Up @@ -323,48 +320,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",
})
Dismissed Show dismissed Hide dismissed

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()

Expand All @@ -381,17 +384,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
}

Expand Down Expand Up @@ -1980,9 +1973,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
Expand All @@ -1991,28 +1988,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 {
Expand All @@ -2034,8 +2021,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 {
Expand Down
7 changes: 7 additions & 0 deletions gateway/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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},
}...)
Expand Down
Loading