Skip to content

Commit

Permalink
Made auth and sessions managers configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Buhr committed Aug 20, 2014
1 parent f975584 commit a3ccb64
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This Branch:

- Refactored AuthManager and SessionManagers so that any identity provider / Session data handler can be used
- Enables swtching out storage managers
42 changes: 39 additions & 3 deletions api_definition_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ import (
"time"
)

type AuthProviderCode string
type SessionProviderCode string
const (
DefaultAuthProvider AuthProviderCode = "default"
DefaultSessionProvider SessionProviderCode = "default"
)

type AuthProviderMeta struct {
Name AuthProviderCode `bson:"name" json:"name"`
Meta interface{} `bson:"meta" json:"meta"`
}

type SessionProviderMeta struct {
Name SessionProviderCode `bson:"name" json:"name"`
Meta interface{} `bson:"meta" json:"meta"`
}

// APIDefinition represents the configuration for a single proxied API and it's versions.
type APIDefinition struct {
ID bson.ObjectId `bson:"_id,omitempty" json:"id"`
Expand Down Expand Up @@ -44,6 +61,8 @@ type APIDefinition struct {
StripListenPath bool `bson:"strip_listen_path" json:"strip_listen_path"`
} `bson:"proxy" json:"proxy"`
Active bool `bson:"active" json:"active"`
AuthProvider AuthProviderMeta `bson:"auth_provider" json:"auth_provider"`
SessionProvider SessionProviderMeta `bson:"session_provider" json:"session_provider"`
RawData map[string]interface{} `bson:"raw_data,omitempty" json:"raw_data,omitempty"` // Not used in actual configuration, loaded by config for plugable arc
}

Expand Down Expand Up @@ -127,9 +146,26 @@ func (a *APIDefinitionLoader) Connect() {
func (a *APIDefinitionLoader) MakeSpec(thisAppConfig APIDefinition) APISpec {
newAppSpec := APISpec{}
newAppSpec.APIDefinition = thisAppConfig
// Create the auth manager and session manager so we can support multiple IdP's
newAppSpec.AuthManager = &AuthorisationManager{}
newAppSpec.SessionManager = &SessionManager{}

// Add any new session managers or auth handlers here
if newAppSpec.APIDefinition.AuthProvider.Name != "" {
switch newAppSpec.APIDefinition.AuthProvider.Name {
case DefaultAuthProvider: newAppSpec.AuthManager = &DefaultAuthorisationManager{}
default: newAppSpec.AuthManager = &DefaultAuthorisationManager{}
}
} else {
newAppSpec.AuthManager = &DefaultAuthorisationManager{}
}

if newAppSpec.APIDefinition.SessionProvider.Name != "" {
switch newAppSpec.APIDefinition.SessionProvider.Name {
case DefaultSessionProvider: newAppSpec.SessionManager = &DefaultSessionManager{}
default: newAppSpec.SessionManager = &DefaultSessionManager{}
}
} else {
newAppSpec.SessionManager = &DefaultSessionManager{}
}


newAppSpec.RxPaths = make(map[string][]URLSpec)
newAppSpec.WhiteListEnabled = make(map[string]bool)
Expand Down
23 changes: 11 additions & 12 deletions auth_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,30 @@ type SessionHandler interface {
RemoveSession(keyName string)
GetSessionDetail(keyName string) (SessionState, bool)
GetSessions(filter string) []string

}

type KeyGenerator interface {
GenerateAuthKey(OrgID string) string
GenerateHMACSecret() string
}

// AuthorisationManager implements AuthorisationHandler,
// DefaultAuthorisationManager implements AuthorisationHandler,
// requires a StorageHandler to interact with key store
type AuthorisationManager struct {
type DefaultAuthorisationManager struct {
Store StorageHandler
}

type SessionManager struct {
type DefaultSessionManager struct {
Store StorageHandler
}

func (b *AuthorisationManager) Init(store StorageHandler) {
func (b *DefaultAuthorisationManager) Init(store StorageHandler) {
b.Store = store
b.Store.Connect()
}

// IsKeyAuthorised checks if key exists and can be read into a SessionState object
func (b AuthorisationManager) IsKeyAuthorised(keyName string) (bool, SessionState) {
func (b DefaultAuthorisationManager) IsKeyAuthorised(keyName string) (bool, SessionState) {
jsonKeyVal, err := b.Store.GetKey(keyName)
var newSession SessionState
if err != nil {
Expand All @@ -68,7 +67,7 @@ func (b AuthorisationManager) IsKeyAuthorised(keyName string) (bool, SessionStat
}

// IsKeyExpired checks if a key has expired, if the value of SessionState.Expires is 0, it will be ignored
func (b AuthorisationManager) IsKeyExpired(newSession *SessionState) bool {
func (b DefaultAuthorisationManager) IsKeyExpired(newSession *SessionState) bool {
if newSession.Expires >= 1 {
diff := newSession.Expires - time.Now().Unix()
if diff > 0 {
Expand All @@ -79,25 +78,25 @@ func (b AuthorisationManager) IsKeyExpired(newSession *SessionState) bool {
return false
}

func (b *SessionManager) Init(store StorageHandler) {
func (b *DefaultSessionManager) Init(store StorageHandler) {
b.Store = store
b.Store.Connect()
}

// UpdateSession updates the session state in the storage engine
func (b SessionManager) UpdateSession(keyName string, session SessionState) {
func (b DefaultSessionManager) UpdateSession(keyName string, session SessionState) {
v, _ := json.Marshal(session)
keyExp := (session.Expires - time.Now().Unix()) + 300 // Add 5 minutes to key expiry, just in case

b.Store.SetKey(keyName, string(v), keyExp)
}

func (b SessionManager) RemoveSession(keyName string) {
func (b DefaultSessionManager) RemoveSession(keyName string) {
b.Store.DeleteKey(keyName)
}

// GetSessionDetail returns the session detail using the storage engine (either in memory or Redis)
func (b SessionManager) GetSessionDetail(keyName string) (SessionState, bool) {
func (b DefaultSessionManager) GetSessionDetail(keyName string) (SessionState, bool) {
jsonKeyVal, err := b.Store.GetKey(keyName)
var thisSession SessionState
if err != nil {
Expand All @@ -115,7 +114,7 @@ func (b SessionManager) GetSessionDetail(keyName string) (SessionState, bool) {
}

// GetSessions returns all sessions in the key store that match a filter key (a prefix)
func (b SessionManager) GetSessions(filter string) []string {
func (b DefaultSessionManager) GetSessions(filter string) []string {
return b.Store.GetKeys(filter)
}

Expand Down
4 changes: 1 addition & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
)

var log = logrus.New()
//var authManager = AuthorisationManager{}
var config = Config{}
var templates = &template.Template{}
var analytics = RedisAnalyticsHandler{}
Expand Down Expand Up @@ -170,15 +169,14 @@ func loadApps(APISpecs []APISpec, Muxer *http.ServeMux) {
}

// Initialise the auth and session managers (use Redis for now)
// TODO: Make this configurable
referenceSpec.Init(&redisStore, &redisStore)

if referenceSpec.UseOauth2 {
thisOauthManager := addOAuthHandlers(&referenceSpec, Muxer, false)
referenceSpec.OAuthManager = thisOauthManager
}



proxy := TykNewSingleHostReverseProxy(remote)
referenceSpec.target = remote

Expand Down
2 changes: 1 addition & 1 deletion oauth_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func GetToken() tokenData {

var thisResponse = tokenData{}
body, _ := ioutil.ReadAll(recorder.Body)
fmt.Println(string(body))
// fmt.Println(string(body))
err := json.Unmarshal(body, &thisResponse)
if err != nil {
fmt.Println(err)
Expand Down
5 changes: 0 additions & 5 deletions session_manager.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"encoding/json"
"fmt"
"time"
)

Expand Down Expand Up @@ -116,8 +114,5 @@ func createSampleSession() SessionState {
thisSession.AccessRights = map[string]AccessDefinition{}
thisSession.AccessRights["1"] = simpleDef

b, _ := json.Marshal(thisSession)

fmt.Println(string(b))
return thisSession
}

0 comments on commit a3ccb64

Please sign in to comment.