Remove Access Control

This commit is contained in:
2022-07-12 12:15:12 -07:00
parent ea93a43004
commit ce48066b6e
7 changed files with 4 additions and 293 deletions

View File

@@ -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 ###

View File

@@ -8,13 +8,10 @@ from sigl.domain.models import (
Product, Product,
ProductLocation, ProductLocation,
) )
from sigl.domain.models.accessKey import AccessKey, AccessToken
from sigl.domain.models.list import ListEntry, ShoppingList from sigl.domain.models.list import ListEntry, ShoppingList
from .globals import db from .globals import db
from .tables import ( from .tables import (
access_keys,
access_tokens,
list_entries, list_entries,
lists, lists,
product_locations, product_locations,
@@ -27,33 +24,6 @@ __all__ = ('init_orm', )
def init_orm(): def init_orm():
"""Initialize the Sigl 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 # # List Entries
db.mapper(ListEntry, list_entries, properties={ db.mapper(ListEntry, list_entries, properties={
'product': db.relationship( 'product': db.relationship(
@@ -68,10 +38,6 @@ def init_orm():
# Products # Products
db.mapper(Product, products, properties={ db.mapper(Product, products, properties={
'accessKey': db.relationship(
AccessKey,
back_populates='products'
),
'entries': db.relationship( 'entries': db.relationship(
ListEntry, ListEntry,
back_populates='product', back_populates='product',
@@ -94,10 +60,6 @@ def init_orm():
# Shopping Lists # Shopping Lists
db.mapper(ShoppingList, lists, properties={ db.mapper(ShoppingList, lists, properties={
'accessKey': db.relationship(
AccessKey,
back_populates='lists'
),
'entries': db.relationship( 'entries': db.relationship(
ListEntry, ListEntry,
back_populates='shoppingList', back_populates='shoppingList',

View File

@@ -15,51 +15,6 @@ sigl_config = db.Table(
db.Column('value', db.String(128)), 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 #: Shopping List Table
lists = db.Table( lists = db.Table(
'lists', 'lists',
@@ -67,9 +22,6 @@ lists = db.Table(
# Primary Key # Primary Key
db.Column('id', db.Integer, primary_key=True), db.Column('id', db.Integer, primary_key=True),
# Access Key
db.Column('key', db.ForeignKey('access_keys.key'), default=None),
# List Attributes # List Attributes
db.Column('name', db.String(128), nullable=False), db.Column('name', db.String(128), nullable=False),
@@ -108,9 +60,6 @@ products = db.Table(
# Primary Key # Primary Key
db.Column('id', db.Integer, primary_key=True), db.Column('id', db.Integer, primary_key=True),
# Access Key
db.Column('key', db.ForeignKey('access_keys.key'), default=None),
# Product Attributes # Product Attributes
db.Column('name', db.String(128), nullable=False), db.Column('name', db.String(128), nullable=False),
db.Column('category', db.String(128), nullable=False, index=True), db.Column('category', db.String(128), nullable=False, index=True),

View File

@@ -4,13 +4,10 @@ Simple Grocery List (Sigl) | sigl.app
Copyright (c) 2022 Asymworks, LLC. All Rights Reserved. Copyright (c) 2022 Asymworks, LLC. All Rights Reserved.
""" """
from .accessKey import AccessKey, AccessToken
from .list import ListEntry, ShoppingList from .list import ListEntry, ShoppingList
from .product import Product, ProductLocation from .product import Product, ProductLocation
__all__ = ( __all__ = (
'AccessKey',
'AccessToken',
'ListEntry', 'ListEntry',
'Product', 'Product',
'ProductLocation', 'ProductLocation',

View File

@@ -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

View File

@@ -7,7 +7,6 @@ Copyright (c) 2022 Asymworks, LLC. All Rights Reserved.
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import List from typing import List
from .accessKey import AccessKey
from .mixins import NotesMixin, TimestampMixin from .mixins import NotesMixin, TimestampMixin
from .product import Product from .product import Product
@@ -22,6 +21,8 @@ class ListEntry(NotesMixin, TimestampMixin):
list, including the quantity to be purchased, notes about the entry, and list, including the quantity to be purchased, notes about the entry, and
whether the Product has been crossed off the list or deleted. whether the Product has been crossed off the list or deleted.
""" """
id: int = None
quantity: str = None quantity: str = None
crossedOff: bool = False crossedOff: bool = False
deleted: bool = False deleted: bool = False
@@ -38,7 +39,7 @@ class ShoppingList(NotesMixin, TimestampMixin):
Contains a collection of `ListEntry` items which are intended to be Contains a collection of `ListEntry` items which are intended to be
purchased. purchased.
""" """
accessKey: AccessKey = None id: int = None
name: str = None name: str = None
# Relationship Fields # Relationship Fields

View File

@@ -7,7 +7,6 @@ Copyright (c) 2022 Asymworks, LLC. All Rights Reserved.
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import List, TYPE_CHECKING from typing import List, TYPE_CHECKING
from .accessKey import AccessKey
from .mixins import NotesMixin, TimestampMixin from .mixins import NotesMixin, TimestampMixin
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -24,12 +23,10 @@ class Product(NotesMixin, TimestampMixin):
shopping list, including the Product Name, Category, Notes, and Product shopping list, including the Product Name, Category, Notes, and Product
Location in one or more stores. Location in one or more stores.
""" """
id: int = None
name: str = None name: str = None
category: str = None category: str = None
# Access Control
accessKey: AccessKey = None
# Relationship Fields # Relationship Fields
entries: List['ListEntry'] = field(default_factory=list) entries: List['ListEntry'] = field(default_factory=list)
locations: List['ProductLocation'] = field(default_factory=list) locations: List['ProductLocation'] = field(default_factory=list)