Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
dc39e85
import container (#462)
longshuicy Apr 25, 2023
8c7f727
446 gui to manage api keys (#465)
longshuicy Apr 25, 2023
3562137
Sharing tab cleanup (#430)
max-zilla Apr 25, 2023
c5bd385
Fix reload bug (#451)
max-zilla Apr 26, 2023
a612602
461 fix library version in pipfile (#468)
longshuicy Apr 26, 2023
931c4c4
443 frontend need to display more verbose backend error (#458)
arunapa Apr 27, 2023
e1f8a4a
469 create profile page (#471)
tcnichol Apr 28, 2023
5ac23fe
Implemented role delete in sharing tab (#472)
arunapa Apr 28, 2023
0695231
Show Creator on Group Page (#428)
tcnichol Apr 28, 2023
7ad8356
Fixed bug where error detail might be empty (#478)
arunapa May 1, 2023
5fc009a
filter the option without group owner
longshuicy May 1, 2023
e72c3e1
filter group owner out
longshuicy May 1, 2023
b04bd1f
Made the updaterole function async, and added a call to fetch roles t…
arunapa May 4, 2023
19d1e2b
Updated remove role logic to automatically refresh the roles list
arunapa May 4, 2023
a297ecc
Executed eslint
arunapa May 4, 2023
3cfd8f8
Merge pull request #488 from clowder-framework/486-list-doesnt-get-po…
tcnichol May 4, 2023
4c4cae7
Merge branch 'main' into 476-add-member-need-to-filter-out-the-creator
tcnichol May 4, 2023
5e615f2
Merge pull request #479 from clowder-framework/476-add-member-need-to…
tcnichol May 4, 2023
174f881
stub for feeds
max-zilla May 4, 2023
d70b0c1
add basic Feed support
max-zilla May 5, 2023
9418b02
various updates
max-zilla May 5, 2023
3360c6a
introduce listener views
max-zilla May 8, 2023
838506c
update config model
max-zilla May 8, 2023
e6c9703
More updates to metadata models
max-zilla May 8, 2023
123ef91
Update datasets.py
max-zilla May 8, 2023
fbe71fe
Merge branch 'main' into beanie-extractors-search
max-zilla May 8, 2023
f7e0046
update metadata usage
max-zilla May 8, 2023
4ab69db
formatting
max-zilla May 8, 2023
80b8d07
replace db["datasets"]
max-zilla May 8, 2023
6135614
Update metadata.py
max-zilla May 8, 2023
eefc314
Merge branch 'beanie' into beanie-extractors-search
max-zilla May 9, 2023
4a0f7e9
ObjectID & response cleanups
max-zilla May 9, 2023
20fc6e0
syntax fix
max-zilla May 9, 2023
5572ee0
author -> creator
max-zilla May 9, 2023
8bf469b
formatting
max-zilla May 9, 2023
c400442
consistent syntax
max-zilla May 9, 2023
c4cda54
fix init of listener views
max-zilla May 10, 2023
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
2 changes: 1 addition & 1 deletion backend/app/beanie_views_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ async def example():
# print(results)

results = await DatasetDBViewList.find(
DatasetDBViewList.author.email == "[email protected]"
DatasetDBViewList.creator.email == "[email protected]"
).to_list()
print(results)

Expand Down
145 changes: 11 additions & 134 deletions backend/app/deps/authorization_deps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from beanie import PydanticObjectId
from beanie.operators import Or
from bson import ObjectId
from fastapi import Depends, HTTPException
Expand All @@ -6,16 +7,15 @@
from app.dependencies import get_db
from app.keycloak_auth import get_current_username
from app.models.authorization import RoleType, AuthorizationDB
from app.models.datasets import DatasetOut
from app.models.datasets import DatasetDB
from app.models.files import FileOut
from app.models.groups import GroupOut
from app.models.metadata import MetadataOut
from app.models.metadata import MetadataDB
from app.models.pyobjectid import PyObjectId


async def get_role(
dataset_id: str,
db: MongoClient = Depends(get_db),
current_user=Depends(get_current_username),
) -> RoleType:
"""Returns the role a specific user has on a dataset. If the user is a creator (owner), they are not listed in
Expand All @@ -28,16 +28,6 @@ async def get_role(
),
)
return authorization.role
# authorization = await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(dataset_id)},
# {"$or": [{"creator": current_user}, {"user_ids": current_user}]},
# ]
# }
# )
# role = AuthorizationDB.from_mongo(authorization).role
# return role


async def get_role_by_file(
Expand All @@ -55,17 +45,6 @@ async def get_role_by_file(
),
)
return authorization.role
# authorization = await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(file_out.dataset_id)},
# {"$or": [{"creator": current_user}, {"user_ids": current_user}]},
# ]
# }
# )
# role = AuthorizationDB.from_mongo(authorization).role
# return role

raise HTTPException(status_code=404, detail=f"File {file_id} not found")


Expand All @@ -74,10 +53,7 @@ async def get_role_by_metadata(
db: MongoClient = Depends(get_db),
current_user=Depends(get_current_username),
) -> RoleType:
if (
metadata := await db["metadata"].find_one({"_id": ObjectId(metadata_id)})
) is not None:
md_out = MetadataOut.from_mongo(metadata)
if (md_out := await MetadataDB.get(PydanticObjectId(metadata_id))) is not None:
resource_type = md_out.resource.collection
resource_id = md_out.resource.resource_id
if resource_type == "files":
Expand All @@ -93,49 +69,19 @@ async def get_role_by_metadata(
),
)
return authorization.role
# authorization = await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(file_out.dataset_id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# role = AuthorizationDB.from_mongo(authorization).role
# return role
elif resource_type == "datasets":

if (
dataset := await db["datasets"].find_one({"_id": ObjectId(resource_id)})
dataset := await DatasetDB.get(PydanticObjectId(resource_id))
) is not None:
dataset_out = DatasetOut.from_mongo(dataset)
authorization = await AuthorizationDB.find_one(
AuthorizationDB.dataset_id == dataset_out.dataset_id,
AuthorizationDB.dataset_id == dataset.id,
Or(
AuthorizationDB.creator == current_user,
AuthorizationDB.user_ids == current_user,
),
)
return authorization.role
# authorization = await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(dataset_out.dataset_id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# role = AuthorizationDB.from_mongo(authorization).role
# return role


async def get_role_by_group(
Expand Down Expand Up @@ -182,22 +128,6 @@ async def __call__(
AuthorizationDB.user_ids == current_user,
),
)
# if (
# authorization_q := await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(dataset_id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# ) is not None:
# authorization = AuthorizationDB.from_mongo(authorization_q)
if authorization is not None:
if access(authorization.role, self.role):
return True
Expand Down Expand Up @@ -235,22 +165,6 @@ async def __call__(
AuthorizationDB.user_ids == current_user,
),
)
# if (
# authorization_q := await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(file_out.dataset_id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# ) is not None:
# authorization = AuthorizationDB.from_mongo(authorization_q)
if authorization is not None:
if access(authorization.role, self.role):
return True
Expand All @@ -275,10 +189,7 @@ async def __call__(
db: MongoClient = Depends(get_db),
current_user: str = Depends(get_current_username),
):
if (
metadata := await db["metadata"].find_one({"_id": ObjectId(metadata_id)})
) is not None:
md_out = MetadataOut.from_mongo(metadata)
if (md_out := await MetadataDB.get(PydanticObjectId(metadata_id))) is not None:
resource_type = md_out.resource.collection
resource_id = md_out.resource.resource_id
if resource_type == "files":
Expand All @@ -293,22 +204,6 @@ async def __call__(
AuthorizationDB.user_ids == current_user,
),
)
# if (
# authorization_q := await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(file_out.dataset_id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# ) is not None:
# authorization = AuthorizationDB.from_mongo(authorization_q)
if authorization is not None:
if access(authorization.role, self.role):
return True
Expand All @@ -322,34 +217,16 @@ async def __call__(
)
elif resource_type == "datasets":
if (
dataset := await db["datasets"].find_one(
{"_id": ObjectId(resource_id)}
)
) is not None:
dataset_out = DatasetOut.from_mongo(dataset)
dataset_out := await DatasetDB.get(PydanticObjectId(resource_id))
is not None
):
authorization = await AuthorizationDB.find_one(
AuthorizationDB.dataset_id == dataset_out.dataset_id,
Or(
AuthorizationDB.creator == current_user,
AuthorizationDB.user_ids == current_user,
),
)
# if (
# authorization_q := await db["authorization"].find_one(
# {
# "$and": [
# {"dataset_id": ObjectId(dataset_out.id)},
# {
# "$or": [
# {"creator": current_user},
# {"user_ids": current_user},
# ]
# },
# ]
# }
# )
# ) is not None:
# authorization = AuthorizationDB.from_mongo(authorization_q)
if authorization is not None:
if access(authorization.role, self.role):
return True
Expand Down
14 changes: 14 additions & 0 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
from app.keycloak_auth import get_current_username
from app.models.authorization import AuthorizationDB
from app.models.datasets import DatasetDB, DatasetDBViewList
from app.models.feeds import FeedDB
from app.models.listeners import (
EventListenerDB,
EventListenerJobDB,
EventListenerJobUpdateDB,
EventListenerJobViewList,
EventListenerJobUpdateViewList,
)
from app.models.metadata import MetadataDB, MetadataDefinitionDB
from app.routers import (
folders,
Expand Down Expand Up @@ -173,6 +181,12 @@ async def startup_beanie():
AuthorizationDB,
MetadataDB,
MetadataDefinitionDB,
FeedDB,
EventListenerDB,
EventListenerJobDB,
EventListenerJobUpdateDB,
EventListenerJobViewList,
EventListenerJobUpdateViewList,
],
recreate_views=True,
)
Expand Down
16 changes: 8 additions & 8 deletions backend/app/models/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,17 @@ class Config:
use_enum_values = True


class AuthorizationDB(MongoModel, AuthorizationBase):
class Provenance:
pass


class AuthorizationDB(Document, AuthorizationBase, Provenance):
"""The creator of the Authorization object should also be the creator of the dataset itself."""

class Settings:
name = "authorization"


class AuthorizationOut(AuthorizationDB):
pass

Expand Down Expand Up @@ -75,10 +82,3 @@ class Provenance(BaseModel):
creator: EmailStr
created: datetime = Field(default_factory=datetime.utcnow)
modified: datetime = Field(default_factory=datetime.utcnow)


class AuthorizationDB(Document, AuthorizationBase, Provenance):
"""The creator of the Authorization object should also be the creator of the dataset itself."""

class Settings:
name = "authorization"
13 changes: 11 additions & 2 deletions backend/app/models/config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from app.models.mongomodel import MongoModel
import pymongo
from beanie import Document


class ConfigEntryBase(MongoModel):
class ConfigEntryBase(Document):
key: str
value: str

class Settings:
name = "config"
indexes = [
[
("key", pymongo.TEXT),
],
]


class ConfigEntryDB(ConfigEntryBase):
pass
Expand Down
5 changes: 3 additions & 2 deletions backend/app/models/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class DatasetPatch(BaseModel):


class DatasetDB(Document, DatasetBase):
author: UserOut
id: PydanticObjectId = Field(None, alias="_id")
creator: UserOut
created: datetime = Field(default_factory=datetime.utcnow)
modified: datetime = Field(default_factory=datetime.utcnow)
status: str = DatasetStatus.PRIVATE.name
Expand All @@ -59,7 +60,7 @@ class Settings:
class DatasetDBViewList(View, DatasetBase):
# FIXME This seems to be required to return _id. Otherwise _id is null in the response.
id: PydanticObjectId = Field(None, alias="_id")
author: UserOut
creator: UserOut
created: datetime = Field(default_factory=datetime.utcnow)
modified: datetime = Field(default_factory=datetime.utcnow)
auth: List[AuthorizationDB]
Expand Down
28 changes: 19 additions & 9 deletions backend/app/models/feeds.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from datetime import datetime
from pydantic import Field, BaseModel
from typing import Optional, List, Union
from app.models.mongomodel import MongoModel
from app.models.users import UserOut
from typing import List

import pymongo
from beanie import Document, PydanticObjectId
from pydantic import BaseModel, Field

from app.models.authorization import Provenance
from app.models.listeners import FeedListener
from app.models.search import SearchObject
from app.models.listeners import EventListenerOut, FeedListener


class JobFeed(BaseModel):
Expand All @@ -24,9 +26,17 @@ class FeedIn(JobFeed):
pass


class FeedDB(JobFeed, MongoModel):
author: Optional[UserOut] = None
updated: datetime = Field(default_factory=datetime.utcnow)
class FeedDB(Document, JobFeed, Provenance):
id: PydanticObjectId = Field(None, alias="_id")

class Settings:
name = "feeds"
indexes = [
[
("name", pymongo.TEXT),
("description", pymongo.TEXT),
],
]


class FeedOut(FeedDB):
Expand Down
Loading