1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
/* Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2019 the ZAP development team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
use serde_json::Value;
use std::collections::HashMap;
trait Serialize {}

pub mod acsrf;
pub mod ajax_spider;
pub mod alert;
pub mod alert_filter;
pub mod ascan;
pub mod authentication;
pub mod authorization;
pub mod autoupdate;
pub mod brk;
pub mod context;
pub mod core;
pub mod forced_user;
pub mod http_sessions;
pub mod import_log_files;
pub mod importurls;
pub mod openapi;
pub mod params;
pub mod pnh;
pub mod pscan;
pub mod replacer;
pub mod reveal;
pub mod script;
pub mod search;
pub mod selenium;
pub mod session_management;
pub mod soap;
pub mod spider;
pub mod stats;
pub mod users;
pub mod websocket;

#[derive(Debug)]
pub struct ZapService {
    pub url: String,     // base url of the ZAP API, eg http://localhost:8080
    pub api_key: String, // API key used for connecting securely to the API
}

#[derive(Debug)]
pub struct ZapApiError {
    kind: String,    // type of the error
    message: String, // error message
}

impl From<reqwest::Error> for ZapApiError {
    fn from(error: reqwest::Error) -> Self {
        ZapApiError {
            kind: String::from("comms"),
            message: error.to_string(),
        }
    }
}

impl From<serde_json::error::Error> for ZapApiError {
    fn from(error: serde_json::error::Error) -> Self {
        ZapApiError {
            kind: String::from("serde"),
            message: error.to_string(),
        }
    }
}

pub fn call(
    service: &ZapService,
    component: &str,
    calltype: &str,
    method: &str,
    _params: HashMap<String, String>,
) -> Result<Value, ZapApiError> {
    let mut url = [&service.url, "JSON", component, calltype, method, ""].join("/");
    if _params.keys().len() > 0 {
        url.push_str("?");
        for (key, value) in _params {
            url.push_str(&key);
            url.push_str("=");
            url.push_str(&value);
            url.push_str("&");
        }
    }

    let client = reqwest::Client::new();
    let text = client
        .get(&url)
        .header("X-ZAP-API-Key", &*service.api_key)
        .send()?
        .text()?;
    let json = serde_json::from_str(&text)?;
    Ok(json)
}