Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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)))
Example #5
0
    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)
Example #6
0
    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)))
Example #7
0
    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)
Example #8
0
    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
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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
Example #12
0
    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