0002-manager-move-user-export-code-43153.patch
src/authentic2/manager/user_export.py | ||
---|---|---|
1 |
# authentic2 - versatile identity manager |
|
2 |
# Copyright (C) 2010-2021 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import collections |
|
18 |
import datetime |
|
19 | ||
20 |
import tablib |
|
21 |
from django.contrib.auth import get_user_model |
|
22 |
from django.contrib.contenttypes.models import ContentType |
|
23 | ||
24 |
from authentic2.manager.resources import UserResource |
|
25 |
from authentic2.models import Attribute, AttributeValue |
|
26 | ||
27 | ||
28 |
def get_user_dataset(qs): |
|
29 |
user_resource = UserResource() |
|
30 |
fields = user_resource._meta.export_order + ('email_verified', 'is_active', 'modified') |
|
31 |
attributes = [attr.name for attr in Attribute.objects.all()] |
|
32 |
headers = fields + tuple(['attribute_%s' % attr for attr in attributes]) |
|
33 | ||
34 |
at_mapping = {a.id: a for a in Attribute.objects.all()} |
|
35 |
avs = ( |
|
36 |
AttributeValue.objects.filter(content_type=ContentType.objects.get_for_model(get_user_model())) |
|
37 |
.filter(attribute__disabled=False) |
|
38 |
.values() |
|
39 |
) |
|
40 | ||
41 |
user_attrs = collections.defaultdict(dict) |
|
42 |
for av in avs: |
|
43 |
user_attrs[av['object_id']][at_mapping[av['attribute_id']].name] = av['content'] |
|
44 | ||
45 |
def iso(rec): |
|
46 |
if rec is None or rec == {}: |
|
47 |
return '' |
|
48 |
if hasattr(rec, 'strftime'): |
|
49 |
if isinstance(rec, datetime.datetime): |
|
50 |
_format = "%Y-%m-%d %H:%M:%S" |
|
51 |
else: |
|
52 |
_format = "%Y-%m-%d" |
|
53 |
return rec.strftime(_format) |
|
54 |
return rec |
|
55 | ||
56 |
def create_record(user): |
|
57 |
record = [] |
|
58 |
for field in fields: |
|
59 |
if field == 'roles': |
|
60 |
value = user_resource.dehydrate_roles(user) |
|
61 |
else: |
|
62 |
value = getattr(user, field) |
|
63 |
record.append(value) |
|
64 | ||
65 |
attr_d = user_attrs[user.pk] |
|
66 |
for attr in attributes: |
|
67 |
record.append(attr_d.get(attr)) |
|
68 | ||
69 |
return [iso(x) for x in record] |
|
70 | ||
71 |
dataset = tablib.Dataset(headers=headers) |
|
72 |
for user in qs: |
|
73 |
dataset.append(create_record(user)) |
|
74 |
return dataset |
src/authentic2/manager/user_views.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import base64 |
18 | 18 |
import collections |
19 |
import datetime |
|
20 | 19 |
import operator |
21 | 20 | |
22 |
import tablib |
|
23 | 21 |
from django.contrib import messages |
24 | 22 |
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model |
25 |
from django.contrib.contenttypes.models import ContentType |
|
26 | 23 |
from django.core.exceptions import PermissionDenied |
27 | 24 |
from django.core.mail import EmailMultiAlternatives |
28 | 25 |
from django.db import models, transaction |
... | ... | |
41 | 38 |
from authentic2 import hooks |
42 | 39 |
from authentic2.a2_rbac.utils import get_default_ou |
43 | 40 |
from authentic2.apps.journal.views import JournalViewWithContext |
44 |
from authentic2.models import Attribute, AttributeValue, PasswordReset
|
|
41 |
from authentic2.models import Attribute, PasswordReset |
|
45 | 42 |
from authentic2.utils import make_url, redirect, select_next_url, send_password_reset_mail, switch_user |
46 | 43 |
from authentic2_idp_oidc.models import OIDCAuthorization, OIDCClient |
47 | 44 |
from django_rbac.utils import get_ou_model, get_role_model, get_role_parenting_model |
... | ... | |
63 | 60 |
from .journal_views import BaseJournalView |
64 | 61 |
from .resources import UserResource |
65 | 62 |
from .tables import OuUserRolesTable, UserAuthorizationsTable, UserRolesTable, UserTable |
63 |
from .user_export import get_user_dataset |
|
66 | 64 |
from .utils import get_ou_count, has_show_username |
67 | 65 |
from .views import ( |
68 | 66 |
Action, |
... | ... | |
516 | 514 |
return self._dataset.export('csv') |
517 | 515 | |
518 | 516 |
def get_dataset(self): |
519 |
user_resource = UserResource() |
|
520 |
fields = user_resource._meta.export_order + ('email_verified', 'is_active', 'modified') |
|
521 |
attributes = [attr.name for attr in Attribute.objects.all()] |
|
522 |
headers = fields + tuple(['attribute_%s' % attr for attr in attributes]) |
|
523 | ||
524 |
at_mapping = {a.id: a for a in Attribute.objects.all()} |
|
525 |
avs = ( |
|
526 |
AttributeValue.objects.filter(content_type=ContentType.objects.get_for_model(get_user_model())) |
|
527 |
.filter(attribute__disabled=False) |
|
528 |
.values() |
|
529 |
) |
|
530 | ||
531 |
user_attrs = collections.defaultdict(dict) |
|
532 |
for av in avs: |
|
533 |
user_attrs[av['object_id']][at_mapping[av['attribute_id']].name] = av['content'] |
|
534 | ||
535 |
def iso(rec): |
|
536 |
if rec is None or rec == {}: |
|
537 |
return '' |
|
538 |
if hasattr(rec, 'strftime'): |
|
539 |
if isinstance(rec, datetime.datetime): |
|
540 |
_format = "%Y-%m-%d %H:%M:%S" |
|
541 |
else: |
|
542 |
_format = "%Y-%m-%d" |
|
543 |
return rec.strftime(_format) |
|
544 |
return rec |
|
545 | ||
546 |
def create_record(user): |
|
547 |
record = [] |
|
548 |
for field in fields: |
|
549 |
if field == 'roles': |
|
550 |
value = user_resource.dehydrate_roles(user) |
|
551 |
else: |
|
552 |
value = getattr(user, field) |
|
553 |
record.append(value) |
|
554 | ||
555 |
attr_d = user_attrs[user.pk] |
|
556 |
for attr in attributes: |
|
557 |
record.append(attr_d.get(attr)) |
|
558 | ||
559 |
return [iso(x) for x in record] |
|
560 | ||
561 |
self._dataset = tablib.Dataset(headers=headers) |
|
562 |
for user in self.get_data(): |
|
563 |
self._dataset.append(create_record(user)) |
|
517 |
self._dataset = get_user_dataset(self.get_data()) |
|
564 | 518 |
return self |
565 | 519 | |
566 | 520 | |
567 |
- |