github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/botman/custom_client.go (about) 1 package botman 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 9 validation "github.com/go-ozzo/ozzo-validation/v4" 10 ) 11 12 type ( 13 // The CustomClient interface supports creating, retrieving, modifying and removing custom clients for a configuration. 14 CustomClient interface { 15 // GetCustomClientList https://techdocs.akamai.com/bot-manager/reference/get-custom-clients 16 GetCustomClientList(ctx context.Context, params GetCustomClientListRequest) (*GetCustomClientListResponse, error) 17 18 // GetCustomClient https://techdocs.akamai.com/bot-manager/reference/get-custom-client 19 GetCustomClient(ctx context.Context, params GetCustomClientRequest) (map[string]interface{}, error) 20 21 // CreateCustomClient https://techdocs.akamai.com/bot-manager/reference/post-custom-clients 22 CreateCustomClient(ctx context.Context, params CreateCustomClientRequest) (map[string]interface{}, error) 23 24 // UpdateCustomClient https://techdocs.akamai.com/bot-manager/reference/put-custom-clients 25 UpdateCustomClient(ctx context.Context, params UpdateCustomClientRequest) (map[string]interface{}, error) 26 27 // RemoveCustomClient https://techdocs.akamai.com/bot-manager/reference/delete-custom-clients 28 RemoveCustomClient(ctx context.Context, params RemoveCustomClientRequest) error 29 } 30 31 // GetCustomClientListRequest is used to retrieve the custom clients for a configuration. 32 GetCustomClientListRequest struct { 33 ConfigID int64 34 Version int64 35 CustomClientID string 36 } 37 38 // GetCustomClientListResponse is used to retrieve the custom clients for a configuration. 39 GetCustomClientListResponse struct { 40 CustomClients []map[string]interface{} `json:"customClients"` 41 } 42 43 // GetCustomClientRequest is used to retrieve a specific custom client. 44 GetCustomClientRequest struct { 45 ConfigID int64 46 Version int64 47 CustomClientID string 48 } 49 50 // CreateCustomClientRequest is used to create a new custom client for a specific configuration. 51 CreateCustomClientRequest struct { 52 ConfigID int64 53 Version int64 54 JsonPayload json.RawMessage 55 } 56 57 // UpdateCustomClientRequest is used to update details for a specific custom client. 58 UpdateCustomClientRequest struct { 59 ConfigID int64 60 Version int64 61 CustomClientID string 62 JsonPayload json.RawMessage 63 } 64 65 // RemoveCustomClientRequest is used to remove an existing custom client. 66 RemoveCustomClientRequest struct { 67 ConfigID int64 68 Version int64 69 CustomClientID string 70 } 71 ) 72 73 // Validate validates a GetCustomClientRequest. 74 func (v GetCustomClientRequest) Validate() error { 75 return validation.Errors{ 76 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 77 "Version": validation.Validate(v.Version, validation.Required), 78 "CustomClientID": validation.Validate(v.CustomClientID, validation.Required), 79 }.Filter() 80 } 81 82 // Validate validates a GetCustomClientsRequest. 83 func (v GetCustomClientListRequest) Validate() error { 84 return validation.Errors{ 85 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 86 "Version": validation.Validate(v.Version, validation.Required), 87 }.Filter() 88 } 89 90 // Validate validates a CreateCustomClientRequest. 91 func (v CreateCustomClientRequest) Validate() error { 92 return validation.Errors{ 93 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 94 "Version": validation.Validate(v.Version, validation.Required), 95 "JsonPayload": validation.Validate(v.JsonPayload, validation.Required), 96 }.Filter() 97 } 98 99 // Validate validates an UpdateCustomClientRequest. 100 func (v UpdateCustomClientRequest) Validate() error { 101 return validation.Errors{ 102 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 103 "Version": validation.Validate(v.Version, validation.Required), 104 "CustomClientID": validation.Validate(v.CustomClientID, validation.Required), 105 "JsonPayload": validation.Validate(v.JsonPayload, validation.Required), 106 }.Filter() 107 } 108 109 // Validate validates a RemoveCustomClientRequest. 110 func (v RemoveCustomClientRequest) Validate() error { 111 return validation.Errors{ 112 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 113 "Version": validation.Validate(v.Version, validation.Required), 114 "CustomClientID": validation.Validate(v.CustomClientID, validation.Required), 115 }.Filter() 116 } 117 118 func (b *botman) GetCustomClient(ctx context.Context, params GetCustomClientRequest) (map[string]interface{}, error) { 119 logger := b.Log(ctx) 120 logger.Debug("GetCustomClient") 121 122 if err := params.Validate(); err != nil { 123 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 124 } 125 126 uri := fmt.Sprintf( 127 "/appsec/v1/configs/%d/versions/%d/custom-clients/%s", 128 params.ConfigID, 129 params.Version, 130 params.CustomClientID) 131 132 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 133 if err != nil { 134 return nil, fmt.Errorf("failed to create GetCustomClient request: %w", err) 135 } 136 137 var result map[string]interface{} 138 resp, err := b.Exec(req, &result) 139 if err != nil { 140 return nil, fmt.Errorf("GetCustomClient request failed: %w", err) 141 } 142 143 if resp.StatusCode != http.StatusOK { 144 return nil, b.Error(resp) 145 } 146 147 return result, nil 148 } 149 150 func (b *botman) GetCustomClientList(ctx context.Context, params GetCustomClientListRequest) (*GetCustomClientListResponse, error) { 151 logger := b.Log(ctx) 152 logger.Debug("GetCustomClientList") 153 154 if err := params.Validate(); err != nil { 155 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 156 } 157 158 uri := fmt.Sprintf( 159 "/appsec/v1/configs/%d/versions/%d/custom-clients", 160 params.ConfigID, 161 params.Version, 162 ) 163 164 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 165 if err != nil { 166 return nil, fmt.Errorf("failed to create GetCustomClientList request: %w", err) 167 } 168 169 var result GetCustomClientListResponse 170 resp, err := b.Exec(req, &result) 171 if err != nil { 172 return nil, fmt.Errorf("GetCustomClientList request failed: %w", err) 173 } 174 175 if resp.StatusCode != http.StatusOK { 176 return nil, b.Error(resp) 177 } 178 179 var filteredResult GetCustomClientListResponse 180 if params.CustomClientID != "" { 181 for _, val := range result.CustomClients { 182 if val["customClientId"].(string) == params.CustomClientID { 183 filteredResult.CustomClients = append(filteredResult.CustomClients, val) 184 } 185 } 186 } else { 187 filteredResult = result 188 } 189 return &filteredResult, nil 190 } 191 192 func (b *botman) UpdateCustomClient(ctx context.Context, params UpdateCustomClientRequest) (map[string]interface{}, error) { 193 logger := b.Log(ctx) 194 logger.Debug("UpdateCustomClient") 195 196 if err := params.Validate(); err != nil { 197 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 198 } 199 200 putURL := fmt.Sprintf( 201 "/appsec/v1/configs/%d/versions/%d/custom-clients/%s", 202 params.ConfigID, 203 params.Version, 204 params.CustomClientID, 205 ) 206 207 req, err := http.NewRequestWithContext(ctx, http.MethodPut, putURL, nil) 208 if err != nil { 209 return nil, fmt.Errorf("failed to create UpdateCustomClient request: %w", err) 210 } 211 212 var result map[string]interface{} 213 resp, err := b.Exec(req, &result, params.JsonPayload) 214 if err != nil { 215 return nil, fmt.Errorf("UpdateCustomClient request failed: %w", err) 216 } 217 218 if resp.StatusCode != http.StatusOK { 219 return nil, b.Error(resp) 220 } 221 222 return result, nil 223 } 224 225 func (b *botman) CreateCustomClient(ctx context.Context, params CreateCustomClientRequest) (map[string]interface{}, error) { 226 logger := b.Log(ctx) 227 logger.Debug("CreateCustomClient") 228 229 if err := params.Validate(); err != nil { 230 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 231 } 232 233 uri := fmt.Sprintf( 234 "/appsec/v1/configs/%d/versions/%d/custom-clients", 235 params.ConfigID, 236 params.Version, 237 ) 238 239 req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil) 240 if err != nil { 241 return nil, fmt.Errorf("failed to create CreateCustomClient request: %w", err) 242 } 243 244 var result map[string]interface{} 245 resp, err := b.Exec(req, &result, params.JsonPayload) 246 if err != nil { 247 return nil, fmt.Errorf("CreateCustomClient request failed: %w", err) 248 } 249 250 if resp.StatusCode != http.StatusCreated { 251 return nil, b.Error(resp) 252 } 253 254 return result, nil 255 } 256 257 func (b *botman) RemoveCustomClient(ctx context.Context, params RemoveCustomClientRequest) error { 258 logger := b.Log(ctx) 259 logger.Debug("RemoveCustomClient") 260 261 if err := params.Validate(); err != nil { 262 return fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 263 } 264 265 uri := fmt.Sprintf("/appsec/v1/configs/%d/versions/%d/custom-clients/%s", 266 params.ConfigID, 267 params.Version, 268 params.CustomClientID) 269 270 req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil) 271 if err != nil { 272 return fmt.Errorf("failed to create RemoveCustomClient request: %w", err) 273 } 274 275 var result map[string]interface{} 276 resp, err := b.Exec(req, &result) 277 if err != nil { 278 return fmt.Errorf("RemoveCustomClient request failed: %w", err) 279 } 280 281 if resp.StatusCode != http.StatusNoContent { 282 return b.Error(resp) 283 } 284 285 return nil 286 }