This commit is contained in:
Cayo Puigdefabregas 2023-01-19 12:26:25 +01:00
parent faa7c1d605
commit 8dd926de80
4 changed files with 193 additions and 73 deletions

View File

@ -17,8 +17,8 @@ from ereuse_devicehub.resources import (
user,
)
from ereuse_devicehub.resources.device import definitions
from ereuse_devicehub.resources.documents import documents
from ereuse_devicehub.resources.did import did
from ereuse_devicehub.resources.documents import documents
from ereuse_devicehub.resources.enums import PriceSoftware
from ereuse_devicehub.resources.licences import licences
from ereuse_devicehub.resources.metric import definitions as metric_def

View File

@ -0,0 +1,86 @@
"""add digital passport dpp
Revision ID: 8334535d56fa
Revises: 4b7f77f121bf
Create Date: 2023-01-19 12:01:54.102326
"""
from alembic import op, context
import sqlalchemy as sa
import citext
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '8334535d56fa'
down_revision = '4b7f77f121bf'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table('proof',
sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='The last time Devicehub recorded a change for \n this thing.\n '),
sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False, comment='When Devicehub created this.'),
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('type', sa.Unicode(), nullable=False),
sa.Column('documentId', citext.CIText(), nullable=True),
sa.Column('documentSignature', citext.CIText(), nullable=True),
sa.Column('timestamp', sa.BigInteger(), nullable=False),
sa.Column('device_id', sa.BigInteger(), nullable=False),
sa.Column('snapshot_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('issuer_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['snapshot_id'], [f'{get_inv()}.snapshot.id'], ),
sa.ForeignKeyConstraint(['device_id'], [f'{get_inv()}.device.id'], ),
sa.ForeignKeyConstraint(['issuer_id'], [f'common.user.id'], ),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}'
)
# op.create_index(op.f('ix_proof_created'), 'proof', ['created'], unique=False, schema=f'{get_inv()}')
# op.create_index(op.f('ix_proof_timestamp'), 'proof', ['timestamp'], unique=False, schema=f'{get_inv()}')
op.add_column('device', sa.Column('chid_dpp', citext.CIText(), nullable=True), schema=f'{get_inv()}')
op.add_column('snapshot', sa.Column('phid_dpp', citext.CIText(), nullable=True), schema=f'{get_inv()}')
op.add_column('snapshot', sa.Column('json_wb', citext.CIText(), nullable=True), schema=f'{get_inv()}')
op.add_column('snapshot', sa.Column('json_hw', citext.CIText(), nullable=True), schema=f'{get_inv()}')
op.create_table('dpp',
sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='The last time Devicehub recorded a change for \n this thing.\n '),
sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False, comment='When Devicehub created this.'),
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('documentId', citext.CIText(), nullable=True),
sa.Column('documentSignature', citext.CIText(), nullable=True),
sa.Column('timestamp', sa.BigInteger(), nullable=False),
sa.Column('device_id', sa.BigInteger(), nullable=False),
sa.Column('snapshot_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('issuer_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['snapshot_id'], [f'{get_inv()}.snapshot.id'], ),
sa.ForeignKeyConstraint(['device_id'], [f'{get_inv()}.device.id'], ),
sa.ForeignKeyConstraint(['issuer_id'], [f'common.user.id'], ),
sa.Column('key', sa.Unicode(), nullable=False),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}'
)
def downgrade():
op.drop_table('dpp', schema=f'{get_inv()}')
op.drop_table('proof', schema=f'{get_inv()}')
# op.drop_index(op.f('ix_proof_created'), table_name='proof', schema=f'{get_inv()}')
# op.drop_index(op.f('ix_proof_timestamp'), table_name='proof', schema=f'{get_inv()}')
op.drop_column('device', 'chid_dpp', schema=f'{get_inv()}')
op.drop_column('snapshot', 'phid_dpp', schema=f'{get_inv()}')
op.drop_column('snapshot', 'json_wb', schema=f'{get_inv()}')
op.drop_column('snapshot', 'json_hw', schema=f'{get_inv()}')

View File

@ -1,9 +1,9 @@
import csv
import json
import enum
import uuid
import time
import datetime
import enum
import json
import time
import uuid
from collections import OrderedDict
from io import StringIO
from typing import Callable, Iterable, Tuple
@ -13,8 +13,8 @@ import flask
import flask_weasyprint
import teal.marshmallow
from boltons import urlutils
from flask import make_response, g, request
from flask import current_app as app
from flask import g, make_response, request
from flask.json import jsonify
from teal.cache import cache
from teal.resource import Resource, View
@ -30,6 +30,7 @@ class DidView(View):
This view render one public ans static page for see the links for to do the check
of one csv file
"""
def get_url_path(self):
url = urlutils.URL(request.url)
url.normalize()
@ -47,8 +48,11 @@ class DidView(View):
if 'json' not in request.headers['Accept']:
result = self.get_result(result, template)
return flask.render_template(template, rq_url=self.get_url_path(),
result={"dpp": dpp, "result": result})
return flask.render_template(
template,
rq_url=self.get_url_path(),
result={"dpp": dpp, "result": result},
)
return jsonify(self.get_result(result, template))
@ -77,7 +81,9 @@ class DidView(View):
return {'data': dpps}
def get_last_dpp(self, dpp):
dpps = [act.dpp[0] for act in dpp.device.actions if act.t == 'Snapshot' and act.dpp]
dpps = [
act.dpp[0] for act in dpp.device.actions if act.t == 'Snapshot' and act.dpp
]
last_dpp = ''
for d in dpps:
if d.key == dpp.key:
@ -93,18 +99,31 @@ class DidDef(Resource):
VIEW = None # We do not want to create default / documents endpoint
AUTH = False
def __init__(self, app,
import_name=__name__,
static_folder='static',
static_url_path=None,
template_folder='templates',
url_prefix=None,
subdomain=None,
url_defaults=None,
root_path=None,
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
url_prefix, subdomain, url_defaults, root_path, cli_commands)
def __init__(
self,
app,
import_name=__name__,
static_folder='static',
static_url_path=None,
template_folder='templates',
url_prefix=None,
subdomain=None,
url_defaults=None,
root_path=None,
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple(),
):
super().__init__(
app,
import_name,
static_folder,
static_url_path,
template_folder,
url_prefix,
subdomain,
url_defaults,
root_path,
cli_commands,
)
view = DidView.as_view('main', definition=self, auth=app.auth)
@ -112,4 +131,6 @@ class DidDef(Resource):
# view = app.auth.requires_auth(view)
did_view = DidView.as_view('DidView', definition=self, auth=app.auth)
self.add_url_rule('/<string:dpp>', defaults={}, view_func=did_view, methods={'GET'})
self.add_url_rule(
'/<string:dpp>', defaults={}, view_func=did_view, methods={'GET'}
)

View File

@ -1,17 +1,15 @@
from sortedcontainers import SortedSet
from sqlalchemy.util import OrderedSet
from sqlalchemy import Unicode, BigInteger, Column, Sequence, ForeignKey
from sqlalchemy.orm import backref, relationship
from sqlalchemy.dialects.postgresql import UUID
from flask import g
from sortedcontainers import SortedSet
from sqlalchemy import BigInteger, Column, ForeignKey, Sequence, Unicode
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import backref, relationship
from sqlalchemy.util import OrderedSet
from teal.db import CASCADE_OWN
from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.action.models import ActionStatus, Snapshot
from ereuse_devicehub.resources.device.models import Device
from ereuse_devicehub.resources.action.models import Snapshot, ActionStatus
from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
from ereuse_devicehub.resources.user.models import User
PROOF_ENUM = {
'Register': 'Register',
@ -19,10 +17,7 @@ PROOF_ENUM = {
'proof_of_recycling': 'proof_of_recycling',
}
_sorted_proofs = {
'order_by': lambda: Proof.created,
'collection_class': SortedSet
}
_sorted_proofs = {'order_by': lambda: Proof.created, 'collection_class': SortedSet}
class Proof(Thing):
@ -36,31 +31,42 @@ class Proof(Thing):
timestamp = Column(BigInteger, nullable=False)
type = Column(Unicode(STR_SM_SIZE), nullable=False)
issuer_id = Column(UUID(as_uuid=True),
ForeignKey(User.id),
nullable=False,
default=lambda: g.user.id)
issuer = relationship(User,
backref=backref('issuered_proofs', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id)
issuer_id = Column(
UUID(as_uuid=True),
ForeignKey(User.id),
nullable=False,
default=lambda: g.user.id,
)
issuer = relationship(
User,
backref=backref('issuered_proofs', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id,
)
issuer_id.comment = """The user that recorded this proof in the system."""
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
device = relationship(Device,
backref=backref('proofs',
lazy=True,
cascade=CASCADE_OWN),
primaryjoin=Device.id == device_id)
device = relationship(
Device,
backref=backref('proofs', lazy=True, cascade=CASCADE_OWN),
primaryjoin=Device.id == device_id,
)
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=True)
snapshot = relationship(Snapshot,
backref=backref('proofs', lazy=True),
collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id)
snapshot = relationship(
Snapshot,
backref=backref('proofs', lazy=True),
collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id,
)
action_status_id = Column(
UUID(as_uuid=True), ForeignKey(ActionStatus.id), nullable=True
)
action_status = relationship(
ActionStatus,
backref=backref('proofs', lazy=True),
primaryjoin=ActionStatus.id == action_status_id,
)
action_status_id = Column(UUID(as_uuid=True), ForeignKey(ActionStatus.id), nullable=True)
action_status = relationship(ActionStatus,
backref=backref('proofs', lazy=True),
primaryjoin=ActionStatus.id == action_status_id)
class Dpp(Thing):
"""
@ -69,6 +75,7 @@ class Dpp(Thing):
Is the official Digital Passport
"""
id = Column(BigInteger, Sequence('device_seq'), primary_key=True)
key = Column(Unicode(STR_SM_SIZE), nullable=False)
key.comment = "chid:phid, (chid it's in device and phid it's in the snapshot)"
@ -78,23 +85,29 @@ class Dpp(Thing):
documentSignature.comment = "is the snapshot.json_wb with the signature of the user"
timestamp = Column(BigInteger, nullable=False)
issuer_id = Column(UUID(as_uuid=True),
ForeignKey(User.id),
nullable=False,
default=lambda: g.user.id)
issuer = relationship(User,
backref=backref('issuered_dpp', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id)
issuer_id = Column(
UUID(as_uuid=True),
ForeignKey(User.id),
nullable=False,
default=lambda: g.user.id,
)
issuer = relationship(
User,
backref=backref('issuered_dpp', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id,
)
issuer_id.comment = """The user that recorded this proof in the system."""
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
device = relationship(Device,
backref=backref('dpps',
lazy=True,
cascade=CASCADE_OWN),
primaryjoin=Device.id == device_id)
device = relationship(
Device,
backref=backref('dpps', lazy=True, cascade=CASCADE_OWN),
primaryjoin=Device.id == device_id,
)
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=False)
snapshot = relationship(Snapshot,
backref=backref('dpp', lazy=True),
collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id)
snapshot = relationship(
Snapshot,
backref=backref('dpp', lazy=True),
collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id,
)