firewall.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package cloudflare
  2. import (
  3. "encoding/json"
  4. "net/url"
  5. "strconv"
  6. "time"
  7. "github.com/pkg/errors"
  8. )
  9. // AccessRule represents a firewall access rule.
  10. type AccessRule struct {
  11. ID string `json:"id,omitempty"`
  12. Notes string `json:"notes,omitempty"`
  13. AllowedModes []string `json:"allowed_modes,omitempty"`
  14. Mode string `json:"mode,omitempty"`
  15. Configuration AccessRuleConfiguration `json:"configuration,omitempty"`
  16. Scope AccessRuleScope `json:"scope,omitempty"`
  17. CreatedOn time.Time `json:"created_on,omitempty"`
  18. ModifiedOn time.Time `json:"modified_on,omitempty"`
  19. }
  20. // AccessRuleConfiguration represents the configuration of a firewall
  21. // access rule.
  22. type AccessRuleConfiguration struct {
  23. Target string `json:"target,omitempty"`
  24. Value string `json:"value,omitempty"`
  25. }
  26. // AccessRuleScope represents the scope of a firewall access rule.
  27. type AccessRuleScope struct {
  28. ID string `json:"id,omitempty"`
  29. Email string `json:"email,omitempty"`
  30. Name string `json:"name,omitempty"`
  31. Type string `json:"type,omitempty"`
  32. }
  33. // AccessRuleResponse represents the response from the firewall access
  34. // rule endpoint.
  35. type AccessRuleResponse struct {
  36. Result AccessRule `json:"result"`
  37. Response
  38. ResultInfo `json:"result_info"`
  39. }
  40. // AccessRuleListResponse represents the response from the list access rules
  41. // endpoint.
  42. type AccessRuleListResponse struct {
  43. Result []AccessRule `json:"result"`
  44. Response
  45. ResultInfo `json:"result_info"`
  46. }
  47. // ListUserAccessRules returns a slice of access rules for the logged-in user.
  48. //
  49. // This takes an AccessRule to allow filtering of the results returned.
  50. //
  51. // API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-list-access-rules
  52. func (api *API) ListUserAccessRules(accessRule AccessRule, page int) (*AccessRuleListResponse, error) {
  53. return api.listAccessRules("/user", accessRule, page)
  54. }
  55. // CreateUserAccessRule creates a firewall access rule for the logged-in user.
  56. //
  57. // API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-create-access-rule
  58. func (api *API) CreateUserAccessRule(accessRule AccessRule) (*AccessRuleResponse, error) {
  59. return api.createAccessRule("/user", accessRule)
  60. }
  61. // UserAccessRule returns the details of a user's account access rule.
  62. //
  63. // API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-list-access-rules
  64. func (api *API) UserAccessRule(accessRuleID string) (*AccessRuleResponse, error) {
  65. return api.retrieveAccessRule("/user", accessRuleID)
  66. }
  67. // UpdateUserAccessRule updates a single access rule for the logged-in user &
  68. // given access rule identifier.
  69. //
  70. // API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-update-access-rule
  71. func (api *API) UpdateUserAccessRule(accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  72. return api.updateAccessRule("/user", accessRuleID, accessRule)
  73. }
  74. // DeleteUserAccessRule deletes a single access rule for the logged-in user and
  75. // access rule identifiers.
  76. //
  77. // API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-update-access-rule
  78. func (api *API) DeleteUserAccessRule(accessRuleID string) (*AccessRuleResponse, error) {
  79. return api.deleteAccessRule("/user", accessRuleID)
  80. }
  81. // ListZoneAccessRules returns a slice of access rules for the given zone
  82. // identifier.
  83. //
  84. // This takes an AccessRule to allow filtering of the results returned.
  85. //
  86. // API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-list-access-rules
  87. func (api *API) ListZoneAccessRules(zoneID string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) {
  88. return api.listAccessRules("/zones/"+zoneID, accessRule, page)
  89. }
  90. // CreateZoneAccessRule creates a firewall access rule for the given zone
  91. // identifier.
  92. //
  93. // API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-create-access-rule
  94. func (api *API) CreateZoneAccessRule(zoneID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  95. return api.createAccessRule("/zones/"+zoneID, accessRule)
  96. }
  97. // ZoneAccessRule returns the details of a zone's access rule.
  98. //
  99. // API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-list-access-rules
  100. func (api *API) ZoneAccessRule(zoneID string, accessRuleID string) (*AccessRuleResponse, error) {
  101. return api.retrieveAccessRule("/zones/"+zoneID, accessRuleID)
  102. }
  103. // UpdateZoneAccessRule updates a single access rule for the given zone &
  104. // access rule identifiers.
  105. //
  106. // API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-update-access-rule
  107. func (api *API) UpdateZoneAccessRule(zoneID, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  108. return api.updateAccessRule("/zones/"+zoneID, accessRuleID, accessRule)
  109. }
  110. // DeleteZoneAccessRule deletes a single access rule for the given zone and
  111. // access rule identifiers.
  112. //
  113. // API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-delete-access-rule
  114. func (api *API) DeleteZoneAccessRule(zoneID, accessRuleID string) (*AccessRuleResponse, error) {
  115. return api.deleteAccessRule("/zones/"+zoneID, accessRuleID)
  116. }
  117. // ListAccountAccessRules returns a slice of access rules for the given
  118. // account identifier.
  119. //
  120. // This takes an AccessRule to allow filtering of the results returned.
  121. //
  122. // API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-list-access-rules
  123. func (api *API) ListAccountAccessRules(accountID string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) {
  124. return api.listAccessRules("/accounts/"+accountID, accessRule, page)
  125. }
  126. // CreateAccountAccessRule creates a firewall access rule for the given
  127. // account identifier.
  128. //
  129. // API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-create-access-rule
  130. func (api *API) CreateAccountAccessRule(accountID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  131. return api.createAccessRule("/accounts/"+accountID, accessRule)
  132. }
  133. // AccountAccessRule returns the details of an account's access rule.
  134. //
  135. // API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-access-rule-details
  136. func (api *API) AccountAccessRule(accountID string, accessRuleID string) (*AccessRuleResponse, error) {
  137. return api.retrieveAccessRule("/accounts/"+accountID, accessRuleID)
  138. }
  139. // UpdateAccountAccessRule updates a single access rule for the given
  140. // account & access rule identifiers.
  141. //
  142. // API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-update-access-rule
  143. func (api *API) UpdateAccountAccessRule(accountID, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  144. return api.updateAccessRule("/accounts/"+accountID, accessRuleID, accessRule)
  145. }
  146. // DeleteAccountAccessRule deletes a single access rule for the given
  147. // account and access rule identifiers.
  148. //
  149. // API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-delete-access-rule
  150. func (api *API) DeleteAccountAccessRule(accountID, accessRuleID string) (*AccessRuleResponse, error) {
  151. return api.deleteAccessRule("/accounts/"+accountID, accessRuleID)
  152. }
  153. func (api *API) listAccessRules(prefix string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) {
  154. // Construct a query string
  155. v := url.Values{}
  156. if page <= 0 {
  157. page = 1
  158. }
  159. v.Set("page", strconv.Itoa(page))
  160. // Request as many rules as possible per page - API max is 100
  161. v.Set("per_page", "100")
  162. if accessRule.Notes != "" {
  163. v.Set("notes", accessRule.Notes)
  164. }
  165. if accessRule.Mode != "" {
  166. v.Set("mode", accessRule.Mode)
  167. }
  168. if accessRule.Scope.Type != "" {
  169. v.Set("scope_type", accessRule.Scope.Type)
  170. }
  171. if accessRule.Configuration.Value != "" {
  172. v.Set("configuration_value", accessRule.Configuration.Value)
  173. }
  174. if accessRule.Configuration.Target != "" {
  175. v.Set("configuration_target", accessRule.Configuration.Target)
  176. }
  177. v.Set("page", strconv.Itoa(page))
  178. query := "?" + v.Encode()
  179. uri := prefix + "/firewall/access_rules/rules" + query
  180. res, err := api.makeRequest("GET", uri, nil)
  181. if err != nil {
  182. return nil, errors.Wrap(err, errMakeRequestError)
  183. }
  184. response := &AccessRuleListResponse{}
  185. err = json.Unmarshal(res, &response)
  186. if err != nil {
  187. return nil, errors.Wrap(err, errUnmarshalError)
  188. }
  189. return response, nil
  190. }
  191. func (api *API) createAccessRule(prefix string, accessRule AccessRule) (*AccessRuleResponse, error) {
  192. uri := prefix + "/firewall/access_rules/rules"
  193. res, err := api.makeRequest("POST", uri, accessRule)
  194. if err != nil {
  195. return nil, errors.Wrap(err, errMakeRequestError)
  196. }
  197. response := &AccessRuleResponse{}
  198. err = json.Unmarshal(res, &response)
  199. if err != nil {
  200. return nil, errors.Wrap(err, errUnmarshalError)
  201. }
  202. return response, nil
  203. }
  204. func (api *API) retrieveAccessRule(prefix, accessRuleID string) (*AccessRuleResponse, error) {
  205. uri := prefix + "/firewall/access_rules/rules/" + accessRuleID
  206. res, err := api.makeRequest("GET", uri, nil)
  207. if err != nil {
  208. return nil, errors.Wrap(err, errMakeRequestError)
  209. }
  210. response := &AccessRuleResponse{}
  211. err = json.Unmarshal(res, &response)
  212. if err != nil {
  213. return nil, errors.Wrap(err, errUnmarshalError)
  214. }
  215. return response, nil
  216. }
  217. func (api *API) updateAccessRule(prefix, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) {
  218. uri := prefix + "/firewall/access_rules/rules/" + accessRuleID
  219. res, err := api.makeRequest("PATCH", uri, accessRule)
  220. if err != nil {
  221. return nil, errors.Wrap(err, errMakeRequestError)
  222. }
  223. response := &AccessRuleResponse{}
  224. err = json.Unmarshal(res, &response)
  225. if err != nil {
  226. return nil, errors.Wrap(err, errUnmarshalError)
  227. }
  228. return response, nil
  229. }
  230. func (api *API) deleteAccessRule(prefix, accessRuleID string) (*AccessRuleResponse, error) {
  231. uri := prefix + "/firewall/access_rules/rules/" + accessRuleID
  232. res, err := api.makeRequest("DELETE", uri, nil)
  233. if err != nil {
  234. return nil, errors.Wrap(err, errMakeRequestError)
  235. }
  236. response := &AccessRuleResponse{}
  237. err = json.Unmarshal(res, &response)
  238. if err != nil {
  239. return nil, errors.Wrap(err, errUnmarshalError)
  240. }
  241. return response, nil
  242. }