From ce48066b6e63fa1ec4d1bdc465d8344479449d4a Mon Sep 17 00:00:00 2001 From: "J.P. Krauss" Date: Tue, 12 Jul 2022 12:15:12 -0700 Subject: [PATCH] Remove Access Control --- migrations/versions/23baf9256373_.py | 112 --------------------------- sigl/database/orm.py | 38 --------- sigl/database/tables.py | 51 ------------ sigl/domain/models/__init__.py | 3 - sigl/domain/models/accessKey.py | 83 -------------------- sigl/domain/models/list.py | 5 +- sigl/domain/models/product.py | 5 +- 7 files changed, 4 insertions(+), 293 deletions(-) delete mode 100644 migrations/versions/23baf9256373_.py delete mode 100644 sigl/domain/models/accessKey.py diff --git a/migrations/versions/23baf9256373_.py b/migrations/versions/23baf9256373_.py deleted file mode 100644 index 61af022..0000000 --- a/migrations/versions/23baf9256373_.py +++ /dev/null @@ -1,112 +0,0 @@ -"""empty message - -Revision ID: 23baf9256373 -Revises: -Create Date: 2022-07-12 10:51:54.236220 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '23baf9256373' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('access_keys', - sa.Column('key', sa.String(length=64), nullable=False), - sa.Column('clientId', sa.String(length=64), nullable=False), - sa.Column('clientIP', sa.String(length=46), nullable=False), - sa.Column('userAgent', sa.String(length=255), nullable=False), - sa.Column('suspended', sa.Boolean(), nullable=False), - sa.Column('revoked', sa.Boolean(), nullable=False), - sa.Column('createdAt', sa.DateTime(), nullable=True), - sa.Column('suspendedAt', sa.DateTime(), nullable=True), - sa.Column('revokedAt', sa.DateTime(), nullable=True), - sa.Column('restoredAt', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('key') - ) - op.create_table('sigl_config', - sa.Column('key', sa.String(), nullable=False), - sa.Column('value', sa.String(length=128), nullable=True), - sa.PrimaryKeyConstraint('key') - ) - op.create_table('access_tokens', - sa.Column('token', sa.String(length=64), nullable=False), - sa.Column('key', sa.String(length=64), nullable=True), - sa.Column('clientIP', sa.String(length=46), nullable=False), - sa.Column('userAgent', sa.String(length=255), nullable=False), - sa.Column('expired', sa.Boolean(), nullable=False), - sa.Column('revoked', sa.Boolean(), nullable=False), - sa.Column('issuedAt', sa.DateTime(), nullable=True), - sa.Column('expiresAt', sa.DateTime(), nullable=True), - sa.Column('revokedAt', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['key'], ['access_keys.key'], ), - sa.PrimaryKeyConstraint('token') - ) - op.create_table('lists', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('key', sa.String(length=64), nullable=True), - sa.Column('name', sa.String(length=128), nullable=False), - sa.Column('notes', sa.String(), nullable=True), - sa.Column('createdAt', sa.DateTime(), nullable=True), - sa.Column('modifiedAt', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['key'], ['access_keys.key'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('products', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('key', sa.String(length=64), nullable=True), - sa.Column('name', sa.String(length=128), nullable=False), - sa.Column('category', sa.String(length=128), nullable=False), - sa.Column('notes', sa.String(), nullable=True), - sa.Column('createdAt', sa.DateTime(), nullable=True), - sa.Column('modifiedAt', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['key'], ['access_keys.key'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_products_category'), 'products', ['category'], unique=False) - op.create_table('list_entries', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('list_id', sa.Integer(), nullable=False), - sa.Column('product_id', sa.Integer(), nullable=False), - sa.Column('quantity', sa.String(length=128), nullable=True), - sa.Column('crossedOff', sa.Boolean(), nullable=True), - sa.Column('deleted', sa.Boolean(), nullable=True), - sa.Column('notes', sa.String(), nullable=True), - sa.Column('createdAt', sa.DateTime(), nullable=True), - sa.Column('modifiedAt', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['list_id'], ['lists.id'], ), - sa.ForeignKeyConstraint(['product_id'], ['products.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('product_locations', - sa.Column('product_id', sa.Integer(), nullable=False), - sa.Column('store', sa.String(length=128), nullable=False), - sa.Column('aisle', sa.String(length=64), nullable=False), - sa.Column('bin', sa.String(length=64), nullable=True), - sa.Column('notes', sa.String(), nullable=True), - sa.Column('createdAt', sa.DateTime(), nullable=True), - sa.Column('modifiedAt', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['product_id'], ['products.id'], ), - sa.PrimaryKeyConstraint('product_id', 'store') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('product_locations') - op.drop_table('list_entries') - op.drop_index(op.f('ix_products_category'), table_name='products') - op.drop_table('products') - op.drop_table('lists') - op.drop_table('access_tokens') - op.drop_table('sigl_config') - op.drop_table('access_keys') - # ### end Alembic commands ### diff --git a/sigl/database/orm.py b/sigl/database/orm.py index f3c1fab..541a62a 100644 --- a/sigl/database/orm.py +++ b/sigl/database/orm.py @@ -8,13 +8,10 @@ from sigl.domain.models import ( Product, ProductLocation, ) -from sigl.domain.models.accessKey import AccessKey, AccessToken from sigl.domain.models.list import ListEntry, ShoppingList from .globals import db from .tables import ( - access_keys, - access_tokens, list_entries, lists, product_locations, @@ -27,33 +24,6 @@ __all__ = ('init_orm', ) def init_orm(): """Initialize the Sigl ORM.""" - # Access Keys - db.mapper(AccessKey, access_keys, properties={ - 'lists': db.relationship( - ShoppingList, - back_populates='accessKey', - cascade='all, delete-orphan', - ), - 'products': db.relationship( - Product, - back_populates='accessKey', - cascade='all, delete-orphan', - ), - 'tokens': db.relationship( - AccessToken, - back_populates='accessKey', - cascade='all, delete-orphan', - ) - }) - - # Access Tokens - db.mapper(AccessToken, access_tokens, properties={ - 'accessKey': db.relationship( - AccessKey, - back_populates='tokens', - ) - }) - # # List Entries db.mapper(ListEntry, list_entries, properties={ 'product': db.relationship( @@ -68,10 +38,6 @@ def init_orm(): # Products db.mapper(Product, products, properties={ - 'accessKey': db.relationship( - AccessKey, - back_populates='products' - ), 'entries': db.relationship( ListEntry, back_populates='product', @@ -94,10 +60,6 @@ def init_orm(): # Shopping Lists db.mapper(ShoppingList, lists, properties={ - 'accessKey': db.relationship( - AccessKey, - back_populates='lists' - ), 'entries': db.relationship( ListEntry, back_populates='shoppingList', diff --git a/sigl/database/tables.py b/sigl/database/tables.py index cd2e191..88cc12d 100644 --- a/sigl/database/tables.py +++ b/sigl/database/tables.py @@ -15,51 +15,6 @@ sigl_config = db.Table( db.Column('value', db.String(128)), ) -#: Access Key Table -access_keys = db.Table( - 'access_keys', - - # Primary Key - db.Column('key', db.String(64), primary_key=True), - - # Client Attributes - db.Column('clientId', db.String(64), nullable=False), - db.Column('clientIP', db.String(46), nullable=False), - db.Column('userAgent', db.String(255), nullable=False), - - # Key Validity - db.Column('suspended', db.Boolean, nullable=False, default=False), - db.Column('revoked', db.Boolean, nullable=False, default=False), - - # Timestamps - db.Column('createdAt', db.DateTime(), default=None), - db.Column('suspendedAt', db.DateTime(), default=None), - db.Column('revokedAt', db.DateTime(), default=None), - db.Column('restoredAt', db.DateTime(), default=None), -) - -#: Access Token Table -access_tokens = db.Table( - 'access_tokens', - - # Primary Key - db.Column('token', db.String(64), primary_key=True), - - # Token Attributes - db.Column('key', db.ForeignKey('access_keys.key'), default=None), - db.Column('clientIP', db.String(46), nullable=False), - db.Column('userAgent', db.String(255), nullable=False), - - # Key Validity - db.Column('expired', db.Boolean, nullable=False, default=False), - db.Column('revoked', db.Boolean, nullable=False, default=False), - - # Timestamps - db.Column('issuedAt', db.DateTime(), default=None), - db.Column('expiresAt', db.DateTime(), default=None), - db.Column('revokedAt', db.DateTime(), default=None), -) - #: Shopping List Table lists = db.Table( 'lists', @@ -67,9 +22,6 @@ lists = db.Table( # Primary Key db.Column('id', db.Integer, primary_key=True), - # Access Key - db.Column('key', db.ForeignKey('access_keys.key'), default=None), - # List Attributes db.Column('name', db.String(128), nullable=False), @@ -108,9 +60,6 @@ products = db.Table( # Primary Key db.Column('id', db.Integer, primary_key=True), - # Access Key - db.Column('key', db.ForeignKey('access_keys.key'), default=None), - # Product Attributes db.Column('name', db.String(128), nullable=False), db.Column('category', db.String(128), nullable=False, index=True), diff --git a/sigl/domain/models/__init__.py b/sigl/domain/models/__init__.py index b152645..1092c51 100644 --- a/sigl/domain/models/__init__.py +++ b/sigl/domain/models/__init__.py @@ -4,13 +4,10 @@ Simple Grocery List (Sigl) | sigl.app Copyright (c) 2022 Asymworks, LLC. All Rights Reserved. """ -from .accessKey import AccessKey, AccessToken from .list import ListEntry, ShoppingList from .product import Product, ProductLocation __all__ = ( - 'AccessKey', - 'AccessToken', 'ListEntry', 'Product', 'ProductLocation', diff --git a/sigl/domain/models/accessKey.py b/sigl/domain/models/accessKey.py deleted file mode 100644 index 026f95f..0000000 --- a/sigl/domain/models/accessKey.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Sigl Access Key Model. - -Simple Grocery List (Sigl) | sigl.app -Copyright (c) 2022 Asymworks, LLC. All Rights Reserved. -""" - -from dataclasses import dataclass, field -from datetime import datetime -from typing import List, TYPE_CHECKING - -if TYPE_CHECKING: - from .list import ShoppingList - from .product import Product - -__all__ = ('AccessKey', 'AccessToken') - - -@dataclass -class AccessKey: - """Sigl Access Key Class. - - The Access Key represents a client or group of clients authorized to - interact with their specific Sigl shopping lists and products. Access Keys - are generally not revoked or deleted and remain for the lifetime of the - server. - - When an Access Key is created, client details including the IP address and - User Agent string are logged for future auditing purposes. The IP address - may also be used for throttling. - """ - key: str = None - - # Client Information - clientId: str = None - clientIP: str = None - userAgent: str = None - - # Key Suspension/Revocation - suspended: bool = False - revoked: bool = False - - # Timestamps - createdAt: datetime = datetime.utcnow() - suspendedAt: datetime = None - revokedAt: datetime = None - restoredAt: datetime = None - - # Relationship Fields - lists: List['ShoppingList'] = field(default_factory=list) - products: List['Product'] = field(default_factory=list) - tokens: List['AccessToken'] = field(default_factory=list) - - -@dataclass -class AccessToken: - """Sigl Access Token Class. - - The Access Token represents authorization for a client (identified by an - Access Key) to interact with the Sigl server. The token string, issue time, - and expiry time must match the client-provided JWT for access to be granted. - Access Tokens are short-lived tokens expected to expire or be revoked, and - new tokens requested by the client. - - When an Access Key is created, client details including the IP address and - User Agent string are logged for future auditing purposes. - """ - token: str = None - - # Relationship Fields - accessKey: 'AccessKey' = None - - # Client Information - clientIP: str = None - userAgent: str = None - - # Key Suspension/Revocation - expired: bool = False - revoked: bool = False - - # Timestamps - issuedAt: datetime = datetime.utcnow() - expiresAt: datetime = None - revokedAt: datetime = None diff --git a/sigl/domain/models/list.py b/sigl/domain/models/list.py index f07a0d6..2636748 100644 --- a/sigl/domain/models/list.py +++ b/sigl/domain/models/list.py @@ -7,7 +7,6 @@ Copyright (c) 2022 Asymworks, LLC. All Rights Reserved. from dataclasses import dataclass, field from typing import List -from .accessKey import AccessKey from .mixins import NotesMixin, TimestampMixin from .product import Product @@ -22,6 +21,8 @@ class ListEntry(NotesMixin, TimestampMixin): list, including the quantity to be purchased, notes about the entry, and whether the Product has been crossed off the list or deleted. """ + id: int = None + quantity: str = None crossedOff: bool = False deleted: bool = False @@ -38,7 +39,7 @@ class ShoppingList(NotesMixin, TimestampMixin): Contains a collection of `ListEntry` items which are intended to be purchased. """ - accessKey: AccessKey = None + id: int = None name: str = None # Relationship Fields diff --git a/sigl/domain/models/product.py b/sigl/domain/models/product.py index 2d0cc67..39cf248 100644 --- a/sigl/domain/models/product.py +++ b/sigl/domain/models/product.py @@ -7,7 +7,6 @@ Copyright (c) 2022 Asymworks, LLC. All Rights Reserved. from dataclasses import dataclass, field from typing import List, TYPE_CHECKING -from .accessKey import AccessKey from .mixins import NotesMixin, TimestampMixin if TYPE_CHECKING: @@ -24,12 +23,10 @@ class Product(NotesMixin, TimestampMixin): shopping list, including the Product Name, Category, Notes, and Product Location in one or more stores. """ + id: int = None name: str = None category: str = None - # Access Control - accessKey: AccessKey = None - # Relationship Fields entries: List['ListEntry'] = field(default_factory=list) locations: List['ProductLocation'] = field(default_factory=list)