Skip to content

Commit a228a01

Browse files
longshuicytcnicholmax-zillaarunapa
authored
491 beanie for file and folder (#496)
* import container (#462) * 446 gui to manage api keys (#465) * add new routes placeholder * add list and delete endpoint; inline docs * codegen and pytest * ugly ui? * onstart clear user keys * delete works but pytest doesn't work yet * pytest all works * codegen * redux * reducer and types * write the table * correctly wire in the apikey and error handling * wire in the delete modal of apikeys * wire in the creation api key * everything working in the gui * formatting --------- Co-authored-by: toddn <[email protected]> * Sharing tab cleanup (#430) * fix bug where users not being fetched * simplifying role query pt 1 * refactor tables and API calls * cleanup * start moving GroupAndRole to separate table * add expanding sub table * remove AddGroup buttons for now * formatting * codegen * add response model * codegen * remove container * fix bug with Roles return object and autocomplete on groups * codegen * Fix reload bug (#451) * 461 fix library version in pipfile (#468) * fix pipfile version * regenerate the piplock file * 443 frontend need to display more verbose backend error (#458) * Updated frontend error message to be more verbose * Backend returns verbose logs, frontend displays it as generic messages depending on the HTTP status code * Updated the error message logic to include original backend logs wherever possible * Fixed report button issue * Rootcause: The onClick event for the report button has a semantic error, which is causing the issue reason string to be replaced with an object * Also added encode for the reason * Fixing issue with error message * Revert "Updated frontend error message to be more verbose" This reverts commit 7d230d3. * Fixing issue with error message * 469 create profile page (#471) * profile page exists * new route for user profile profile page includes layout * codegen new route for get current user profile * we now get the profile, but nothing shows yet * page has fake data * we see the profile now * formatting * Implemented role delete in sharing tab (#472) * Tested by deleting a user, group. Verified entry is removed upon refresh * Show Creator on Group Page (#428) * the owner is visible, and we cannot change the owner in the table * showing group creator on top * creator link is wrong, need to fix * bold text for word 'creator' * using more conditionals to reduce duplicate code * missing modal added creator name matches other names --------- Co-authored-by: Chen Wang <[email protected]> * Fixed bug where error detail might be empty (#478) * Fixed bug where error detail might be empty * Added null check to the detail string to prevent errors when detail is not set * Second check to validate the body field * filter the option without group owner * filter group owner out * Made the updaterole function async, and added a call to fetch roles to refresh the list of roles in state * Updated remove role logic to automatically refresh the roles list * Executed eslint * remove _beanie * wire in folder db * download folder * refactored everything in file/folder * reformat * missed a spot * codegen * forget to add FileVersionDB * add await * fix more merge conflict * duplicate * fix inc * black fromat * codegen * fix inconsistency * black * fix frontend author/creator * fix detail * fix some of the async bug * download works * init & use TokenDB everywhere * fix files/submit endpoint * remove manual index creation * fix extractor submission --------- Co-authored-by: toddn <[email protected]> Co-authored-by: Max Burnette <[email protected]> Co-authored-by: Aruna Parameswaran <[email protected]> Co-authored-by: Todd Nicholson <[email protected]>
1 parent e99da9c commit a228a01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+377
-324
lines changed

backend/app/database/errors.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pymongo import MongoClient
77

88
from app.config import settings
9-
from app.mongo import create_mongo_indexes
109
from app.models.errors import Error
1110
from app.models.mongomodel import MongoDBRef
1211

@@ -17,7 +16,6 @@ async def _get_db() -> Generator:
1716
"""Duplicate of app.dependencies.get_db(), but importing that causes circular import."""
1817
mongo_client = motor.motor_asyncio.AsyncIOMotorClient(settings.MONGODB_URL)
1918
db = mongo_client[settings.MONGO_DATABASE]
20-
await create_mongo_indexes(db)
2119
yield db
2220

2321

backend/app/dependencies.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@
1212
from app.config import settings
1313
from minio.commonconfig import ENABLED
1414
from minio.versioningconfig import VersioningConfig
15-
from app.mongo import create_mongo_indexes
1615
from app.search.connect import connect_elasticsearch
1716

1817

1918
async def get_db() -> Generator:
2019
mongo_client = motor.motor_asyncio.AsyncIOMotorClient(settings.MONGODB_URL)
2120
db = mongo_client[settings.MONGO_DATABASE]
22-
await create_mongo_indexes(db)
2321
if db is None:
2422
raise HTTPException(status_code=503, detail="Service not available")
2523
return

backend/app/deps/authorization_deps.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ async def get_role_by_metadata(
7070
)
7171
return authorization.role
7272
elif resource_type == "datasets":
73-
7473
if (
7574
dataset := await DatasetDB.get(PydanticObjectId(resource_id))
7675
) is not None:

backend/app/keycloak_auth.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from . import dependencies
1919
from .config import settings
20+
from .models.tokens import TokenDB
2021
from .models.users import UserOut, UserAPIKey, UserDB
2122

2223
logger = logging.getLogger(__name__)
@@ -144,8 +145,8 @@ async def get_current_user(
144145
if token:
145146
try:
146147
userinfo = keycloak_openid.userinfo(token)
147-
user_out = await db["users"].find_one({"email": userinfo["email"]})
148-
return UserOut.from_mongo(user_out)
148+
user = await UserDB.find_one({"email": userinfo["email"]})
149+
return UserOut(**user.dict())
149150
except KeycloakAuthenticationError as e:
150151
raise HTTPException(
151152
status_code=e.response_code,
@@ -296,18 +297,16 @@ async def create_user(email: str, password: str, firstName: str, lastName: str):
296297
async def retreive_refresh_token(
297298
email: str, db: MongoClient = Depends(dependencies.get_db)
298299
):
299-
if (token_exist := await db["tokens"].find_one({"email": email})) is not None:
300+
if (token_exist := await TokenDB.find_one({"email": email})) is not None:
300301
try:
301302
new_tokens = keycloak_openid.refresh_token(token_exist["refresh_token"])
302303
# update the refresh token in the database
303304
token_exist.update({"refresh_token": new_tokens["refresh_token"]})
304-
await db["tokens"].replace_one(
305-
{"_id": ObjectId(token_exist["_id"])}, token_exist
306-
)
305+
await token_exist.save()
307306
return {"access_token": new_tokens["access_token"]}
308307
except KeycloakGetError as e:
309308
# refresh token invalid; remove from database
310-
await db["tokens"].delete_one({"_id": ObjectId(token_exist["_id"])})
309+
await token_exist.delete()
311310
raise HTTPException(
312311
status_code=401,
313312
detail=str(e), # "Invalid authentication credentials",

backend/app/main.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
from app.config import settings
1111
from app.keycloak_auth import get_current_username
1212
from app.models.authorization import AuthorizationDB
13-
from app.models.users import UserDB, UserAPIKey
14-
from app.models.groups import GroupDB
13+
from app.models.config import ConfigEntryDB
1514
from app.models.datasets import DatasetDB, DatasetDBViewList
1615
from app.models.feeds import FeedDB
16+
from app.models.files import FileDB, FileVersionDB
17+
from app.models.folders import FolderDB
18+
from app.models.groups import GroupDB
1719
from app.models.listeners import (
1820
EventListenerDB,
1921
EventListenerJobDB,
@@ -22,6 +24,8 @@
2224
EventListenerJobUpdateViewList,
2325
)
2426
from app.models.metadata import MetadataDB, MetadataDefinitionDB
27+
from app.models.tokens import TokenDB
28+
from app.models.users import UserDB, UserAPIKey
2529
from app.routers import (
2630
folders,
2731
groups,
@@ -179,11 +183,15 @@ async def startup_beanie():
179183
database=getattr(client, settings.MONGO_DATABASE),
180184
# Make sure to include all models. If one depends on another that is not in the list it is not clear which one is missing.
181185
document_models=[
186+
ConfigEntryDB,
182187
DatasetDB,
183188
DatasetDBViewList,
184189
AuthorizationDB,
185190
MetadataDB,
186191
MetadataDefinitionDB,
192+
FolderDB,
193+
FileDB,
194+
FileVersionDB,
187195
FeedDB,
188196
EventListenerDB,
189197
EventListenerJobDB,
@@ -193,6 +201,7 @@ async def startup_beanie():
193201
UserDB,
194202
UserAPIKey,
195203
GroupDB,
204+
TokenDB,
196205
],
197206
recreate_views=True,
198207
)

backend/app/models/config.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import pymongo
22
from beanie import Document
3+
from pydantic import BaseModel
34

45

5-
class ConfigEntryBase(Document):
6+
class ConfigEntryBase(BaseModel):
67
key: str
78
value: str
89

10+
11+
class ConfigEntryDB(Document, ConfigEntryBase):
912
class Settings:
1013
name = "config"
1114
indexes = [
@@ -15,9 +18,5 @@ class Settings:
1518
]
1619

1720

18-
class ConfigEntryDB(ConfigEntryBase):
19-
pass
20-
21-
22-
class ConfigEntryOut(ConfigEntryBase):
21+
class ConfigEntryOut(ConfigEntryDB):
2322
pass

backend/app/models/files.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22
from typing import Optional
33

4+
from beanie import Document, PydanticObjectId
45
from pydantic import Field, BaseModel
56

67
from app.models.mongomodel import MongoModel
@@ -28,6 +29,13 @@ class FileVersion(MongoModel):
2829
bytes: int = 0
2930

3031

32+
class FileVersionDB(Document, FileVersion):
33+
id: PydanticObjectId = Field(None, alias="_id")
34+
35+
class Settings:
36+
name = "file_versions"
37+
38+
3139
class FileBase(MongoModel):
3240
name: str = "N/A"
3341

@@ -36,7 +44,8 @@ class FileIn(FileBase):
3644
pass
3745

3846

39-
class FileDB(FileBase):
47+
class FileDB(Document, FileBase):
48+
id: PydanticObjectId = Field(None, alias="_id")
4049
creator: UserOut
4150
created: datetime = Field(default_factory=datetime.utcnow)
4251
version_id: str = "N/A"
@@ -48,6 +57,9 @@ class FileDB(FileBase):
4857
bytes: int = 0
4958
content_type: FileContentType = FileContentType()
5059

60+
class Settings:
61+
name = "files"
62+
5163

5264
class FileOut(FileDB):
5365
pass

backend/app/models/folders.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22
from typing import Optional
33

4+
from beanie import Document, PydanticObjectId
45
from pydantic import Field
56

67
from app.models.mongomodel import MongoModel
@@ -16,13 +17,17 @@ class FolderIn(FolderBase):
1617
parent_folder: Optional[PyObjectId]
1718

1819

19-
class FolderDB(FolderBase):
20+
class FolderDB(Document, FolderBase):
21+
id: PydanticObjectId = Field(None, alias="_id")
2022
dataset_id: PyObjectId
2123
parent_folder: Optional[PyObjectId]
2224
creator: UserOut
2325
created: datetime = Field(default_factory=datetime.utcnow)
2426
modified: datetime = Field(default_factory=datetime.utcnow)
2527

28+
class Settings:
29+
name = "folders"
30+
2631

2732
class FolderOut(FolderDB):
2833
pass

backend/app/models/tokens.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
from app.models.mongomodel import MongoModel, BaseModel
2-
from beanie import Document, View, PydanticObjectId
1+
import pymongo
2+
from beanie import Document
3+
4+
from app.models.mongomodel import BaseModel
35

46

57
class TokenBase(BaseModel):
@@ -8,4 +10,10 @@ class TokenBase(BaseModel):
810

911

1012
class TokenDB(Document, TokenBase):
11-
pass
13+
class Settings:
14+
name = "tokens"
15+
indexes = [
16+
[
17+
("email", pymongo.TEXT),
18+
],
19+
]

backend/app/mongo.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)