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 | ||
22 |
from django.contrib.auth import get_user_model |
|
23 |
from django.contrib.contenttypes.models import ContentType |
|
24 | ||
25 |
from authentic2.manager.resources import UserResource |
|
26 |
from authentic2.models import Attribute, AttributeValue |
|
27 | ||
28 | ||
29 |
def iso(rec): |
|
30 |
if rec is None or rec == {}: |
|
31 |
return '' |
|
32 |
if hasattr(rec, 'strftime'): |
|
33 |
if isinstance(rec, datetime.datetime): |
|
34 |
_format = "%Y-%m-%d %H:%M:%S" |
|
35 |
else: |
|
36 |
_format = "%Y-%m-%d" |
|
37 |
return rec.strftime(_format) |
|
38 |
return rec |
|
39 | ||
40 | ||
41 |
def get_user_attrs(): |
|
42 |
at_mapping = {a.id: a for a in Attribute.objects.all()} |
|
43 |
avs = AttributeValue.objects.filter( |
|
44 |
content_type=ContentType.objects.get_for_model(get_user_model()))\ |
|
45 |
.filter(attribute__disabled=False).values() |
|
46 | ||
47 |
user_attrs = collections.defaultdict(dict) |
|
48 |
for av in avs: |
|
49 |
user_attrs[av['object_id']][at_mapping[av['attribute_id']].name] = av['content'] |
|
50 | ||
51 |
return user_attrs |
|
52 | ||
53 | ||
54 |
def get_user_dataset(qs): |
|
55 |
user_resource = UserResource() |
|
56 |
fields = user_resource._meta.export_order + ('email_verified', 'is_active', 'modified') |
|
57 |
attributes = [attr.name for attr in Attribute.objects.all()] |
|
58 |
headers = fields + tuple(['attribute_%s' % attr for attr in attributes]) |
|
59 |
user_attrs = get_user_attrs() |
|
60 | ||
61 |
def create_record(user): |
|
62 |
record = [] |
|
63 |
for field in fields: |
|
64 |
if field == 'roles': |
|
65 |
value = user_resource.dehydrate_roles(user) |
|
66 |
else: |
|
67 |
value = getattr(user, field) |
|
68 |
record.append(value) |
|
69 | ||
70 |
attr_d = user_attrs[user.pk] |
|
71 |
for attr in attributes: |
|
72 |
record.append(attr_d.get(attr)) |
|
73 | ||
74 |
return [iso(x) for x in record] |
|
75 | ||
76 |
dataset = tablib.Dataset(headers=headers) |
|
77 |
for user in qs: |
|
78 |
dataset.append(create_record(user)) |
|
79 | ||
80 |
return dataset |
src/authentic2/manager/user_views.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import base64 |
18 |
import datetime |
|
19 | 18 |
import collections |
20 | 19 |
import operator |
21 | 20 | |
... | ... | |
28 | 27 |
from django.core.mail import EmailMultiAlternatives |
29 | 28 |
from django.template import loader |
30 | 29 |
from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME |
31 |
from django.contrib.contenttypes.models import ContentType |
|
32 | 30 |
from django.contrib import messages |
33 | 31 |
from django.views.generic import FormView, TemplateView, DetailView |
34 | 32 |
from django.views.generic.edit import BaseFormView |
... | ... | |
36 | 34 |
from django.http import Http404, FileResponse, HttpResponseRedirect |
37 | 35 |
from django.shortcuts import get_object_or_404 |
38 | 36 | |
39 |
import tablib |
|
40 | ||
41 |
from authentic2.models import Attribute, AttributeValue, PasswordReset |
|
37 |
from authentic2.models import Attribute, PasswordReset |
|
42 | 38 |
from authentic2.utils import send_password_reset_mail, redirect, select_next_url, make_url, switch_user |
43 | 39 |
from authentic2.a2_rbac.utils import get_default_ou |
44 | 40 |
from authentic2 import hooks |
... | ... | |
59 | 55 |
from .resources import UserResource |
60 | 56 |
from .utils import get_ou_count, has_show_username |
61 | 57 |
from .journal_views import BaseJournalView |
58 |
from .user_export import get_user_dataset |
|
62 | 59 |
from . import app_settings |
63 | 60 | |
64 | 61 |
User = get_user_model() |
... | ... | |
485 | 482 |
return self._dataset.export('csv') |
486 | 483 | |
487 | 484 |
def get_dataset(self): |
488 |
user_resource = UserResource() |
|
489 |
fields = user_resource._meta.export_order + ('email_verified', 'is_active', 'modified') |
|
490 |
attributes = [attr.name for attr in Attribute.objects.all()] |
|
491 |
headers = fields + tuple(['attribute_%s' % attr for attr in attributes]) |
|
492 | ||
493 |
at_mapping = {a.id: a for a in Attribute.objects.all()} |
|
494 |
avs = AttributeValue.objects.filter( |
|
495 |
content_type=ContentType.objects.get_for_model(get_user_model()))\ |
|
496 |
.filter(attribute__disabled=False).values() |
|
497 | ||
498 |
user_attrs = collections.defaultdict(dict) |
|
499 |
for av in avs: |
|
500 |
user_attrs[av['object_id']][at_mapping[av['attribute_id']].name] = av['content'] |
|
501 | ||
502 |
def iso(rec): |
|
503 |
if rec is None or rec == {}: |
|
504 |
return '' |
|
505 |
if hasattr(rec, 'strftime'): |
|
506 |
if isinstance(rec, datetime.datetime): |
|
507 |
_format = "%Y-%m-%d %H:%M:%S" |
|
508 |
else: |
|
509 |
_format = "%Y-%m-%d" |
|
510 |
return rec.strftime(_format) |
|
511 |
return rec |
|
512 | ||
513 |
def create_record(user): |
|
514 |
record = [] |
|
515 |
for field in fields: |
|
516 |
if field == 'roles': |
|
517 |
value = user_resource.dehydrate_roles(user) |
|
518 |
else: |
|
519 |
value = getattr(user, field) |
|
520 |
record.append(value) |
|
521 | ||
522 |
attr_d = user_attrs[user.pk] |
|
523 |
for attr in attributes: |
|
524 |
record.append(attr_d.get(attr)) |
|
525 | ||
526 |
return [iso(x) for x in record] |
|
527 | ||
528 |
self._dataset = tablib.Dataset(headers=headers) |
|
529 |
for user in self.get_data(): |
|
530 |
self._dataset.append(create_record(user)) |
|
485 |
self._dataset = get_user_dataset(self.get_data()) |
|
531 | 486 |
return self |
532 | 487 | |
533 | 488 | |
534 |
- |