createsonline 0.1.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- createsonline/__init__.py +46 -0
- createsonline/admin/__init__.py +7 -0
- createsonline/admin/content.py +526 -0
- createsonline/admin/crud.py +805 -0
- createsonline/admin/field_builder.py +559 -0
- createsonline/admin/integration.py +482 -0
- createsonline/admin/interface.py +2562 -0
- createsonline/admin/model_creator.py +513 -0
- createsonline/admin/model_manager.py +388 -0
- createsonline/admin/modern_dashboard.py +498 -0
- createsonline/admin/permissions.py +264 -0
- createsonline/admin/user_forms.py +594 -0
- createsonline/ai/__init__.py +202 -0
- createsonline/ai/fields.py +1226 -0
- createsonline/ai/orm.py +325 -0
- createsonline/ai/services.py +1244 -0
- createsonline/app.py +506 -0
- createsonline/auth/__init__.py +8 -0
- createsonline/auth/management.py +228 -0
- createsonline/auth/models.py +552 -0
- createsonline/cli/__init__.py +5 -0
- createsonline/cli/commands/__init__.py +122 -0
- createsonline/cli/commands/database.py +416 -0
- createsonline/cli/commands/info.py +173 -0
- createsonline/cli/commands/initdb.py +218 -0
- createsonline/cli/commands/project.py +545 -0
- createsonline/cli/commands/serve.py +173 -0
- createsonline/cli/commands/shell.py +93 -0
- createsonline/cli/commands/users.py +148 -0
- createsonline/cli/main.py +2041 -0
- createsonline/cli/manage.py +274 -0
- createsonline/config/__init__.py +9 -0
- createsonline/config/app.py +2577 -0
- createsonline/config/database.py +179 -0
- createsonline/config/docs.py +384 -0
- createsonline/config/errors.py +160 -0
- createsonline/config/orm.py +43 -0
- createsonline/config/request.py +93 -0
- createsonline/config/settings.py +176 -0
- createsonline/data/__init__.py +23 -0
- createsonline/data/dataframe.py +925 -0
- createsonline/data/io.py +453 -0
- createsonline/data/series.py +557 -0
- createsonline/database/__init__.py +60 -0
- createsonline/database/abstraction.py +440 -0
- createsonline/database/assistant.py +585 -0
- createsonline/database/fields.py +442 -0
- createsonline/database/migrations.py +132 -0
- createsonline/database/models.py +604 -0
- createsonline/database.py +438 -0
- createsonline/http/__init__.py +28 -0
- createsonline/http/client.py +535 -0
- createsonline/ml/__init__.py +55 -0
- createsonline/ml/classification.py +552 -0
- createsonline/ml/clustering.py +680 -0
- createsonline/ml/metrics.py +542 -0
- createsonline/ml/neural.py +560 -0
- createsonline/ml/preprocessing.py +784 -0
- createsonline/ml/regression.py +501 -0
- createsonline/performance/__init__.py +19 -0
- createsonline/performance/cache.py +444 -0
- createsonline/performance/compression.py +335 -0
- createsonline/performance/core.py +419 -0
- createsonline/project_init.py +789 -0
- createsonline/routing.py +528 -0
- createsonline/security/__init__.py +34 -0
- createsonline/security/core.py +811 -0
- createsonline/security/encryption.py +349 -0
- createsonline/server.py +295 -0
- createsonline/static/css/admin.css +263 -0
- createsonline/static/css/common.css +358 -0
- createsonline/static/css/dashboard.css +89 -0
- createsonline/static/favicon.ico +0 -0
- createsonline/static/icons/icon-128x128.png +0 -0
- createsonline/static/icons/icon-128x128.webp +0 -0
- createsonline/static/icons/icon-16x16.png +0 -0
- createsonline/static/icons/icon-16x16.webp +0 -0
- createsonline/static/icons/icon-180x180.png +0 -0
- createsonline/static/icons/icon-180x180.webp +0 -0
- createsonline/static/icons/icon-192x192.png +0 -0
- createsonline/static/icons/icon-192x192.webp +0 -0
- createsonline/static/icons/icon-256x256.png +0 -0
- createsonline/static/icons/icon-256x256.webp +0 -0
- createsonline/static/icons/icon-32x32.png +0 -0
- createsonline/static/icons/icon-32x32.webp +0 -0
- createsonline/static/icons/icon-384x384.png +0 -0
- createsonline/static/icons/icon-384x384.webp +0 -0
- createsonline/static/icons/icon-48x48.png +0 -0
- createsonline/static/icons/icon-48x48.webp +0 -0
- createsonline/static/icons/icon-512x512.png +0 -0
- createsonline/static/icons/icon-512x512.webp +0 -0
- createsonline/static/icons/icon-64x64.png +0 -0
- createsonline/static/icons/icon-64x64.webp +0 -0
- createsonline/static/image/android-chrome-192x192.png +0 -0
- createsonline/static/image/android-chrome-512x512.png +0 -0
- createsonline/static/image/apple-touch-icon.png +0 -0
- createsonline/static/image/favicon-16x16.png +0 -0
- createsonline/static/image/favicon-32x32.png +0 -0
- createsonline/static/image/favicon.ico +0 -0
- createsonline/static/image/favicon.svg +17 -0
- createsonline/static/image/icon-128x128.png +0 -0
- createsonline/static/image/icon-128x128.webp +0 -0
- createsonline/static/image/icon-16x16.png +0 -0
- createsonline/static/image/icon-16x16.webp +0 -0
- createsonline/static/image/icon-180x180.png +0 -0
- createsonline/static/image/icon-180x180.webp +0 -0
- createsonline/static/image/icon-192x192.png +0 -0
- createsonline/static/image/icon-192x192.webp +0 -0
- createsonline/static/image/icon-256x256.png +0 -0
- createsonline/static/image/icon-256x256.webp +0 -0
- createsonline/static/image/icon-32x32.png +0 -0
- createsonline/static/image/icon-32x32.webp +0 -0
- createsonline/static/image/icon-384x384.png +0 -0
- createsonline/static/image/icon-384x384.webp +0 -0
- createsonline/static/image/icon-48x48.png +0 -0
- createsonline/static/image/icon-48x48.webp +0 -0
- createsonline/static/image/icon-512x512.png +0 -0
- createsonline/static/image/icon-512x512.webp +0 -0
- createsonline/static/image/icon-64x64.png +0 -0
- createsonline/static/image/icon-64x64.webp +0 -0
- createsonline/static/image/logo-header-h100.png +0 -0
- createsonline/static/image/logo-header-h100.webp +0 -0
- createsonline/static/image/logo-header-h200@2x.png +0 -0
- createsonline/static/image/logo-header-h200@2x.webp +0 -0
- createsonline/static/image/logo.png +0 -0
- createsonline/static/js/admin.js +274 -0
- createsonline/static/site.webmanifest +35 -0
- createsonline/static/templates/admin/base.html +87 -0
- createsonline/static/templates/admin/dashboard.html +217 -0
- createsonline/static/templates/admin/model_form.html +270 -0
- createsonline/static/templates/admin/model_list.html +202 -0
- createsonline/static/test_script.js +15 -0
- createsonline/static/test_styles.css +59 -0
- createsonline/static_files.py +365 -0
- createsonline/templates/404.html +100 -0
- createsonline/templates/admin_login.html +169 -0
- createsonline/templates/base.html +102 -0
- createsonline/templates/index.html +151 -0
- createsonline/templates.py +205 -0
- createsonline/testing.py +322 -0
- createsonline/utils.py +448 -0
- createsonline/validation/__init__.py +49 -0
- createsonline/validation/fields.py +598 -0
- createsonline/validation/models.py +504 -0
- createsonline/validation/validators.py +561 -0
- createsonline/views.py +184 -0
- createsonline-0.1.26.dist-info/METADATA +46 -0
- createsonline-0.1.26.dist-info/RECORD +152 -0
- createsonline-0.1.26.dist-info/WHEEL +5 -0
- createsonline-0.1.26.dist-info/entry_points.txt +2 -0
- createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
- createsonline-0.1.26.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# createsonline/admin/permissions.py
|
|
2
|
+
"""
|
|
3
|
+
CREATESONLINE Admin Permission System
|
|
4
|
+
|
|
5
|
+
Permission decorators and helpers for admin views.
|
|
6
|
+
"""
|
|
7
|
+
from functools import wraps
|
|
8
|
+
from typing import Callable, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PermissionDenied(Exception):
|
|
12
|
+
"""Raised when user doesn't have required permission"""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def staff_required(func: Callable) -> Callable:
|
|
17
|
+
"""
|
|
18
|
+
Decorator to require user to be staff
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
@staff_required
|
|
22
|
+
async def my_view(request):
|
|
23
|
+
...
|
|
24
|
+
"""
|
|
25
|
+
@wraps(func)
|
|
26
|
+
async def wrapper(self, request, *args, **kwargs):
|
|
27
|
+
user = getattr(request, 'user', None)
|
|
28
|
+
|
|
29
|
+
if not user or not user.is_staff:
|
|
30
|
+
return await self._show_login(request, error="Staff access required")
|
|
31
|
+
|
|
32
|
+
return await func(self, request, *args, **kwargs)
|
|
33
|
+
|
|
34
|
+
return wrapper
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def superuser_required(func: Callable) -> Callable:
|
|
38
|
+
"""
|
|
39
|
+
Decorator to require user to be superuser
|
|
40
|
+
|
|
41
|
+
Usage:
|
|
42
|
+
@superuser_required
|
|
43
|
+
async def my_view(request):
|
|
44
|
+
...
|
|
45
|
+
"""
|
|
46
|
+
@wraps(func)
|
|
47
|
+
async def wrapper(self, request, *args, **kwargs):
|
|
48
|
+
user = getattr(request, 'user', None)
|
|
49
|
+
|
|
50
|
+
if not user or not user.is_superuser:
|
|
51
|
+
return await self._show_permission_denied(request, "Superuser access required")
|
|
52
|
+
|
|
53
|
+
return await func(self, request, *args, **kwargs)
|
|
54
|
+
|
|
55
|
+
return wrapper
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def permission_required(permission: str, raise_exception: bool = True) -> Callable:
|
|
59
|
+
"""
|
|
60
|
+
Decorator to require specific permission
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
permission: Permission string like "auth.add_user"
|
|
64
|
+
raise_exception: If True, raise PermissionDenied; else redirect to login
|
|
65
|
+
|
|
66
|
+
Usage:
|
|
67
|
+
@permission_required("auth.add_user")
|
|
68
|
+
async def my_view(request):
|
|
69
|
+
...
|
|
70
|
+
"""
|
|
71
|
+
def decorator(func: Callable) -> Callable:
|
|
72
|
+
@wraps(func)
|
|
73
|
+
async def wrapper(self, request, *args, **kwargs):
|
|
74
|
+
user = getattr(request, 'user', None)
|
|
75
|
+
|
|
76
|
+
if not user or not user.has_permission(permission):
|
|
77
|
+
if raise_exception:
|
|
78
|
+
raise PermissionDenied(f"Permission required: {permission}")
|
|
79
|
+
return await self._show_permission_denied(
|
|
80
|
+
request,
|
|
81
|
+
f"You don't have permission: {permission}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return await func(self, request, *args, **kwargs)
|
|
85
|
+
|
|
86
|
+
return wrapper
|
|
87
|
+
|
|
88
|
+
return decorator
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def permissions_required(*permissions, require_all: bool = True) -> Callable:
|
|
92
|
+
"""
|
|
93
|
+
Decorator to require multiple permissions
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
*permissions: Permission strings
|
|
97
|
+
require_all: If True, require all permissions; else require any
|
|
98
|
+
|
|
99
|
+
Usage:
|
|
100
|
+
@permissions_required("auth.add_user", "auth.change_user")
|
|
101
|
+
async def my_view(request):
|
|
102
|
+
...
|
|
103
|
+
"""
|
|
104
|
+
def decorator(func: Callable) -> Callable:
|
|
105
|
+
@wraps(func)
|
|
106
|
+
async def wrapper(self, request, *args, **kwargs):
|
|
107
|
+
user = getattr(request, 'user', None)
|
|
108
|
+
|
|
109
|
+
if not user:
|
|
110
|
+
return await self._show_permission_denied(request, "Authentication required")
|
|
111
|
+
|
|
112
|
+
if require_all:
|
|
113
|
+
# User must have all permissions
|
|
114
|
+
missing = [p for p in permissions if not user.has_permission(p)]
|
|
115
|
+
if missing:
|
|
116
|
+
return await self._show_permission_denied(
|
|
117
|
+
request,
|
|
118
|
+
f"Missing permissions: {', '.join(missing)}"
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
# User must have at least one permission
|
|
122
|
+
if not any(user.has_permission(p) for p in permissions):
|
|
123
|
+
return await self._show_permission_denied(
|
|
124
|
+
request,
|
|
125
|
+
f"Requires one of: {', '.join(permissions)}"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return await func(self, request, *args, **kwargs)
|
|
129
|
+
|
|
130
|
+
return wrapper
|
|
131
|
+
|
|
132
|
+
return decorator
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def module_permission_required(app_label: str) -> Callable:
|
|
136
|
+
"""
|
|
137
|
+
Decorator to require any permission for a module
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
app_label: Application label like "auth"
|
|
141
|
+
|
|
142
|
+
Usage:
|
|
143
|
+
@module_permission_required("auth")
|
|
144
|
+
async def my_view(request):
|
|
145
|
+
...
|
|
146
|
+
"""
|
|
147
|
+
def decorator(func: Callable) -> Callable:
|
|
148
|
+
@wraps(func)
|
|
149
|
+
async def wrapper(self, request, *args, **kwargs):
|
|
150
|
+
user = getattr(request, 'user', None)
|
|
151
|
+
|
|
152
|
+
if not user or not user.has_module_permission(app_label):
|
|
153
|
+
return await self._show_permission_denied(
|
|
154
|
+
request,
|
|
155
|
+
f"No permissions for module: {app_label}"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
return await func(self, request, *args, **kwargs)
|
|
159
|
+
|
|
160
|
+
return wrapper
|
|
161
|
+
|
|
162
|
+
return decorator
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class PermissionChecker:
|
|
166
|
+
"""Helper class for checking permissions in templates and views"""
|
|
167
|
+
|
|
168
|
+
def __init__(self, user):
|
|
169
|
+
self.user = user
|
|
170
|
+
|
|
171
|
+
def has_perm(self, permission: str) -> bool:
|
|
172
|
+
"""Check if user has permission"""
|
|
173
|
+
if not self.user:
|
|
174
|
+
return False
|
|
175
|
+
return self.user.has_permission(permission)
|
|
176
|
+
|
|
177
|
+
def has_perms(self, permissions: list, require_all: bool = True) -> bool:
|
|
178
|
+
"""Check if user has multiple permissions"""
|
|
179
|
+
if not self.user:
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
if require_all:
|
|
183
|
+
return all(self.user.has_permission(p) for p in permissions)
|
|
184
|
+
else:
|
|
185
|
+
return any(self.user.has_permission(p) for p in permissions)
|
|
186
|
+
|
|
187
|
+
def has_module_perms(self, app_label: str) -> bool:
|
|
188
|
+
"""Check if user has any permission for module"""
|
|
189
|
+
if not self.user:
|
|
190
|
+
return False
|
|
191
|
+
return self.user.has_module_permission(app_label)
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def is_staff(self) -> bool:
|
|
195
|
+
"""Check if user is staff"""
|
|
196
|
+
return self.user and self.user.is_staff
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def is_superuser(self) -> bool:
|
|
200
|
+
"""Check if user is superuser"""
|
|
201
|
+
return self.user and self.user.is_superuser
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def is_authenticated(self) -> bool:
|
|
205
|
+
"""Check if user is authenticated"""
|
|
206
|
+
return self.user and self.user.is_authenticated
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def get_model_permissions(model_class) -> list:
|
|
210
|
+
"""
|
|
211
|
+
Get default permissions for a model
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
List of permission codenames
|
|
215
|
+
"""
|
|
216
|
+
model_name = model_class.__name__.lower()
|
|
217
|
+
return [
|
|
218
|
+
f"add_{model_name}",
|
|
219
|
+
f"change_{model_name}",
|
|
220
|
+
f"delete_{model_name}",
|
|
221
|
+
f"view_{model_name}",
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def create_model_permissions(model_class, content_type: str):
|
|
226
|
+
"""
|
|
227
|
+
Create Permission objects for a model
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
model_class: SQLAlchemy model class
|
|
231
|
+
content_type: Content type string (e.g., "auth")
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
List of Permission instances
|
|
235
|
+
"""
|
|
236
|
+
from createsonline.auth.models import Permission
|
|
237
|
+
|
|
238
|
+
model_name = model_class.__name__.lower()
|
|
239
|
+
verbose_name = model_class.__name__.replace('_', ' ').title()
|
|
240
|
+
|
|
241
|
+
permissions = [
|
|
242
|
+
Permission(
|
|
243
|
+
name=f"Can add {verbose_name}",
|
|
244
|
+
codename=f"add_{model_name}",
|
|
245
|
+
content_type=content_type
|
|
246
|
+
),
|
|
247
|
+
Permission(
|
|
248
|
+
name=f"Can change {verbose_name}",
|
|
249
|
+
codename=f"change_{model_name}",
|
|
250
|
+
content_type=content_type
|
|
251
|
+
),
|
|
252
|
+
Permission(
|
|
253
|
+
name=f"Can delete {verbose_name}",
|
|
254
|
+
codename=f"delete_{model_name}",
|
|
255
|
+
content_type=content_type
|
|
256
|
+
),
|
|
257
|
+
Permission(
|
|
258
|
+
name=f"Can view {verbose_name}",
|
|
259
|
+
codename=f"view_{model_name}",
|
|
260
|
+
content_type=content_type
|
|
261
|
+
),
|
|
262
|
+
]
|
|
263
|
+
|
|
264
|
+
return permissions
|