Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.12.0 #357

Merged
merged 110 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 103 commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
5c3bea6
add skeleton for creating user developer keys
nleroy917 Jun 28, 2024
73b957a
complete api key minting mvp (#313)
nleroy917 Jun 28, 2024
7e443b4
styling
nleroy917 Jun 28, 2024
7c3cb7e
tweaks
nleroy917 Jul 2, 2024
77cebf1
bump version
nleroy917 Jul 2, 2024
afc4e89
reqs update
nleroy917 Jul 2, 2024
6de1602
rate limit key generation. limit num keys
nleroy917 Jul 2, 2024
b11e8dc
better error handling
nleroy917 Jul 2, 2024
e958771
Merge branch 'dev' into 313_mint_tokens
nleroy917 Jul 3, 2024
1118c07
add the bad_jwts list functionality
nleroy917 Jul 3, 2024
e16fda9
Merge remote-tracking branch 'refs/remotes/origin/313_mint_tokens' in…
nleroy917 Jul 3, 2024
c6d3c61
lint
nleroy917 Jul 3, 2024
394d483
remove comment
nleroy917 Jul 3, 2024
7211d14
renmove u nused imports
nleroy917 Jul 3, 2024
a092a4a
add something for account settings
nleroy917 Jul 3, 2024
99a79ea
clean up upload mutation
nleroy917 Jul 3, 2024
3465600
more clean up of that mutation
nleroy917 Jul 3, 2024
c8d5a77
remove onChange
nleroy917 Jul 3, 2024
4adfee0
dont disable upload PEP form button unless submitting (#332)
nleroy917 Jul 3, 2024
87b9a48
minor upload form tweaks
nleroy917 Jul 3, 2024
54779b0
added project history to pephub
khoroshevskyi Jul 8, 2024
907a1fe
added delete namespace endpoint
khoroshevskyi Jul 8, 2024
607903d
Merge pull request #348 from pepkit/history
nleroy917 Jul 8, 2024
75473a0
history queries
nleroy917 Jul 8, 2024
cbcf351
Merge branch '130_versioning' into dev
nleroy917 Jul 8, 2024
68d2552
work on history modal
nleroy917 Jul 8, 2024
cb3ba64
Merge branch 'dev' into 130_versioning
nleroy917 Jul 8, 2024
07b2463
added restore function
khoroshevskyi Jul 8, 2024
e2d93ba
Merge branch 'refs/heads/history' into dev
khoroshevskyi Jul 8, 2024
2b5f0c7
Merge remote-tracking branch 'refs/remotes/origin/dev' into dev
nleroy917 Jul 8, 2024
5629e0a
fixed argument
khoroshevskyi Jul 8, 2024
694986b
Merge branch 'dev' into 130_versioning
nleroy917 Jul 8, 2024
b27383b
history indicators
nleroy917 Jul 9, 2024
5fea5fa
added zip endpoint
khoroshevskyi Jul 9, 2024
384df01
close in on history implementation
nleroy917 Jul 9, 2024
9ca4974
restore from history done
nleroy917 Jul 9, 2024
25ede07
Merge remote-tracking branch 'refs/remotes/origin/dev' into dev
nleroy917 Jul 9, 2024
bd90ef2
Merge branch 'dev' into 130_versioning
nleroy917 Jul 9, 2024
26cfece
fix bug preventing users from deleting projects in their authorized orgs
nleroy917 Jul 9, 2024
79a20b9
enable downloading zip of history
nleroy917 Jul 9, 2024
7c82bd8
add download to modal
nleroy917 Jul 9, 2024
72f22a9
Merge pull request #349 from pepkit/130_versioning
nleroy917 Jul 9, 2024
fd2141d
add function to delete all PEPs
nleroy917 Jul 10, 2024
e16a847
add window reload
nleroy917 Jul 10, 2024
8b0a471
namespace loading page
nleroy917 Jul 10, 2024
1ad76c0
Merge branch 'dev' into 313_mint_tokens
nleroy917 Jul 10, 2024
7c6e37d
update blank project form labels
nleroy917 Jul 10, 2024
5af14b6
update pop form labels
nleroy917 Jul 10, 2024
095d4d1
update project upload form labels
nleroy917 Jul 10, 2024
74c9058
soten nav bar for namespace page
nleroy917 Jul 10, 2024
feff27d
revert tooltip
nleroy917 Jul 10, 2024
65e3c8a
address some comments
nleroy917 Jul 10, 2024
922ed0a
address comments
nleroy917 Jul 10, 2024
83e7fe5
Merge pull request #330 from pepkit/313_mint_tokens
nleroy917 Jul 10, 2024
cc94033
Merge pull request #336 from pepkit/332_upload_bugs
nleroy917 Jul 12, 2024
e1da1db
add some tooltips
nleroy917 Jul 12, 2024
22d9b43
Merge pull request #351 from pepkit/documentation_ux
nleroy917 Jul 12, 2024
110474c
remove project history stuff from project page context
nleroy917 Jul 12, 2024
de27dbf
fix issue with samples in progress on pageView switch
nleroy917 Jul 12, 2024
2d0f5e7
fix issues with the tab switching
nleroy917 Jul 12, 2024
a172472
more fixes
nleroy917 Jul 12, 2024
70b75f4
fixed validation endpoint
khoroshevskyi Jul 12, 2024
aaf122b
still, weirdness but will keep working
nleroy917 Jul 12, 2024
06a60f9
work on sample table query
nleroy917 Jul 14, 2024
5462337
doc strings
nleroy917 Jul 14, 2024
651f4c8
clean up stars queries
nleroy917 Jul 14, 2024
2882ff6
more cleanup to mutations
nleroy917 Jul 14, 2024
5304921
update delete project mutation
nleroy917 Jul 14, 2024
ec02235
update project history delete mutation
nleroy917 Jul 14, 2024
be8befc
update edit project metadata mutation + form
nleroy917 Jul 14, 2024
d76a1d5
update fork mutation
nleroy917 Jul 14, 2024
f2ed5bb
remove unnecessary components, update revoke key stuff
nleroy917 Jul 14, 2024
285b99d
update sample table mutations
nleroy917 Jul 14, 2024
3ab9a77
yet more mutation updates
nleroy917 Jul 14, 2024
1011a2f
update the uploading mutation
nleroy917 Jul 14, 2024
a2d52fb
remove console.log
nleroy917 Jul 14, 2024
1c4d502
last tweaks
nleroy917 Jul 14, 2024
e42580c
restructure the edit metadata form
nleroy917 Jul 15, 2024
190bf1e
so much rework
nleroy917 Jul 15, 2024
175e233
Merge branch 'dev' into sample_table_fixes
nleroy917 Jul 15, 2024
ea3a8dc
update more things
nleroy917 Jul 15, 2024
9cad95b
Merge remote-tracking branch 'refs/remotes/origin/sample_table_fixes'…
nleroy917 Jul 15, 2024
a3fdac2
Merge pull request #354 from pepkit/sample_table_fixes
nleroy917 Jul 15, 2024
5a754e5
cleaning namespace
khoroshevskyi Jul 15, 2024
60bfe6b
cleaned project
khoroshevskyi Jul 15, 2024
37e578b
fix namespace page
nleroy917 Jul 15, 2024
9b20ecb
fixed peppy issue
khoroshevskyi Jul 15, 2024
5e4b714
Merge pull request #355 from pepkit/328_models
khoroshevskyi Jul 15, 2024
c5d93cb
fixed config endpoint
khoroshevskyi Jul 15, 2024
75db29b
small tweaks
nleroy917 Jul 15, 2024
d0fc98f
add type generation script
nleroy917 Jul 15, 2024
6d274a5
remove jwt signing secret leak
nleroy917 Jul 16, 2024
5ca8fc6
do not verify sample_name column (#347)
nleroy917 Jul 16, 2024
a331a65
change local data model for sample table
nleroy917 Jul 17, 2024
c5b2969
sample table stability
nleroy917 Jul 17, 2024
db4716c
pephub sample table stability changes
nleroy917 Jul 17, 2024
1612824
stability
nleroy917 Jul 17, 2024
9a5acc4
removed digest from namespace page
khoroshevskyi Jul 17, 2024
d1ac9b4
type fixes
nleroy917 Jul 17, 2024
4d0bbcf
Merge remote-tracking branch 'refs/remotes/origin/dev' into dev
nleroy917 Jul 17, 2024
8b447f5
stability
nleroy917 Jul 17, 2024
e95a7b8
address issue with duplicate phids
nleroy917 Jul 18, 2024
2d0db2d
better border box styling
nleroy917 Jul 18, 2024
30fe548
cleaning code
khoroshevskyi Jul 18, 2024
d4092d4
add validation back
nleroy917 Jul 18, 2024
f7966c1
Merge remote-tracking branch 'refs/remotes/origin/dev' into dev
nleroy917 Jul 18, 2024
a129550
styling
nleroy917 Jul 18, 2024
ca79f37
more updates
nleroy917 Jul 18, 2024
a13ea96
bump version
nleroy917 Jul 18, 2024
5be862e
fixed logo img
khoroshevskyi Jul 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion environment/dev.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export HF_MODEL="BAAI/bge-small-en-v1.5"

export GH_CLIENT_ID=`pass databio/pephub/gh_client_id`
export GH_CLIENT_SECRET=`pass databio/pephub/gh_client_secret`
export BASE_URI=http://localhost:8000
export BASE_URI=http://localhost:8000

export PH_DEV_MODE=true
2 changes: 1 addition & 1 deletion pephub/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.11.8"
__version__ = "0.11.9"
3 changes: 2 additions & 1 deletion pephub/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@
"CRITICAL": logging.CRITICAL,
}

JWT_SECRET = token_hex(32)
JWT_SECRET = "0" * 64 if os.getenv("PH_DEV_MODE") is not None else token_hex(32)
JWT_EXPIRATION = 4320 # 3 days in minutes
JWT_EXPIRATION_SECONDS = JWT_EXPIRATION * 60 # seconds
MAX_NEW_KEYS = 5

AUTH_CODE_EXPIRATION = 5 * 60 # seconds

Expand Down
42 changes: 20 additions & 22 deletions pephub/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
import logging
import os
from datetime import datetime, timedelta
from datetime import datetime
from secrets import token_hex
from typing import Any, Dict, Generator, List, Optional, Union
from typing import Any, Dict, List, Optional, Union
from cachetools import cached, TTLCache

import jwt
Expand Down Expand Up @@ -31,10 +31,11 @@
DEFAULT_POSTGRES_USER,
DEFAULT_QDRANT_HOST,
DEFAULT_QDRANT_PORT,
JWT_EXPIRATION,
JWT_SECRET,
)
from .helpers import jwt_encode_user_data
from .routers.models import ForkRequest
from .developer_keys import dev_key_handler

_LOGGER_PEPHUB = logging.getLogger("uvicorn.access")

Expand Down Expand Up @@ -83,14 +84,8 @@ def _request_user_data_from_github(access_token: str) -> UserData:
)

@staticmethod
def jwt_encode_user_data(user_data: dict) -> str:
exp = datetime.utcnow() + timedelta(minutes=JWT_EXPIRATION)
encoded_user_data = jwt.encode(
{**user_data, "exp": exp}, JWT_SECRET, algorithm="HS256"
)
if isinstance(encoded_user_data, bytes):
encoded_user_data = encoded_user_data.decode("utf-8")
return encoded_user_data
def jwt_encode_user_data(user_data: dict, exp: datetime = None) -> str:
return jwt_encode_user_data(user_data, exp=exp)


# database connection
Expand Down Expand Up @@ -132,19 +127,22 @@ def get_db() -> PEPDatabaseAgent:
return agent


def read_authorization_header(Authorization: str = Header(None)) -> Union[dict, None]:
def read_authorization_header(authorization: str = Header(None)) -> Union[dict, None]:
"""
Reads and decodes a JWT, returning the decoded variables.

:param Authorization: JWT provided via FastAPI injection from the API cookie.
"""
if Authorization is None:
if authorization is None:
return None
else:
Authorization = Authorization.replace("Bearer ", "")
authorization = authorization.replace("Bearer ", "")
try:
# Python jwt.decode verifies content as well so this is safe.
session_info = jwt.decode(Authorization, JWT_SECRET, algorithms=["HS256"])
# check last 5 chars
if dev_key_handler.is_key_bad(authorization[-5:]):
raise HTTPException(401, "JWT has been revoked")
session_info = jwt.decode(authorization, JWT_SECRET, algorithms=["HS256"])
except jwt.exceptions.InvalidSignatureError as e:
_LOGGER_PEPHUB.error(e)
return None
Expand Down Expand Up @@ -201,7 +199,7 @@ def get_project(
description="Return the project with the samples pephub_id",
include_in_schema=False,
),
) -> Dict[str, Any]:
) -> Dict[str, Any]: # type: ignore
try:
proj = agent.project.get(namespace, project, tag, raw=True, with_id=with_id)
yield proj
Expand All @@ -217,7 +215,7 @@ def get_config(
project: str,
tag: Optional[str] = DEFAULT_TAG,
agent: PEPDatabaseAgent = Depends(get_db),
) -> Dict[str, Any]:
) -> Dict[str, Any]: # type: ignore
try:
config = agent.project.get_config(namespace, project, tag)
yield config
Expand All @@ -233,7 +231,7 @@ def get_subsamples(
project: str,
tag: Optional[str] = DEFAULT_TAG,
agent: PEPDatabaseAgent = Depends(get_db),
) -> Dict[str, Any]:
) -> Dict[str, Any]: # type: ignore # type: ignore
try:
subsamples = agent.project.get_subsamples(namespace, project, tag)
yield subsamples
Expand All @@ -250,7 +248,7 @@ def get_project_annotation(
tag: Optional[str] = DEFAULT_TAG,
agent: PEPDatabaseAgent = Depends(get_db),
namespace_access_list: List[str] = Depends(get_namespace_access_list),
) -> AnnotationModel:
) -> AnnotationModel: # type: ignore
try:
anno = agent.annotation.get(
namespace, project, tag, admin=namespace_access_list
Expand Down Expand Up @@ -320,7 +318,7 @@ def verify_user_can_read_project(
def verify_user_can_fork(
fork_request: ForkRequest,
namespace_access_list: List[str] = Depends(get_namespace_access_list),
) -> bool:
) -> bool: # type: ignore
fork_namespace = fork_request.fork_to
if fork_namespace in (namespace_access_list or []):
yield
Expand All @@ -344,7 +342,7 @@ def get_qdrant_enabled() -> bool:

def get_qdrant(
qdrant_enabled: bool = Depends(get_qdrant_enabled),
) -> Union[QdrantClient, None]:
) -> Union[QdrantClient, None]: # type: ignore
"""
Return connection to qdrant client
"""
Expand Down Expand Up @@ -383,7 +381,7 @@ def get_namespace_info(
namespace: str,
agent: PEPDatabaseAgent = Depends(get_db),
user: str = Depends(get_user_from_session_info),
) -> Namespace:
) -> Namespace: # type: ignore
"""
Get the information on a namespace, if it exists.
"""
Expand Down
81 changes: 81 additions & 0 deletions pephub/developer_keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from datetime import datetime, timedelta
from typing import Dict, List

import secrets

from fastapi import HTTPException

from .routers.models import DeveloperKey

from .helpers import jwt_encode_user_data
from .const import MAX_NEW_KEYS


class DeveloperKeyHandler:
def __init__(self, default_exp: int = 30 * 24 * 60 * 60):
self._keys: Dict[str, List[DeveloperKey]] = {}
self._default_exp = default_exp
self._bad_jwts = []

def add_key(self, namespace: str, key: DeveloperKey):
"""
Add a key to the handler for a given namespace/user

:param namespace: namespace for the key
:param key: DeveloperKey object
"""
if namespace not in self._keys:
self._keys[namespace] = []
if len(self._keys[namespace]) >= MAX_NEW_KEYS:
raise HTTPException(
status_code=400,
detail="You have reached the maximum number of keys allowed",
)
self._keys[namespace].append(key)

def get_keys_for_namespace(self, namespace: str) -> List[DeveloperKey]:
"""
Get all the keys for a given namespace

:param namespace: namespace for the key
"""
return self._keys.get(namespace) or []

def remove_key(self, namespace: str, last_five_chars: str):
"""
Remove a key from the handler for a given namespace/user

:param namespace: namespace for the key
:param key: key to remove
"""
if namespace in self._keys:
self._keys[namespace] = [
key for key in self._keys[namespace] if key.key[-5:] != last_five_chars
]
self._bad_jwts.append(last_five_chars)

def mint_key_for_namespace(
self, namespace: str, session_info: dict
) -> DeveloperKey:
"""
Mint a new key for a given namespace

:param namespace: namespace for the key
"""
salt = secrets.token_hex(32)
session_info["salt"] = salt
expiry = datetime.utcnow() + timedelta(seconds=self._default_exp)
new_key = jwt_encode_user_data(session_info, exp=expiry)
key = DeveloperKey(
key=new_key,
created_at=datetime.utcnow().isoformat(),
expires=expiry.isoformat(),
)
self.add_key(namespace, key)
return key

def is_key_bad(self, last_five_chars: str) -> bool:
return last_five_chars in self._bad_jwts


dev_key_handler = DeveloperKeyHandler()
Loading
Loading