Skip to content

Commit

Permalink
Merge pull request #173 from raphaelrpl/b-1.0
Browse files Browse the repository at this point in the history
Add minimal role support for collections management
  • Loading branch information
raphaelrpl authored Sep 6, 2022
2 parents c27326d + ec0e288 commit 2deaf05
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
Changes
=======

Version 1.0.0-alpha3 (2022-09-06)
---------------------------------

- Change way to manage control to collections: use roles instead bool flag `#168 <https://github.com/brazil-data-cube/bdc-catalog/issues/168>`_.
- Review static checking: import orders
- Update docs - model png and schema.


Version 1.0.0-alpha2 (2022-09-01)
---------------------------------
Expand Down
68 changes: 68 additions & 0 deletions bdc_catalog/alembic/5067fb4381c0_add_roles_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""add minimal roles system
Revision ID: 5067fb4381c0
Revises: d01f09b5dd8b
Create Date: 2022-08-15 09:01:16.510820
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '5067fb4381c0'
down_revision = 'd01f09b5dd8b'
branch_labels = ()
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('items', 'is_public', schema='bdc')

op.create_table(
'roles',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=64), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('roles_pkey')),
sa.UniqueConstraint('name', name=op.f('roles_name_key')),
schema='bdc'
)
op.create_index(op.f('idx_bdc_roles_name'), 'roles', ['name'], unique=False, schema='bdc')
op.create_table(
'collections_roles',
sa.Column('collection_id', sa.Integer(), nullable=False),
sa.Column('role_id', sa.Integer(), nullable=False),
sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.ForeignKeyConstraint(['collection_id'], ['bdc.collections.id'], name=op.f('collections_roles_collection_id_collections_fkey'), onupdate='CASCADE', ondelete='CASCADE'),
sa.ForeignKeyConstraint(['role_id'], ['bdc.roles.id'], name=op.f('collections_roles_role_id_roles_fkey'), onupdate='CASCADE', ondelete='CASCADE'),
sa.PrimaryKeyConstraint('collection_id', 'role_id', name=op.f('collections_roles_pkey')),
schema='bdc'
)

op.drop_constraint('collections_classification_system_id_class_systems_fkey', 'collections', schema='bdc', type_='foreignkey')
op.create_foreign_key(op.f('collections_classification_system_id_classification_systems_fkey'), 'collections', 'classification_systems', ['classification_system_id'], ['id'], source_schema='bdc', referent_schema='lccs', onupdate='CASCADE', ondelete='CASCADE')
op.drop_column('collections', 'is_public', schema='bdc')

op.create_index(op.f('idx_bdc_quicklook_collection_id'), 'quicklook', ['collection_id'], unique=False, schema='bdc')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('idx_bdc_quicklook_collection_id'), table_name='quicklook', schema='bdc')

op.drop_constraint(op.f('collections_classification_system_id_classification_systems_fkey'), 'collections', schema='bdc', type_='foreignkey')
op.create_foreign_key('collections_classification_system_id_class_systems_fkey', 'collections', 'classification_systems', ['classification_system_id'], ['id'], source_schema='bdc', referent_schema='lccs')

op.drop_table('collections_roles', schema='bdc')
op.drop_index(op.f('idx_bdc_roles_name'), table_name='roles', schema='bdc')
op.drop_table('roles', schema='bdc')

op.add_column('items', sa.Column('is_public', sa.Boolean, nullable=True, default=True, server_default='true'),
schema='bdc')
# ### end Alembic commands ###
3 changes: 1 addition & 2 deletions bdc_catalog/alembic/d01f09b5dd8b_v1_0_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
Revision ID: d01f09b5dd8b
Revises: 561ebe6266ad
Create Date: 2022-06-08 12:06:57.476168
"""
from alembic import op
import geoalchemy2.types
Expand Down Expand Up @@ -100,9 +99,9 @@ def upgrade():
op.drop_index('idx_bdc_collections_extent', table_name='collections', schema='bdc')
op.create_index(op.f('idx_bdc_collections_category'), 'collections', ['category'], unique=False, schema='bdc')
op.create_index(op.f('idx_bdc_collections_is_available'), 'collections', ['is_available'], unique=False, schema='bdc')
op.create_index(op.f('idx_bdc_collections_is_public'), 'collections', ['is_public'], unique=False, schema='bdc')
op.create_index(op.f('idx_bdc_collections_spatial_extent'), 'collections', ['spatial_extent'], unique=False, schema='bdc', postgresql_using='gist')
op.create_index(op.f('idx_bdc_collections_start_date'), 'collections', ['start_date', 'end_date'], unique=False, schema='bdc')
op.create_index(op.f('idx_bdc_collections_is_public'), 'collections', ['is_public'], unique=False, schema='bdc')

# For Collection Providers table, identify version 0.8.0 before
op.execute('CREATE TABLE IF NOT EXISTS bdc.collections_providers_legacy AS '
Expand Down
6 changes: 5 additions & 1 deletion bdc_catalog/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

from .band import Band, BandSRC
from .base_sql import db
from .collection import Collection, CollectionsProviders, CollectionSRC
from .collection import (Collection, CollectionRole, CollectionsProviders,
CollectionSRC)
from .composite_function import CompositeFunction
from .grid_ref_sys import GridRefSys
from .item import Item, ItemsProcessors, SpatialRefSys
Expand All @@ -19,6 +20,7 @@
from .provider import Provider
from .quicklook import Quicklook
from .resolution_unit import ResolutionUnit
from .role import Role
from .tile import Tile
from .timeline import Timeline

Expand All @@ -27,6 +29,7 @@
'Band',
'BandSRC',
'Collection',
'CollectionRole',
'CollectionSRC',
'CollectionsProviders',
'CompositeFunction',
Expand All @@ -38,6 +41,7 @@
'Provider',
'Quicklook',
'ResolutionUnit',
'Role',
'SpatialRefSys',
'Tile',
'Timeline',
Expand Down
27 changes: 24 additions & 3 deletions bdc_catalog/models/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from ..config import BDC_CATALOG_SCHEMA
from .base_sql import BaseModel, db
from .provider import Provider
from .role import Role

name_collection_type = 'collection_type'
options_collection_type = ('cube', 'collection', 'classification', 'mosaic')
Expand Down Expand Up @@ -57,7 +58,6 @@ class Collection(BaseModel):
comment='Contains the STAC Collection summaries.')
item_assets = Column('item_assets', JSONB('bdc-catalog/collection-item-assets.json'),
comment='Contains the STAC Extension Item Assets.')
is_public = Column(Boolean(), nullable=False, default=True, server_default='True')
is_available = Column(Boolean(), nullable=False, default=False, server_default='False')
category = Column(enum_collection_category, nullable=False)
start_date = Column(TIMESTAMP(timezone=True))
Expand All @@ -82,7 +82,6 @@ class Collection(BaseModel):
Index(None, spatial_extent, postgresql_using='gist'),
Index(None, classification_system_id),
Index(None, category),
Index(None, is_public),
Index(None, is_available),
Index(None, start_date, end_date),
dict(schema=BDC_CATALOG_SCHEMA),
Expand Down Expand Up @@ -204,4 +203,26 @@ def to_dict(self) -> dict:
The properties follows the STAC specification in `Provider Object <https://github.com/radiantearth/stac-spec/blob/v1.0.0/collection-spec/collection-spec.md#provider-object>`_.
"""
return dict(name=self.provider.name, description=self.provider.description,
url=self.provider.url, roles=self.roles)
url=self.provider.url, roles=self.roles)


class CollectionRole(BaseModel):
"""Model to represent the link between Collection and Role."""

__tablename__ = 'collections_roles'

collection_id = db.Column('collection_id', db.Integer(),
db.ForeignKey(Collection.id, onupdate='CASCADE', ondelete='CASCADE'),
nullable=False)

role_id = db.Column('role_id', db.Integer(),
db.ForeignKey(Role.id, onupdate='CASCADE', ondelete='CASCADE'),
nullable=False)

collection = relationship('Collection', lazy='joined', foreign_keys=[collection_id])
role = relationship('Role', lazy='joined')

__table_args__ = (
PrimaryKeyConstraint(collection_id, role_id),
dict(schema=BDC_CATALOG_SCHEMA),
)
5 changes: 2 additions & 3 deletions bdc_catalog/models/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class Item(BaseModel):

id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
is_public = Column(Boolean, default=True, nullable=False, server_default=expression.true())
is_available = Column(Boolean, default=False, nullable=False, server_default=expression.false())
collection_id = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.collections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False)
tile_id = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.tiles.id', onupdate='CASCADE', ondelete='CASCADE'))
Expand All @@ -111,12 +110,12 @@ class Item(BaseModel):
Index(None, bbox, postgresql_using='gist'),
Index(None, footprint, postgresql_using='gist'),
Index(None, name),
Index(None, is_public),
Index(None, is_available),
Index(None, provider_id),
Index('idx_items_start_date_end_date', start_date, end_date),
Index(None, tile_id),
Index(None, start_date.desc()),
Index(None, start_date),
Index('idx_bdc_items_start_date_desc', start_date.desc()),
Index(None, metadata_),
dict(schema=BDC_CATALOG_SCHEMA),
)
Expand Down
21 changes: 17 additions & 4 deletions bdc_catalog/models/quicklook.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,37 @@

"""Model for collection QuickLook info."""

from sqlalchemy import Column, ForeignKey
from typing import Tuple

from sqlalchemy import Column, ForeignKey, Index
from sqlalchemy.orm import relationship

from ..config import BDC_CATALOG_SCHEMA
from .band import Band
from .base_sql import BaseModel


class Quicklook(BaseModel):
"""Model for collection QuickLook info."""

__tablename__ = 'quicklook'
__table_args__ = dict(
schema=BDC_CATALOG_SCHEMA
)

collection_id = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.collections.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True)
red = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.bands.id', onupdate='CASCADE', ondelete='CASCADE'))
green = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.bands.id', onupdate='CASCADE', ondelete='CASCADE'))
blue = Column(ForeignKey(f'{BDC_CATALOG_SCHEMA}.bands.id', onupdate='CASCADE', ondelete='CASCADE'))

collection = relationship('Collection', back_populates='quicklook')

__table_args__ = (
Index(None, collection_id),
dict(schema=BDC_CATALOG_SCHEMA),
)

def get_bands(self) -> Tuple[Band, Band, Band]:
"""Retrieve the Band object reference for each RGB channel."""
red = Band.query().filter(Band.id == self.red).first()
green = Band.query().filter(Band.id == self.green).first()
blue = Band.query().filter(Band.id == self.blue).first()

return red, green, blue
34 changes: 34 additions & 0 deletions bdc_catalog/models/role.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# This file is part of Brazil Data Cube Database module.
# Copyright (C) 2022 INPE.
#
# Brazil Data Cube Database module is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
#

"""Model for table ``bdc.role``."""

from sqlalchemy import Column, Index, Integer, String, Text
from sqlalchemy.orm import relationship

from ..config import BDC_CATALOG_SCHEMA
from .base_sql import BaseModel


class Role(BaseModel):
"""Model for table ``bdc.role``.
The role model consists in a basic way to specify a required roles to access collections/items.
These values are used by BDC-Catalog NGINX plugin in order to validate user access.
"""

__tablename__ = 'roles'

id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False)
description = Column(Text)

__table_args__ = (
Index(None, name),
dict(schema=BDC_CATALOG_SCHEMA),
)
2 changes: 1 addition & 1 deletion bdc_catalog/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
"""Version information for BDC-Catalog."""


__version__ = '1.0.0-alpha2'
__version__ = '1.0.0-alpha3'
Binary file modified docs/model/db-schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2deaf05

Please sign in to comment.