Projet

Général

Profil

0001-manager-add-help-on-users-imports-34238.patch

Benjamin Dauvergne, 23 juin 2019 15:24

Télécharger (10,7 ko)

Voir les différences:

Subject: [PATCH] manager: add help on users imports (#34238)

 src/authentic2/attribute_kinds.py             |   1 +
 .../static/authentic2/manager/css/style.css   |   8 +
 .../authentic2/manager/user_imports.html      | 177 +++++++++++++++---
 src/authentic2/manager/user_views.py          |  30 +++
 4 files changed, 193 insertions(+), 23 deletions(-)
src/authentic2/attribute_kinds.py
244 244
        },
245 245
        'html_value': profile_image_html_value,
246 246
        'attributes_ng_serialize': profile_attributes_ng_serialize,
247
        'csv_importable': False,
247 248
    },
248 249
]
249 250

  
src/authentic2/manager/static/authentic2/manager/css/style.css
52 52
.email, #user-table .first_name, #user-table .last_name, #user-table .ou {
53 53
        text-align: left;
54 54
}
55
table.main.left {
56
	padding-left: 1rem;
57
}
58
table.main.left td,
59
table.main.left th {
60
	text-align: left;
61
}
62

  
55 63
table.feeds td.url {
56 64
	text-align: left;
57 65
	padding-left: 1em;
src/authentic2/manager/templates/authentic2/manager/user_imports.html
21 21
{% endblock %}
22 22

  
23 23
{% block content %}
24
  <h3>{% trans "Imports" %}</h3>
25
  <table class="main">
26
    <thead>
27
      <tr>
28
        <td>{% trans "Filename" %}</td>
29
        <td>{% trans "Creation date" %}</td>
30
        <td>{% trans "By" %}</td>
31
        <td>{% trans "Rows" %}</td>
32
        <td></td>
33
      </tr>
34
    </thead>
35
    <tbody>
36
      {% for import in imports %}
37
        <tr>
38
          <td><a href="{% url "a2-manager-users-import" uuid=import.uuid %}">{{ import.filename }}</a></td>
39
          <td>{{ import.created }}</td>
40
          <td>{{ import.user }}</td>
41
          <td>{{ import.rows_count }}</td>
42
          <td><form method="post">{% csrf_token %}<button name="delete" value="{{ import.uuid }}">{% trans "Delete" %}</button></form></td>
43
        </tr>
44
      {% endfor %}
45
    </tbody>
46
  </table>
24

  
25
  <div class="section">
26
    <h3>{% trans "Imports" %}</h3>
27
    <table class="main left">
28
      <thead>
29
        <tr>
30
          <th>{% trans "Filename" %}</th>
31
          <th>{% trans "Creation date" %}</th>
32
          <th>{% trans "By" %}</th>
33
          <th>{% trans "Rows" %}</th>
34
          <th></th>
35
        </tr>
36
      </thead>
37
      <tbody>
38
        {% for import in imports %}
39
          <tr>
40
            <td><a href="{% url "a2-manager-users-import" uuid=import.uuid %}">{{ import.filename }}</a></td>
41
            <td>{{ import.created }}</td>
42
            <td>{{ import.user }}</td>
43
            <td>{{ import.rows_count }}</td>
44
            <td><form method="post">{% csrf_token %}<button name="delete" value="{{ import.uuid }}">{% trans "Delete" %}</button></form></td>
45
          </tr>
46
        {% endfor %}
47
      </tbody>
48
    </table>
49
  </div>
50

  
51
  <div class="section">
52
    <h3>{% trans "Help" %}</h3>
53
    <p>
54
      {% blocktrans trimmed %}
55
        The first line of your CSV file must be a header <a href="#help-attributes">mapping columns to user's attributes identifier</a>.
56
        Each user attribute name can be followed by <a href="#help-flags">flags</a> separated by spaces.
57
        You can also import an <a href="#help-external-identifier">external identifier</a> to prevent creating duplicates when doing multiple import from the same source.
58
      {% endblocktrans %}
59
    </p>
60
    <h4 id="help-attributes">{% trans "Attributes" %}</h4>
61
    <table class="main left">
62
      <thead>
63
        <tr>
64
          <th>{% trans "Label" %}</th>
65
          <th>{% trans "Identifier" %}</th>
66
        </tr>
67
      </thead>
68
      <tbody>
69
        {% for column in help_columns %}
70
          <tr>
71
            <td>{{ column.label }}</td>
72
            <td><var>{{ column.name }}</var></td>
73
          </tr>
74
        {% endfor %}
75
      </tbody>
76
    </table>
77
    <h4 id="help-flags">{% trans "Flags" %}</h4>
78
    <p>{% blocktrans trimmed %}Each column can receive flags after its name, separated by spaces. Each modifier can be prefixed by <var>no-</var> to set its value to false.{% endblocktrans %}</p>
79
    <table class="main left">
80
      <thead>
81
        <tr>
82
          <th>{% trans "Flag" %}</th>
83
          <th>{% trans "Meaning" %}</th>
84
          <th>{% trans "Default value" %}</th>
85
        </tr>
86
      </thead>
87
      <tbody>
88
        <tr>
89
          <td>key</td>
90
          <td>
91
            {% blocktrans trimmed %}
92
            The column is an import key, it is used to match the row with an existing user. Only one column can be an import key.
93
            {% endblocktrans %}
94
          </td>
95
          <td>{% trans "False" %}</td>
96
        </tr>
97
        <tr>
98
          <td>create</td>
99
          <td>
100
            {% blocktrans trimmed %}
101
            Values will be used when creating a new user.
102
            {% endblocktrans %}
103
          </td>
104
          <td>{% trans "True" %}</td>
105
        </tr>
106
        <tr>
107
          <td>update</td>
108
          <td>
109
            {% blocktrans trimmed %}
110
            Values will be used when updating an existing user.
111
            {% endblocktrans %}
112
          </td>
113
          <td>{% trans "True" %}</td>
114
        </tr>
115
        <tr>
116
          <td>unique</td>
117
          <td>
118
            {% blocktrans trimmed %}
119
            Values must be unique in the target organizational unit.
120
            {% endblocktrans %}
121
          </td>
122
          <td>{% trans "False" %} {% blocktrans trimmed %}
123
            (default is True for the <var>email</var> and <var>username</var> columns if they are configured to be unique in the target organizational unit)
124
            {% endblocktrans %}
125
          </td>
126
        </tr>
127
        <tr>
128
          <td>globally-unique</td>
129
          <td>
130
            {% blocktrans trimmed %}
131
            Values must be unique among all users.
132
            {% endblocktrans %}
133
          </td>
134
          <td>{% trans "False" %} {% blocktrans trimmed %}
135
            (default is True for the <var>email</var> and <var>username</var> columns if they are configured to be globally unique)
136
            {% endblocktrans %}</td>
137
        </tr>
138
        <tr>
139
          <td>verified</td>
140
          <td>
141
            {% blocktrans trimmed %}
142
            Values are verified.
143
            {% endblocktrans %}
144
          </td>
145
          <td>{% trans "False" %} {% blocktrans %}(default is True for the <var>email</var> column){% endblocktrans %}</td>
146
        </tr>
147
      </tbody>
148
    </table>
149

  
150
    <h4 id="help-external-identifier">{% trans "External identifier" %}</h4>
151
    <p>
152
      {% blocktrans trimmed %}
153
        You can also use two special columns <var>_source_name</var> and
154
        <var>_source_id</var>. <var>_source_name</var> must be the name of the
155
        source directory from which the users are exported, it must not
156
        change between imports. <var>_source_id</var> is the unique identifier
157
        from the source directory from which the users are extracted, it must
158
        not change between imports and should never be reused for different
159
        users. <var>_source_id</var> is automatically the key column, and you
160
        cannot use another key column.
161
      {% endblocktrans %}
162
    </p>
163
    <h4>{% trans "Examples" %}</h4>
164
    <p>Importing verified first and last name of users keyed by email</p>
165
    <blockquote>
166
      <pre>email key,first_name verified,last_name verified
167
john.doe@example.com,John,Doe
168
</pre>
169
    </blockquote>
170
    <p>Importing email, family_reference, first and last name of users from application <var>app1</var>, ensuring family_reference is unique.</p>
171
    <blockquote>
172
      <pre>_source_name,_source_id,email,family_reference,first_name,last_name
173
app1,1,john.doe@example.com,1234,John,Doe
174
</pre>
175
    </blockquote>
176
  </div>
177

  
47 178
{% endblock %}
src/authentic2/manager/user_views.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import base64
17 18
import datetime
18 19
import collections
19 20
import operator
......
52 53
from .utils import get_ou_count, has_show_username
53 54
from . import app_settings
54 55

  
56
User = get_user_model()
57

  
55 58

  
56 59
class UsersView(HideOUColumnMixin, BaseTableView):
57 60
    template_name = 'authentic2/manager/users.html'
......
659 662

  
660 663
        ctx = super(UserImportsView, self).get_context_data(**kwargs)
661 664
        ctx['imports'] = sorted(user_import.UserImport.all(), key=operator.attrgetter('created'), reverse=True)
665
        help_columns = []
666
        field_columns = ['username', 'email', 'first_name', 'last_name']
667
        if not has_show_username:
668
            field_columns.remove('username')
669
        for field_column in field_columns:
670
            field = User._meta.get_field(field_column)
671
            help_columns.append({
672
                'label': field.verbose_name,
673
                'name': field.name
674
            })
675
        for attribute in Attribute.objects.all():
676
            kind = attribute.get_kind()
677
            if not kind.get('csv_importable', True):
678
                continue
679
            help_columns.append({
680
                'label': attribute.label,
681
                'name': attribute.name,
682
            })
683
        ctx['help_columns'] = help_columns
684
        example_data = u','.join(column['name'] for column in help_columns) + '\n'
685
        example_url = 'data:text/csv;base64,%s' % base64.b64encode(example_data.encode('utf-8'))
686
        ctx['form'].fields['import_file'].help_text = format_html(
687
            _('{0}. {1} <a download="{3}" href="{2}">{3}</a>'),
688
            ctx['form'].fields['import_file'].help_text,
689
            _('ex.:'),
690
            example_url,
691
            _('users.csv'))
662 692
        return ctx
663 693

  
664 694
user_imports = UserImportsView.as_view()
665
-