summaryrefslogtreecommitdiff
path: root/wowarmopy/auth.py
blob: 97a698140ae1cc003cd9659dd79ca8b19f4b739d (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import re
import httplib, urllib, urlparse

import constants

def login_http (url, cookies = None, data = None, post = False):
    parsed_url = urlparse.urlsplit (url)
    scheme, domain, path, query, fragment = parsed_url
    if scheme == "https":
        h = httplib.HTTPSConnection (domain)
    else:
        h = httplib.HTTPConnection (domain)
    headers = {"User-Agent": "Mozilla/5.0 Gecko/20070219 Firefox/2.0.0.2", # ensure returns XML
               "Cookie": "cookieMenu=all; cookies=true; "}
    if data:
        headers["Content-type"] = "application/x-www-form-urlencoded"
    if cookies:
        headers["Cookie"] += " ".join (["%s=%s;" % cookie for cookie in cookies.items ()])
    if post:
        params = urllib.urlencode (data)
        method = "POST"
    else:
        params = None
        method = "GET"

    h.request (method, "%s?%s#%s" % (path, query, fragment), params, headers)
    return h.getresponse ()

def login_final_bounce (url):
    # Let's bounce to our page that will give us our short term cookie, URL has Kerbrose style ticket.
    finalstage = login_http (url)

    # Did we get a 200?
    if finalstage.status == 200:
        # Get the short term cookie at last
        short_cookie = None
        match = re.search ("%s=(.*?);" % constants.temporary_cookie,
                           finalstage.getheader ("set-cookie"))
        if match:
            short_cookie = match.groups ()[0]
        return short_cookie

    # Finally we didn't get 200?
    raise RuntimeError, "Login broken"

class ArmoryAuth (object):

    short_cookie = None
    long_cookie = None

    def __init__ (self, armory):
        self.armory = armory
    
    def login (self, username, password):
        # Create the base URL we will be POSTing to.
        url = self.armory.get_base_url (login = True, secure = True) \
            + constants.login_url \
            + "?app=armory"
        
        # Ensure we add the correct bounce point.
        if self.armory.locale == "us":
            url += "&ref=http://www.wowarmory.com/index.xml"
        else:
            url += "&ref=http://%s.wowarmory.com/index.xml" % self.armory.locale

        # Ensure we have no final stage.
        redirectstage = None
    
        # Post the first stage
        stage1 = login_http (url, None, { 'accountName': username, 'password': password }, True)

        # Check what happened.
        if stage1.status == 200:
            raise RuntimeError, "Could not login, authenticators unsupported"
        elif stage1.status == 302:
            redirectstage = stage1
        
        # We should have been redirected by now.
        if not redirectstage:
            raise RuntimeError, "Login broken"
        
        # Time to obtain our next URL and our long term cookie.
        long_cookie = None
        #print redirectstage.getheaders ()
        match = re.search ("%s=(.*?);" % constants.persistant_cookie,
                           redirectstage.getheader ("set-cookie"))
        if match:
            long_cookie = match.groups ()[0]
        
        # Let's bounce to our page that will give us our short term cookie, URL has Kerbrose style ticket.
        short_cookie = login_final_bounce (redirectstage.getheader ("location"))
        
        self.short_cookie = short_cookie
        self.long_cookie = long_cookie

        #print self.short_cookie, self.long_cookie

    def get_cookie (self):
        if self.short_cookie:
            return "%s=%s; " % (constants.temporary_cookie, self.short_cookie)
        else:
            return ""

    # FIXME : doesn't work, meh
    def refresh_login (self):
        # Create the base URL we will be POSTing to.
        url = self.armory.get_base_url (login = True, secure = True) \
            + constants.login_url \
            + "?app=armory"
        
        # Ensure we add the correct bounce point.
        if self.armory.locale == "us":
            url += "&ref=http://www.wowarmory.com/index.xml"
        else:
            url += "&ref=http://%s.wowarmory.com/index.xml" % self.armory.locale
        
        # All we need to do is goto the armory login page passing our long life cookie, we should get 302 instantly.
        stage1 = login_http (url, { constants.persistant_cookie: self.long_cookie })

        # Let's see
        if stage1.status == 200:
            # It's no good, our cookie doesn't work anymore.
            raise RuntimeError, "Invalid login details"
        elif stage1.status == 302:
            # Let's bounce to our page that will give us our short term cookie, URL has Kerbrose style ticket.
            short_cookie = login_final_bounce (stage1.getheader ("location"))
            self.short_cookie = short_cookie
        
        # Finally we didn't get 302 or 200?
        raise RuntimeError, "Login broken"