github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/policy.go (about) 1 package gateway 2 3 import ( 4 "encoding/json" 5 "errors" 6 "io/ioutil" 7 "net/http" 8 "os" 9 10 "github.com/TykTechnologies/tyk/rpc" 11 12 "github.com/sirupsen/logrus" 13 14 "github.com/TykTechnologies/tyk/user" 15 ) 16 17 type DBAccessDefinition struct { 18 APIName string `json:"apiname"` 19 APIID string `json:"apiid"` 20 Versions []string `json:"versions"` 21 AllowedURLs []user.AccessSpec `bson:"allowed_urls" json:"allowed_urls"` // mapped string MUST be a valid regex 22 Limit *user.APILimit `json:"limit"` 23 } 24 25 func (d *DBAccessDefinition) ToRegularAD() user.AccessDefinition { 26 return user.AccessDefinition{ 27 APIName: d.APIName, 28 APIID: d.APIID, 29 Versions: d.Versions, 30 AllowedURLs: d.AllowedURLs, 31 Limit: d.Limit, 32 } 33 } 34 35 type DBPolicy struct { 36 user.Policy 37 AccessRights map[string]DBAccessDefinition `bson:"access_rights" json:"access_rights"` 38 } 39 40 func (d *DBPolicy) ToRegularPolicy() user.Policy { 41 policy := d.Policy 42 policy.AccessRights = make(map[string]user.AccessDefinition) 43 44 for k, v := range d.AccessRights { 45 policy.AccessRights[k] = v.ToRegularAD() 46 } 47 return policy 48 } 49 50 func LoadPoliciesFromFile(filePath string) map[string]user.Policy { 51 f, err := os.Open(filePath) 52 if err != nil { 53 log.WithFields(logrus.Fields{ 54 "prefix": "policy", 55 }).Error("Couldn't open policy file: ", err) 56 return nil 57 } 58 defer f.Close() 59 60 var policies map[string]user.Policy 61 if err := json.NewDecoder(f).Decode(&policies); err != nil { 62 log.WithFields(logrus.Fields{ 63 "prefix": "policy", 64 }).Error("Couldn't unmarshal policies: ", err) 65 } 66 return policies 67 } 68 69 // LoadPoliciesFromDashboard will connect and download Policies from a Tyk Dashboard instance. 70 func LoadPoliciesFromDashboard(endpoint, secret string, allowExplicit bool) map[string]user.Policy { 71 72 // Get the definitions 73 newRequest, err := http.NewRequest("GET", endpoint, nil) 74 if err != nil { 75 log.Error("Failed to create request: ", err) 76 } 77 78 newRequest.Header.Set("authorization", secret) 79 newRequest.Header.Set("x-tyk-nodeid", GetNodeID()) 80 81 newRequest.Header.Set("x-tyk-nonce", ServiceNonce) 82 83 log.WithFields(logrus.Fields{ 84 "prefix": "policy", 85 }).Info("Mutex lock acquired... calling") 86 c := initialiseClient() 87 88 log.WithFields(logrus.Fields{ 89 "prefix": "policy", 90 }).Info("Calling dashboard service for policy list") 91 resp, err := c.Do(newRequest) 92 if err != nil { 93 log.Error("Policy request failed: ", err) 94 return nil 95 } 96 defer resp.Body.Close() 97 98 if resp.StatusCode == http.StatusForbidden { 99 body, _ := ioutil.ReadAll(resp.Body) 100 log.Error("Policy request login failure, Response was: ", string(body)) 101 reLogin() 102 return nil 103 } 104 105 // Extract Policies 106 var list struct { 107 Message []DBPolicy 108 Nonce string 109 } 110 if err := json.NewDecoder(resp.Body).Decode(&list); err != nil { 111 log.Error("Failed to decode policy body: ", err) 112 return nil 113 } 114 115 ServiceNonce = list.Nonce 116 log.Debug("Loading Policies Finished: Nonce Set: ", ServiceNonce) 117 118 policies := make(map[string]user.Policy, len(list.Message)) 119 120 log.WithFields(logrus.Fields{ 121 "prefix": "policy", 122 }).Info("Processing policy list") 123 for _, p := range list.Message { 124 id := p.MID.Hex() 125 if allowExplicit && p.ID != "" { 126 id = p.ID 127 } 128 p.ID = id 129 if _, ok := policies[id]; ok { 130 log.WithFields(logrus.Fields{ 131 "prefix": "policy", 132 "policyID": p.ID, 133 "OrgID": p.OrgID, 134 }).Warning("--> Skipping policy, new item has a duplicate ID!") 135 continue 136 } 137 policies[id] = p.ToRegularPolicy() 138 } 139 140 return policies 141 } 142 143 func parsePoliciesFromRPC(list string) (map[string]user.Policy, error) { 144 var dbPolicyList []user.Policy 145 146 if err := json.Unmarshal([]byte(list), &dbPolicyList); err != nil { 147 return nil, err 148 } 149 150 policies := make(map[string]user.Policy, len(dbPolicyList)) 151 152 for _, p := range dbPolicyList { 153 p.ID = p.MID.Hex() 154 policies[p.MID.Hex()] = p 155 } 156 157 return policies, nil 158 } 159 160 func LoadPoliciesFromRPC(orgId string) (map[string]user.Policy, error) { 161 if rpc.IsEmergencyMode() { 162 return LoadPoliciesFromRPCBackup() 163 } 164 165 store := &RPCStorageHandler{} 166 if !store.Connect() { 167 return nil, errors.New("Policies backup: Failed connecting to database") 168 } 169 170 rpcPolicies := store.GetPolicies(orgId) 171 172 policies, err := parsePoliciesFromRPC(rpcPolicies) 173 174 if err != nil { 175 log.WithFields(logrus.Fields{ 176 "prefix": "policy", 177 }).Error("Failed decode: ", err, rpcPolicies) 178 return nil, err 179 } 180 181 if err := saveRPCPoliciesBackup(rpcPolicies); err != nil { 182 return nil, err 183 } 184 185 return policies, nil 186 }