예제 #1
0
파일: download.py 프로젝트: mestaki/qiita
    def get(self, jti):
        # Grab the jwt out of the database
        jwt = DownloadLink.get(jti)

        # If no jwt, error response
        if jwt is None:
            raise HTTPError(
                404,
                reason='Download Not Found.  Link may have expired.')

        # If jwt doesn't validate, error response
        jwt_data = jose_jwt.decode(jwt, qiita_config.jwt_secret, 'HS256')
        if jwt_data is None:
            raise HTTPError(403, reason='Invalid JWT')

        # Triple check expiration and user permissions
        user = User(jwt_data["sub"])
        artifact = Artifact(jwt_data["artifactId"])

        utc_millis = datetime.now(timezone.utc).timestamp() * 1000

        if utc_millis < jwt_data["iat"]:
            raise HTTPError(403, reason="This download link is not yet valid")
        if utc_millis > jwt_data["exp"]:
            raise HTTPError(403, reason="This download link has expired")
        if jwt_data["perm"] != "download":
            raise HTTPError(403, reason="This download link is invalid")

        check_artifact_access(user, artifact)

        # All checks out, let's give them the files then!
        to_download = self._list_artifact_files_nginx(artifact)
        if not to_download:
            raise HTTPError(422, reason='Nothing to download. If '
                                        'this is a mistake contact: '
                                        '*****@*****.**')
        else:
            self._write_nginx_file_list(to_download)

            zip_fn = 'artifact_%s_%s.zip' % (
                jwt_data["artifactId"], datetime.now().strftime(
                    '%m%d%y-%H%M%S'))

            self._set_nginx_headers(zip_fn)
            self.finish()
예제 #2
0
파일: download.py 프로젝트: mestaki/qiita
    def post(self, artifact_id):
        # Generate a new download link:
        #   1. Build a signed jwt specifying the user and
        #      the artifact they wish to download
        #   2. Write that jwt to the database keyed by its jti
        #      (jwt ID/ json token identifier)
        #   3. Return the jti as a short url to be used for download

        user = self.current_user
        artifact = Artifact(artifact_id)

        # Check that user is currently allowed to access artifact, else throw
        check_artifact_access(user, artifact)

        # Generate a jwt id as a random uuid in base64
        jti = b64encode(uuid4().bytes).decode("utf-8")
        # Sign a jwt allowing access
        utcnow = datetime.now(timezone.utc)
        jwt = jose_jwt.encode({
                "artifactId": str(artifact_id),
                "perm": "download",
                "sub": str(user._id),
                "email": str(user.email),
                "iat": int(utcnow.timestamp() * 1000),
                "exp": int((utcnow + timedelta(days=7)).timestamp() * 1000),
                "jti": jti
            },
            qiita_config.jwt_secret,
            algorithm='HS256'
        )

        # Save the jwt to the database
        DownloadLink.create(jwt)

        url = qiita_config.base_url + '/private_download/' + jti
        user_msg = "This link will expire in 7 days on: " + \
                   (utcnow + timedelta(days=7)).strftime('%Y-%m-%d')

        self.set_status(200)
        self.finish({"url": url, "msg": user_msg})
예제 #3
0
    def test_check_artifact_access(self):
        # "Study" artifact
        a = Artifact(1)
        # The user has access
        u = User('*****@*****.**')
        check_artifact_access(u, a)

        # Admin has access to everything
        admin = User('*****@*****.**')
        check_artifact_access(admin, a)

        # Demo user doesn't have access
        demo_u = User('*****@*****.**')
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)

        # "Analysis" artifact
        a = Artifact(8)
        a.visibility = 'private'
        check_artifact_access(u, a)
        check_artifact_access(admin, a)
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)
        check_artifact_access(User('*****@*****.**'), a)
        a.visibility = 'public'
        check_artifact_access(demo_u, a)
예제 #4
0
    def test_check_artifact_access(self):
        # "Study" artifact
        a = Artifact(1)
        # The user has access
        u = User('*****@*****.**')
        check_artifact_access(u, a)

        # Admin has access to everything
        admin = User('*****@*****.**')
        check_artifact_access(admin, a)

        # Demo user doesn't have access
        demo_u = User('*****@*****.**')
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)

        # "Analysis" artifact
        a = Artifact(8)
        a.visibility = 'private'
        check_artifact_access(u, a)
        check_artifact_access(admin, a)
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)
        check_artifact_access(User('*****@*****.**'), a)
        a.visibility = 'public'
        check_artifact_access(demo_u, a)