201 lines
6.0 KiB
Python
201 lines
6.0 KiB
Python
"""
|
|
Admin configuration for accounts app.
|
|
"""
|
|
|
|
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
|
|
|
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
from django.utils.html import format_html
|
|
from .models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
|
|
from hr.models import Employee
|
|
|
|
class EmployeeInline(admin.StackedInline):
|
|
model = Employee
|
|
can_delete = False
|
|
fk_name = 'user'
|
|
extra = 0
|
|
|
|
|
|
@admin.register(User)
|
|
class UserAdmin(DjangoUserAdmin):
|
|
inlines = [EmployeeInline]
|
|
list_display = ('username', 'email', 'tenant', 'is_active', 'is_staff', 'two_factor_enabled', 'locked_until')
|
|
list_filter = ('tenant', 'is_active', 'is_staff', 'is_superuser', 'two_factor_enabled')
|
|
search_fields = ('username', 'email', 'first_name', 'last_name')
|
|
readonly_fields = ('last_login', 'date_joined', 'last_password_change')
|
|
fieldsets = (
|
|
(None, {'fields': ('tenant', 'username', 'password')}),
|
|
('Personal info', {'fields': ('first_name', 'last_name', 'email')}),
|
|
('Security', {'fields': (
|
|
'force_password_change', 'password_expires_at', 'last_password_change',
|
|
'failed_login_attempts', 'locked_until', 'two_factor_enabled',
|
|
'max_concurrent_sessions', 'session_timeout_minutes',
|
|
)}),
|
|
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
|
|
('Important dates', {'fields': ('last_login', 'date_joined')}),
|
|
)
|
|
add_fieldsets = (
|
|
(None, {
|
|
'classes': ('wide',),
|
|
'fields': ('tenant', 'username', 'email', 'password1', 'password2'),
|
|
}),
|
|
)
|
|
|
|
|
|
@admin.register(TwoFactorDevice)
|
|
class TwoFactorDeviceAdmin(admin.ModelAdmin):
|
|
"""
|
|
Admin configuration for TwoFactorDevice model.
|
|
"""
|
|
list_display = [
|
|
'user', 'name', 'device_type', 'is_active', 'is_verified',
|
|
'last_used_at', 'usage_count'
|
|
]
|
|
list_filter = ['device_type', 'is_active', 'is_verified']
|
|
search_fields = ['user__username', 'user__email', 'name']
|
|
ordering = ['-created_at']
|
|
|
|
fieldsets = (
|
|
('Device Information', {
|
|
'fields': ('user', 'device_id', 'name', 'device_type')
|
|
}),
|
|
('Configuration', {
|
|
'fields': ('secret_key', 'phone_number', 'email_address')
|
|
}),
|
|
('Status', {
|
|
'fields': ('is_active', 'is_verified', 'verified_at')
|
|
}),
|
|
('Usage Statistics', {
|
|
'fields': ('last_used_at', 'usage_count')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_at', 'updated_at'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['device_id', 'created_at', 'updated_at']
|
|
|
|
|
|
@admin.register(SocialAccount)
|
|
class SocialAccountAdmin(admin.ModelAdmin):
|
|
"""
|
|
Admin configuration for SocialAccount model.
|
|
"""
|
|
list_display = [
|
|
'user', 'provider', 'provider_email', 'display_name',
|
|
'is_active', 'last_login_at'
|
|
]
|
|
list_filter = ['provider', 'is_active']
|
|
search_fields = [
|
|
'user__username', 'user__email', 'provider_email',
|
|
'display_name', 'provider_id'
|
|
]
|
|
ordering = ['-created_at']
|
|
|
|
fieldsets = (
|
|
('User Information', {
|
|
'fields': ('user',)
|
|
}),
|
|
('Provider Information', {
|
|
'fields': (
|
|
'provider', 'provider_id', 'provider_email',
|
|
'display_name', 'profile_url', 'avatar_url'
|
|
)
|
|
}),
|
|
('Tokens', {
|
|
'fields': ('access_token', 'refresh_token', 'token_expires_at'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Status', {
|
|
'fields': ('is_active',)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_at', 'updated_at', 'last_login_at'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
|
|
|
|
@admin.register(UserSession)
|
|
class UserSessionAdmin(admin.ModelAdmin):
|
|
"""
|
|
Admin configuration for UserSession model.
|
|
"""
|
|
list_display = [
|
|
'user', 'ip_address', 'device_type', 'browser',
|
|
'is_active', 'login_method', 'created_at', 'expires_at'
|
|
]
|
|
list_filter = [
|
|
'device_type', 'is_active', 'login_method',
|
|
'country', 'created_at'
|
|
]
|
|
search_fields = [
|
|
'user__username', 'user__email', 'ip_address',
|
|
'user_agent', 'browser', 'operating_system'
|
|
]
|
|
ordering = ['-created_at']
|
|
|
|
fieldsets = (
|
|
('User Information', {
|
|
'fields': ('user', 'session_key', 'session_id')
|
|
}),
|
|
('Device Information', {
|
|
'fields': (
|
|
'ip_address', 'user_agent', 'device_type',
|
|
'browser', 'operating_system'
|
|
)
|
|
}),
|
|
('Location Information', {
|
|
'fields': ('country', 'region', 'city')
|
|
}),
|
|
('Session Status', {
|
|
'fields': ('is_active', 'login_method')
|
|
}),
|
|
('Timestamps', {
|
|
'fields': (
|
|
'created_at', 'last_activity_at',
|
|
'expires_at', 'ended_at'
|
|
)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = [
|
|
'session_id', 'created_at', 'last_activity_at'
|
|
]
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|
|
|
|
@admin.register(PasswordHistory)
|
|
class PasswordHistoryAdmin(admin.ModelAdmin):
|
|
"""
|
|
Admin configuration for PasswordHistory model.
|
|
"""
|
|
list_display = ['user', 'created_at']
|
|
list_filter = ['created_at']
|
|
search_fields = ['user__username', 'user__email']
|
|
ordering = ['-created_at']
|
|
|
|
fieldsets = (
|
|
('User Information', {
|
|
'fields': ('user',)
|
|
}),
|
|
('Password Information', {
|
|
'fields': ('password_hash',)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_at',)
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['created_at']
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|