Mercurial > hg > orthanc-tests
diff NewTests/Authorization/models.py @ 576:80ba6f1d521c
new tests for authorization plugin (native only)
author | Alain Mazy <am@osimis.io> |
---|---|
date | Wed, 06 Sep 2023 17:04:36 +0200 |
parents | |
children | 0649a19df194 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NewTests/Authorization/models.py Wed Sep 06 17:04:36 2023 +0200 @@ -0,0 +1,150 @@ +# SPDX-FileCopyrightText: 2022 - 2023 Orthanc Team SRL <info@orthanc.team> +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from typing import Optional, List +from pydantic import BaseModel, Field +from pydantic.datetime_parse import parse_datetime +from enum import Enum +from datetime import datetime + + +class StringDateTime(datetime): + @classmethod + def __get_validators__(cls): + yield parse_datetime + yield cls.validate + + @classmethod + def validate(cls, v: datetime): + return v.isoformat() + + +class Levels(str, Enum): + PATIENT = 'patient' + STUDY = 'study' + SERIES = 'series' + INSTANCE = 'instance' + + SYSTEM = 'system' + + +class Methods(str, Enum): + GET = 'get' + POST = 'post' + PUT = 'put' + DELETE = 'delete' + + +class DecoderErrorCodes(str, Enum): + EXPIRED = 'expired' + INVALID = 'invalid' + UNKNOWN = 'unknown' + + +class TokenType(str, Enum): + OSIMIS_VIEWER_PUBLICATION = 'osimis-viewer-publication' # a link to open the Osimis viewer valid for a long period + MEDDREAM_VIEWER_PUBLICATION = 'meddream-viewer-publication' # a link to open the MedDream viewer valid for a long period + STONE_VIEWER_PUBLICATION = 'stone-viewer-publication' # a link to open the Stone viewer valid for a long period + OHIF_VIEWER_PUBLICATION = 'ohif-viewer-publication' # a link to open the OHIF viewer valid for a long period + + MEDDREAM_INSTANT_LINK = 'meddream-instant-link' # a direct link to MedDream viewer that is valid only a few minutes to open the viewer directly + + # OSIMIS_VIEWER_INSTANT_LINK = 'osimis-viewer-instant-link' # a direct link to Osimis viewer that is valid only a few minutes to open the viewer directly + # STONE_VIEWER_INSTANT_LINK = 'stone-viewer-instant-link' # a direct link to Stone viewer that is valid only a few minutes to open the viewer directly + # + # DOWNLOAD_INSTANT_LINK = 'download-instant-link' # a link to download a study/series/instance directly + VIEWER_INSTANT_LINK = 'viewer-instant-link' # a link to a resource to be used directly. + DOWNLOAD_INSTANT_LINK = 'download-instant-link' # a link to a resource to be used directly. + + + INVALID = 'invalid' + +class OrthancResource(BaseModel): + dicom_uid: Optional[str] = Field(alias="dicom-uid", default=None) + orthanc_id: Optional[str] = Field(alias="orthanc-id", default=None) + url: Optional[str] = None # e.g. a download link /studies/.../archive + level: Levels + + class Config: # allow creating object from dict (used when deserializing the JWT) + allow_population_by_field_name = True + + +class TokenCreationRequest(BaseModel): + id: Optional[str] = None + resources: List[OrthancResource] + type: TokenType = Field(default=TokenType.INVALID) + expiration_date: Optional[StringDateTime] = Field(alias="expiration-date", default=None) + validity_duration: Optional[int] = Field(alias='validity-duration', default=None) # alternate way to provide an expiration_date, more convenient for instant-links since the duration is relative to the server time, not the client time ! + + class Config: # allow creating object from dict (used when deserializing the JWT) + allow_population_by_field_name = True + + +class TokenCreationResponse(BaseModel): + request: TokenCreationRequest + token: str + url: Optional[str] = None + + +class TokenValidationRequest(BaseModel): + dicom_uid: Optional[str] = Field(alias="dicom-uid", default=None) + orthanc_id: Optional[str] = Field(alias="orthanc-id", default=None) + token_key: Optional[str] = Field(alias="token-key", default=None) + token_value: Optional[str] = Field(alias="token-value", default=None) + server_id: Optional[str] = Field(alias="server-id", default=None) + level: Optional[Levels] + method: Methods + uri: Optional[str] +# labels: Optional[List[str]] + + +class TokenValidationResponse(BaseModel): + granted: bool + validity: int + + +class TokenDecoderRequest(BaseModel): + token_key: Optional[str] = Field(alias="token-key", default=None) + token_value: Optional[str] = Field(alias="token-value", default=None) + + +class TokenDecoderResponse(BaseModel): + token_type: Optional[TokenType] = Field(alias="token-type", default=None) + error_code: Optional[DecoderErrorCodes] = Field(alias="error-code", default=None) + redirect_url: Optional[str] = Field(alias="redirect-url", default=None) + + +class UserProfileRequest(BaseModel): + token_key: Optional[str] = Field(alias="token-key", default=None) + token_value: Optional[str] = Field(alias="token-value", default=None) + server_id: Optional[str] = Field(alias="server-id", default=None) + + +class UserPermissions(str, Enum): + ALL = 'all' + VIEW = 'view' + DOWNLOAD = 'download' + DELETE = 'delete' + SEND = 'send' + MODIFY = 'modify' + ANONYMIZE = 'anonymize' + UPLOAD = 'upload' + Q_R_REMOTE_MODALITIES = 'q-r-remote-modalities' + SETTINGS = 'settings' + API_VIEW = 'api-view' + EDIT_LABELS = 'edit-labels' + + SHARE = 'share' + + +class UserProfileResponse(BaseModel): + name: str + authorized_labels: List[str] = Field(alias="authorized-labels", default_factory=list) + # authorized_labels: List[str] = Field(default_factory=list) + permissions: List[UserPermissions] = Field(default_factory=list) + validity: int + + class Config: + use_enum_values = True + allow_population_by_field_name = True \ No newline at end of file