Skip to content

Commit

Permalink
Merge pull request #448 from bcgov/feature/pydantic2Update
Browse files Browse the repository at this point in the history
Updated version of FastAPI (migrate to Pydantic2 and others)
  • Loading branch information
loneil authored Apr 2, 2024
2 parents 8fbdfea + b3e7d73 commit c6f7b68
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 138 deletions.
5 changes: 2 additions & 3 deletions oidc-controller/api/authSessions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from api.core.acapy.client import AcapyClient
from api.core.models import UUIDModel
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field

from ..core.config import settings

Expand All @@ -27,8 +27,7 @@ class AuthSessionBase(BaseModel):
response_url: str
presentation_request_msg: Optional[dict] = None

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)


class AuthSession(AuthSessionBase, UUIDModel):
Expand Down
18 changes: 8 additions & 10 deletions oidc-controller/api/clientConfigurations/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field

from ..core.config import settings
from .examples import ex_client_config
Expand All @@ -27,9 +27,7 @@ class ClientConfigurationBase(BaseModel):

client_secret: str = Field(default=settings.OIDC_CLIENT_SECRET)

class Config:
allow_population_by_field_name = True
schema_extra = {"example": ex_client_config}
model_config = ConfigDict(populate_by_name=True, json_schema_extra={"example": ex_client_config})


class ClientConfiguration(ClientConfigurationBase):
Expand All @@ -41,11 +39,11 @@ class ClientConfigurationRead(ClientConfigurationBase):


class ClientConfigurationPatch(ClientConfigurationBase):
client_id: Optional[str]
client_name: Optional[str]
response_types: Optional[List[str]]
redirect_uris: Optional[List[str]]
token_endpoint_auth_method: Optional[TOKENENDPOINTAUTHMETHODS]
client_secret: Optional[str]
client_id: Optional[str] = None
client_name: Optional[str] = None
response_types: Optional[List[str]] = None
redirect_uris: Optional[List[str]] = None
token_endpoint_auth_method: Optional[TOKENENDPOINTAUTHMETHODS] = None
client_secret: Optional[str] = None

pass
2 changes: 1 addition & 1 deletion oidc-controller/api/core/acapy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class WalletDid(BaseModel):


class WalletDidPublicResponse(BaseModel):
result: Optional[WalletDid]
result: Optional[WalletDid] = None


class CreatePresentationResponse(BaseModel):
Expand Down
8 changes: 3 additions & 5 deletions oidc-controller/api/core/aries/out_of_band.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Dict, List, Union
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
from .service_decorator import OOBServiceDecorator


Expand All @@ -8,8 +8,7 @@ class OutOfBandPresentProofAttachment(BaseModel):
mime_type: str = Field(default="application/json", alias="mime-type")
data: Dict

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)


class OutOfBandMessage(BaseModel):
Expand All @@ -28,5 +27,4 @@ class OutOfBandMessage(BaseModel):
)
services: List[Union[OOBServiceDecorator, str]] = Field(alias="services")

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)
7 changes: 3 additions & 4 deletions oidc-controller/api/core/aries/present_proof_presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import base64
from typing import Optional, List

from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
from api.core.aries import PresentProofv10Attachment, ServiceDecorator


Expand All @@ -17,10 +17,9 @@ class PresentationRequestMessage(BaseModel):
alias="request_presentations~attach"
)
comment: Optional[str] = None
service: Optional[ServiceDecorator] = Field(alias="~service")
service: Optional[ServiceDecorator] = Field(None, alias="~service")

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)

def b64_str(self):
# object->dict->jsonString->ascii->ENCODE->ascii
Expand Down
18 changes: 8 additions & 10 deletions oidc-controller/api/core/aries/service_decorator.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
from typing import List, Optional
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field


class ServiceDecorator(BaseModel):
# https://github.com/hyperledger/aries-rfcs/tree/main/features/0056-service-decorator
recipient_keys: Optional[List[str]] = Field(alias="recipientKeys")
routing_keys: Optional[List[str]] = Field(alias="routingKeys")
service_endpoint: Optional[str] = Field(alias="serviceEndpoint")
recipient_keys: Optional[List[str]] = Field(default=None, alias="recipientKeys")
routing_keys: Optional[List[str]] = Field(default=None, alias="routingKeys")
service_endpoint: Optional[str] = Field(default=None, alias="serviceEndpoint")

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)


class OOBServiceDecorator(ServiceDecorator):
# ServiceDecorator
recipient_keys: Optional[List[str]]
recipient_keys: Optional[List[str]] = None
routing_keys: Optional[List[str]] = Field(default=[])
service_endpoint: Optional[str]
service_endpoint: Optional[str] = None
id: str = Field(default="did:vc-authn-oidc:123456789zyxwvutsr#did-communication")
type: str = Field(default="did-communication")
priority: int = 0

class Config:
allow_population_by_field_name = True
model_config = ConfigDict(populate_by_name=True)
14 changes: 7 additions & 7 deletions oidc-controller/api/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from functools import lru_cache
from pathlib import Path
from typing import Optional, Union
from pydantic_settings import BaseSettings
from pydantic import ConfigDict

import structlog
from pydantic import BaseSettings


# Removed in later versions of python
Expand Down Expand Up @@ -162,7 +163,7 @@ class GlobalConfig(BaseSettings):
"CONTROLLER_CAMERA_REDIRECT_URL"
)
# The number of seconds to wait for a presentation to be verified, Default: 10
CONTROLLER_PRESENTATION_EXPIRE_TIME: Union[int, str] = os.environ.get(
CONTROLLER_PRESENTATION_EXPIRE_TIME: int = os.environ.get(
"CONTROLLER_PRESENTATION_EXPIRE_TIME", 10
)

Expand All @@ -188,11 +189,11 @@ class GlobalConfig(BaseSettings):
DEFAULT_PAGE_SIZE: Union[int, str] = os.environ.get("DEFAULT_PAGE_SIZE", 10)

# openssl rand -hex 32
SIGNING_KEY_SIZE = os.environ.get("SIGNING_KEY_SIZE", 2048)
SIGNING_KEY_SIZE: int = os.environ.get("SIGNING_KEY_SIZE", 2048)
# SIGNING_KEY_FILEPATH expects complete path including filename and extension.
SIGNING_KEY_FILEPATH: Optional[str] = os.environ.get("SIGNING_KEY_FILEPATH")
SIGNING_KEY_ALGORITHM: str = os.environ.get("SIGNING_KEY_ALGORITHM", "RS256")
SUBJECT_ID_HASH_SALT = os.environ.get("SUBJECT_ID_HASH_SALT", "test_hash_salt")
SUBJECT_ID_HASH_SALT: str = os.environ.get("SUBJECT_ID_HASH_SALT", "test_hash_salt")

# OIDC Client Settings
OIDC_CLIENT_ID: str = os.environ.get("OIDC_CLIENT_ID", "keycloak")
Expand All @@ -213,15 +214,14 @@ class GlobalConfig(BaseSettings):
)
SET_NON_REVOKED: bool = strtobool(os.environ.get("SET_NON_REVOKED", True))

class Config:
case_sensitive = True
model_config = ConfigDict(case_sensitive=True)


class LocalConfig(GlobalConfig):
"""Local configurations."""

DEBUG: bool = True
DB_ECHO_LOG = True
DB_ECHO_LOG: bool = True
ENVIRONMENT: EnvironmentEnum = EnvironmentEnum.LOCAL


Expand Down
14 changes: 7 additions & 7 deletions oidc-controller/api/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
from typing import TypedDict

from bson import ObjectId
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
from pyop.userinfo import Userinfo
from pydantic_core import core_schema


class PyObjectId(ObjectId):
@classmethod
def __get_validators__(cls):
yield cls.validate
def __get_pydantic_core_schema__(cls, source_type, handler) -> core_schema.CoreSchema:
return core_schema.general_plain_validator_function(cls.validate)

@classmethod
def validate(cls, v):
def validate(cls, v, info):
if not ObjectId.is_valid(v):
raise ValueError("Invalid objectid")
return ObjectId(v)

@classmethod
def __modify_schema__(cls, field_schema):
def __get_pydantic_json_schema__(cls, field_schema):
field_schema.update(type="string")


Expand All @@ -36,8 +37,7 @@ class StatusMessage(BaseModel):
class UUIDModel(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")

class Config:
json_encoders = {ObjectId: str}
model_config = ConfigDict(json_encoders={ObjectId: str})


class TimestampModel(BaseModel):
Expand Down
65 changes: 0 additions & 65 deletions oidc-controller/api/routers/quick-socket/app.py

This file was deleted.

2 changes: 1 addition & 1 deletion oidc-controller/api/routers/socketio.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')

sio_app = socketio.ASGIApp(socketio_server=sio)
sio_app = socketio.ASGIApp(socketio_server=sio, socketio_path='/ws/socket.io')

@sio.event
async def connect(sid, socket):
Expand Down
4 changes: 3 additions & 1 deletion oidc-controller/api/templates/verified_credentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<html>
<head>
<title>Scan QR Code</title>
<script src="https://cdn.socket.io/4.3.2/socket.io.min.js"></script>
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"
integrity="sha384-2huaZvOR9iDzHqslqwpR87isEmrfxqyWOF7hr7BY6KG0+hVKLoEXMPUJw3ynWuhO"
crossorigin="anonymous"></script>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
Expand Down
33 changes: 16 additions & 17 deletions oidc-controller/api/verificationConfigs/models.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import time
from typing import Optional, List
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field

from .examples import ex_ver_config
from ..core.config import settings


# Slightly modified from ACAPY models.
class AttributeFilter(BaseModel):
schema_id: Optional[str]
cred_def_id: Optional[str]
schema_name: Optional[str]
schema_issuer_did: Optional[str]
schema_version: Optional[str]
issuer_did: Optional[str]
schema_id: Optional[str] = None
cred_def_id: Optional[str] = None
schema_name: Optional[str] = None
schema_issuer_did: Optional[str] = None
schema_version: Optional[str] = None
issuer_did: Optional[str] = None


class ReqAttr(BaseModel):
names: List[str]
label: Optional[str]
label: Optional[str] = None
restrictions: List[AttributeFilter]


class ReqPred(BaseModel):
name: str
label: Optional[str]
label: Optional[str] = None
restrictions: List[AttributeFilter]
p_value: str
p_type: str


class VerificationProofRequest(BaseModel):
name: Optional[str]
version: str = Field(regex="[0-9](.[0.9])*", example="0.0.1")
non_revoked: Optional[str]
name: Optional[str] = None
version: str = Field(pattern="[0-9](.[0.9])*", examples=["0.0.1"])
non_revoked: Optional[str] = None
requested_attributes: List[ReqAttr]
requested_predicates: List[ReqPred]

Expand Down Expand Up @@ -69,9 +69,8 @@ def generate_proof_request(self):
"to": int(time.time()),
}
return result

class Config:
schema_extra = {"example": ex_ver_config}

model_config = ConfigDict(json_schema_extra={"example": ex_ver_config})


class VerificationConfig(VerificationConfigBase):
Expand All @@ -83,7 +82,7 @@ class VerificationConfigRead(VerificationConfigBase):


class VerificationConfigPatch(VerificationConfigBase):
subject_identifier: Optional[str] = Field()
proof_request: Optional[VerificationProofRequest] = Field()
subject_identifier: Optional[str] = Field(None)
proof_request: Optional[VerificationProofRequest] = Field(None)

pass
Loading

0 comments on commit c6f7b68

Please sign in to comment.