add dpp
This commit is contained in:
parent
faa7c1d605
commit
8dd926de80
|
@ -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
|
||||||
|
|
|
@ -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()}')
|
|
@ -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,18 +99,31 @@ 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__(
|
||||||
import_name=__name__,
|
self,
|
||||||
static_folder='static',
|
app,
|
||||||
static_url_path=None,
|
import_name=__name__,
|
||||||
template_folder='templates',
|
static_folder='static',
|
||||||
url_prefix=None,
|
static_url_path=None,
|
||||||
subdomain=None,
|
template_folder='templates',
|
||||||
url_defaults=None,
|
url_prefix=None,
|
||||||
root_path=None,
|
subdomain=None,
|
||||||
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
url_defaults=None,
|
||||||
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
root_path=None,
|
||||||
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
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)
|
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'}
|
||||||
|
)
|
||||||
|
|
|
@ -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(
|
||||||
ForeignKey(User.id),
|
UUID(as_uuid=True),
|
||||||
nullable=False,
|
ForeignKey(User.id),
|
||||||
default=lambda: g.user.id)
|
nullable=False,
|
||||||
issuer = relationship(User,
|
default=lambda: g.user.id,
|
||||||
backref=backref('issuered_proofs', lazy=True, collection_class=set),
|
)
|
||||||
primaryjoin=User.id == issuer_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."""
|
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(
|
||||||
backref=backref('proofs', lazy=True),
|
Snapshot,
|
||||||
collection_class=OrderedSet,
|
backref=backref('proofs', lazy=True),
|
||||||
primaryjoin=Snapshot.id == snapshot_id)
|
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):
|
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(
|
||||||
ForeignKey(User.id),
|
UUID(as_uuid=True),
|
||||||
nullable=False,
|
ForeignKey(User.id),
|
||||||
default=lambda: g.user.id)
|
nullable=False,
|
||||||
issuer = relationship(User,
|
default=lambda: g.user.id,
|
||||||
backref=backref('issuered_dpp', lazy=True, collection_class=set),
|
)
|
||||||
primaryjoin=User.id == issuer_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."""
|
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(
|
||||||
backref=backref('dpp', lazy=True),
|
Snapshot,
|
||||||
collection_class=OrderedSet,
|
backref=backref('dpp', lazy=True),
|
||||||
primaryjoin=Snapshot.id == snapshot_id)
|
collection_class=OrderedSet,
|
||||||
|
primaryjoin=Snapshot.id == snapshot_id,
|
||||||
|
)
|
||||||
|
|
Reference in a new issue