|
a |
|
b/qiita_db/download_link.py |
|
|
1 |
# ----------------------------------------------------------------------------- |
|
|
2 |
# Copyright (c) 2014--, The Qiita Development Team. |
|
|
3 |
# |
|
|
4 |
# Distributed under the terms of the BSD 3-clause License. |
|
|
5 |
# |
|
|
6 |
# The full license is in the file LICENSE, distributed with this software. |
|
|
7 |
# ----------------------------------------------------------------------------- |
|
|
8 |
|
|
|
9 |
import qiita_db as qdb |
|
|
10 |
|
|
|
11 |
from jose import jwt as jose_jwt |
|
|
12 |
from datetime import datetime, timezone |
|
|
13 |
from qiita_core.qiita_settings import qiita_config |
|
|
14 |
|
|
|
15 |
|
|
|
16 |
class DownloadLink(qdb.base.QiitaObject): |
|
|
17 |
r""" |
|
|
18 |
A shortened url for downloading artifacts |
|
|
19 |
alongside a signed jwt and expiration |
|
|
20 |
|
|
|
21 |
Methods |
|
|
22 |
------- |
|
|
23 |
delete_expired |
|
|
24 |
|
|
|
25 |
See Also |
|
|
26 |
-------- |
|
|
27 |
qiita_db.QiitaObject |
|
|
28 |
""" |
|
|
29 |
|
|
|
30 |
_table = "download_link" |
|
|
31 |
|
|
|
32 |
@classmethod |
|
|
33 |
def create(cls, jwt): |
|
|
34 |
r"""Creates a new object with a new id on the storage system |
|
|
35 |
|
|
|
36 |
Parameters |
|
|
37 |
---------- |
|
|
38 |
jwt : Json Web Token signing the access link. |
|
|
39 |
This jwt will have, at a minimum, jti and exp fields |
|
|
40 |
|
|
|
41 |
Raises |
|
|
42 |
------ |
|
|
43 |
IncompetentQiitaDeveloperError |
|
|
44 |
If the jwt is improperly signed or doesn't contain a jti or exp |
|
|
45 |
QiitaDBDuplicateError |
|
|
46 |
If the jti already exists in the database |
|
|
47 |
""" |
|
|
48 |
|
|
|
49 |
jwt_data = jose_jwt.decode(jwt, |
|
|
50 |
qiita_config.jwt_secret, |
|
|
51 |
algorithms='HS256') |
|
|
52 |
jti = jwt_data["jti"] |
|
|
53 |
exp = datetime.utcfromtimestamp(jwt_data["exp"] / 1000) |
|
|
54 |
|
|
|
55 |
with qdb.sql_connection.TRN: |
|
|
56 |
if cls.exists(jti): |
|
|
57 |
raise qdb.exceptions.QiitaDBDuplicateError( |
|
|
58 |
"JTI Already Exists") |
|
|
59 |
|
|
|
60 |
# insert token into database |
|
|
61 |
sql = """INSERT INTO qiita.{0} (jti, jwt, exp) |
|
|
62 |
VALUES (%s, %s, %s) RETURNING jti""".format(cls._table) |
|
|
63 |
qdb.sql_connection.TRN.add(sql, [jti, jwt, exp]) |
|
|
64 |
qdb.sql_connection.TRN.execute() |
|
|
65 |
|
|
|
66 |
@classmethod |
|
|
67 |
def delete(cls, jti): |
|
|
68 |
r"""Deletes the link with specified jti from the storage system |
|
|
69 |
|
|
|
70 |
Parameters |
|
|
71 |
---------- |
|
|
72 |
jti : object |
|
|
73 |
The jwt token identifier |
|
|
74 |
""" |
|
|
75 |
sql = """DELETE FROM qiita.{0} WHERE jti=%s""".format(cls._table) |
|
|
76 |
qdb.sql_connection.perform_as_transaction(sql, [jti]) |
|
|
77 |
|
|
|
78 |
@classmethod |
|
|
79 |
def exists(cls, jti): |
|
|
80 |
r"""Checks if a link with specified jti exists |
|
|
81 |
|
|
|
82 |
Returns |
|
|
83 |
------- |
|
|
84 |
bool |
|
|
85 |
True if link exists else false |
|
|
86 |
""" |
|
|
87 |
|
|
|
88 |
with qdb.sql_connection.TRN: |
|
|
89 |
sql = """SELECT COUNT(jti) FROM qiita.{0} |
|
|
90 |
WHERE jti=%s""".format(cls._table) |
|
|
91 |
qdb.sql_connection.TRN.add(sql, [jti]) |
|
|
92 |
return qdb.sql_connection.TRN.execute_fetchlast() == 1 |
|
|
93 |
|
|
|
94 |
@classmethod |
|
|
95 |
def delete_expired(cls): |
|
|
96 |
r"""Deletes all expired download links""" |
|
|
97 |
now = datetime.now(timezone.utc) |
|
|
98 |
|
|
|
99 |
sql = """DELETE FROM qiita.{0} WHERE exp<%s""".format(cls._table) |
|
|
100 |
qdb.sql_connection.perform_as_transaction(sql, [now]) |
|
|
101 |
|
|
|
102 |
@classmethod |
|
|
103 |
def get(cls, jti): |
|
|
104 |
r"""Retrieves a jwt by its jti |
|
|
105 |
|
|
|
106 |
Returns |
|
|
107 |
------- |
|
|
108 |
str |
|
|
109 |
A JSON web token |
|
|
110 |
|
|
|
111 |
""" |
|
|
112 |
|
|
|
113 |
with qdb.sql_connection.TRN: |
|
|
114 |
sql = """SELECT jwt FROM qiita.{0} |
|
|
115 |
WHERE jti=%s""".format(cls._table) |
|
|
116 |
qdb.sql_connection.TRN.add(sql, [jti]) |
|
|
117 |
return qdb.sql_connection.TRN.execute_fetchlast() |