예제 #1
0
 def raise_auth_required(self):
     self.set_status(401)
     data = self.render_template('kerberos_login_error.html',
                                 login_url=self.settings['login_url'])
     self.write(data)
     self.set_header("WWW-Authenticate", "Negotiate")
     raise web.Finish()
예제 #2
0
 def get_book(self, book_id):
     books = self.get_books(ids=[int(book_id)])
     if not books:
         self.write({'err': 'not_found', 'msg': _(u"抱歉,这本书不存在")})
         self.set_status(200)
         raise web.Finish()
     return books[0]
예제 #3
0
 async def send_event(self, event):
     try:
         self.write('data: {}\n\n'.format(json.dumps(event)))
         await self.flush()
     except StreamClosedError:
         self.log.warning("Stream closed while handling %s", self.request.uri)
         # raise Finish to halt the handler
         raise web.Finish()
예제 #4
0
 async def _emit(self, msg):
     try:
         self.write(f"data: {json.dumps(msg)}\n\n")
         await self.flush()
     except StreamClosedError:
         self.log.warning("Stream closed while handling %s",
                          self.request.uri)
         raise web.Finish()
예제 #5
0
 async def lookup_user(self, phone_number):
     user = await graph.find_user_by_phone(phone_number)
     if user is None:
         self.set_status(404)
         self.write(
             json.dumps({
                 "phone_number": phone_number,
                 "found_in_system": False,
             }))
         raise web.Finish()
     return user
예제 #6
0
 def get(self, action):
     if action == 'fail':
         raise RuntimeError('something unexpected')
     if action == 'http-error':
         raise web.HTTPError(500)
     if action == 'web-finish':
         raise web.Finish()
     if action == 'add-tags':
         self.sentry_tags['some_tag'] = 'some_value'
         raise RuntimeError
     self.set_status(int(action))
     self.finish()
예제 #7
0
 async def emit(self, data):
     if type(data) is not str:
         serialized_data = json.dumps(data)
     else:
         serialized_data = data
     try:
         self.write('data: {}\n\n'.format(serialized_data))
         await self.flush()
     except StreamClosedError:
         app_log.warning("Stream closed while handling %s", self.request.uri)
         # raise Finish to halt the handler
         raise web.Finish()
예제 #8
0
    async def refresh_auth(self, handler):
        """Refresh authentication if needed

        Checks authentication expiry and refresh it if needed.
        See Spawner.

        If the auth is expired and cannot be refreshed
        without forcing a new login, a few things can happen:

        1. if this is a normal user spawn,
           the user should be redirected to login
           and back to spawn after login.
        2. if this is a spawn via API or other user,
           spawn will fail until the user logs in again.

        Args:
            handler (RequestHandler):
                The handler for the request triggering the spawn.
                May be None
        """
        authenticator = self.authenticator
        if authenticator is None or not authenticator.refresh_pre_spawn:
            # nothing to do
            return

        # refresh auth
        auth_user = await handler.refresh_auth(self, force=True)

        if auth_user:
            # auth refreshed, all done
            return

        # if we got to here, auth is expired and couldn't be refreshed
        self.log.error(
            "Auth expired for %s; cannot spawn until they login again",
            self.name,
        )
        # auth expired, cannot spawn without a fresh login
        # it's the current user *and* spawn via GET, trigger login redirect
        if handler.request.method == 'GET' and handler.current_user is self:
            self.log.info("Redirecting %s to login to refresh auth", self.name)
            url = self.get_login_url()
            next_url = self.request.uri
            sep = '&' if '?' in url else '?'
            url += sep + urlencode(dict(next=next_url))
            self.redirect(url)
            raise web.Finish()
        else:
            # spawn via POST or on behalf of another user.
            # nothing we can do here but fail
            raise web.HTTPError(
                400, "{}'s authentication has expired".format(self.name))
예제 #9
0
    async def get_device_ids(self, user, phone_number):
        device_ids = []
        async for device_id in graph.device_ids_for_user(user):
            device_ids.append(device_id)

        if not device_ids:
            # no devices, so we have no info to return
            # treat the same as not found at all
            self.set_status(404)
            self.write(
                json.dumps({
                    "phone_number": phone_number,
                    "found_in_system": False
                }))
            raise web.Finish()

        return device_ids
예제 #10
0
    def post(self):
        if not self.authed:
            self.set_status(403)
            raise web.Finish('Forbidden')

        try:
            data = escape.json_decode(self.request.body)
        except ValueError:
            self.set_status(400)
            raise web.Finish('Request is invalid JSON')

        def get_or_fail(key):
            try:
                return data[key]
            except KeyError:
                self.set_status(400)
                raise web.Finish('You must pass key: %s' % (key, ))

        domain = str(get_or_fail('domain'))
        if not revalid.match(domain):
            self.set_status(400)
            raise web.Finish('Invalid domain name')
        domain = domain.lower()

        op = str(get_or_fail('op'))
        if op not in ('add', 'del'):
            self.set_status(400)
            raise web.Finish('Invalid operation, must be "add" or "del": %s' %
                             (op, ))

        if op == 'del' and 'type' in data:
            if data['type'] in ('A', 'AAAA'):
                ip = ipaddress.ip_address({
                    'A': '127.0.0.1',
                    'AAAA': '::1'
                }[data['type']])
            else:
                self.set_status(400)
                raise web.Finish('Invalid DNS type: %s' % (data['type'], ))
        else:
            try:
                ip = ipaddress.ip_address(get_or_fail('address'))
            except ValueError:
                self.set_status(400)
                raise web.Finish('Invalid IP address: %s' %
                                 (data['address'], ))

        if (yield self._do_edit_dns(domain, ip, op == 'add')):
            self.finish('success')
        else:
            self.set_status(500)
            self.finish('failed')
예제 #11
0
 def should_be_installed(self):
     if CONF.get("installed", None) == False:
         self.write({'err': 'not_installed'})
         self.set_status(200)
         raise web.Finish()
예제 #12
0
 def send_error_of_not_invited(self):
     self.write({'err': 'not_invited'})
     self.set_status(200)
     raise web.Finish()
예제 #13
0
 def raise_auth_required(self, handler):
     handler.set_status(401)
     handler.write("Authentication required")
     handler.set_header("WWW-Authenticate", "Negotiate")
     raise web.Finish()
예제 #14
0
 def _raise_auth_required(self):
     from tornado import web
     self.set_status(401)
     self.write("Authentication required")
     self.set_header("WWW-Authenticate", "Negotiate")
     raise web.Finish()
예제 #15
0
    def get(self):
        '''This handles GET requests to the /api/list-objects endpoint.

        Parameters
        ----------

        review_status : str, optional, default = 'all'
            Sets the type of list retrieval:

            - 'all' -> all objects
            - 'complete-good' -> objects that have at least 2 'good' votes
            - 'complete-bad' -> objects that have at least 2 'bad' votes
            - 'incomplete' -> objects that don't have 2 votes either way
            - 'self-complete-good' -> this user's voted objects good-complete
            - 'self-complete-bad' -> this user's voted objects bad-complete
            - 'self-incomplete' -> this user's voted objects incomplete
            - 'other-incomplete' -> other users' voted objects incomplete

        page : int, optional, default = 0
           The page number to retrieve.

        '''

        # check if we're actually logged in
        if not self.current_user:
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # if the current user is anonymous or locked, ignore their request
        if self.current_user and self.current_user['user_role'] in (
                'anonymous', 'locked'):
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # otherwise, go ahead and process the request
        try:

            # parse the args
            review_status = xhtml_escape(
                self.get_argument('review_status', 'all'))

            if review_status not in ('all', 'incomplete', 'complete-good',
                                     'complete-bad', 'self-incomplete',
                                     'self-complete-good', 'self-complete-bad',
                                     'other-incomplete'):
                raise ValueError("Unknown review status requested: '%s'" %
                                 review_status)

            keytype = xhtml_escape(self.get_argument('keytype', 'start'))
            keyid = int(xhtml_escape(self.get_argument('keyid', '1')))
            max_objects = self.siteinfo['rows_per_page']

            if keytype.strip() == 'start':

                objectlist_info = yield self.executor.submit(
                    worker_get_objects,
                    review_status=review_status,
                    userid=self.current_user['user_id'],
                    start_keyid=keyid,
                    end_keyid=None,
                    max_objects=max_objects,
                )

            elif keytype.strip() == 'end':

                objectlist_info = yield self.executor.submit(
                    worker_get_objects,
                    review_status=review_status,
                    userid=self.current_user['user_id'],
                    start_keyid=None,
                    end_keyid=keyid,
                    max_objects=max_objects,
                )

            else:

                objectlist_info = yield self.executor.submit(
                    worker_get_objects,
                    review_status=review_status,
                    userid=self.current_user['user_id'],
                    start_keyid=keyid,
                    end_keyid=None,
                    max_objects=max_objects,
                )

            # render the result
            if objectlist_info is not None:

                retdict = {
                    'status': 'ok',
                    'message': 'objectlist OK',
                    'result': objectlist_info
                }

            else:

                retdict = {
                    'status': 'failed',
                    'message': "Unable to retrieve object list.",
                    'result': None
                }
                self.set_status(404)

            self.write(retdict)
            self.finish()

        except Exception:

            LOGGER.exception('Failed to retrieve the object list.')
            self.set_status(400)
            retdict = {
                'status': 'failed',
                'message': 'Invalid request for object list.',
                'result': None
            }
            self.write(retdict)
            self.finish()
예제 #16
0
 def get(self):
     raise web.Finish('ok\n')
예제 #17
0
 def get_or_fail(key):
     try:
         return data[key]
     except KeyError:
         self.set_status(400)
         raise web.Finish('You must pass key: %s' % (key, ))
예제 #18
0
 def send_error_of_not_invited(self):
     self.set_header("WWW-Authenticate", "Basic")
     self.set_status(401)
     raise web.Finish()
예제 #19
0
    def post(self, objectid):
        '''This handles POST requests to /api/save-object/<objectid>.

        This saves the current object.

        '''

        # check if we're actually logged in
        if not self.current_user:
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # if the current user is anonymous or locked, ignore their request
        if self.current_user and self.current_user['user_role'] in (
                'anonymous', 'locked'):
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # check the POST request for validity
        if ((not self.keycheck['status'] == 'ok')
                or (not self.xsrf_type == 'session')):

            self.set_status(403)
            retdict = {
                'status':
                'failed',
                'result':
                None,
                'message': ("Sorry, you don't have access. "
                            "API keys are not allowed for this endpoint.")
            }
            self.write(retdict)
            raise web.Finish()

        try:

            objectid = int(xhtml_escape(objectid))
            comment_text = self.get_argument('comment_text', None)
            user_flags = self.get_argument('user_flags', None)
            userid = self.current_user['user_id']
            username = self.current_user['full_name']

            # check if there's more than one flag selected
            user_flags = json.loads(user_flags)
            if sum(user_flags[k] for k in user_flags) > 1:
                LOGGER.error("More than one flag is selected for "
                             "object: %s, userid: %s" %
                             (objectid, self.current_user['user_id']))
                retdict = {
                    'status': 'failed',
                    'result': None,
                    'message':
                    ("You can't choose more than one flag per object.")
                }
                self.write(retdict)
                raise web.Finish()

            if comment_text is not None and len(comment_text.strip()) == 0:
                comment_text = ''

            if comment_text is not None or user_flags is not None:

                # check if the user is allowed to comment on this object
                objectinfo = yield self.executor.submit(
                    worker_get_object,
                    self.current_user['user_id'],
                    objectid,
                    self.basedir,
                )

                # if this object actually exists and is writable, we can do
                # stuff on it

                if (objectinfo is None):
                    LOGGER.error("Object: %s doesn't exist (userid: %s)" %
                                 (objectid, self.current_user['user_id']))
                    retdict = {
                        'status':
                        'failed',
                        'result':
                        None,
                        'message':
                        ("You can't choose more than one flag per object.")
                    }
                    self.write(retdict)
                    self.finish()

                elif (objectinfo is not None
                      and objectinfo['already_reviewed'] is True):

                    LOGGER.error(
                        "Object: %s has been already reviewed by userid: %s" %
                        (objectid, self.current_user['user_id']))
                    retdict = {
                        'status': 'failed',
                        'result': None,
                        'message': ("You have already reviewed this object.")
                    }
                    self.write(retdict)
                    self.finish()

                elif (objectinfo is not None
                      and objectinfo['already_reviewed'] is False
                      and objectinfo['review_status'] == 'incomplete'):

                    commentdict = {
                        'objectid': objectid,
                        'comment': comment_text,
                        'user_flags': user_flags
                    }

                    updated = yield self.executor.submit(
                        worker_insert_object_comments,
                        userid,
                        username,
                        commentdict,
                        [
                            x.strip()
                            for x in self.siteinfo['good_flag_keys'].split(',')
                        ],
                        self.siteinfo['max_good_votes'],
                        [
                            x.strip()
                            for x in self.siteinfo['bad_flag_keys'].split(',')
                        ],
                        self.siteinfo['max_bad_votes'],
                        self.siteinfo['max_all_votes'],
                    )

                    if updated is not None:

                        retdict = {
                            'status': 'ok',
                            'message': 'object updated OK',
                            'result': updated
                        }

                        LOGGER.info("Object: %s successfully "
                                    "reviewed by userid: %s: %r" %
                                    (objectid, self.current_user['user_id'],
                                     commentdict))

                        self.write(retdict)
                        self.finish()

                    else:

                        retdict = {
                            'status':
                            'failed',
                            'message': ("Object with specified ID "
                                        "could not be updated."),
                            'result':
                            None
                        }
                        self.write(retdict)
                        self.finish()

                else:

                    retdict = {
                        'status':
                        'failed',
                        'message':
                        ("Object not found, or is already complete. "
                         "Your comments were not saved."),
                        'result':
                        None
                    }
                    self.write(retdict)
                    self.finish()

            # if no comment content was supplied, do nothing
            else:

                retdict = {
                    'status': 'ok',
                    'message': 'No comments supplied. Object is unchanged.',
                    'result': None
                }
                self.write(retdict)
                self.finish()

        except Exception:

            LOGGER.exception('failed to save changes for object ID: %r' %
                             objectid)
            self.set_status(400)
            retdict = {
                'status': 'failed',
                'message': 'Invalid save request for object ID',
                'result': None
            }
            self.write(retdict)
            self.finish()
예제 #20
0
    def get(self, objectid):
        '''This handles GET requests to the /api/load-object/<index> endpoint.

        Gets catalog and comment info, plots the object if not already plotted,
        and then returns JSON with everything.

        '''

        # check if we're actually logged in
        if not self.current_user:
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # if the current user is anonymous or locked, ignore their request
        if self.current_user and self.current_user['user_role'] in (
                'anonymous', 'locked'):
            retdict = {
                'status': 'failed',
                'message': 'You must be logged in to view objects.',
                'result': None
            }
            self.set_status(401)
            self.write(retdict)
            raise web.Finish()

        # otherwise, go ahead and process the request
        try:

            objindex = int(xhtml_escape(objectid))
            if objindex < 0:
                objindex = 0

            # get the object information
            objectinfo = yield self.executor.submit(
                worker_get_object,
                self.current_user['user_id'],
                objindex,
                self.basedir,
            )

            if objectinfo is not None:
                retdict = {
                    'status': 'ok',
                    'message': 'object found OK',
                    'result': objectinfo
                }

            else:
                retdict = {
                    'status': 'failed',
                    'message': "Object with specified ID not found.",
                    'result': None
                }
                self.set_status(404)

            self.write(retdict)
            self.finish()

        except Exception:

            LOGGER.exception('failed to get requested object ID: %r' %
                             objectid)
            self.set_status(400)
            retdict = {
                'status': 'failed',
                'message': 'Invalid request for object ID',
                'result': None
            }
            self.write(retdict)
            self.finish()