Remove Access Control
This commit is contained in:
@@ -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 ###
|
|
||||||
@@ -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',
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user