#!/usr/bin/env python

import requests
import re
import urlparse
from BeautifulSoup import BeautifulSoup

class Scanner:
    def __init__(self, url, ignore_links):
        self.session = requests.Session()
        self.url = url
        self.non_protocol_url = "/".join(self.url.split("/")[2:])
        self.target_domain_links = []
        self.ignore_links = ignore_links
        self.count = 0  # TODO

    def extract_links_from(self, url):
        response = self.session.get(url)
        return re.findall('(?:href=")(.*?)"', response.content)

    def crawl(self, url=None):
        if not url:
            url = self.url
        http_https_get_links = self.extract_links_from(url)
        for link in http_https_get_links:
            if link.startswith(("/", ".", "?", "#")) or link[:1].isdigit() or link[:1].isalpha():
                link = urlparse.urljoin(url, link)
                if "#" in link:
                    link = link.split("#")[0]
                if self.non_protocol_url in link and link not in self.target_domain_links and link not in self.ignore_links:
                    self.target_domain_links.append(link)
                    self.count += 1  # TODO
                    print(str(self.count) + " " + link)  # TODO: print
                    self.crawl(link)

    def extract_forms(self, url):
        response = self.session.get(url)
        parsed_html = BeautifulSoup(response.content)
        return parsed_html.findAll("form")

    def submit_form(self, form, value, url):
        action = form.get("action")
        url = urlparse.urljoin(url, action)
        method = form.get("method")
        input_list = form.findAll("input")
        data = {}
        textarea_list = form.findAll("textarea")
        for textarea in textarea_list:                 # TODO: doesnt work!!!
            textarea_name = textarea.get("name")
            textarea_value = textarea.get("value")
            textarea_value = value
            data[textarea_name] = textarea_value
        for input_field in input_list:
            input_name = input_field.get("name")
            input_value = input_field.get("value")
            input_type = input_field.get("type")
            if input_type == "text":
                input_value = value
            data[input_name] = input_value
            if "post" == method.lower():
                return self.session.post(url, data=data)
            elif "get" == method.lower():
                return self.session.get(url, params=data)

    def run_scanner(self):
        for link in self.target_domain_links:
            forms = self.extract_forms(link)
            for form in forms:
                print("\r\n[+] Testing form in " + link)
                is_vulnerable_to_xss = self.test_xss_in_form(form, link)
                if is_vulnerable_to_xss:
                    print("[***] XSS discovered in " + link + " in the following form")
                    print(form)
            if "=" in link:
                print("\r\n[+] Testing " + link)
                is_vulnerable_to_xss = self.test_xss_in_link(link)
                if is_vulnerable_to_xss:
                    print("[***] XSS discovered in " + link)

    def test_xss_in_link(self, url):
        xss_test_script = "<Script>alert('xss')</Script>"
        url = url.replace("=", "=" + xss_test_script)
        response = self.session.get(url)
        return xss_test_script in response.content

    def test_xss_in_form(self, form, url):
        xss_test_script = "<scripT>alert('xss')</scripT>"
        response = self.submit_form(form, xss_test_script, url)
        return xss_test_script in response.content
