Skip to content

Commit

Permalink
Merge 2218227 into 7e70c43
Browse files Browse the repository at this point in the history
  • Loading branch information
dencoded committed Dec 24, 2018
2 parents 7e70c43 + 2218227 commit 7a98d61
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 7 deletions.
27 changes: 23 additions & 4 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,21 +660,32 @@ func keyHandler(w http.ResponseWriter, r *http.Request) {
orgID := r.URL.Query().Get("org_id")

// check if passed key is user name and convert it to real key with respect to current hashing algorithm
origKeyName := keyName
if r.Method != http.MethodPost && isUserName {
keyName = generateToken(orgID, keyName)
}

var obj interface{}
var code int
hashKeyFunction := config.Global().HashKeyFunction

switch r.Method {
case "POST", "PUT":
case http.MethodPost:
obj, code = handleAddOrUpdate(keyName, r)

case "GET":
case http.MethodPut:
obj, code = handleAddOrUpdate(keyName, r)
if code != http.StatusOK && hashKeyFunction != "" {
// try to use legacy key format
obj, code = handleAddOrUpdate(origKeyName, r)
}
case http.MethodGet:
if keyName != "" {
// Return single key detail
obj, code = handleGetDetail(keyName, apiID, isHashed)
if code != http.StatusOK && hashKeyFunction != "" {
// try to use legacy key format
obj, code = handleGetDetail(origKeyName, apiID, isHashed)
}
} else {
// Return list of keys
if config.Global().HashKeys {
Expand All @@ -696,13 +707,21 @@ func keyHandler(w http.ResponseWriter, r *http.Request) {
}
}

case "DELETE":
case http.MethodDelete:
// Remove a key
if !isHashed {
obj, code = handleDeleteKey(keyName, apiID)
} else {
obj, code = handleDeleteHashedKey(keyName, apiID)
}
if code != http.StatusOK && hashKeyFunction != "" {
// try to use legacy key format
if !isHashed {
obj, code = handleDeleteKey(origKeyName, apiID)
} else {
obj, code = handleDeleteHashedKey(origKeyName, apiID)
}
}
}

doJSONWrite(w, code, obj)
Expand Down
53 changes: 53 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,59 @@ func TestHashKeyHandler(t *testing.T) {
}
}

func TestHashKeyHandlerLegacyWithHashFunc(t *testing.T) {
globalConf := config.Global()

globalConf.HashKeys = true
globalConf.EnableHashedKeysListing = true
// settings to create BA session with legacy key format
globalConf.HashKeyFunction = ""
config.SetGlobal(globalConf)
defer resetTestConfig()

ts := newTykTestServer()
defer ts.Close()

// create session with legacy key format
session := testPrepareBasicAuth(false)

ts.Run(t, []test.TestCase{
{
Method: "POST",
Path: "/tyk/keys/defaultuser",
Data: session,
AdminAuth: true,
Code: 200,
},
{
Method: "GET",
Path: "/tyk/keys/defaultuser?username=true&org_id=default",
AdminAuth: true,
Code: 200,
},
}...)

// set custom hashing function and check if we still can get BA session with legacy key format
globalConf.HashKeyFunction = storage.HashMurmur64
config.SetGlobal(globalConf)

ts.Run(t, []test.TestCase{
{
Method: "GET",
Path: "/tyk/keys/defaultuser?username=true&org_id=default",
AdminAuth: true,
Code: 200,
},
{
Method: "DELETE",
Path: "/tyk/keys/defaultuser?username=true&org_id=default",
AdminAuth: true,
Code: 200,
BodyMatch: `"action":"deleted"`,
},
}...)
}

func testHashKeyHandlerHelper(t *testing.T, expectedHashSize int) {
ts := newTykTestServer()
defer ts.Close()
Expand Down
19 changes: 16 additions & 3 deletions mw_basic_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (
"strings"
"time"

"github.com/TykTechnologies/tyk/config"
"github.com/TykTechnologies/tyk/storage"

"github.com/Sirupsen/logrus"
"github.com/pmylund/go-cache"
"golang.org/x/crypto/bcrypt"
Expand Down Expand Up @@ -82,9 +85,19 @@ func (k *BasicAuthKeyIsValid) ProcessRequest(w http.ResponseWriter, r *http.Requ
logger = k.Logger().WithField("key", obfuscateKey(keyName))
session, keyExists := k.CheckSessionAndIdentityForValidKey(keyName, r)
if !keyExists {
logger.Info("Attempted access with non-existent user.")

return k.handleAuthFail(w, r, token)
if config.Global().HashKeyFunction == "" {
logger.Warning("Attempted access with non-existent user.")
return k.handleAuthFail(w, r, token)
} else { // check for key with legacy format "org_id" + "user_name"
logger.Info("Could not find user, falling back to legacy format key.")
legacyKeyName := strings.TrimPrefix(authValues[0], k.Spec.OrgID)
keyName, _ = storage.GenerateToken(k.Spec.OrgID, legacyKeyName, "")
session, keyExists = k.CheckSessionAndIdentityForValidKey(keyName, r)
if !keyExists {
logger.Warning("Attempted access with non-existent user.")
return k.handleAuthFail(w, r, token)
}
}
}

switch session.BasicAuthData.Hash {
Expand Down
36 changes: 36 additions & 0 deletions mw_basic_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"
"testing"

"github.com/TykTechnologies/tyk/storage"

"github.com/TykTechnologies/tyk/config"
"github.com/TykTechnologies/tyk/test"
"github.com/TykTechnologies/tyk/user"
Expand Down Expand Up @@ -57,6 +59,40 @@ func TestBasicAuth(t *testing.T) {
}...)
}

func TestBasicAuthLegacyWithHashFunc(t *testing.T) {
globalConf := config.Global()

globalConf.HashKeys = true
globalConf.EnableHashedKeysListing = true
// settings to create BA session with legacy key format
globalConf.HashKeyFunction = ""
config.SetGlobal(globalConf)
defer resetTestConfig()

ts := newTykTestServer()
defer ts.Close()

// create session with legacy key format
session := testPrepareBasicAuth(false)

validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")}

ts.Run(t, []test.TestCase{
// Create base auth based key
{Method: "POST", Path: "/tyk/keys/defaultuser", Data: session, AdminAuth: true, Code: 200},
{Method: "GET", Path: "/", Headers: validPassword, Code: 200},
}...)

// set custom hashing function and check if we still do BA session auth with legacy key format
globalConf.HashKeyFunction = storage.HashMurmur64
config.SetGlobal(globalConf)

ts.Run(t, []test.TestCase{
// Create base auth based key
{Method: "GET", Path: "/", Headers: validPassword, Code: 200},
}...)
}

func TestBasicAuthCachedUserCollision(t *testing.T) {
globalConf := config.Global()
globalConf.HashKeys = true
Expand Down

0 comments on commit 7a98d61

Please sign in to comment.