Initial dump of the idea for Porter Schema definition.

pull/2664/head
derekpierre 2021-05-26 14:48:46 -04:00
parent 589ddff4de
commit b126fbcecb
9 changed files with 379 additions and 0 deletions

View File

@ -0,0 +1,16 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""

View File

@ -0,0 +1,16 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""

View File

@ -0,0 +1,58 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from typing import List
from nucypher.control.interfaces import ControlInterface, attach_schema
from nucypher.utilities.porter.control.specifications import porter_schema
class PorterInterface(ControlInterface):
#
# Alice Endpoints
#
@attach_schema(porter_schema.AliceGetUrsulas)
def get_ursulas(self,
quantity: int,
duration_periods: int,
exclude_ursulas: List[str],
include_ursulas: List[str]) -> dict:
pass
@attach_schema(porter_schema.AlicePublishTreasureMap)
def publish_treasure_map(self,
treasure_map: bytes,
bob_encrypting_key: bytes) -> dict:
pass
@attach_schema(porter_schema.AliceRevoke)
def revoke(self) -> dict:
pass
#
# Bob Endpoints
#
@attach_schema(porter_schema.BobGetTreasureMap)
def get_treasure_map(self,
treasure_map_id: bytes,
bob_encrypting_key: bytes) -> dict:
pass
@attach_schema(porter_schema.BobExecWorkOrder)
def exec_work_order(self,
ursula: str,
work_order: bytes) -> dict:
pass

View File

@ -0,0 +1,16 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""

View File

@ -0,0 +1,20 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from nucypher.utilities.porter.control.specifications.fields.ursula import *
from nucypher.utilities.porter.control.specifications.fields.treasuremapid import *
from nucypher.utilities.porter.control.specifications.fields.workorder import *

View File

@ -0,0 +1,42 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from marshmallow import fields
from nucypher.characters.control.specifications.exceptions import InvalidNativeDataTypes
from nucypher.control.specifications.exceptions import InvalidInputData
from nucypher.control.specifications.fields.base import BaseField
class TreasureMapID(BaseField, fields.Field):
def _serialize(self, value, attr, obj, **kwargs):
return bytes(value).hex()
def _deserialize(self, value, attr, data, **kwargs):
if isinstance(value, bytes):
return value
try:
return bytes.fromhex(value)
except InvalidNativeDataTypes as e:
raise InvalidInputData(f"Could not convert input for {self.name} to a TreasureMap ID: {e}")
def _validate(self, value):
try:
return len(value) == 32 # should be 32-bytes
except InvalidNativeDataTypes as e:
raise InvalidInputData(f"Could not convert input for {self.name} to an TreasureMap ID: {e}")

View File

@ -0,0 +1,25 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from nucypher.cli import types
from nucypher.control.specifications.fields import String
class ChecksumAddress(String):
"""Ursula checksum address."""
click_type = types.EIP55_CHECKSUM_ADDRESS

View File

@ -0,0 +1,51 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from base64 import b64encode, b64decode
from marshmallow import fields
from nucypher.characters.control.specifications.exceptions import InvalidNativeDataTypes
from nucypher.control.specifications.exceptions import InvalidInputData
from nucypher.control.specifications.fields import BaseField
from nucypher.policy.collections import WorkOrder as WorkOrderClass
class WorkOrder(BaseField, fields.Field):
def _serialize(self, value: WorkOrderClass, attr, obj, **kwargs):
return b64encode(value.payload()).decode()
def _deserialize(self, value, attr, data, **kwargs):
if isinstance(value, bytes):
return value
try:
return b64decode(value)
except InvalidNativeDataTypes as e:
raise InvalidInputData(f"Could not convert input for {self.name} to a WorkOrder: {e}")
class WorkOrderResult(BaseField, fields.Field):
def _serialize(self, value, attr, obj, **kwargs):
return bytes(value).hex()
def _deserialize(self, value, attr, data, **kwargs):
if isinstance(value, bytes):
return value
try:
return bytes.fromhex(value)
except InvalidNativeDataTypes as e:
raise InvalidInputData(f"Could not convert input for {self.name} to a WorkOrder result: {e}")

View File

@ -0,0 +1,135 @@
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import click
from nucypher.control.specifications.base import BaseSchema
from nucypher.control.specifications import fields as base_fields
from nucypher.utilities.porter.control.specifications import fields
from nucypher.characters.control.specifications import fields as character_fields
from nucypher.cli import types
def option_ursula():
return click.option(
'--ursula',
'-u',
help="Ursula checksum address",
type=types.EIP55_CHECKSUM_ADDRESS,
required=True)
def option_bob_encrypting_key():
click.option(
'--bob-encrypting-key',
'-bek',
help="Bob's encrypting key as a hexadecimal string",
type=click.STRING,
required=True)
#
# Alice Endpoints
#
class AliceGetUrsulas(BaseSchema):
quantity = base_fields.PositiveInteger(
required=True, load_only=True,
click=click.option(
'--quantity',
'-n',
help="Total number of ursualas needed",
type=click.INT, required=True))
duration_periods = base_fields.PositiveInteger(
required=True, load_only=True,
click=click.option(
'--periods',
'-p',
help="Required duration of service for Ursulas",
type=click.INT, required=True))
# optional
exclude_ursulas = base_fields.List(fields.ChecksumAddress(
required=False,
click=click.option(
'--exclude-ursula',
'-e',
help="Ursula checksum address",
type=types.EIP55_CHECKSUM_ADDRESS, required=False)))
include_ursulas = base_fields.List(fields.ChecksumAddress(
required=False,
click=click.option(
'--include-ursula',
'-i',
help="Ursula checksum address",
type=types.EIP55_CHECKSUM_ADDRESS, required=False)))
# output
ursulas = base_fields.List(fields.ChecksumAddress(), dump_only=True)
class AlicePublishTreasureMap(BaseSchema):
treasure_map = character_fields.TreasureMap(
required=True,
click=click.option(
'--treasure-map',
'-t',
help="TreasureMap",
type=click.STRING,
required=True))
bob_encrypting_key = character_fields.Key(
required=True, load_only=True,
click=option_bob_encrypting_key())
class AliceRevoke(BaseSchema):
pass # TODO need to understand revoke process better
#
# Bob Endpoints
#
class BobGetTreasureMap(BaseSchema):
treasure_map_id = fields.TreasureMapID(
required=True,
click=click.option(
'--treasure-map-id',
'-tid',
help="TreasureMap ID as hex",
type=click.STRING,
required=True))
bob_encrypting_key = character_fields.Key(
required=True, load_only=True,
click=option_bob_encrypting_key())
# output
treasure_map = character_fields.TreasureMap(dump_only=True)
class BobExecWorkOrder(BaseSchema):
ursula = fields.ChecksumAddress(
required=True,
click=option_ursula())
work_order = fields.WorkOrder(
required=True,
click=click.option(
'--work-order',
'-w',
help="Re-encryption work order",
type=click.STRING, required=True))
# output
work_order_result = fields.WorkOrderResult(dump_only=True)