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, user,
) )
from ereuse_devicehub.resources.device import definitions 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.did import did
from ereuse_devicehub.resources.documents import documents
from ereuse_devicehub.resources.enums import PriceSoftware from ereuse_devicehub.resources.enums import PriceSoftware
from ereuse_devicehub.resources.licences import licences from ereuse_devicehub.resources.licences import licences
from ereuse_devicehub.resources.metric import definitions as metric_def 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 csv
import json
import enum
import uuid
import time
import datetime import datetime
import enum
import json
import time
import uuid
from collections import OrderedDict from collections import OrderedDict
from io import StringIO from io import StringIO
from typing import Callable, Iterable, Tuple from typing import Callable, Iterable, Tuple
@ -13,8 +13,8 @@ import flask
import flask_weasyprint import flask_weasyprint
import teal.marshmallow import teal.marshmallow
from boltons import urlutils from boltons import urlutils
from flask import make_response, g, request
from flask import current_app as app from flask import current_app as app
from flask import g, make_response, request
from flask.json import jsonify from flask.json import jsonify
from teal.cache import cache from teal.cache import cache
from teal.resource import Resource, View 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 This view render one public ans static page for see the links for to do the check
of one csv file of one csv file
""" """
def get_url_path(self): def get_url_path(self):
url = urlutils.URL(request.url) url = urlutils.URL(request.url)
url.normalize() url.normalize()
@ -47,8 +48,11 @@ class DidView(View):
if 'json' not in request.headers['Accept']: if 'json' not in request.headers['Accept']:
result = self.get_result(result, template) result = self.get_result(result, template)
return flask.render_template(template, rq_url=self.get_url_path(), return flask.render_template(
result={"dpp": dpp, "result": result}) template,
rq_url=self.get_url_path(),
result={"dpp": dpp, "result": result},
)
return jsonify(self.get_result(result, template)) return jsonify(self.get_result(result, template))
@ -77,7 +81,9 @@ class DidView(View):
return {'data': dpps} return {'data': dpps}
def get_last_dpp(self, dpp): 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 = '' last_dpp = ''
for d in dpps: for d in dpps:
if d.key == dpp.key: if d.key == dpp.key:
@ -93,7 +99,9 @@ class DidDef(Resource):
VIEW = None # We do not want to create default / documents endpoint VIEW = None # We do not want to create default / documents endpoint
AUTH = False AUTH = False
def __init__(self, app, def __init__(
self,
app,
import_name=__name__, import_name=__name__,
static_folder='static', static_folder='static',
static_url_path=None, static_url_path=None,
@ -102,9 +110,20 @@ class DidDef(Resource):
subdomain=None, subdomain=None,
url_defaults=None, url_defaults=None,
root_path=None, root_path=None,
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()): 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) 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) view = DidView.as_view('main', definition=self, auth=app.auth)
@ -112,4 +131,6 @@ class DidDef(Resource):
# view = app.auth.requires_auth(view) # view = app.auth.requires_auth(view)
did_view = DidView.as_view('DidView', definition=self, auth=app.auth) 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 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 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.device.models import Device
from ereuse_devicehub.resources.action.models import Snapshot, ActionStatus from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE
PROOF_ENUM = { PROOF_ENUM = {
'Register': 'Register', 'Register': 'Register',
@ -19,10 +17,7 @@ PROOF_ENUM = {
'proof_of_recycling': 'proof_of_recycling', 'proof_of_recycling': 'proof_of_recycling',
} }
_sorted_proofs = { _sorted_proofs = {'order_by': lambda: Proof.created, 'collection_class': SortedSet}
'order_by': lambda: Proof.created,
'collection_class': SortedSet
}
class Proof(Thing): class Proof(Thing):
@ -36,31 +31,42 @@ class Proof(Thing):
timestamp = Column(BigInteger, nullable=False) timestamp = Column(BigInteger, nullable=False)
type = Column(Unicode(STR_SM_SIZE), nullable=False) type = Column(Unicode(STR_SM_SIZE), nullable=False)
issuer_id = Column(UUID(as_uuid=True), issuer_id = Column(
UUID(as_uuid=True),
ForeignKey(User.id), ForeignKey(User.id),
nullable=False, nullable=False,
default=lambda: g.user.id) default=lambda: g.user.id,
issuer = relationship(User, )
issuer = relationship(
User,
backref=backref('issuered_proofs', lazy=True, collection_class=set), backref=backref('issuered_proofs', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id) primaryjoin=User.id == issuer_id,
)
issuer_id.comment = """The user that recorded this proof in the system.""" issuer_id.comment = """The user that recorded this proof in the system."""
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False) device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
device = relationship(Device, device = relationship(
backref=backref('proofs', Device,
lazy=True, backref=backref('proofs', lazy=True, cascade=CASCADE_OWN),
cascade=CASCADE_OWN), primaryjoin=Device.id == device_id,
primaryjoin=Device.id == device_id) )
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=True) snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=True)
snapshot = relationship(Snapshot, snapshot = relationship(
Snapshot,
backref=backref('proofs', lazy=True), backref=backref('proofs', lazy=True),
collection_class=OrderedSet, collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id) primaryjoin=Snapshot.id == snapshot_id,
)
action_status_id = Column(UUID(as_uuid=True), ForeignKey(ActionStatus.id), nullable=True) action_status_id = Column(
action_status = relationship(ActionStatus, UUID(as_uuid=True), ForeignKey(ActionStatus.id), nullable=True
)
action_status = relationship(
ActionStatus,
backref=backref('proofs', lazy=True), backref=backref('proofs', lazy=True),
primaryjoin=ActionStatus.id == action_status_id) primaryjoin=ActionStatus.id == action_status_id,
)
class Dpp(Thing): class Dpp(Thing):
""" """
@ -69,6 +75,7 @@ class Dpp(Thing):
Is the official Digital Passport Is the official Digital Passport
""" """
id = Column(BigInteger, Sequence('device_seq'), primary_key=True) id = Column(BigInteger, Sequence('device_seq'), primary_key=True)
key = Column(Unicode(STR_SM_SIZE), nullable=False) key = Column(Unicode(STR_SM_SIZE), nullable=False)
key.comment = "chid:phid, (chid it's in device and phid it's in the snapshot)" 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" documentSignature.comment = "is the snapshot.json_wb with the signature of the user"
timestamp = Column(BigInteger, nullable=False) timestamp = Column(BigInteger, nullable=False)
issuer_id = Column(UUID(as_uuid=True), issuer_id = Column(
UUID(as_uuid=True),
ForeignKey(User.id), ForeignKey(User.id),
nullable=False, nullable=False,
default=lambda: g.user.id) default=lambda: g.user.id,
issuer = relationship(User, )
issuer = relationship(
User,
backref=backref('issuered_dpp', lazy=True, collection_class=set), backref=backref('issuered_dpp', lazy=True, collection_class=set),
primaryjoin=User.id == issuer_id) primaryjoin=User.id == issuer_id,
)
issuer_id.comment = """The user that recorded this proof in the system.""" issuer_id.comment = """The user that recorded this proof in the system."""
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False) device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
device = relationship(Device, device = relationship(
backref=backref('dpps', Device,
lazy=True, backref=backref('dpps', lazy=True, cascade=CASCADE_OWN),
cascade=CASCADE_OWN), primaryjoin=Device.id == device_id,
primaryjoin=Device.id == device_id) )
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=False) snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=False)
snapshot = relationship(Snapshot, snapshot = relationship(
Snapshot,
backref=backref('dpp', lazy=True), backref=backref('dpp', lazy=True),
collection_class=OrderedSet, collection_class=OrderedSet,
primaryjoin=Snapshot.id == snapshot_id) primaryjoin=Snapshot.id == snapshot_id,
)