Projet

Général

Profil

Télécharger (5,49 ko) Statistiques
| Branche: | Révision:

root / larpe / tags / release-1.1.1 / larpe / plugins / site_authentication / agirhe.py @ d03cb81c

1
import re
2
import urllib
3

    
4
from quixote import get_request, get_response, get_session
5

    
6
from qommon.misc import http_post_request
7
from qommon.errors import ConnectionError
8
from qommon import get_logger
9

    
10
from larpe.qommon.misc import http_get_page
11
from larpe.plugins import site_authentication_plugins
12
from larpe.site_authentication import SiteAuthentication
13

    
14
class AgirheSiteAuthentication(SiteAuthentication):
15
    plugin_name = 'agirhe'
16

    
17
    def auto_detect_site(cls, html_doc):
18
        if re.search(
19
                """<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/""",
20
                html_doc):
21
            return True
22
        return False
23
    auto_detect_site = classmethod(auto_detect_site)
24

    
25
    def local_auth_check_post(self, username, password, select=None):
26
        select = select or {}
27
        url = self.host.auth_check_url
28

    
29
        # Build request body
30
        body = '%s=%s&%s=%s' % (
31
            self.host.login_field_name, username, self.host.password_field_name, password)
32
        # Add select fields to the body
33
        for name, value in select.iteritems():
34
            body += '&%s=%s' % (name, value)
35

    
36
        # Get the authentication page
37
        try:
38
            response, status, page, auth_headers = http_get_page(
39
                self.host.auth_form_url, use_proxy=self.host.use_proxy)
40
        except ConnectionError, err:
41
            get_logger().warn(err)
42
            return None, None
43

    
44
        # Get current hidden fields everytime
45
        self.parse_forms(page)
46
        if self.host.auth_form is not None:
47
            self.parse_other_fields()
48

    
49
        # Add hidden fields to the body
50
        for key, value in self.host.other_fields.iteritems():
51
            value = urllib.quote_plus(value)
52
            body += '&%s=%s' % (key, value)
53

    
54
        # Build request HTTP headers
55
        headers = {'Content-Type': 'application/x-www-form-urlencoded',
56
                   'X-Forwarded-For': get_request().get_environ('REMOTE_ADDR', '-'),
57
                   'X-Forwarded-Host': self.host.reversed_hostname}
58

    
59
        # Send request
60
        response, status, data, auth_headers = http_post_request(
61
            url, body, headers, self.host.use_proxy)
62

    
63
        cookies = response.getheader('Set-Cookie', None)
64
        self.host.cookies = []
65
        if cookies is not None:
66
            cookies_list = []
67
            cookies_set_list = []
68
            for cookie in cookies.split(', '):
69
                # Drop the path and other attributes
70
                cookie_only = cookie.split('; ')[0]
71
                regexp = re.compile('=')
72
                if regexp.search(cookie_only) is None:
73
                    continue
74
                # Split name and value
75
                cookie_split = cookie_only.split('=')
76
                cookie_name = cookie_split[0]
77
                cookie_value = cookie_split[1]
78
                cookies_list.append('%s=%s' % (cookie_name, cookie_value))
79
                set_cookie = '%s=%s; path=/' % (cookie_name, cookie_value)
80
                cookies_set_list.append(set_cookie)
81
                self.host.cookies.append(cookie_name)
82
            cookies_headers = '\r\nSet-Cookie: '.join(cookies_set_list)
83
            get_response().set_header('Set-Cookie', cookies_headers)
84
            self.host.store()
85
            get_session().cookies = '; '.join(cookies_list)
86
        else:
87
            get_logger().warn('No cookie from local authentication')
88

    
89
        return response.status, data
90

    
91
    # The 3 following functions have been copied from admin/hosts.ptl
92

    
93
    def parse_forms(self, page):
94
        '''Search for an authentication form'''
95
        # Get all forms
96
        regexp = re.compile("""<form.*?</form>""", re.DOTALL | re.IGNORECASE)
97
        found_forms = regexp.findall(page)
98
        if not found_forms:
99
            return
100

    
101
        # Get the first form with a password field
102
        for found_form in found_forms:
103
            regexp = re.compile(
104
                """<input[^>]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
105
            if regexp.search(found_form) is not None:
106
                self.host.auth_form = found_form
107
                break
108

    
109
    def parse_other_fields(self):
110
        '''Get the default value of all other fields'''
111
        self.host.other_fields = {}
112

    
113
        # Get hidden fields
114
        regexp = re.compile(
115
            """<input[^>]*?type=["']?hidden["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
116
        other_fields = regexp.findall(self.host.auth_form)
117

    
118
        # Only get first submit field
119
        regexp = re.compile(
120
            """<input[^>]*?type=["']?submit["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
121
        found = regexp.findall(self.host.auth_form)
122
        if found:
123
            if other_fields:
124
                other_fields.append(found[0])
125
            else:
126
                other_fields = found[0]
127

    
128
        for field in other_fields:
129
            try:
130
                regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
131
                name = regexp.findall(field)[0]
132
                regexp = re.compile("""value=["'](.*?)["'][\s/>]""", re.DOTALL | re.IGNORECASE)
133
                value = regexp.findall(field)[0]
134
                self.host.other_fields[name] = value
135
                if not self.host.post_parameters.has_key(name):
136
                    self.host.post_parameters[name] = { 'enabled': True,
137
                                                        'value': value,
138
                                                        'immutable': False }
139
            except IndexError:
140
                continue
141

    
142
site_authentication_plugins.register(AgirheSiteAuthentication)
(2-2/6)