Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions fastid/admin/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
from sqlalchemy.ext.asyncio import AsyncEngine

from fastid.admin.auth import admin_auth
from fastid.admin.views import (
EmailTemplateAdmin,
NotificationAdmin,
OAuthAccountAdmin,
OAuthClientAdmin,
TelegramTemplateAdmin,
UserAdmin,
from fastid.admin.views.entities import NotificationAdmin, OAuthAccountAdmin, UserAdmin
from fastid.admin.views.settings import AppAdmin, EmailTemplateAdmin, TelegramTemplateAdmin
from fastid.admin.views.versioning import (
AppVersionAdmin,
EmailTemplateVersionAdmin,
TelegramTemplateVersionAdmin,
TransactionAdmin,
UserVersionAdmin,
)
from fastid.core.base import MiniApp

Expand All @@ -39,12 +40,20 @@ def create(self) -> FastAPI:
authentication_backend=admin_auth,
**self.admin_kwargs,
)
# Users
admin.add_view(UserAdmin)
admin.add_view(OAuthClientAdmin)
admin.add_view(OAuthAccountAdmin)
admin.add_view(NotificationAdmin)
# Settings
admin.add_view(AppAdmin)
admin.add_view(EmailTemplateAdmin)
admin.add_view(TelegramTemplateAdmin)
admin.add_view(NotificationAdmin)
# Versioning
admin.add_view(TransactionAdmin)
admin.add_view(UserVersionAdmin)
admin.add_view(AppVersionAdmin)
admin.add_view(EmailTemplateVersionAdmin)
admin.add_view(TelegramTemplateVersionAdmin)
return app

def install(self, app: FastAPI) -> None:
Expand Down
2 changes: 1 addition & 1 deletion fastid/admin/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async def login(self, request: Request) -> bool:
assert isinstance(username, str)
assert isinstance(password, str)

if not secrets.compare_digest(username, admin_settings.username) or not secrets.compare_digest(
if not secrets.compare_digest(username, admin_settings.email) or not secrets.compare_digest(
password,
admin_settings.password,
):
Expand Down
1 change: 0 additions & 1 deletion fastid/admin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
class AdminSettings(BaseSettings):
enabled: bool = True
email: str = "admin@fastid.com"
username: str = "admin"
password: str = "admin"
favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png"
logo_url: str = "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
Expand Down
145 changes: 0 additions & 145 deletions fastid/admin/views.py

This file was deleted.

Empty file added fastid/admin/views/__init__.py
Empty file.
19 changes: 19 additions & 0 deletions fastid/admin/views/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from sqladmin import ModelView

from fastid.admin.views.utils import time_format


class BaseView(ModelView):
column_sortable_list = [
"created_at",
"updated_at",
]
column_searchable_list = ["id"]
column_default_sort = [("created_at", True)]
column_formatters = {
"created_at": time_format,
"updated_at": time_format,
}
column_exclude_list = ["versions"]
column_details_exclude_list = ["versions"]
form_excluded_columns = ["versions"]
73 changes: 73 additions & 0 deletions fastid/admin/views/entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from sqladmin.filters import AllUniqueStringValuesFilter, BooleanFilter, OperationColumnFilter

from fastid.admin.views.base import BaseView
from fastid.database.models import Notification, OAuthAccount, User


class UserAdmin(BaseView, model=User):
name = "User"
name_plural = "Users"
icon = "fa-solid fa-users"
category = "Entities"
category_icon = "fa-solid fa-cloud"

column_list = [
User.id,
User.email,
User.first_name,
User.is_active,
User.is_superuser,
User.is_verified,
User.created_at,
User.updated_at,
]

column_filters = [
BooleanFilter(User.is_active),
BooleanFilter(User.is_verified),
BooleanFilter(User.is_superuser),
OperationColumnFilter(User.email),
]


class OAuthAccountAdmin(BaseView, model=OAuthAccount):
name = "OAuth Account"
name_plural = "OAuth Accounts"
icon = "fa-brands fa-google"
category = "Entities"

column_list = [
OAuthAccount.id,
OAuthAccount.user,
OAuthAccount.provider,
OAuthAccount.email,
OAuthAccount.display_name,
OAuthAccount.created_at,
OAuthAccount.updated_at,
]
column_filters = [
AllUniqueStringValuesFilter(OAuthAccount.provider),
OperationColumnFilter(OAuthAccount.user_id),
OperationColumnFilter(OAuthAccount.email),
]


class NotificationAdmin(BaseView, model=Notification):
name = "Notification"
name_plural = "Notifications"
icon = "fa-solid fa-bell"
category = "Entities"

column_list = [
Notification.id,
Notification.user,
Notification.type,
Notification.template,
Notification.created_at,
Notification.updated_at,
]
column_filters = [
AllUniqueStringValuesFilter(Notification.type),
OperationColumnFilter(Notification.user_id),
OperationColumnFilter(Notification.template),
]
59 changes: 59 additions & 0 deletions fastid/admin/views/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from sqladmin.filters import BooleanFilter, OperationColumnFilter

from fastid.admin.views.base import BaseView
from fastid.database.models import App, EmailTemplate, TelegramTemplate


class AppAdmin(BaseView, model=App):
name = "App"
name_plural = "Apps"
icon = "fa-solid fa-cube"
category = "Settings"
category_icon = "fa-solid fa-star"

column_list = [
App.id,
App.name,
App.is_active,
App.created_at,
App.updated_at,
]
column_filters = [
BooleanFilter(App.is_active),
OperationColumnFilter(App.client_id),
]


class EmailTemplateAdmin(BaseView, model=EmailTemplate):
name = "Email Template"
name_plural = "Email Templates"
icon = "fa-solid fa-envelope"
category = "Settings"

column_list = [
EmailTemplate.id,
EmailTemplate.slug,
EmailTemplate.subject,
EmailTemplate.created_at,
EmailTemplate.updated_at,
]
column_filters = [
OperationColumnFilter(EmailTemplate.slug),
]


class TelegramTemplateAdmin(BaseView, model=TelegramTemplate):
name = "Telegram Template"
name_plural = "Telegram Templates"
icon = "fa-brands fa-telegram"
category = "Settings"

column_list = [
TelegramTemplate.id,
TelegramTemplate.slug,
TelegramTemplate.created_at,
TelegramTemplate.updated_at,
]
column_filters = [
OperationColumnFilter(EmailTemplate.slug),
]
29 changes: 29 additions & 0 deletions fastid/admin/views/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Any

import humanize

from fastid.database.utils import naive_utc

OPERATION_TYPES = {0: "CREATE", 1: "UPDATE", 2: "DELETE"}


def getattr_dot(m: Any, a: Any) -> Any:
# Handle dot notation for nested attributes
if "." not in a:
return getattr(m, a)
parts = a.split(".")
obj = m
for part in parts:
obj = getattr(obj, part, None)
if obj is None:
return None
return obj


def time_format(m: Any, a: Any) -> Any:
return humanize.naturaltime(getattr_dot(m, a), when=naive_utc())


def operation_type_format(m: Any, a: Any) -> Any:
val = getattr(m, a)
return OPERATION_TYPES[val]
Loading