micro-users 1.0.4__py3-none-any.whl → 1.1.1__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.
Potentially problematic release.
This version of micro-users might be problematic. Click here for more details.
- {micro_users-1.0.4.dist-info → micro_users-1.1.1.dist-info}/METADATA +6 -5
- {micro_users-1.0.4.dist-info → micro_users-1.1.1.dist-info}/RECORD +7 -8
- users/forms.py +19 -44
- users/templates/users/user_actions.html +3 -3
- users/static/css/login.css +0 -134
- {micro_users-1.0.4.dist-info → micro_users-1.1.1.dist-info}/LICENSE +0 -0
- {micro_users-1.0.4.dist-info → micro_users-1.1.1.dist-info}/WHEEL +0 -0
- {micro_users-1.0.4.dist-info → micro_users-1.1.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: micro-users
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Arabic Django user management app with abstract user, permissions, and activity logging
|
|
5
5
|
Home-page: https://github.com/debeski/micro-users
|
|
6
6
|
Author: DeBeski
|
|
@@ -15,6 +15,8 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
19
21
|
Classifier: Operating System :: OS Independent
|
|
20
22
|
Requires-Python: >=3.9
|
|
@@ -36,7 +38,7 @@ Requires-Dist: babel (>=2.1)
|
|
|
36
38
|
|
|
37
39
|
## Requirements
|
|
38
40
|
- **Must be installed on a fresh database.**
|
|
39
|
-
- Python 3.
|
|
41
|
+
- Python 3.11+
|
|
40
42
|
- Django 5.1+
|
|
41
43
|
- django-crispy-forms 2.4+
|
|
42
44
|
- django-tables2 2.7+
|
|
@@ -48,7 +50,7 @@ Requires-Dist: babel (>=2.1)
|
|
|
48
50
|
## Features
|
|
49
51
|
- Custom AbstractUser model
|
|
50
52
|
- User permissions system
|
|
51
|
-
- Activity logging (login/logout tracking)
|
|
53
|
+
- Activity logging (login/logout, CRUD tracking)
|
|
52
54
|
- Localization support
|
|
53
55
|
- Admin interface integration
|
|
54
56
|
- CRUD views and templates
|
|
@@ -87,9 +89,8 @@ urlpatterns = [
|
|
|
87
89
|
]
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
4.
|
|
92
|
+
4. Run migrations:
|
|
91
93
|
```bash
|
|
92
|
-
python manage.py makemigrations users
|
|
93
94
|
python manage.py migrate users
|
|
94
95
|
```
|
|
95
96
|
|
|
@@ -2,7 +2,7 @@ users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
2
2
|
users/admin.py,sha256=VF0V6hQ9Obcdinnjb8nBHaknas2p3O5w-6yAJ-DeARQ,636
|
|
3
3
|
users/apps.py,sha256=Xb1nGvCl08KaUVqcUG82-jYdG6-KTVjaw_lgr5GIuYY,1133
|
|
4
4
|
users/filters.py,sha256=9-yrWBF-CdWb1nrAhmifWb1AHI0z4LQma1uR_9jLr2U,4797
|
|
5
|
-
users/forms.py,sha256=
|
|
5
|
+
users/forms.py,sha256=GHC8pFm2i9PD3MVaakrgMXEszsBrXieHq7DYiAfo8Fw,14977
|
|
6
6
|
users/models.py,sha256=KX_6LoiNJN6PCTFOuuGp5so4CNn5pAh1Vpaigv4fKk4,2060
|
|
7
7
|
users/signals.py,sha256=5Kd3KyfPT6740rvwZj4vy1yXsmjVhmaQ__RB8p5R5aE,1336
|
|
8
8
|
users/tables.py,sha256=JS3fvZvwzcNPGAH1LfCCUNnuQXgauDnB--rFt4okC0I,1717
|
|
@@ -10,16 +10,15 @@ users/urls.py,sha256=gmk_ZkSg9Bj-fUpIRACL_X7MEADTgZ7uvmbvXoAo5fo,956
|
|
|
10
10
|
users/views.py,sha256=yfzWkIDha66YK-Rgz7GH7MhQsupSCojf59C7fBqkppI,7209
|
|
11
11
|
users/migrations/0001_initial.py,sha256=lx9sSKS-lxHhI6gelVH52NOkwqEMJ32TvOJUn9zaOXM,4709
|
|
12
12
|
users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
users/static/css/login.css,sha256=SiJ6jBbWQAP2Nxt7DOTZbTcFYP9JEp557AuQZ9Eirb0,2120
|
|
14
13
|
users/templates/user_activity_log.html,sha256=S_FDN6vVLz_mB826yjeU9vtVGtzk7E_LKBmQIeYtdkQ,611
|
|
15
14
|
users/templates/registration/login.html,sha256=owbzO_XjqMeSncwWxkTzsvbkhjEZd7LdbblC3HBnld0,4091
|
|
16
15
|
users/templates/users/manage_users.html,sha256=jaYxUGRPyqx8tj9M6aApUZOgmgAIQekFtaL5j1mRPRQ,2951
|
|
17
16
|
users/templates/users/profile.html,sha256=9ahVF6YZUR-6-c8SKc0rN2pVdis2lI9gbcOQZeMaFnY,2909
|
|
18
17
|
users/templates/users/profile_edit.html,sha256=sgO3h9ffVK1vnDNl4E6l5x3xfam3FTQl6Lqkrw5gmlw,4215
|
|
19
|
-
users/templates/users/user_actions.html,sha256=
|
|
18
|
+
users/templates/users/user_actions.html,sha256=kuNMZBK9qwrLDU6hhp836Ru_yGVOr-uAeoJBJsZtzP8,1386
|
|
20
19
|
users/templates/users/user_form.html,sha256=jcyI7OQZOY4ue4DajPtfjAt2SmAYO5ZgHNOqTp2-FO0,1352
|
|
21
|
-
micro_users-1.
|
|
22
|
-
micro_users-1.
|
|
23
|
-
micro_users-1.
|
|
24
|
-
micro_users-1.
|
|
25
|
-
micro_users-1.
|
|
20
|
+
micro_users-1.1.1.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
|
|
21
|
+
micro_users-1.1.1.dist-info/METADATA,sha256=sXwfJIZTPf798hq2QIih9Z33O_1jwySSksk1AaPXhrY,2807
|
|
22
|
+
micro_users-1.1.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
23
|
+
micro_users-1.1.1.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
|
|
24
|
+
micro_users-1.1.1.dist-info/RECORD,,
|
users/forms.py
CHANGED
|
@@ -10,6 +10,7 @@ from crispy_forms.bootstrap import FormActions
|
|
|
10
10
|
from PIL import Image
|
|
11
11
|
from django.core.exceptions import ValidationError
|
|
12
12
|
from django.utils.translation import gettext_lazy as _
|
|
13
|
+
from django.db.models import Q
|
|
13
14
|
|
|
14
15
|
User = get_user_model()
|
|
15
16
|
|
|
@@ -48,28 +49,15 @@ class CustomUserCreationForm(UserCreationForm):
|
|
|
48
49
|
|
|
49
50
|
# Split permissions queryset into two parts for 2 columns
|
|
50
51
|
permissions_list = list(Permissions.objects.exclude(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
|
|
60
|
-
'add_minister', 'delete_minister', 'view_minister',
|
|
61
|
-
'add_decreecategory', 'delete_decreecategory', 'view_decreecategory',
|
|
62
|
-
'add_periodictask', 'change_periodictask', 'delete_periodictask', 'view_periodictask',
|
|
63
|
-
'add_periodictasks', 'change_periodictasks', 'delete_periodictasks', 'view_periodictasks',
|
|
64
|
-
'add_clockedschedule', 'change_clockedschedule', 'delete_clockedschedule', 'view_clockedschedule',
|
|
65
|
-
'add_crontabschedule', 'change_crontabschedule', 'delete_crontabschedule', 'view_crontabschedule',
|
|
66
|
-
'add_intervalschedule', 'change_intervalschedule', 'delete_intervalschedule', 'view_intervalschedule',
|
|
67
|
-
'add_solarschedule', 'change_solarschedule', 'delete_solarschedule', 'view_solarschedule',
|
|
68
|
-
'add_customuser', 'change_customuser', 'delete_customuser', 'view_customuser',
|
|
69
|
-
'add_useractivitylog', 'change_useractivitylog', 'delete_useractivitylog', 'view_useractivitylog',
|
|
70
|
-
'download_doc', 'gen_pub_pdf', 'download_doc', 'delete_decree', 'delete_publication', 'delete_objection',
|
|
71
|
-
'delete_formplus', 'view_decree', 'view_formplus', 'gen_pub_pdf', 'view_publication',
|
|
72
|
-
]
|
|
52
|
+
Q(codename__regex=r'^(delete_)') |
|
|
53
|
+
Q(content_type__app_label__in=[
|
|
54
|
+
'admin',
|
|
55
|
+
'auth',
|
|
56
|
+
'contenttypes',
|
|
57
|
+
'sessions',
|
|
58
|
+
'django_celery_beat',
|
|
59
|
+
'users'
|
|
60
|
+
])
|
|
73
61
|
))
|
|
74
62
|
mid_point = len(permissions_list) // 2
|
|
75
63
|
permissions_right = permissions_list[:mid_point]
|
|
@@ -176,28 +164,15 @@ class CustomUserChangeForm(UserChangeForm):
|
|
|
176
164
|
|
|
177
165
|
# Split permissions queryset into two parts for 2 columns
|
|
178
166
|
permissions_list = list(Permissions.objects.exclude(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
'
|
|
182
|
-
'
|
|
183
|
-
'
|
|
184
|
-
'
|
|
185
|
-
'
|
|
186
|
-
'
|
|
187
|
-
|
|
188
|
-
'add_minister', 'delete_minister', 'view_minister',
|
|
189
|
-
'add_decreecategory', 'delete_decreecategory', 'view_decreecategory',
|
|
190
|
-
'add_periodictask', 'change_periodictask', 'delete_periodictask', 'view_periodictask',
|
|
191
|
-
'add_periodictasks', 'change_periodictasks', 'delete_periodictasks', 'view_periodictasks',
|
|
192
|
-
'add_clockedschedule', 'change_clockedschedule', 'delete_clockedschedule', 'view_clockedschedule',
|
|
193
|
-
'add_crontabschedule', 'change_crontabschedule', 'delete_crontabschedule', 'view_crontabschedule',
|
|
194
|
-
'add_intervalschedule', 'change_intervalschedule', 'delete_intervalschedule', 'view_intervalschedule',
|
|
195
|
-
'add_solarschedule', 'change_solarschedule', 'delete_solarschedule', 'view_solarschedule',
|
|
196
|
-
'add_customuser', 'change_customuser', 'delete_customuser', 'view_customuser',
|
|
197
|
-
'add_useractivitylog', 'change_useractivitylog', 'delete_useractivitylog', 'view_useractivitylog',
|
|
198
|
-
'download_doc', 'gen_pub_pdf', 'download_doc', 'delete_decree', 'delete_publication', 'delete_objection',
|
|
199
|
-
'delete_formplus', 'view_decree', 'view_formplus', 'gen_pub_pdf', 'view_publication',
|
|
200
|
-
]
|
|
167
|
+
Q(codename__regex=r'^(delete_)') |
|
|
168
|
+
Q(content_type__app_label__in=[
|
|
169
|
+
'admin',
|
|
170
|
+
'auth',
|
|
171
|
+
'contenttypes',
|
|
172
|
+
'sessions',
|
|
173
|
+
'django_celery_beat',
|
|
174
|
+
'users'
|
|
175
|
+
])
|
|
201
176
|
))
|
|
202
177
|
mid_point = len(permissions_list) // 2
|
|
203
178
|
self.permissions_right = permissions_list[:mid_point]
|
|
@@ -9,20 +9,20 @@
|
|
|
9
9
|
<i class="bi bi-person-lines-fill text-dark me-1 h5"> </i> عرض
|
|
10
10
|
</a>
|
|
11
11
|
</li> {% endcomment %}
|
|
12
|
+
{% if not record.is_superuser %}
|
|
12
13
|
<li>
|
|
13
14
|
<a class="dropdown-item" href="{% url 'edit_user' record.id %}" title="تعديل">
|
|
14
15
|
<i class="bi bi-person-dash-fill text-dark me-1 h5"> </i> تعديل
|
|
15
16
|
</a>
|
|
16
17
|
</li>
|
|
17
|
-
{%
|
|
18
|
-
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% if user.is_superuser and not record.is_staff %}
|
|
19
20
|
<li>
|
|
20
21
|
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#deleteModal"
|
|
21
22
|
data-user-id="{{ record.id }}" data-user-name="{{ record.username }}">
|
|
22
23
|
<i class="bi bi-x-octagon text-danger me-1 h5"> </i> حذف
|
|
23
24
|
</a>
|
|
24
25
|
</li>
|
|
25
|
-
{% endif %}
|
|
26
26
|
{% endif %}
|
|
27
27
|
</ul>
|
|
28
28
|
</div>
|
users/static/css/login.css
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
::selection {
|
|
2
|
-
background: #d4c591;
|
|
3
|
-
}
|
|
4
|
-
::-webkit-selection {
|
|
5
|
-
background: #d4c591;
|
|
6
|
-
}
|
|
7
|
-
::-moz-selection {
|
|
8
|
-
background: #c9aa5e;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.page {
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
height: calc(100% - 15vh);
|
|
15
|
-
position: absolute;
|
|
16
|
-
place-content: center;
|
|
17
|
-
width: calc(100% - 40px);
|
|
18
|
-
}
|
|
19
|
-
@media (max-width: 767px) {
|
|
20
|
-
.page {
|
|
21
|
-
height: auto;
|
|
22
|
-
margin-bottom: 20px;
|
|
23
|
-
padding-bottom: 20px;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
.container {
|
|
27
|
-
height: 320px;
|
|
28
|
-
margin: 0 auto;
|
|
29
|
-
width: 640px;
|
|
30
|
-
}
|
|
31
|
-
@media (max-width: 767px) {
|
|
32
|
-
.container {
|
|
33
|
-
flex-direction: column;
|
|
34
|
-
height: 630px;
|
|
35
|
-
width: 320px;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
.left {
|
|
39
|
-
background: white;
|
|
40
|
-
height: calc(100% - 40px);
|
|
41
|
-
top: 20px;
|
|
42
|
-
position: relative;
|
|
43
|
-
width: 60%;
|
|
44
|
-
box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.03);
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
@media (max-width: 767px) {
|
|
48
|
-
.left {
|
|
49
|
-
height: 100%;
|
|
50
|
-
left: 5%;
|
|
51
|
-
width: 110%;
|
|
52
|
-
max-height: 270px;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/* .login {
|
|
56
|
-
font-size: 38px;
|
|
57
|
-
font-weight: 600;
|
|
58
|
-
}
|
|
59
|
-
.eula {
|
|
60
|
-
color: #adadad;
|
|
61
|
-
font-size: 14px;
|
|
62
|
-
line-height: 1.5;
|
|
63
|
-
margin: 40px;
|
|
64
|
-
} */
|
|
65
|
-
.right {
|
|
66
|
-
background: #cb9447;
|
|
67
|
-
box-shadow: 0px 0px 20px 8px rgba(0,0,0,0.07);
|
|
68
|
-
color: #F1F1F2;
|
|
69
|
-
position: relative;
|
|
70
|
-
width: 58%;
|
|
71
|
-
}
|
|
72
|
-
@media (max-width: 767px) {
|
|
73
|
-
.right {
|
|
74
|
-
flex-shrink: 0;
|
|
75
|
-
height: 100%;
|
|
76
|
-
width: 100%;
|
|
77
|
-
max-height: 350px;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
svg {
|
|
81
|
-
position: absolute;
|
|
82
|
-
width: 320px;
|
|
83
|
-
}
|
|
84
|
-
path {
|
|
85
|
-
fill: none;
|
|
86
|
-
stroke: url(#linearGradient);;
|
|
87
|
-
stroke-width: 3;
|
|
88
|
-
stroke-dasharray: 240 1386;
|
|
89
|
-
}
|
|
90
|
-
.form {
|
|
91
|
-
margin: 35px 35px 35px 20px;
|
|
92
|
-
position: absolute;
|
|
93
|
-
}
|
|
94
|
-
label {
|
|
95
|
-
color: #c2c2c5;
|
|
96
|
-
display: block;
|
|
97
|
-
font-size: 14px;
|
|
98
|
-
height: 16px;
|
|
99
|
-
margin-top: 20px;
|
|
100
|
-
margin-bottom: 5px;
|
|
101
|
-
}
|
|
102
|
-
input {
|
|
103
|
-
background: transparent;
|
|
104
|
-
border: 0;
|
|
105
|
-
color: #2d0202;
|
|
106
|
-
font-size: 20px;
|
|
107
|
-
height: 30px;
|
|
108
|
-
line-height: 30px;
|
|
109
|
-
outline: none !important;
|
|
110
|
-
width: 100%;
|
|
111
|
-
margin-top: 30px;
|
|
112
|
-
margin-bottom: 10px;
|
|
113
|
-
}
|
|
114
|
-
input::-moz-focus-inner {
|
|
115
|
-
border: 0;
|
|
116
|
-
}
|
|
117
|
-
#submit {
|
|
118
|
-
color: #707075;
|
|
119
|
-
margin-top: 40px;
|
|
120
|
-
transition: color 300ms;
|
|
121
|
-
}
|
|
122
|
-
#submit:focus {
|
|
123
|
-
color: #575757;
|
|
124
|
-
}
|
|
125
|
-
#submit:active {
|
|
126
|
-
color: #4d4d4d;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.titlebar {
|
|
130
|
-
background-color: var(--title);
|
|
131
|
-
flex-direction: row;
|
|
132
|
-
height: 7vh;
|
|
133
|
-
justify-content: center !important
|
|
134
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|