Browse Source

Make whitelist optional

Thomas Dy 7 years ago
parent
commit
424f2acd8c
4 changed files with 71 additions and 47 deletions
  1. 2 1
      config.json.example
  2. 1 1
      rust-server/src/config.rs
  3. 46 30
      rust-server/src/handler.rs
  4. 22 15
      server.js

+ 2 - 1
config.json.example

@@ -3,7 +3,8 @@
     "email": "<user email>",
     "token": "<user token>",
     "whitelist": [
-        "example.com"
+        "example.com",
+        "this can be null to disable whitelist"
     ]
 }
 

+ 1 - 1
rust-server/src/config.rs

@@ -9,7 +9,7 @@ pub struct Config {
     pub port: Option<u16>,
     pub email: String,
     pub token: String,
-    pub whitelist: Vec<String>
+    pub whitelist: Option<Vec<String>>
 }
 
 fn stringify(err: Error) -> String {

+ 46 - 30
rust-server/src/handler.rs

@@ -55,14 +55,23 @@ impl SiteHandler {
         request.send().unwrap()
     }
 
+    fn has_whitelist(&self) -> bool {
+        self.cfg.whitelist.is_some()
+    }
+
     fn is_valid(&self, path: &str) -> bool {
-        let zone: String = path.chars()
-            .skip(1)
-            .skip_while(|c| *c != '/')
-            .skip(1)
-            .take_while(|c| *c != '/')
-            .collect();
-        self.whitelist.contains(&zone)
+        if self.has_whitelist() {
+            let zone: String = path.chars()
+                .skip(1)
+                .skip_while(|c| *c != '/')
+                .skip(1)
+                .take_while(|c| *c != '/')
+                .collect();
+            self.whitelist.contains(&zone)
+        }
+        else {
+            true
+        }
     }
 }
 
@@ -84,8 +93,7 @@ pub fn new(cfg: Config) -> SiteHandler {
         whitelist: HashSet::new()
     };
     let mut response = handler.request(Get, "/zones", None);
-    {
-        let domain_whitelist = &handler.cfg.whitelist;
+    if let Some(ref domain_whitelist) = handler.cfg.whitelist {
         let mut whitelist: HashSet<String> = HashSet::new();
         match Json::from_reader(&mut response) {
             Ok(body) => {
@@ -143,29 +151,37 @@ impl Handler for SiteHandler {
                     let whitelist = &self.whitelist;
                     if path == "/zones" {
                         let mut proxy_res = self.request(method, &path, None);
-                        match Json::from_reader(&mut proxy_res) {
-                            Ok(mut body) => {
-                                // filter out non-whitelisted domains
-                                body.as_object_mut()
-                                    .and_then(|mut root| root.get_mut("result"))
-                                    .and_then(|mut result| result.as_array_mut())
-                                    .map(|mut zones| {
-                                        zones.retain(|zone| {
-                                            let id = zone.find("id").and_then(|id| id.as_string()).unwrap();
-                                            whitelist.contains(id)
+                        if self.has_whitelist() {
+                            match Json::from_reader(&mut proxy_res) {
+                                Ok(mut body) => {
+                                    // filter out non-whitelisted domains
+                                    body.as_object_mut()
+                                        .and_then(|mut root| root.get_mut("result"))
+                                        .and_then(|mut result| result.as_array_mut())
+                                        .map(|mut zones| {
+                                            zones.retain(|zone| {
+                                                let id = zone.find("id").and_then(|id| id.as_string()).unwrap();
+                                                whitelist.contains(id)
+                                            });
                                         });
-                                    });
 
-                                let json = json::encode(&body).unwrap();
-                                res.headers_mut().set(ContentType(mime!(Application/Json; Charset=Utf8)));
-                                res.send(json.as_bytes()).unwrap();
-                            },
-                            Err(error) => {
-                                println!("Error: {}", error);
-                                *res.status_mut() = InternalServerError;
-                                res.send(b"Unexpected response from CloudFlare").unwrap();
-                            }
-                        };
+                                    let json = json::encode(&body).unwrap();
+                                    res.headers_mut().set(ContentType(mime!(Application/Json; Charset=Utf8)));
+                                    res.send(json.as_bytes()).unwrap();
+                                },
+                                Err(error) => {
+                                    println!("Error: {}", error);
+                                    *res.status_mut() = InternalServerError;
+                                    res.send(b"Unexpected response from CloudFlare").unwrap();
+                                }
+                            };
+                        }
+                        else {
+                            res.headers_mut().set(ContentType(mime!(Application/Json; Charset=Utf8)));
+                            let mut res = res.start().unwrap();
+                            io::copy(&mut proxy_res, &mut res).ok().expect("Failed to proxy");
+                            res.end().unwrap();
+                        }
                     }
                     else if self.is_valid(&path) {
                         let mut proxy_res = self.request(method, &path, Some(req));

+ 22 - 15
server.js

@@ -33,30 +33,37 @@ app.use(function(req, res, next) {
         }
 
         var path = req.url.substring(4);
+        var noWhitelist = config.whitelist == null;
 
         // filter out only zones in the whitelist
         if(path === '/zones') {
-            request.get({uri: apiEndpoint+path, headers: headers, json: true}, function(err, inc, body) {
-                var filtered = body.result.filter(function(zone) {
-                    return config.whitelist.indexOf(zone.name) >= 0;
-                });
-                // TODO prefetch entire zone list
-                if(identifierWhitelist === null) {
-                    identifierWhitelist = filtered.map(function(zone) {
-                        return zone.id;
+            var params = {uri: apiEndpoint+path, headers: headers, json: true};
+            if(noWhitelist) {
+                request.get(params).pipe(res);
+            }
+            else {
+                request.get(params, function(err, inc, body) {
+                    var filtered = body.result.filter(function(zone) {
+                        return config.whitelist.indexOf(zone.name) >= 0;
                     });
-                }
-                body.result = filtered;
-                body.result_info.count = filtered.length;
-                res.setHeader('Content-Type', 'application/json');
-                res.end(JSON.stringify(body));
-            });
+                    // TODO prefetch entire zone list
+                    if(identifierWhitelist === null) {
+                        identifierWhitelist = filtered.map(function(zone) {
+                            return zone.id;
+                        });
+                    }
+                    body.result = filtered;
+                    body.result_info.count = filtered.length;
+                    res.setHeader('Content-Type', 'application/json');
+                    res.end(JSON.stringify(body));
+                });
+            }
         }
 
         else if(path.startsWith('/zones')) {
             // allow any requests for zones in whitelist
             var identifier = path.replace(/^\/zones\/([0-9a-f]+).*$/, "$1");
-            if(identifierWhitelist.indexOf(identifier) >= 0) {
+            if(noWhitelist || identifierWhitelist.indexOf(identifier) >= 0) {
                 request({
                     method: req.method,
                     uri: apiEndpoint+path,