async def list_catalog_records(
        record_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_READ)),
        paginator: Paginator = Depends(),
):
    if not (record := Session.get(Record, record_id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
async def get_catalog_record(
        record_id: str,
        catalog_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_READ)),
):
    if not (catalog_record := Session.get(CatalogRecord,
                                          (catalog_id, record_id))):
        raise HTTPException(HTTP_404_NOT_FOUND)
async def get_new_doi(
        collection_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_READ)),
):
    if auth.collection_ids != '*' and collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if not (collection := Session.get(Collection, collection_id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
Exemple #4
0
async def update_role(
        role_in: RoleModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.ROLE_ADMIN)),
):
    if auth.collection_ids != '*' and role_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if not (role := Session.get(Role, role_in.id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
async def update_collection(
        collection_in: CollectionModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_ADMIN)),
):
    if auth.collection_ids != '*' and collection_in.id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if not (collection := Session.get(Collection, collection_in.id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
Exemple #6
0
async def update_client(
        client_in: ClientModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.CLIENT_ADMIN)),
):
    if auth.collection_ids != '*' and client_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if not (client := Session.get(Client, client_in.id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
async def update_record(
        record_id: str,
        record_in: RecordModelIn,
        metadata_schema: JSONSchema = Depends(get_metadata_schema),
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_WRITE)),
):
    if auth.collection_ids != '*' and record_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if not (record := Session.get(Record, record_id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
async def get_collection(
        collection_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_READ)),
):
    if auth.collection_ids != '*' and collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    stmt = (select(Collection, func.count(Record.id)).outerjoin(Record).where(
        Collection.id == collection_id).group_by(Collection))

    if not (result := Session.execute(stmt).one_or_none()):
        raise HTTPException(HTTP_404_NOT_FOUND)
Exemple #9
0
async def list_clients(
        auth: Authorized = Depends(Authorize(ODPScope.CLIENT_READ)),
        paginator: Paginator = Depends(),
):
    stmt = select(Client)
    if auth.collection_ids != '*':
        stmt = stmt.where(Client.collection_id.in_(auth.collection_ids))

    return paginator.paginate(
        stmt,
        lambda row: output_client_model(row.Client),
    )
Exemple #10
0
async def list_roles(
        auth: Authorized = Depends(Authorize(ODPScope.ROLE_READ)),
        paginator: Paginator = Depends(),
):
    stmt = select(Role)
    if auth.collection_ids != '*':
        stmt = stmt.where(Role.collection_id.in_(auth.collection_ids))

    return paginator.paginate(
        stmt, lambda row: RoleModel(
            id=row.Role.id,
            scope_ids=[scope.id for scope in row.Role.scopes],
            collection_id=row.Role.collection_id,
        ))
async def list_collections(
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_READ)),
        paginator: Paginator = Depends(),
):
    stmt = (select(Collection, func.count(
        Record.id)).outerjoin(Record).group_by(Collection))
    if auth.collection_ids != '*':
        stmt = stmt.where(Collection.id.in_(auth.collection_ids))

    return paginator.paginate(
        stmt,
        lambda row: output_collection_model(row),
        sort_model=Collection,
    )
async def list_records(
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_READ)),
        paginator: Paginator = Depends(),
        collection_id: list[str] = Query(None),
):
    stmt = (select(Record).join(Collection))
    if auth.collection_ids != '*':
        stmt = stmt.where(Collection.id.in_(auth.collection_ids))
    if collection_id:
        stmt = stmt.where(Collection.id.in_(collection_id))

    return paginator.paginate(
        stmt,
        lambda row: output_record_model(row.Record),
    )
Exemple #13
0
async def create_role(
        role_in: RoleModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.ROLE_ADMIN)),
):
    if auth.collection_ids != '*' and role_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if Session.get(Role, role_in.id):
        raise HTTPException(HTTP_409_CONFLICT, 'Role id is already in use')

    role = Role(
        id=role_in.id,
        scopes=select_scopes(role_in.scope_ids,
                             [ScopeType.odp, ScopeType.client]),
        collection_id=role_in.collection_id,
    )
    role.save()
async def admin_set_record(
        # this route allows a record to be created with an externally
        # generated id, so we must validate that it is a uuid
        record_id: UUID,
        record_in: RecordModelIn,
        metadata_schema: JSONSchema = Depends(get_metadata_schema),
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_ADMIN)),
):
    if auth.collection_ids != '*' and record_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    create = False
    record = Session.get(Record, str(record_id))
    if not record:
        create = True
        record = Record(id=str(record_id))

    return _set_record(create, record, record_in, metadata_schema, auth, True)
async def create_collection(
        collection_in: CollectionModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_ADMIN)),
):
    if auth.collection_ids != '*':
        raise HTTPException(HTTP_403_FORBIDDEN)

    if Session.get(Collection, collection_in.id):
        raise HTTPException(HTTP_409_CONFLICT,
                            'Collection id is already in use')

    collection = Collection(
        id=collection_in.id,
        name=collection_in.name,
        doi_key=collection_in.doi_key,
        provider_id=collection_in.provider_id,
        timestamp=(timestamp := datetime.now(timezone.utc)),
    )
Exemple #16
0
async def create_client(
        client_in: ClientModelIn,
        auth: Authorized = Depends(Authorize(ODPScope.CLIENT_ADMIN)),
):
    if auth.collection_ids != '*' and client_in.collection_id not in auth.collection_ids:
        raise HTTPException(HTTP_403_FORBIDDEN)

    if Session.get(Client, client_in.id):
        raise HTTPException(HTTP_409_CONFLICT, 'Client id is already in use')

    if client_in.secret is None:
        raise HTTPException(HTTP_422_UNPROCESSABLE_ENTITY,
                            'Client secret must be provided on create')

    client = Client(
        id=client_in.id,
        scopes=select_scopes(client_in.scope_ids),
        collection_id=client_in.collection_id,
    )
    client.save()
    create_or_update_hydra_client(client_in)
Exemple #17
0
from starlette.status import HTTP_404_NOT_FOUND, HTTP_409_CONFLICT

from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import ProjectModel, ProjectModelIn
from odp.db import Session
from odp.db.models import Collection, Project

router = APIRouter()


@router.get(
    '/',
    response_model=Page[ProjectModel],
    dependencies=[Depends(Authorize(ODPScope.PROJECT_READ))],
)
async def list_projects(
        paginator: Paginator = Depends(),
):
    return paginator.paginate(
        select(Project),
        lambda row: ProjectModel(
            id=row.Project.id,
            name=row.Project.name,
            collection_ids=[collection.id for collection in row.Project.collections],
        )
    )


@router.get(
async def admin_delete_record(
        record_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_ADMIN)),
):
    _delete_record(record_id, auth, True)
Exemple #19
0
async def delete_role(
        role_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.ROLE_ADMIN)),
):
    if not (role := Session.get(Role, role_id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import SchemaModel
from odp.db import Session
from odp.db.models import Schema, SchemaType
from odp.lib.schema import schema_catalog

router = APIRouter()


@router.get(
    '/',
    response_model=Page[SchemaModel],
    dependencies=[Depends(Authorize(ODPScope.SCHEMA_READ))],
)
async def list_schemas(
        schema_type: SchemaType = None,
        paginator: Paginator = Depends(),
):
    stmt = select(Schema)
    if schema_type:
        stmt = stmt.where(Schema.type == schema_type)

    return paginator.paginate(
        stmt,
        lambda row: SchemaModel(
            id=row.Schema.id,
            type=row.Schema.type,
            uri=row.Schema.uri,
async def admin_create_record(
        record_in: RecordModelIn,
        metadata_schema: JSONSchema = Depends(get_metadata_schema),
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_ADMIN)),
):
    return _create_record(record_in, metadata_schema, auth, True)
async def admin_untag_collection(
        collection_id: str,
        tag_instance_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.COLLECTION_ADMIN)),
):
    _untag_collection(collection_id, tag_instance_id, auth, True)
async def delete_record(
        record_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_WRITE)),
):
    _delete_record(record_id, auth)
Exemple #24
0
from fastapi import APIRouter, Depends
from sqlalchemy import select

from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import ScopeModel
from odp.db.models import Scope

router = APIRouter()


@router.get(
    '/',
    response_model=Page[ScopeModel],
    dependencies=[Depends(Authorize(ODPScope.SCOPE_READ))],
)
async def list_scopes(paginator: Paginator = Depends(), ):
    return paginator.paginate(
        select(Scope),
        lambda row: ScopeModel(
            id=row.Scope.id,
            type=row.Scope.type,
        ),
        custom_sort="array_position(array['openid'], id),"
        "array_position(array['oauth','odp','client'], type::text),"
        "id")
Exemple #25
0
from starlette.status import HTTP_404_NOT_FOUND

from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import UserModelIn, UserModel
from odp.db import Session
from odp.db.models import User, Role

router = APIRouter()


@router.get(
    '/',
    response_model=Page[UserModel],
    dependencies=[Depends(Authorize(ODPScope.USER_READ))],
)
async def list_users(paginator: Paginator = Depends(), ):
    return paginator.paginate(
        select(User), lambda row: UserModel(
            id=row.User.id,
            email=row.User.email,
            active=row.User.active,
            verified=row.User.verified,
            name=row.User.name,
            picture=row.User.picture,
            role_ids=[role.id for role in row.User.roles],
        ))


@router.get(
Exemple #26
0
async def get_client(
        client_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.CLIENT_READ)),
):
    if not (client := Session.get(Client, client_id)):
        raise HTTPException(HTTP_404_NOT_FOUND)
Exemple #27
0
from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import CatalogModel, PublishedRecordModel
from odp.db import Session
from odp.db.models import Catalog, CatalogRecord
from odp.lib.schema import schema_catalog

router = APIRouter()


@router.get(
    '/',
    response_model=Page[CatalogModel],
    dependencies=[Depends(Authorize(ODPScope.CATALOG_READ))],
)
async def list_catalogs(paginator: Paginator = Depends(), ):
    return paginator.paginate(
        select(Catalog), lambda row: CatalogModel(
            id=row.Catalog.id,
            schema_id=row.Catalog.schema_id,
            schema_uri=row.Catalog.schema.uri,
            schema_=schema_catalog.get_schema(URI(row.Catalog.schema.uri)).
            value,
        ))


@router.get(
    '/{catalog_id}',
    response_model=CatalogModel,
async def admin_untag_record(
        record_id: str,
        tag_instance_id: str,
        auth: Authorized = Depends(Authorize(ODPScope.RECORD_ADMIN)),
):
    _untag_record(record_id, tag_instance_id, auth, True)
Exemple #29
0
from odp import ODPScope
from odp.api.lib.auth import Authorize
from odp.api.lib.paging import Page, Paginator
from odp.api.models import TagModel
from odp.db import Session
from odp.db.models import Tag
from odp.lib.schema import schema_catalog

router = APIRouter()


@router.get(
    '/',
    response_model=Page[TagModel],
    dependencies=[Depends(Authorize(ODPScope.TAG_READ))],
)
async def list_tags(paginator: Paginator = Depends(), ):
    return paginator.paginate(
        select(Tag), lambda row: TagModel(
            id=row.Tag.id,
            cardinality=row.Tag.cardinality,
            public=row.Tag.public,
            scope_id=row.Tag.scope_id,
            schema_id=row.Tag.schema_id,
            schema_uri=row.Tag.schema.uri,
            schema_=schema_catalog.get_schema(URI(row.Tag.schema.uri)).value,
        ))


@router.get(