diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 7853c83e..f11bb4ee 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -19,6 +19,7 @@ # Mike McLean import datetime +import http.cookies import inspect import logging import os @@ -811,6 +812,19 @@ def application(environ, start_response): ('Content-Length', str(len(response))), ('Content-Type', "text/xml"), ] + cookies = http.cookies.SimpleCookie(environ.get('HTTP_SET_COOKIE')) + if hasattr(context, 'session') and context.session.logged_in: + cookies['session-id'] = context.session.id + cookies['session-key'] = context.session.key + cookies['callnum'] = context.session.callnum + cookies['logged_in'] = "1" + else: + # good for not mistaking for the older hub with small overhead + cookies['logged_in'] = "0" + for c in cookies.values(): + c.path = '/' + c.secure = True + headers.append(('Set-Cookie', c.OutputString())) start_response('200 OK', headers) if h.traceback: # rollback diff --git a/koji/__init__.py b/koji/__init__.py index 18cedcd3..62ff9725 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -57,6 +57,7 @@ except ImportError: # pragma: no cover from fnmatch import fnmatch import dateutil.parser +import http.cookies import requests import six import six.moves.configparser @@ -2701,10 +2702,11 @@ class ClientSession(object): return self._prepUpload(*args, **kwargs) args = encode_args(*args, **kwargs) if self.logged_in: - sinfo = self.sinfo.copy() - sinfo['callnum'] = self.callnum + for c in self.rsession.cookies: + if c.name == 'callnum': + c.value = str(self.callnum) self.callnum += 1 - handler = "%s?%s" % (self.baseurl, six.moves.urllib.parse.urlencode(sinfo)) + handler = self.baseurl elif name == 'sslLogin': handler = self.baseurl + '/ssllogin' else: @@ -2799,6 +2801,13 @@ class ClientSession(object): warnings.simplefilter("ignore") r = self.rsession.post(handler, **callopts) r.raise_for_status() + if self.logged_in and len(r.cookies.items()) == 0: + # we have session, sent the cookies, but server is old + # and didn't sent them back, use old url-encoded style + sinfo = self.sinfo.copy() + handler = "%s?%s" % (handler, six.moves.urllib.parse.urlencode(sinfo)) + r = self.rsession.post(handler, **callopts) + r.raise_for_status() try: ret = self._read_xmlrpc_response(r) finally: diff --git a/koji/auth.py b/koji/auth.py index 9ab19f1c..b7a1984f 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -29,7 +29,6 @@ import string import six from six.moves import range, urllib - import koji from .context import context from .util import to_list @@ -79,24 +78,23 @@ class Session(object): self._perms = None self._groups = None self._host_id = '' - # get session data from request - if args is None: - environ = getattr(context, 'environ', {}) - args = environ.get('QUERY_STRING', '') - if not args: - self.message = 'no session args' - return - args = urllib.parse.parse_qs(args, strict_parsing=True) + environ = getattr(context, 'environ', {}) + # prefer new cookie-based sessions + if 'HTTP_COOKIE' in environ: + cookies = http.cookies.SimpleCookie(environ['HTTP_COOKIE']) + try: + id = int(cookies['session-id'].value) + key = str(cookies['session-key'].value) + except KeyError as field: + raise koji.AuthError('%s not specified in session args' % field) + try: + callnum = int(cookies['callnum'].value) + except KeyError: + callnum = None + else: + self.message = 'no session cookies' + return hostip = self.get_remote_ip(override=hostip) - try: - id = int(args['session-id'][0]) - key = args['session-key'][0] - except KeyError as field: - raise koji.AuthError('%s not specified in session args' % field) - try: - callnum = args['callnum'][0] - except Exception: - callnum = None # lookup the session # sort for stability (unittests) @@ -500,6 +498,12 @@ class Session(object): insert.execute() context.cnx.commit() + # update it here, so it can be propagated to the cookies in kojixmlrpc.py + context.session.id = session_id + context.session.key = key + context.session.logged_in = True + context.session.callnum = 0 + # return session info return {'session-id': session_id, 'session-key': key}