]>
jfr.im git - irc/quakenet/qwebirc.git/blob - qwebirc/engines/authgateengine.py
1 from twisted
.web
import resource
, server
, static
2 import config
, urlparse
, urllib
, hashlib
, re
3 import qwebirc
.util
.rijndael
, qwebirc
.util
.ciphers
5 import qwebirc
.util
.qjson
as json
7 authgate
= config
.AUTHGATEPROVIDER
.twisted
10 class AuthgateEngine(resource
.Resource
):
13 def __init__(self
, prefix
):
14 self
.__prefix
= prefix
15 self
.__hit
= qwebirc
.util
.HitCounter()
17 def deleteCookie(self
, request
, key
):
18 request
.addCookie(key
, "", path
="/", expires
="Sat, 29 Jun 1996 01:44:48 GMT")
20 def render_GET(self
, request
):
21 if request
.args
.get("logout"):
22 self
.deleteCookie(request
, "user")
24 a
= authgate(request
, config
.AUTHGATEDOMAIN
)
26 ticket
= a
.login_required(accepting
=lambda x
: True)
27 except a
.redirect_exception
, e
:
30 # only used for informational purposes, the backend stores this seperately
31 # so if the user changes it just their front end will be messed up!
32 request
.addCookie("user", ticket
.username
, path
="/")
34 qt
= ticket
.get("qticket")
36 getSessionData(request
)["qticket"] = decodeQTicket(qt
)
39 if request
.getCookie("jslogin"):
40 self
.deleteCookie(request
, "jslogin")
41 return """<html><head><script>window.opener.__qwebircAuthCallback(%s);</script></head></html>""" % json
.dumps(ticket
.username
)
43 location
= request
.getCookie("redirect")
47 self
.deleteCookie(request
, "redirect")
48 _
, _
, path
, params
, query
, _
= urlparse
.urlparse(urllib
.unquote(location
))
49 location
= urlparse
.urlunparse(("", "", path
, params
, query
, ""))
51 request
.redirect(location
)
54 return server
.NOT_DONE_YET
57 def adminEngine(self
):
58 return dict(Logins
=((self
.__hit
,),))
60 def decodeQTicket(qticket
, p
=re
.compile("\x00*$"), cipher
=qwebirc
.util
.rijndael
.rijndael(hashlib
.sha256(config
.QTICKETKEY
).digest()[:16])):
63 if l
< BLOCK_SIZE
* 2 or l
% BLOCK_SIZE
!= 0:
64 raise Exception("Bad qticket.")
66 iv
, data
= data
[:16], data
[16:]
67 cbc
= qwebirc
.util
.ciphers
.CBC(cipher
, iv
)
69 # technically this is a flawed padding algorithm as it allows chopping at BLOCK_SIZE, we don't
70 # care about that though!
71 b
= range(0, l
-BLOCK_SIZE
, BLOCK_SIZE
)
72 for i
, v
in enumerate(b
):
73 q
= cbc
.decrypt(data
[v
:v
+BLOCK_SIZE
])
75 yield re
.sub(p
, "", q
)
78 return "".join(decrypt(qticket
))
80 def getSessionData(request
):
81 return authgate
.get_session_data(request
)
83 def login_optional(request
):
84 return authgate(request
, config
.AUTHGATEDOMAIN
).login_optional()