-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dynamic options and auto assign users/scopes to groups (#169)
## Изменения Делал автоматическое присваивание юзеров в группу users и автоматическое добавление скоупов группе root ## Детали реализации - Во время миграции создается новая таблица с опциями. Опции бывают строковыми, даблавыми и интовыми - Создаются 2 интовые опции: для группы root и для группы users, хранящие их id - Если групп с такими именами еще не существует, создает группы и добавляет в них все существующие скоупы/юзеров соответственно
- Loading branch information
Showing
8 changed files
with
168 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from .base import Base | ||
from .db import AuthMethod, User, UserSession | ||
from .dynamic_settings import DynamicOption | ||
|
||
|
||
__all__ = ["Base", "User", "UserSession", "AuthMethod"] | ||
__all__ = ["Base", "User", "UserSession", "AuthMethod", "DynamicOption"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from datetime import datetime | ||
|
||
from sqlalchemy import DateTime, Double, Integer, String | ||
from sqlalchemy.orm import Mapped, Session, mapped_column | ||
|
||
from .base import Base | ||
|
||
|
||
class DynamicOption(Base): | ||
id: Mapped[int] = mapped_column(Integer, primary_key=True) | ||
name: Mapped[str] = mapped_column(String, unique=True) | ||
value_integer: Mapped[int] = mapped_column(Integer, nullable=True) | ||
value_double: Mapped[float] = mapped_column(Double, nullable=True) | ||
value_string: Mapped[str] = mapped_column(String, nullable=True) | ||
create_ts: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) | ||
update_ts: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) | ||
|
||
@property | ||
def value(self) -> str | float | int: | ||
return self.value_double or self.value_integer or self.value_string | ||
|
||
@value.setter | ||
def set_value(self, value: str | float | int): | ||
if isinstance(value, str): | ||
self.value_string = value | ||
elif isinstance(value, float): | ||
self.value_double = value | ||
elif isinstance(value, int): | ||
self.value_integer = value | ||
else: | ||
raise TypeError("Only str, float or int options allowed") | ||
|
||
@staticmethod | ||
def get(name, default=None, *, session: Session): | ||
return session.query(DynamicOption).filter(DynamicOption.name == name).one_or_none() or default |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
"""Dynamic option model | ||
Revision ID: 7c1cd7ceacd8 | ||
Revises: bda218c91211 | ||
Create Date: 2024-04-05 22:36:58.224670 | ||
""" | ||
|
||
import sqlalchemy as sa | ||
from alembic import op | ||
from sqlalchemy.orm import Session | ||
|
||
from auth_backend.models.db import Group, Scope, User | ||
|
||
|
||
# revision identifiers, used by Alembic. | ||
revision = '7c1cd7ceacd8' | ||
down_revision = 'bda218c91211' | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
dynamic_option_table = op.create_table( | ||
'dynamic_option', | ||
sa.Column('id', sa.Integer(), nullable=False), | ||
sa.Column('name', sa.String(), nullable=False, unique=True), | ||
sa.Column('value_integer', sa.Integer(), nullable=True), | ||
sa.Column('value_double', sa.Double(), nullable=True), | ||
sa.Column('value_string', sa.String(), nullable=True), | ||
sa.Column('create_ts', sa.DateTime(), nullable=False), | ||
sa.Column('update_ts', sa.DateTime(), nullable=False), | ||
sa.PrimaryKeyConstraint('id'), | ||
sa.UniqueConstraint('name'), | ||
) | ||
|
||
conn = op.get_bind() | ||
session = Session(conn) | ||
try: | ||
root_group_id = session.execute(sa.text("SELECT \"id\" FROM \"group\" WHERE name = 'root'")).scalar() | ||
except Exception: | ||
pass | ||
|
||
if root_group_id is None: | ||
group: Group = Group.create(name="root", session=session) | ||
scopes = session.execute(sa.text("SELECT id FROM \"scope\"")).fetchall() | ||
for scope_id in scopes: | ||
scope_id = Scope.get(scope_id[0], with_deleted=True, session=session) | ||
group.scopes.add(scope_id) | ||
root_group_id = group.id | ||
|
||
try: | ||
users_group_id = session.execute(sa.text("SELECT \"id\" FROM \"group\" WHERE name = 'users'")).scalar() | ||
except Exception: | ||
pass | ||
|
||
if users_group_id is None: | ||
group: Group = Group.create(name="users", session=session) | ||
users = session.execute(sa.text("SELECT id FROM \"user\"")).fetchall() | ||
for user_id in users: | ||
user = User.get(user_id[0], with_deleted=True, session=session) | ||
group.users.append(user) | ||
users_group_id = group.id | ||
|
||
session.flush() | ||
|
||
values = [ | ||
{"name": "root_group_id", "create_ts": "now()", "update_ts": "now()", "value_integer": root_group_id}, | ||
{"name": "users_group_id", "create_ts": "now()", "update_ts": "now()", "value_integer": users_group_id}, | ||
] | ||
op.bulk_insert(dynamic_option_table, values) | ||
|
||
|
||
def downgrade(): | ||
op.drop_table('dynamic_option') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters