def get_user_id(self, validate=True): if (self._user_id is None) or (validate and (not self._valid_user)): try: jbox_cookie = self.get_cookie(JBoxCookies.COOKIE_AUTH) if jbox_cookie is None: return None jbox_cookie = json.loads(base64.b64decode(jbox_cookie)) if validate: sign = signstr(jbox_cookie['u'] + jbox_cookie['t'], JBoxCfg.get('sesskey')) if sign != jbox_cookie['x']: self.log_info("signature mismatch for " + jbox_cookie['u']) return None d = isodate.parse_datetime(jbox_cookie['t']) age = (datetime.datetime.now(pytz.utc) - d).total_seconds() if age > JBoxCookies.AUTH_VALID_SECS: self.log_info("cookie older than allowed days: " + jbox_cookie['t']) return None self._valid_user = True self._user_id = jbox_cookie['u'] except: self.log_error("exception while reading auth cookie") traceback.print_exc() return None return self._user_id
def get(self): self.log_debug("APIInfo handler got GET request") key = self.get_argument("key", None) sign = self.get_argument("sign", None) if key is None or sign is None: self.send_error() return sign2 = signstr(key, JBoxCfg.get('sesskey')) if sign != sign2: self.log_info("signature mismatch. key:%r sign:%r expected:%r", key, sign, sign2) self.send_error() return api_status = APIContainer.get_cluster_api_status() self.log_info("cluster api status: %r", api_status) # filter out instances that should not accept more load filtered_api_status = {k: v for (k, v) in api_status.iteritems() if v['accept']} preferred_instances = filtered_api_status.keys() # flip the dict per_api_instances = dict() for (inst, status) in filtered_api_status.iteritems(): api_names = status['api_status'].keys() for api_name in api_names: v = per_api_instances.get(api_name, []) v.append(inst) per_api_instances[" preferred "] = preferred_instances self.log_info("per api instances: %r", per_api_instances) self.write(per_api_instances) return
def set_authenticated(self, user_id): """ Marks user_id as authenticated with a cookie named COOKIE_AUTH (juliabox). Cookie contains: - Creation timestamp and is treated as valid for AUTH_VALID_SECS time. - Signature for validity check. :param user_id: the user id being marked as authenticated :return: None """ t = datetime.datetime.now(pytz.utc).isoformat() sign = signstr(user_id + t, JBoxCfg.get('sesskey')) jbox_cookie = {'u': user_id, 't': t, 'x': sign} self.set_cookie(JBoxCookies.COOKIE_AUTH, base64.b64encode(json.dumps(jbox_cookie)))
def set_container_ports(self, ports): """ Sets cookies to mark the ports being accessible. :param ports: dict of portname and port numbers. Port name can be referred to in the URL path. :return: """ sig1 = self._get_sig(JBoxCookies.COOKIE_AUTH) sig2 = self._get_sig(JBoxCookies.COOKIE_SESS) cookies = dict() for portname, portnum in ports.iteritems(): sign = signstr(sig1 + sig2 + portname + str(portnum), JBoxCfg.get('sesskey')) port_cookie = {'p': portnum, 'x': sign} cookies[JBoxCookies.COOKIE_PFX_PORT + portname] = base64.b64encode(json.dumps(port_cookie)) self._set_container_cookies(cookies)
def set_container_ports(self, ports): """ Sets cookies to mark the ports being accessible. :param ports: dict of portname and port numbers. Port name can be referred to in the URL path. :return: """ sig1 = self._get_sig(JBoxCookies.COOKIE_AUTH) sig2 = self._get_sig(JBoxCookies.COOKIE_SESS) cookies = dict() for portname, portnum in ports.iteritems(): sign = signstr(sig1 + sig2 + portname + str(portnum), JBoxCfg.get('sesskey')) port_cookie = {'p': portnum, 'x': sign} cookies[JBoxCookies.COOKIE_PFX_PORT + portname] = base64.b64encode( json.dumps(port_cookie)) self._set_container_cookies(cookies)
def get(self): self.log_debug("APIInfo handler got GET request") key = self.get_argument("key", None) sign = self.get_argument("sign", None) if key is None or sign is None: self.send_error() return sign2 = signstr(key, JBoxCfg.get('sesskey')) if sign != sign2: self.log_info("signature mismatch. key:%r sign:%r expected:%r", key, sign, sign2) self.send_error() return api_status = JBoxInstanceProps.get_instance_status( Compute.get_install_id()) self.log_info("cluster api status: %r", api_status) # filter out instances that should not accept more load filtered_api_status = { k: v for (k, v) in api_status.iteritems() if v['accept'] } preferred_instances = filtered_api_status.keys() # flip the dict per_api_instances = dict() for (inst, status) in filtered_api_status.iteritems(): api_names = status['api_status'].keys() for api_name in api_names: v = per_api_instances.get(api_name, []) v.append(inst) per_api_instances[" preferred "] = preferred_instances self.log_info("per api instances: %r", per_api_instances) self.write(per_api_instances) return
def set_container_initialized(self, instance_id, user_id): """ Marks a container as being allocated to a user session. Sets a cookie named COOKIE_SESS (jb_sess). Cookie contains: - Container id (session name / docker container name). - Container location (instance id). - Creation time stamp. - Signature for validity check. It also clears any stale port mapping cookies, and sets the loading state to 1. :param instance_id: The instance where container is allocated, to redirect future requests to. :param user_id: The user id for which container is allocated. :return: None """ self.set_redirect_instance_id(instance_id) t = datetime.datetime.now(pytz.utc).isoformat() cid = unique_sessname(user_id) sign = signstr(cid + instance_id + t, JBoxCfg.get('sesskey')) sess_cookie = {'c': cid, 't': t, 'i': instance_id, 'x': sign} self._set_container_cookies({ JBoxCookies.COOKIE_SESS: base64.b64encode(json.dumps(sess_cookie)) }) self._clear_container_ports() self.set_loading_state(1)
def _get_container(self, validate=True): if (self._session_id is None) or (validate and (not self._valid_session)): lenpfx = len(JBoxCookies.COOKIE_PFX_PORT) rcvd_cookies = dict() for cname in [JBoxCookies.COOKIE_SESS, JBoxCookies.COOKIE_INSTANCEID]: rcvd_cookies[cname] = unquote(self.get_cookie(cname)) for cookie in self.cookies: if cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): rcvd_cookies[cookie] = unquote(self.get_cookie(cookie)) # self.log_debug("received cookies %r", rcvd_cookies) try: sess_cookie = rcvd_cookies[JBoxCookies.COOKIE_SESS] sess_cookie = json.loads(base64.b64decode(sess_cookie)) # self.log_debug("received sess cookie %r", sess_cookie) self._session_id = sess_cookie['c'] self._instance_id = sess_cookie['i'] # self.log_debug("received sess_id %r, inst_id %r", self._session_id, self._instance_id) self._ports = dict() for port_cookie, port_val in rcvd_cookies.iteritems(): if port_cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): portname = port_cookie[lenpfx:] port_val = base64.b64decode(port_val) # self.log_debug("read port %s=%s", port_cookie, port_val) port_val = json.loads(port_val) if len(portname) > 0: self._ports[portname] = port_val['p'] except: self._valid_session = False self.log_error("exception while reading sess/port cookie") traceback.print_exc() return False if validate: # validate the session try: sign = signstr(sess_cookie['c'] + sess_cookie['i'] + sess_cookie['t'], JBoxCfg.get('sesskey')) if sign != sess_cookie['x']: self._valid_session = False self.log_info("signature mismatch for %s", sess_cookie['c']) return False d = isodate.parse_datetime(sess_cookie['t']) age = (datetime.datetime.now(pytz.utc) - d).total_seconds() if age > JBoxCookies.AUTH_VALID_SECS: self.log_info("cookie for %s older than allowed days: %r", sess_cookie['c'], sess_cookie['t']) return False self._valid_session = True except: self.log_error("exception while validating sess/port cookie") traceback.print_exc() return False # validate the ports # failure to validate a port still returns True, but removes ports from the port list sig1 = self._get_sig(JBoxCookies.COOKIE_AUTH) sig2 = sess_cookie['x'] for port_cookie, port_val in rcvd_cookies.iteritems(): if port_cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): portname = port_cookie[lenpfx:] try: port_val = base64.b64decode(port_val) # self.log_debug("session %s, port %s=%s", self._session_id, portname, port_val) port_val = json.loads(port_val) sign = signstr(sig1 + sig2 + portname + str(port_val['p']), JBoxCfg.get('sesskey')) if sign != port_val['x']: self.log_info('session %s port %s has signature mismatch', self._session_id, portname) del self._ports[portname] except: self.log_error('exception parsing session %r port %r', self._session_id, portname) traceback.print_exc() del self._ports[portname] return True
def _get_container(self, validate=True): if (self._session_id is None) or (validate and (not self._valid_session)): lenpfx = len(JBoxCookies.COOKIE_PFX_PORT) rcvd_cookies = dict() for cname in [ JBoxCookies.COOKIE_SESS, JBoxCookies.COOKIE_INSTANCEID ]: rcvd_cookies[cname] = unquote(self.get_cookie(cname)) for cookie in self.cookies: if cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): rcvd_cookies[cookie] = unquote(self.get_cookie(cookie)) # self.log_debug("received cookies %r", rcvd_cookies) try: sess_cookie = rcvd_cookies[JBoxCookies.COOKIE_SESS] sess_cookie = json.loads(base64.b64decode(sess_cookie)) # self.log_debug("received sess cookie %r", sess_cookie) self._session_id = sess_cookie['c'] self._instance_id = sess_cookie['i'] # self.log_debug("received sess_id %r, inst_id %r", self._session_id, self._instance_id) self._ports = dict() for port_cookie, port_val in rcvd_cookies.iteritems(): if port_cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): portname = port_cookie[lenpfx:] port_val = base64.b64decode(port_val) # self.log_debug("read port %s=%s", port_cookie, port_val) port_val = json.loads(port_val) if len(portname) > 0: self._ports[portname] = port_val['p'] except: self._valid_session = False self.log_error("exception while reading sess/port cookie") traceback.print_exc() return False if validate: # validate the session try: sign = signstr( sess_cookie['c'] + sess_cookie['i'] + sess_cookie['t'], JBoxCfg.get('sesskey')) if sign != sess_cookie['x']: self._valid_session = False self.log_info("signature mismatch for %s", sess_cookie['c']) return False d = isodate.parse_datetime(sess_cookie['t']) age = (datetime.datetime.now(pytz.utc) - d).total_seconds() if age > JBoxCookies.AUTH_VALID_SECS: self.log_info( "cookie for %s older than allowed days: %r", sess_cookie['c'], sess_cookie['t']) return False self._valid_session = True except: self.log_error( "exception while validating sess/port cookie") traceback.print_exc() return False # validate the ports # failure to validate a port still returns True, but removes ports from the port list sig1 = self._get_sig(JBoxCookies.COOKIE_AUTH) sig2 = sess_cookie['x'] for port_cookie, port_val in rcvd_cookies.iteritems(): if port_cookie.startswith(JBoxCookies.COOKIE_PFX_PORT): portname = port_cookie[lenpfx:] try: port_val = base64.b64decode(port_val) # self.log_debug("session %s, port %s=%s", self._session_id, portname, port_val) port_val = json.loads(port_val) sign = signstr( sig1 + sig2 + portname + str(port_val['p']), JBoxCfg.get('sesskey')) if sign != port_val['x']: self.log_info( 'session %s port %s has signature mismatch', self._session_id, portname) del self._ports[portname] except: self.log_error( 'exception parsing session %r port %r', self._session_id, portname) traceback.print_exc() del self._ports[portname] return True