newnm.html 17.3 KB
Newer Older
Enrico Zini's avatar
Enrico Zini committed
1
{% extends "nm2-base.html" %}
2
{% load static %}
3
{% load nm %}
4
{% load i18n %}
5

6
7
8
9
10
11
12
13
14
15
16
{% block head %}
{{block.super}}
<style type="text/css">
table.tableform, table.tableform tbody, table.tableform tr, table.tableform th, table.tableform td {
  border: none;
  background-image: none;
}
table.tableform th {
  font-weight: normal;
  text-align: right;
}
Enrico Zini's avatar
Enrico Zini committed
17
18
19
.errorlist {
  color: red;
}
20
21
</style>
<script type="text/javascript">
Enrico Zini's avatar
Enrico Zini committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(function($) {
"use strict";

class FingerprintComments
{
    constructor(el)
    {
        this.element = el;
        this.reset();
    }

    reset()
    {
        $(this.element).empty();
        this.has_errors = false;
    }

    add_error(tag)
    {
        this.has_errors = true;
        let li = $("<li>").text(tag);
        $(this.element).append(li);
    }

    add_uid_stats(uid)
    {
        let msg = "Signatures: " + uid.sigs_ok.length + " good from Debian Developers, "
                     + uid.sigs_bad + " bad from Debian Developers, ";
                     + uid.sigs_no_key + " from others (including self).";
        let p = $("<p>").text(msg);
        $(this.element).append(p);
        if (uid.sigs_ok.length)
        {
            var ul = $("<ul>").hide();
            for (const name of uid.sigs_ok)
                ul.append($("<li>").text(name));
            $(this.element).append(ul);
            p.css("cursor", "pointer");
            p.click(evt => { ul.toggle(); });
        }
    }

    commit()
    {
        if (!this.has_errors)
        {
            let li = $("<li>").text("Everything seems ok.");
            $(this.element).append(li);
        }
    }
}


class Fingerprint
{
    constructor(element)
78
    {
Enrico Zini's avatar
Enrico Zini committed
79
80
81
82
83
84
85
86
87
88
89
90
        this.element = $(element);
        this.el_check_button = $("#fpr_check");
        this.el_check_spinner = $("#{{form.person.fpr.id_for_label}}_spinner");
        this.el_comments = $("#fpr_comments");
        this.el_fpr_field = $("#{{form.person.fpr.id_for_label}}");
        this.el_keycheck = this.element.find(".fpr_keycheck");
        this._set_loading(false);

        this.el_check_button.click(evt => {
            evt.preventDefault();
            this.run_check();
        });
91
92
    }

Enrico Zini's avatar
Enrico Zini committed
93
    _set_loading(val)
94
    {
Enrico Zini's avatar
Enrico Zini committed
95
96
97
98
99
100
101
        this.el_check_button.toggle(!val);
        this.el_check_spinner.toggle(val);
    }

    read_fpr() {
        let fpr = this.el_fpr_field.val();
        return fpr.replace(/\s+/g, "");
102
    }
Enrico Zini's avatar
Enrico Zini committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

    run_check() {
        var fpr = this.read_fpr();
        this._set_loading(true);
        $.ajax({
            url: "{% url 'keyring_keycheck' fpr='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' %}".replace(
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", fpr),
            method: "GET",
            success: data => {
                this._set_loading(false);
                this.render_result(data);
            },
            error: (xhr, status, error) => {
                this._set_loading(false);
                this.render_error(xhr, status, error);
            },
        });
    }

    _add_keycheck_title(msg)
123
    {
Enrico Zini's avatar
Enrico Zini committed
124
125
        let el = $("<h4>").text(msg);
        this.el_keycheck.append(el);
126
    }
Enrico Zini's avatar
Enrico Zini committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

    render_result(data)
    {
        this.el_keycheck.empty();

        // Render key comments
        this._add_keycheck_title("General key comments");
        let ul = document.createElement("ul");
        this.el_keycheck.append(ul);
        let key_comments = new FingerprintComments(ul);
        for (const tag of data.errors)
            key_comments.add_error(tag);
        key_comments.commit();

        // Render UID comments
        let valid_uids = [];
        for (const uid of data.uids)
        {
            this._add_keycheck_title("UID " + uid.name);
            let ul = document.createElement("ul");
            this.el_keycheck.append(ul);
            var uid_comments = new FingerprintComments(ul);
            uid_comments.add_uid_stats(uid);
            for (const tag of uid.errors)
                uid_comments.add_error(tag);

            // Take note of UIDs that look legit to use later for auto-filling the
            // form
            if (uid.sigs_ok.length > 0 && $.inArray("skip", uid.errors) == -1)
                valid_uids.push(uid.name);
        }

        autofill_from_uids(valid_uids);
    }

    render_error(xhr, status, error)
    {
        this.el_keycheck.empty();
        this._add_keycheck_title("Key download failed");
        var msg = xhr.responseText;
        var ul = $("<ul class='errorlist'>")
        if (msg[0] == "{")
        {
            msg = $.parseJSON(msg);
            var pre = $("<pre class='errorlist'>").text(msg.error);
            ul.append($("<li>").append(pre));
        } else if (xhr.status == 404) {
            ul.append($("<li>").text("invalid fingerprint"));
        } else {
            ul.append($("<li>").text(xhr.responseText));
        }
        this.el_keycheck.append(ul);
    }
}
181
182
183
184
185

// Parse a uid of the form 'Real Name <email@example.com>' into email
// and realname parts.
function parse_uid(uid)
{
Enrico Zini's avatar
Enrico Zini committed
186
187
188
189
190
191
192
193
    uid = $.trim(uid);
    var re_uid = /^(?:(.+?)\s*)?(?:\(([^)]+)\)\s*)?(?:<([^>]+)>)?$/;
    var matches = re_uid.exec(uid);
    return {
      name: matches[1],
      comment: matches[2],
      email: matches[3],
    }
194
195
196
197
}

function autofill_from_uids(uids)
{
Enrico Zini's avatar
Enrico Zini committed
198
199
200
    // Harvest first, middle, last names; email; uid
    let cn, mn, sn, email, uid;
    for (const uid of uids)
201
    {
Enrico Zini's avatar
Enrico Zini committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
        const info = parse_uid(uid);

        // Infer cn, mn, sn with some crude heuristics
        if (info.name && !cn)
        {
            var names = info.name.split(/\s+/);
            if (names.length == 1)
            {
              cn = names[0];
            }
            else if (names.length == 3)
            {
              cn = names[0];
              mn = names[1];
              sn = names[2];
            }
            else
            {
              cn = names.slice(0, names.length/2).join(" ");
              sn = names.slice(names.length/2).join(" ");
            }
        }

        if (info.email && !email)
        {
            email = info.email;
        }
229
230
    }

Enrico Zini's avatar
Enrico Zini committed
231
232
233
234
235
236
    if (email)
        uid = email.replace(/@.+$/, "");
    else if (cn)
        uid = cn.split(" ")[0].toLowerCase();

    function set_if_empty(id, val)
237
    {
Enrico Zini's avatar
Enrico Zini committed
238
239
240
241
        if (!val) return;
        let el = $("#" + id);
        if (!el.val())
            el.val(val);
242
    }
Enrico Zini's avatar
Enrico Zini committed
243
244
245
246
247
    set_if_empty("{{form.ldap_fields.cn.id_for_label}}", cn);
    set_if_empty("{{form.ldap_fields.mn.id_for_label}}", mn);
    set_if_empty("{{form.ldap_fields.sn.id_for_label}}", sn);
    set_if_empty("{{form.person.email.id_for_label}}", email);
    set_if_empty("{{form.ldap_fields.uid.id_for_label}}", uid);
248
249
250
251
}

function main()
{
Enrico Zini's avatar
Enrico Zini committed
252
    new Fingerprint(document.getElementById("np_fpr"));
253
}
254
255

document.addEventListener("DOMContentLoaded", evt => { main(); });
Enrico Zini's avatar
Enrico Zini committed
256
257

})(jQuery);
258
259
260
</script>
{% endblock %}

261
262
{% block content %}

263
<h1>{% trans "Debian New Member - Join the NM process" %}</h1>
264

Enrico Zini's avatar
Enrico Zini committed
265
{% if errors %}
266
<div class="warning">
267
268
    {% blocktrans count num=errors|length %}There is an issue in your submission:
    {% plural %}There are {{ num }} issues in your submission:{% endblocktrans %}
Enrico Zini's avatar
Enrico Zini committed
269
270
271
272
273
  <ul>
  {% for e in errors %}
  <li><a href="#np_{{e.section}}">{{e.label}}</a>: {{e.errors}}</li>
  {% endfor %}
  </ul>
274
275
  {% blocktrans %}Click on the label to jump to the relevant section. The
errors are also shown next to the fields in the form.{% endblocktrans %}
Enrico Zini's avatar
Enrico Zini committed
276
277
278
</div>
{% endif %}

Enrico Zini's avatar
Enrico Zini committed
279
{% if has_entry %}
280
<h2 id="hasentry">{% trans "You already have an entry in the system." %}</h2>
281

282
283
<p>{% blocktrans %}You already have an entry in the system if you are a DD, a
DM, have a guest account on Debian machines or have already applied on this page.{% endblocktrans %}</p>
284

Enrico Zini's avatar
Enrico Zini committed
285
{% if is_dd %}
286
<p><em>{% blocktrans with person_status=person|desc_status %}Not only do you already have an entry, but you are also
287
<i>{{person_status}}</i>.
Enrico Zini's avatar
Enrico Zini committed
288
289
290
291
The rest of this page does not apply to you, but you can still see it so that
you know how it looks like if you want to refer prospective new applicants to
this page.
{% endblocktrans %}</em></p>
292
293
{% endif %}

294
<p>{% blocktrans with person_url=person.get_absolute_url %}To request to become a Debian Maintainer or a Debian
295
Developer, to get a porter box guest account, and more, visit
296
<a href="{{person_url}}">your personal page</a> and follow the
297
"request new status" link.{% endblocktrans %}</p>
298
299
{% endif %}

Enrico Zini's avatar
Enrico Zini committed
300
{% if require_login %}
Enrico Zini's avatar
Enrico Zini committed
301

302
<h2>{% trans "Please login first" %}</h2>
Enrico Zini's avatar
Enrico Zini committed
303

Enrico Zini's avatar
Enrico Zini committed
304
<p>{% trans "You need to be logged in to join the New Member process." %}</p>
Enrico Zini's avatar
Enrico Zini committed
305

306
<p><a href="{% url 'signon:login' %}" class="btn btn-lg btn-primary"><span class="fa fa-sign-in"></span> {% trans "Login" %}</a></p>
307

Enrico Zini's avatar
Enrico Zini committed
308
309
310
{% endif %}

{% if show_apply_form %}
311

312
<h2>{% trans "Apply for an entry in the system" %}</h2>
313

314
<div class="important">
315
316
317
{% url 'public_findperson' as public_findperson_url %}
{% url 'dm_claim' as dm_claim_url %}
<p>{% blocktrans %}<strong>Debian Maintainers:</strong> if you are already a
Enrico Zini's avatar
Enrico Zini committed
318
319
320
Debian Maintainer you should already be known to this system, but the account
you used to log in might not be linked to your entry in the system.
Please first <a href="{{public_findperson_url}}">check if this is true</a> and if so,
321
<a href="{{dm_claim_url}}">claim your account</a>.{% endblocktrans %}</p>
322
</div>
323

324
325
326
327
<p>{% blocktrans %}With the form below you can apply to have an entry in the
system, so that people can advocate you to have some permission granted or
some new role in Debian. The form is quite long, so you may want to read it
all from top to bottom before starting to fill it in.{% endblocktrans %}</p>
328

329
330
<p>{% blocktrans %}Note that after you submit the form, you will have
{{DAYS_VALID}} days to visit a URL that you will receive encrypted in an email.
331
You may want to make sure that you can read encrypted email before spending time
332
on this form.{% endblocktrans %}</p>
333
334

<form action="{{request.build_absolute_uri}}" method="post">{% csrf_token %}
Enrico Zini's avatar
Enrico Zini committed
335
336
  {{ form.person.non_field_errors }}
  {{ form.ldap_fields.non_field_errors }}
337
338

  <div id="np_rules">
339
    <h3>{% trans "Ground Rules" %}</h3>
340
341
342
343
344
345
346
347

    <p>{% blocktrans %}First thing first, if you contribute to Debian,
everyone will assume that you have read the
<a href="http://www.debian.org/social_contract">Debian Social Contract</a> (SC)
and the <a href="http://www.debian.org/social_contract#guidelines">Debian Free
Software Guidelines</a> (DFSG) and agree with them. If you have not read them
yet, please take a moment to do so now.{% endblocktrans %}</p>
    <p>{% trans "Do you agree to uphold the Social Contract and the DFSG in your Debian work?" %}
Enrico Zini's avatar
Enrico Zini committed
348
    {% for r in form.person.sc_ok %} {{r}} {% endfor %}
349
    </p>
Enrico Zini's avatar
Enrico Zini committed
350
    {{form.person.sc_ok.errors}}
351

352
353
    <p>{% blocktrans %}If you contribute to Debian, you will also sooner or
later get access to Debian hardware or infrastructure. When that happens,
354
you will be required to comply with the
355
<a href="http://www.debian.org/devel/dmup">Debian Machine Usage Policies</a>
356
357
(DMUP).{% endblocktrans %}<p>
    <p>{% blocktrans %}Do you agree to follow the Debian Machine Usage
358
Policies (DMUP) when you use Debian resources?{% endblocktrans %}
Enrico Zini's avatar
Enrico Zini committed
359
    {% for r in form.person.dmup_ok %} {{r}} {% endfor %}
360
    </p>
Enrico Zini's avatar
Enrico Zini committed
361
    {{form.person.dmup_ok.errors}}
362
  </div>
Enrico Zini's avatar
Enrico Zini committed
363

364
  <div id="np_fpr">
365
    <h3>{% trans "OpenPGP Key" %}</h3>
366
367

    <p>{% blocktrans %}Most Debian work is not anonymous, and requires the
368
use of an <a
369
    href="https://www.gnupg.org/howtos/en/GPGMiniHowto.html">OpenPGP</a>
370
key. We require the key to be signed or endorsed by two (one for people applying to become
371
Debian Maintainer) or more Debian Developers to make reasonably sure that you
372
are who you claim to be. This is called the
373
<a href="http://www.w4kwh.org/privacy/keysign.html">"web of trust"</a>.{% endblocktrans %}</p>
Enrico Zini's avatar
Enrico Zini committed
374
    <p>{% blocktrans with form_fpr_label=form.person.fpr.label %}We also have some
375
requirements about the key itself: it needs to be version 4 or later, it must not
376
377
378
379
use DSA and it should be at least 4096 bits long (2048 bits are acceptable only
in exceptional circumstances). Please enter the fingerprint of your OpenPGP key
in the "{{form_fpr_label}}" field below, press "Check" and I will check it for
you now while you keep reading the page. For your convenience, I will also try
380
381
382
383
384
385
386
387
to autofill many fields in this page based on the first User ID in your key.
Keys are first searched in <code>hkps://keyring.debian.org</code>. If no key is found,
then the key will be imported from <code>hkps://keyserver.ubuntu.com/</code>. Please
ensure that you have sent your key to Ubuntu's key server. Sending public keys to
keyring.debian.org will only work if your key is already in Debian's keyring and will
only be taken into account after the Keyring Maintainers updated it. For Debian
Maintainers and Developers, please remember to send your key to both servers.
{% endblocktrans %}</p>
388
389
390
391
392
393
394
395
396
    <div class="form-row">
      <div class="form-group col-md-8">
        {{form.person.fpr.label_tag}}
        {{form.person.fpr}}
      </div>
      <div class="form-group col-md-4 mt-auto">
        <button class="btn btn-primary ml-2" id="fpr_check">{% trans "Check" %}</button>
      </div>
    </div>
397
    <img id="{{form.person.fpr.id_for_label}}_spinner" src="{% static "img/spinner.gif" %}"></img>
Enrico Zini's avatar
Enrico Zini committed
398
    {{form.person.fpr.errors}}
399
400
401
402
403
    <div class="fpr_keycheck">
    </div>
  </div>
 
  <div id="np_name">
404
405
    <h3>{% trans "Name" %}</h3>

406
407
408
409
410
411
412
413
    <p>{% trans "You can enter here your full name as it makes sense for you to write it:" %}</p>

    <div class="form-group">
      {{form.person.fullname.label_tag}}
      {{form.person.fullname}}
      {{form.person.fullname.errors}}
    </div>

414
415
416
417
418
419
    <p>{% blocktrans %}I need to collect data that may eventually feed the
Debian LDAP user directory, which follows
<a href="http://tools.ietf.org/html/rfc2798">RFC-2798</a>. It uses a
first/middle/last name model which
<a href="http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/">
does not fit many cultures well</a>; it is a known problem, but we will have
420
421
422
423
424
425
426
427
to make do for now. Please try to split your name into the fields below:{% endblocktrans %}</p>
    <div class="form-row">
      <div class="form-group col-md-4">
        {{form.ldap_fields.cn.label_tag}}
        {{form.ldap_fields.cn}}
        {{form.ldap_fields.cn.errors}}
      </div>
      <div class="form-group col-md-4">
428
        {{form.ldap_fields.mn.label_tag}} ({% trans "if any" %})
429
430
431
432
        {{form.ldap_fields.mn}}
        {{form.ldap_fields.mn.errors}}
      </div>
      <div class="form-group col-md-4">
433
        {{form.ldap_fields.sn.label_tag}} ({% trans "if any" %})
434
435
436
437
        {{form.ldap_fields.sn}}
        {{form.ldap_fields.sn.errors}}
      </div>
    </div>
438
  </div>
439

440
  <div id="np_email">
441
    <h3>{% trans "Email address" %}</h3>
Enrico Zini's avatar
Enrico Zini committed
442

443
444
445
    <p>{% blocktrans %}I need an email to contact you. If you will eventually
get an address @debian.org, it will initially forward to this email. You can
change this at any time later.{% endblocktrans %}</p>
446
    <div class="form-group">
Enrico Zini's avatar
Enrico Zini committed
447
448
    {{form.person.email.label_tag}} {{form.person.email}}
    {{form.person.email.errors}}
449
    </div>
450
  </div>
Enrico Zini's avatar
Enrico Zini committed
451

452
  <div id="np_uid">
453
454
455
456
457
458
459
460
461
    <h3>{% trans "User name" %}</h3>

{% url 'public_findperson' as public_findperson_url %}
    <p>{% blocktrans %}Please select a username. You will need this if you are
requesting a guest account on Debian machines, or if you are going to become a
Debian Developer. This is not needed for Debian Maintainers, but if you want,
you can reserve one now.{% endblocktrans %}</p>
    <p>{% blocktrans %}If you choose a username that is already in use, I will
let you know once you submit the form and you will be able to change it. In the
462
463
meantime, you can <a href="{{public_findperson_url}}">check
which usernames are already taken</a>.{% endblocktrans %}</p>
464
    <p>{% blocktrans %}Account names should have three or more letters, unless
465
466
you have a really good reason why it should be shorter. Debian Account Managers
at their discretion may refuse some usernames (like "root" or "enricoisasillyperson"),
467
and get in touch asking you to please choose another one.{% endblocktrans %}</p>
468
    <div class="form-group">
Enrico Zini's avatar
Enrico Zini committed
469
470
    {{form.ldap_fields.uid.label_tag}} {{form.ldap_fields.uid}}
    {{form.ldap_fields.uid.errors}}
471
    </div>
472
  </div>
Enrico Zini's avatar
Enrico Zini committed
473

474
  <div id="np_bio">
475
    <h3>{% trans "Short presentation" %}</h3>
Enrico Zini's avatar
Enrico Zini committed
476

477
478
479
480
    <p>{% blocktrans %}Finally, please tell something about yourself, how you
came to Debian and Free Software, and why you want to volunteer your time.
Please describe the contributions you have made to Debian, your primary areas
of interest and any goals you wish to accomplish.{% endblocktrans %}</p>
481

482
483
484
    <p>{% blocktrans %}The intention is to use this to introduce you publicly
to the rest of the project: it will be shown on your personal page on
nm.debian.org.{% endblocktrans %}</p>
485
    <div class="form-group">
Enrico Zini's avatar
Enrico Zini committed
486
487
    {{form.person.bio.label_tag}}<br>{{form.person.bio}}
    {{form.person.bio.errors}}
488
    </div>
489
490
491
  </div>
  
  <div id="np_submit">
492
    <h3>{% trans "Submit" %}</h3>
Enrico Zini's avatar
Enrico Zini committed
493

494
495
496
497
    <p>{% blocktrans %}You can now submit the form, and you will get an email
with a link to visit to confirm your data. The link will be encrypted with your
GPG key. Once you have confirmed, other Debian Developers can go to your
personal page and advocate you for what you require.{% endblocktrans %}</p>
498
499

    {% if has_entry %}
Enrico Zini's avatar
Enrico Zini committed
500
    <button type="submit" class="btn btn-primary" disabled="disabled">{% trans "Submit disabled because you already have an entry in the system." %}</button>
501
    {% else %}
Enrico Zini's avatar
Enrico Zini committed
502
    <button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
503
    {% endif %}
504
505
  </div>
</form>
Enrico Zini's avatar
Enrico Zini committed
506

507
508
{% endif %}

509
{% endblock %}