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 }