Example #1
0
    def post(self, ar, grant=None, character=None):
        from brave.core.character.model import EVECharacter
        from brave.core.application.model import ApplicationGrant

        ar = self.ar(ar)
        u = user._current_obj()

        if not grant:
            # Deny access.
            ar.user = u
            ar.grant = None
            ar.expires = datetime.utcnow() + timedelta(
                minutes=10)  # extend to allow time for verification
            ar.save()

            target = URL(ar.failure)
            target.query.update(dict(token=str(ar.id)))

            return 'json:', dict(success=True, location=str(target))

        try:
            character = EVECharacter.objects.get(owner=u, id=character)
        except EVECharacter.DoesNotExist:
            return 'json:', dict(success=False,
                                 message="Unknown character ID.")
        except:
            log.exception("Error loading character.")
            return 'json:', dict(success=False,
                                 message="Error loading character.")

        # TODO: Non-zero grants.
        grant = ApplicationGrant(user=u,
                                 application=ar.application,
                                 mask=0,
                                 expires=datetime.utcnow() +
                                 timedelta(days=30),
                                 character=character)
        grant.save()

        ar.user = u
        ar.grant = grant
        ar.expires = datetime.utcnow() + timedelta(
            minutes=10)  # extend to allow time for verification
        ar.save()

        target = URL(ar.success)
        target.query.update(dict(token=str(grant.id)))
        return 'json:', dict(success=True, location=str(target))
Example #2
0
 def _partial(self, path, params, anchor):
     """Prepare a resource path."""
     
     base, current, controller = self._base
     url = URL()
     
     if not path:
         url.path = str(URL(current).path)
     else:
         url.path = base if path.startswith('/') else controller
         url.path.append(path[1:] if path.startswith('/') else path)
     
     url.query = params
     url.fragment = anchor
     
     return str(url)
Example #3
0
    def get(self, ar):
        from brave.core.application.model import ApplicationGrant

        ar = self.ar(ar)
        u = user._current_obj()
        grant = ApplicationGrant.objects(user=u,
                                         application=ar.application).first()

        if not grant:
            # TODO: We need a 'just logged in' flag in the request.

            characters = list(u.characters.order_by('name').all())
            if len(characters):
                default = u.primary or characters[0]
            else:
                return (
                    'brave.core.template.authorize',
                    dict(
                        success=False,
                        message=
                        _("This application requires that you have a character connected to your"
                          " account. Please <a href=\"/key/\">add an API key</a> to your account."
                          ),
                        ar=ar))
            return 'brave.core.template.authorize', dict(success=True,
                                                         ar=ar,
                                                         characters=characters,
                                                         default=default)

        ngrant = ApplicationGrant(user=u,
                                  application=ar.application,
                                  mask=grant.mask,
                                  expires=datetime.utcnow() +
                                  timedelta(days=30),
                                  character=grant.character)
        ngrant.save()

        ar.user = u
        ar.grant = ngrant
        ar.expires = datetime.utcnow() + timedelta(
            minutes=10)  # extend to allow time for verification
        ar.save()

        r = grant.delete()

        target = URL(ar.success)
        target.query.update(dict(token=str(ngrant.id)))
        raise HTTPFound(location=str(target))
Example #4
0
 def _full(self, path, params, anchor, protocol, host, port):
     """Prepare a complete URL."""
     
     base, current, controller = self._base
     url = URL(current)
     
     url.path = self._partial(path, None, None)
     
     if protocol:
         url.scheme = protocol
     
     if host:
         url.host = host
     
     if port:
         url.port = port
     
     url.params = params
     url.fragment = anchor
     
     return str(url)
Example #5
0
    def authorize(self, success=None, failure=None):
        """Prepare a incoming session request.
        
        Error 'message' attributes are temporary; base your logic on the status and code attributes.
        
        success: web.core.url:URL (required)
        failure: web.core.url:URL (required)
        
        returns:
            location: web.core.url:URL
                the location to direct users to
        """

        # Ensure success and failure URLs are present.

        if success is None:
            response.status_int = 400
            return dict(
                status='error',
                code='argument.success.missing',
                message=
                "URL to return users to upon successful authentication is missing from your request."
            )

        if failure is None:
            response.status_int = 400
            return dict(
                status='error',
                code='argument.failure.missing',
                message=
                "URL to return users to upon authentication failure or dismissal is missing from your request."
            )

        # Also ensure they are valid URIs.

        try:
            success_ = success
            success = URL(success)
        except:
            response.status_int = 400
            return dict(status='error',
                        code='argument.success.malformed',
                        message="Successful authentication URL is malformed.")

        try:
            failure_ = failure
            failure = URL(failure)
        except:
            response.status_int = 400
            return dict(
                status='error',
                code='argument.response.malformed',
                message=
                "URL to return users to upon successful authentication is missing from your request."
            )

        # Deny localhost/127.0.0.1 loopbacks and 192.* and 10.* unless in development mode.

        if not boolean(config.get('debug', False)) and (success.host in ('localhost', '127.0.0.1') or \
                success.host.startswith('192.168.') or \
                success.host.startswith('10.')):
            response.status_int = 400
            return dict(
                status='error',
                code='development-only',
                message=
                "Loopback and local area-network URLs disallowd in production."
            )

        # Check blacklist and bail early.

        if AuthenticationBlacklist.objects(
                reduce(__or__, [
                    Q(scheme=success.scheme),
                    Q(scheme=failure.scheme),
                    Q(protocol=success.port or success.scheme),
                    Q(protocol=failure.port or failure.scheme),
                ] + ([] if not success.host else [Q(domain=success.host)]) +
                       ([] if not failure.host else [Q(
                           domain=failure.host)]))).count():
            response.status_int = 400
            return dict(
                status='error',
                code='blacklist',
                message="You have been blacklisted.  To dispute, contact {0}".
                format(config['mail.blackmail.author']))

        # TODO: Check DNS.  Yes, really.

        # Generate authentication token.

        log.info("Creating request for {0} with callbacks {1} and {2}.".format(
            request.service, success_, failure_))
        ar = AuthenticationRequest(
            request.
            service,  # We have an authenticated request, so we know the service ID is valid.
            success=success_,
            failure=failure_)
        ar.save()

        return dict(location=url.complete('/authorize/{0}'.format(ar.id)))