github.com/Tyktechnologies/tyk@v2.9.5+incompatible/user/session.go (about)

     1  package user
     2  
     3  import (
     4  	"crypto/md5"
     5  	"fmt"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/TykTechnologies/tyk/config"
    10  	logger "github.com/TykTechnologies/tyk/log"
    11  )
    12  
    13  var log = logger.Get()
    14  
    15  type HashType string
    16  
    17  const (
    18  	HashPlainText HashType = ""
    19  	HashBCrypt    HashType = "bcrypt"
    20  )
    21  
    22  // AccessSpecs define what URLS a user has access to an what methods are enabled
    23  type AccessSpec struct {
    24  	URL     string   `json:"url" msg:"url"`
    25  	Methods []string `json:"methods" msg:"methods"`
    26  }
    27  
    28  // APILimit stores quota and rate limit on ACL level (per API)
    29  type APILimit struct {
    30  	Rate               float64 `json:"rate" msg:"rate"`
    31  	Per                float64 `json:"per" msg:"per"`
    32  	ThrottleInterval   float64 `json:"throttle_interval" msg:"throttle_interval"`
    33  	ThrottleRetryLimit int     `json:"throttle_retry_limit" msg:"throttle_retry_limit"`
    34  	QuotaMax           int64   `json:"quota_max" msg:"quota_max"`
    35  	QuotaRenews        int64   `json:"quota_renews" msg:"quota_renews"`
    36  	QuotaRemaining     int64   `json:"quota_remaining" msg:"quota_remaining"`
    37  	QuotaRenewalRate   int64   `json:"quota_renewal_rate" msg:"quota_renewal_rate"`
    38  	SetBy              string  `json:"-" msg:"-"`
    39  }
    40  
    41  // AccessDefinition defines which versions of an API a key has access to
    42  type AccessDefinition struct {
    43  	APIName     string       `json:"api_name" msg:"api_name"`
    44  	APIID       string       `json:"api_id" msg:"api_id"`
    45  	Versions    []string     `json:"versions" msg:"versions"`
    46  	AllowedURLs []AccessSpec `bson:"allowed_urls" json:"allowed_urls" msg:"allowed_urls"` // mapped string MUST be a valid regex
    47  	Limit       *APILimit    `json:"limit" msg:"limit"`
    48  
    49  	AllowanceScope string `json:"allowance_scope" msg:"allowance_scope"`
    50  }
    51  
    52  type BasicAuthData struct {
    53  	Password string   `json:"password" msg:"password"`
    54  	Hash     HashType `json:"hash_type" msg:"hash_type"`
    55  }
    56  
    57  type JWTData struct {
    58  	Secret string `json:"secret" msg:"secret"`
    59  }
    60  
    61  type Monitor struct {
    62  	TriggerLimits []float64 `json:"trigger_limits" msg:"trigger_limits"`
    63  }
    64  
    65  // SessionState objects represent a current API session, mainly used for rate limiting.
    66  // There's a data structure that's based on this and it's used for Protocol Buffer support, make sure to update "coprocess/proto/coprocess_session_state.proto" and generate the bindings using: cd coprocess/proto && ./update_bindings.sh
    67  //
    68  // swagger:model
    69  type SessionState struct {
    70  	Mutex              *sync.RWMutex
    71  	LastCheck          int64                       `json:"last_check" msg:"last_check"`
    72  	Allowance          float64                     `json:"allowance" msg:"allowance"`
    73  	Rate               float64                     `json:"rate" msg:"rate"`
    74  	Per                float64                     `json:"per" msg:"per"`
    75  	ThrottleInterval   float64                     `json:"throttle_interval" msg:"throttle_interval"`
    76  	ThrottleRetryLimit int                         `json:"throttle_retry_limit" msg:"throttle_retry_limit"`
    77  	DateCreated        time.Time                   `json:"date_created" msg:"date_created"`
    78  	Expires            int64                       `json:"expires" msg:"expires"`
    79  	QuotaMax           int64                       `json:"quota_max" msg:"quota_max"`
    80  	QuotaRenews        int64                       `json:"quota_renews" msg:"quota_renews"`
    81  	QuotaRemaining     int64                       `json:"quota_remaining" msg:"quota_remaining"`
    82  	QuotaRenewalRate   int64                       `json:"quota_renewal_rate" msg:"quota_renewal_rate"`
    83  	AccessRights       map[string]AccessDefinition `json:"access_rights" msg:"access_rights"`
    84  	OrgID              string                      `json:"org_id" msg:"org_id"`
    85  	OauthClientID      string                      `json:"oauth_client_id" msg:"oauth_client_id"`
    86  	OauthKeys          map[string]string           `json:"oauth_keys" msg:"oauth_keys"`
    87  	Certificate        string                      `json:"certificate" msg:"certificate"`
    88  	BasicAuthData      struct {
    89  		Password string   `json:"password" msg:"password"`
    90  		Hash     HashType `json:"hash_type" msg:"hash_type"`
    91  	} `json:"basic_auth_data" msg:"basic_auth_data"`
    92  	JWTData struct {
    93  		Secret string `json:"secret" msg:"secret"`
    94  	} `json:"jwt_data" msg:"jwt_data"`
    95  	HMACEnabled                   bool     `json:"hmac_enabled" msg:"hmac_enabled"`
    96  	EnableHTTPSignatureValidation bool     `json:"enable_http_signature_validation" msg:"enable_http_signature_validation"`
    97  	HmacSecret                    string   `json:"hmac_string" msg:"hmac_string"`
    98  	RSACertificateId              string   `json:"rsa_certificate_id" msg:"rsa_certificate_id"`
    99  	IsInactive                    bool     `json:"is_inactive" msg:"is_inactive"`
   100  	ApplyPolicyID                 string   `json:"apply_policy_id" msg:"apply_policy_id"`
   101  	ApplyPolicies                 []string `json:"apply_policies" msg:"apply_policies"`
   102  	DataExpires                   int64    `json:"data_expires" msg:"data_expires"`
   103  	Monitor                       struct {
   104  		TriggerLimits []float64 `json:"trigger_limits" msg:"trigger_limits"`
   105  	} `json:"monitor" msg:"monitor"`
   106  	EnableDetailedRecording bool                   `json:"enable_detail_recording" msg:"enable_detail_recording"`
   107  	MetaData                map[string]interface{} `json:"meta_data" msg:"meta_data"`
   108  	Tags                    []string               `json:"tags" msg:"tags"`
   109  	Alias                   string                 `json:"alias" msg:"alias"`
   110  	LastUpdated             string                 `json:"last_updated" msg:"last_updated"`
   111  	IdExtractorDeadline     int64                  `json:"id_extractor_deadline" msg:"id_extractor_deadline"`
   112  	SessionLifetime         int64                  `bson:"session_lifetime" json:"session_lifetime"`
   113  
   114  	// Used to store token hash
   115  	keyHash string
   116  }
   117  
   118  func (s *SessionState) SetAccessRights(accessRights map[string]AccessDefinition) {
   119  	s.Mutex.Lock()
   120  	s.AccessRights = accessRights
   121  	s.Mutex.Unlock()
   122  }
   123  
   124  func (s *SessionState) SetAccessRight(key string, accessRight AccessDefinition) {
   125  	s.Mutex.Lock()
   126  	s.AccessRights[key] = accessRight
   127  	s.Mutex.Unlock()
   128  }
   129  
   130  func (s *SessionState) SetMetaData(metadata map[string]interface{}) {
   131  	s.Mutex.Lock()
   132  	s.MetaData = metadata
   133  	s.Mutex.Unlock()
   134  }
   135  
   136  func (s *SessionState) SetMetaDataKey(key string, metadata interface{}) {
   137  	s.Mutex.Lock()
   138  	s.MetaData[key] = metadata
   139  	s.Mutex.Unlock()
   140  }
   141  
   142  func (s *SessionState) RemoveMetaData(key string) {
   143  	s.Mutex.Lock()
   144  	delete(s.MetaData, key)
   145  	s.Mutex.Unlock()
   146  }
   147  
   148  func (s *SessionState) SetKeyHash(hash string) {
   149  	s.keyHash = hash
   150  }
   151  
   152  func (s *SessionState) KeyHashEmpty() bool {
   153  	return s.keyHash == ""
   154  }
   155  
   156  func (s *SessionState) Lifetime(fallback int64) int64 {
   157  	if config.Global().ForceGlobalSessionLifetime {
   158  		return config.Global().GlobalSessionLifetime
   159  	}
   160  	if s.SessionLifetime > 0 {
   161  		return s.SessionLifetime
   162  	}
   163  	if fallback > 0 {
   164  		return fallback
   165  	}
   166  	return 0
   167  }
   168  
   169  func (s *SessionState) GetAccessRights() (AccessRights map[string]AccessDefinition) {
   170  	s.Mutex.RLock()
   171  	defer s.Mutex.RUnlock()
   172  	return s.AccessRights
   173  }
   174  
   175  func (s *SessionState) GetAccessRightByAPIID(key string) (AccessRight AccessDefinition, found bool) {
   176  	s.Mutex.RLock()
   177  	defer s.Mutex.RUnlock()
   178  	accessRight, found := s.AccessRights[key]
   179  	return accessRight, found
   180  }
   181  
   182  // PolicyIDs returns the IDs of all the policies applied to this
   183  // session. For backwards compatibility reasons, this falls back to
   184  // ApplyPolicyID if ApplyPolicies is empty.
   185  func (s *SessionState) GetPolicyIDs() []string {
   186  	s.Mutex.RLock()
   187  	defer s.Mutex.RUnlock()
   188  
   189  	if len(s.ApplyPolicies) > 0 {
   190  		return s.ApplyPolicies
   191  	}
   192  	if s.ApplyPolicyID != "" {
   193  		return []string{s.ApplyPolicyID}
   194  	}
   195  	return nil
   196  }
   197  
   198  func (s *SessionState) GetMetaData() (metaData map[string]interface{}) {
   199  	s.Mutex.RLock()
   200  	defer s.Mutex.RUnlock()
   201  	return s.MetaData
   202  }
   203  
   204  func (s *SessionState) GetMetaDataByKey(key string) (metaData interface{}, found bool) {
   205  	s.Mutex.RLock()
   206  	defer s.Mutex.RUnlock()
   207  	value, ok := s.MetaData[key]
   208  	return value, ok
   209  }
   210  
   211  func (s *SessionState) MD5Hash() string {
   212  	return fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%+v", s))))
   213  }
   214  
   215  func (s *SessionState) GetKeyHash() string {
   216  	if s.keyHash == "" {
   217  		panic("KeyHash cache not found. You should call `SetKeyHash` before.")
   218  	}
   219  
   220  	return s.keyHash
   221  }
   222  
   223  func (s *SessionState) SetPolicies(ids ...string) {
   224  	s.ApplyPolicyID = ""
   225  	s.ApplyPolicies = ids
   226  }
   227  
   228  // PoliciesEqualTo compares and returns true if passed slice if IDs contains only current ApplyPolicies
   229  func (s *SessionState) PoliciesEqualTo(ids []string) bool {
   230  
   231  	s.Mutex.RLock()
   232  	policies := s.ApplyPolicies
   233  	s.Mutex.RUnlock()
   234  
   235  	if len(policies) != len(ids) {
   236  		return false
   237  	}
   238  
   239  	polIDMap := make(map[string]bool, len(ids))
   240  	for _, id := range ids {
   241  		polIDMap[id] = true
   242  	}
   243  
   244  	for _, curID := range policies {
   245  		if !polIDMap[curID] {
   246  			return false
   247  		}
   248  	}
   249  
   250  	return true
   251  }
   252  
   253  // GetQuotaLimitByAPIID return quota max, quota remaining, quota renewal rate and quota renews for the given session
   254  func (s *SessionState) GetQuotaLimitByAPIID(apiID string) (int64, int64, int64, int64) {
   255  	s.Mutex.RLock()
   256  	defer s.Mutex.RUnlock()
   257  
   258  	if access, ok := s.AccessRights[apiID]; ok && access.Limit != nil {
   259  		return access.Limit.QuotaMax,
   260  			access.Limit.QuotaRemaining,
   261  			access.Limit.QuotaRenewalRate,
   262  			access.Limit.QuotaRenews
   263  	}
   264  
   265  	return s.QuotaMax, s.QuotaRemaining, s.QuotaRenewalRate, s.QuotaRenews
   266  }