Diff of /qiita_db/download_link.py [000000] .. [879b32]

Switch to side-by-side view

--- a
+++ b/qiita_db/download_link.py
@@ -0,0 +1,117 @@
+# -----------------------------------------------------------------------------
+# Copyright (c) 2014--, The Qiita Development Team.
+#
+# Distributed under the terms of the BSD 3-clause License.
+#
+# The full license is in the file LICENSE, distributed with this software.
+# -----------------------------------------------------------------------------
+
+import qiita_db as qdb
+
+from jose import jwt as jose_jwt
+from datetime import datetime, timezone
+from qiita_core.qiita_settings import qiita_config
+
+
+class DownloadLink(qdb.base.QiitaObject):
+    r"""
+    A shortened url for downloading artifacts
+    alongside a signed jwt and expiration
+
+    Methods
+    -------
+    delete_expired
+
+    See Also
+    --------
+    qiita_db.QiitaObject
+    """
+
+    _table = "download_link"
+
+    @classmethod
+    def create(cls, jwt):
+        r"""Creates a new object with a new id on the storage system
+
+        Parameters
+        ----------
+        jwt : Json Web Token signing the access link.
+        This jwt will have, at a minimum, jti and exp fields
+
+        Raises
+        ------
+        IncompetentQiitaDeveloperError
+            If the jwt is improperly signed or doesn't contain a jti or exp
+        QiitaDBDuplicateError
+            If the jti already exists in the database
+        """
+
+        jwt_data = jose_jwt.decode(jwt,
+                                   qiita_config.jwt_secret,
+                                   algorithms='HS256')
+        jti = jwt_data["jti"]
+        exp = datetime.utcfromtimestamp(jwt_data["exp"] / 1000)
+
+        with qdb.sql_connection.TRN:
+            if cls.exists(jti):
+                raise qdb.exceptions.QiitaDBDuplicateError(
+                    "JTI Already Exists")
+
+            # insert token into database
+            sql = """INSERT INTO qiita.{0} (jti, jwt, exp)
+            VALUES (%s, %s, %s) RETURNING jti""".format(cls._table)
+            qdb.sql_connection.TRN.add(sql, [jti, jwt, exp])
+            qdb.sql_connection.TRN.execute()
+
+    @classmethod
+    def delete(cls, jti):
+        r"""Deletes the link with specified jti from the storage system
+
+        Parameters
+        ----------
+        jti : object
+            The jwt token identifier
+        """
+        sql = """DELETE FROM qiita.{0} WHERE jti=%s""".format(cls._table)
+        qdb.sql_connection.perform_as_transaction(sql, [jti])
+
+    @classmethod
+    def exists(cls, jti):
+        r"""Checks if a link with specified jti exists
+
+        Returns
+        -------
+        bool
+            True if link exists else false
+        """
+
+        with qdb.sql_connection.TRN:
+            sql = """SELECT COUNT(jti) FROM qiita.{0}
+                     WHERE jti=%s""".format(cls._table)
+            qdb.sql_connection.TRN.add(sql, [jti])
+            return qdb.sql_connection.TRN.execute_fetchlast() == 1
+
+    @classmethod
+    def delete_expired(cls):
+        r"""Deletes all expired download links"""
+        now = datetime.now(timezone.utc)
+
+        sql = """DELETE FROM qiita.{0} WHERE exp<%s""".format(cls._table)
+        qdb.sql_connection.perform_as_transaction(sql, [now])
+
+    @classmethod
+    def get(cls, jti):
+        r"""Retrieves a jwt by its jti
+
+        Returns
+        -------
+        str
+            A JSON web token
+
+        """
+
+        with qdb.sql_connection.TRN:
+            sql = """SELECT jwt FROM qiita.{0}
+                     WHERE jti=%s""".format(cls._table)
+            qdb.sql_connection.TRN.add(sql, [jti])
+            return qdb.sql_connection.TRN.execute_fetchlast()