diff --git a/avisstage/forms.py b/avisstage/forms.py
index 8af5c57..12e88ea 100644
--- a/avisstage/forms.py
+++ b/avisstage/forms.py
@@ -1,11 +1,14 @@
-# coding: utf-8
+import unicodedata
from django import forms
+from django.contrib.auth.forms import PasswordResetForm
from django.utils import timezone
+from simple_email_confirmation.models import EmailAddress
+
import re
-from .models import Normalien, Stage, Lieu, AvisLieu, AvisStage
+from .models import Normalien, Stage, Lieu, AvisLieu, AvisStage, User
from .widgets import LatLonField
# Sur-classe utile
@@ -107,3 +110,40 @@ class FeedbackForm(forms.Form):
objet = forms.CharField(label="Objet", required=True)
message = forms.CharField(label="Message", required=True, widget=forms.widgets.Textarea())
+# Nouvelle adresse mail
+class AdresseEmailForm(forms.Form):
+ def __init__(self, _user, **kwargs):
+ self._user = _user
+ super().__init__(**kwargs)
+ email = forms.EmailField(widget=forms.widgets.EmailInput(attrs={"placeholder": "Nouvelle adresse"}))
+
+ def clean_email(self):
+ email = self.cleaned_data["email"]
+ if EmailAddress.objects.filter(user=self._user, email=email).exists():
+ raise forms.ValidationError(
+ "Cette adresse est déjà associée à ce compte")
+ return email
+
+
+def _unicode_ci_compare(s1, s2):
+ """
+ Perform case-insensitive comparison of two identifiers, using the
+ recommended algorithm from Unicode Technical Report 36, section
+ 2.11.2(B)(2).
+ """
+ return unicodedata.normalize('NFKC', s1).casefold() == unicodedata.normalize('NFKC', s2).casefold()
+
+
+# (Ré)initialisation du mot de passe
+class ReinitMdpForm(PasswordResetForm):
+ def get_users(self, email):
+ """Override default method to allow unusable passwords"""
+ email_field_name = User.get_email_field_name()
+ active_users = User._default_manager.filter(**{
+ '%s__iexact' % email_field_name: email,
+ 'is_active': True,
+ })
+ return (
+ u for u in active_users
+ if _unicode_ci_compare(email, getattr(u, email_field_name))
+ )
diff --git a/avisstage/migrations/0004_allauth_to_authens.py b/avisstage/migrations/0004_allauth_to_authens.py
index 164e9ab..3998752 100644
--- a/avisstage/migrations/0004_allauth_to_authens.py
+++ b/avisstage/migrations/0004_allauth_to_authens.py
@@ -77,8 +77,14 @@ def forwards(apps, schema_editor):
if "@" not in user.username:
print(user.username)
continue
- entrance_year = "20" + saccount.extra_data.get(
+ entrance_year = saccount.extra_data.get(
"entrance_year", user.username.split("@")[1])
+ try:
+ entrance_year = 2000 + int(entrance_year)
+ except ValueError:
+ print(entrance_year)
+ continue
+
new_conns.append(CASAccount(user=user, cas_login=clipper,
entrance_year=int(entrance_year)))
diff --git a/avisstage/models.py b/avisstage/models.py
index 79f96f0..7588207 100644
--- a/avisstage/models.py
+++ b/avisstage/models.py
@@ -35,8 +35,9 @@ class Normalien(models.Model):
promotion = models.CharField(u"Promotion", max_length=40, blank=True)
mail = models.EmailField(u"Adresse e-mail permanente",
max_length=200, blank=True)
- contactez_moi = models.BooleanField(u"Inviter les visiteurs à me contacter",
- default=True)
+ contactez_moi = models.BooleanField(
+ u"Inviter les visiteurs à me contacter",
+ default=True, help_text="Affiche votre adresse e-mail principale sur votre profil public")
bio = models.TextField(u"À propos de moi", blank=True, default="")
en_scolarite = models.BooleanField(default=False, blank=True)
diff --git a/avisstage/sass/_responsive.scss b/avisstage/sass/_responsive.scss
index c37acef..fb1457c 100644
--- a/avisstage/sass/_responsive.scss
+++ b/avisstage/sass/_responsive.scss
@@ -177,14 +177,14 @@
display: block;
text-align: left;
font-size: 0.95em;
- color: $compl * 0.8;
+ color: darken($compl, 20%);
margin-top: 0;
width: auto;
}
.help_text {
text-align: right;
- color: $fond * 0.4;
+ color: darken($fond, 60%);
}
.input {
diff --git a/avisstage/sass/screen.scss b/avisstage/sass/screen.scss
index 9147b3a..8ee09e5 100644
--- a/avisstage/sass/screen.scss
+++ b/avisstage/sass/screen.scss
@@ -46,7 +46,7 @@ em, i {
a {
font-weight: bold;
- color: $compl * 0.9;
+ color: darken($compl, 10%);
text-decoration: none;
}
@@ -107,7 +107,7 @@ header {
color: lighten($fond, 40%);
&:hover {
- background: $barre * 0.6;
+ background: darken($barre, 40%);
}
}
}
@@ -181,7 +181,6 @@ p.warning {
li {
display: table;
width: 100%;
- //border: 1px solid $fond * 1.3;
background: #fff;
margin: 12px;
@@ -363,6 +362,57 @@ section.profil {
}
}
+section.two-cols {
+ display: flex;
+ display: flexbox;
+ align-items: center;
+ & > * {
+ flex: 1;
+ width: 50%;
+ margin: 10px;
+ }
+}
+
+ul.mes-emails {
+ li {
+ display: flex;
+ background: #fff;
+ margin: 5px;
+ padding: 10px;
+ min-height: 70px;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+
+ & > * {
+ flex: 1;
+ text-align: center;
+ }
+
+ .adresse {
+ text-align: left;
+ font-weight: bold;
+ }
+
+ .confirmee {
+ width: 20px;
+ }
+
+ .supprimer {
+ flex: 0.7;
+ }
+
+ form {
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ .field {
+ flex: 1;
+ }
+ }
+ }
+}
+
//
//
// Détail d'un stage
@@ -432,7 +482,7 @@ input[type="submit"], .btn {
font: $textfontsize $textfont;
background-color: $fond;
color: #fff;
- border: 1px solid $fond * 0.7;
+ border: 1px solid darken($fond, 30%);
border-radius: 5px;
padding: 8px 12px;
display: inline-block;
diff --git a/avisstage/static/css/screen.css b/avisstage/static/css/screen.css
index 0acc127..c1a8b02 100644
--- a/avisstage/static/css/screen.css
+++ b/avisstage/static/css/screen.css
@@ -1,5 +1,5 @@
@charset "UTF-8";
-/* line 5, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 5, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
@@ -21,45 +21,45 @@ time, mark, audio, video {
vertical-align: baseline;
}
-/* line 22, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 22, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html {
line-height: 1;
}
-/* line 24, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 24, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
-/* line 26, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 26, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
-/* line 28, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 28, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
-/* line 30, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 30, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
-/* line 103, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 103, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
-/* line 32, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 32, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
-/* line 116, ../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
+/* line 116, ../../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}
@@ -170,7 +170,7 @@ em, i {
/* line 47, ../../sass/screen.scss */
a {
font-weight: bold;
- color: #e08c1d;
+ color: #e08206;
text-decoration: none;
}
@@ -235,7 +235,7 @@ header nav ul li a {
}
/* line 109, ../../sass/screen.scss */
header nav ul li a:hover {
- background: #446219;
+ background: black;
}
/* line 117, ../../sass/screen.scss */
header a {
@@ -306,22 +306,22 @@ p.warning {
background: #fff;
margin: 12px;
}
-/* line 188, ../../sass/screen.scss */
+/* line 187, ../../sass/screen.scss */
.condensed-stages li > *, .condensed-stages li:before {
display: table-cell;
vertical-align: middle;
padding: 15px;
}
-/* line 193, ../../sass/screen.scss */
+/* line 192, ../../sass/screen.scss */
.condensed-stages li a {
width: auto;
}
-/* line 195, ../../sass/screen.scss */
+/* line 194, ../../sass/screen.scss */
.condensed-stages li a:hover {
background: #e08206;
color: #fff;
}
-/* line 200, ../../sass/screen.scss */
+/* line 199, ../../sass/screen.scss */
.condensed-stages li:before {
content: "";
text-align: right;
@@ -329,78 +329,78 @@ p.warning {
opacity: 0.8;
color: #000;
}
-/* line 207, ../../sass/screen.scss */
+/* line 206, ../../sass/screen.scss */
.condensed-stages li.stage-brouillon:before {
content: "Brouillon";
background: #f93a93;
}
-/* line 211, ../../sass/screen.scss */
+/* line 210, ../../sass/screen.scss */
.condensed-stages li.stage-publie:before {
content: "Publié";
background: #419be9;
}
-/* line 215, ../../sass/screen.scss */
+/* line 214, ../../sass/screen.scss */
.condensed-stages li.stage-ajout:before {
content: "+";
color: #000;
}
-/* line 223, ../../sass/screen.scss */
+/* line 222, ../../sass/screen.scss */
.stage-liste li {
display: block;
position: relative;
}
-/* line 227, ../../sass/screen.scss */
+/* line 226, ../../sass/screen.scss */
.stage-liste li.date-maj {
font-weight: 300;
font-size: 0.9em;
padding: 3px 0;
font-style: italic;
}
-/* line 233, ../../sass/screen.scss */
+/* line 232, ../../sass/screen.scss */
.stage-liste li.stage {
padding: 10px;
background: #fff;
margin: 10px;
border-left: 5px solid #f99b20;
}
-/* line 239, ../../sass/screen.scss */
+/* line 238, ../../sass/screen.scss */
.stage-liste li.stage h3 {
font-size: 1.4em;
padding-left: 5px;
}
-/* line 243, ../../sass/screen.scss */
+/* line 242, ../../sass/screen.scss */
.stage-liste li.stage h3 > a {
color: #0f4c82;
}
-/* line 247, ../../sass/screen.scss */
+/* line 246, ../../sass/screen.scss */
.stage-liste li.stage h3 .auteur {
font-size: 0.8em;
}
-/* line 250, ../../sass/screen.scss */
+/* line 249, ../../sass/screen.scss */
.stage-liste li.stage h3 .auteur, .stage-liste li.stage h3 .auteur a {
font-family: "Dosis", sans-serif;
font-weight: normal;
}
-/* line 257, ../../sass/screen.scss */
+/* line 256, ../../sass/screen.scss */
.stage-liste li .misc-hdr {
margin-bottom: 10px;
}
-/* line 261, ../../sass/screen.scss */
+/* line 260, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates > span {
display: table-cell;
vertical-align: middle;
}
-/* line 265, ../../sass/screen.scss */
+/* line 264, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates .year {
padding-left: 8px;
}
-/* line 268, ../../sass/screen.scss */
+/* line 267, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates svg text {
font-size: 0.8;
}
-/* line 276, ../../sass/screen.scss */
+/* line 275, ../../sass/screen.scss */
a.hoverlink {
position: absolute;
display: block;
@@ -411,7 +411,7 @@ a.hoverlink {
z-index: 2;
}
-/* line 286, ../../sass/screen.scss */
+/* line 285, ../../sass/screen.scss */
ul.infos {
margin: 0 -3px;
padding: 0;
@@ -420,7 +420,7 @@ ul.infos {
justify-content: space-between;
width: 100;
}
-/* line 294, ../../sass/screen.scss */
+/* line 293, ../../sass/screen.scss */
ul.infos li {
display: inline-block;
padding: 5px;
@@ -432,28 +432,28 @@ ul.infos li {
text-align: center;
background-color: #ddd;
}
-/* line 305, ../../sass/screen.scss */
+/* line 304, ../../sass/screen.scss */
ul.infos li.thematique {
color: #0d3f6b;
background-color: #86bff1;
}
-/* line 309, ../../sass/screen.scss */
+/* line 308, ../../sass/screen.scss */
ul.infos li.matiere {
color: #395214;
background-color: #c7e699;
}
-/* line 313, ../../sass/screen.scss */
+/* line 312, ../../sass/screen.scss */
ul.infos li.lieu {
color: #7c043c;
background-color: #fb84bc;
}
-/* line 317, ../../sass/screen.scss */
+/* line 316, ../../sass/screen.scss */
ul.infos li.year {
background-color: #950548;
color: #fff;
display: none;
}
-/* line 322, ../../sass/screen.scss */
+/* line 321, ../../sass/screen.scss */
ul.infos li.avis-len {
background-color: transparent;
border: 1px solid #eee;
@@ -461,29 +461,29 @@ ul.infos li.avis-len {
padding: 4px;
padding-bottom: 2px;
}
-/* line 329, ../../sass/screen.scss */
+/* line 328, ../../sass/screen.scss */
ul.infos li.avis-len.avis-vide {
border-bottom-color: #ddd;
}
-/* line 332, ../../sass/screen.scss */
+/* line 331, ../../sass/screen.scss */
ul.infos li.avis-len.avis-court {
border-bottom-color: #ffff66;
}
-/* line 335, ../../sass/screen.scss */
+/* line 334, ../../sass/screen.scss */
ul.infos li.avis-len.avis-moyen {
border-bottom-color: #86bff1;
}
-/* line 338, ../../sass/screen.scss */
+/* line 337, ../../sass/screen.scss */
ul.infos li.avis-len.avis-long {
border-bottom-color: #a5d65c;
}
-/* line 344, ../../sass/screen.scss */
+/* line 343, ../../sass/screen.scss */
ul.infos:after {
content: "";
flex: 1000;
}
-/* line 350, ../../sass/screen.scss */
+/* line 349, ../../sass/screen.scss */
section.profil {
background: #fff;
max-width: 600px;
@@ -491,7 +491,7 @@ section.profil {
margin: 5px auto;
margin-bottom: 15px;
}
-/* line 357, ../../sass/screen.scss */
+/* line 356, ../../sass/screen.scss */
section.profil div.infos {
border-bottom: 3px solid #1a82dd;
display: flex;
@@ -500,6 +500,59 @@ section.profil div.infos {
flex-wrap: wrap;
}
+/* line 365, ../../sass/screen.scss */
+section.two-cols {
+ display: flex;
+ display: flexbox;
+ align-items: center;
+}
+/* line 369, ../../sass/screen.scss */
+section.two-cols > * {
+ flex: 1;
+ width: 50%;
+ margin: 10px;
+}
+
+/* line 377, ../../sass/screen.scss */
+ul.mes-emails li {
+ display: flex;
+ background: #fff;
+ margin: 5px;
+ padding: 10px;
+ min-height: 70px;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+}
+/* line 387, ../../sass/screen.scss */
+ul.mes-emails li > * {
+ flex: 1;
+ text-align: center;
+}
+/* line 392, ../../sass/screen.scss */
+ul.mes-emails li .adresse {
+ text-align: left;
+ font-weight: bold;
+}
+/* line 397, ../../sass/screen.scss */
+ul.mes-emails li .confirmee {
+ width: 20px;
+}
+/* line 401, ../../sass/screen.scss */
+ul.mes-emails li .supprimer {
+ flex: 0.7;
+}
+/* line 405, ../../sass/screen.scss */
+ul.mes-emails li form {
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+}
+/* line 409, ../../sass/screen.scss */
+ul.mes-emails li form .field {
+ flex: 1;
+}
+
/* line 4, ../../sass/_stage_detail.scss */
article.stage .avis ul, article.stage .avis ol, div.tinymce ul, div.tinymce ol {
list-style: unset;
@@ -783,7 +836,7 @@ article.stage .section-wrapper .toc .toc-active a {
border: 1px solid #ad0654;
}
-/* line 378, ../../sass/screen.scss */
+/* line 428, ../../sass/screen.scss */
input, textarea, select, div.tinymce, option, optgroup:before {
background: #fff;
font-size: 1em;
@@ -793,13 +846,13 @@ input, textarea, select, div.tinymce, option, optgroup:before {
padding: 5px;
text-align: left;
}
-/* line 387, ../../sass/screen.scss */
+/* line 437, ../../sass/screen.scss */
input:focus, input.mce-edit-focus, textarea:focus, textarea.mce-edit-focus, select:focus, select.mce-edit-focus, div.tinymce:focus, div.tinymce.mce-edit-focus, option:focus, option.mce-edit-focus, optgroup:before:focus, optgroup:before.mce-edit-focus {
background-color: #e9f5d6;
outline: none;
}
-/* line 394, ../../sass/screen.scss */
+/* line 444, ../../sass/screen.scss */
input[type='text'], input[type='password'],
input[type='email'], input[type='number'], textarea, select {
border: none;
@@ -809,7 +862,7 @@ input[type='email'], input[type='number'], textarea, select {
transition: border 1s ease-out, background 1s ease-out;
}
-/* line 403, ../../sass/screen.scss */
+/* line 453, ../../sass/screen.scss */
select {
-moz-appearance: none;
appearance: none;
@@ -823,42 +876,42 @@ select {
background-color: #fff;
background-size: contain;
}
-/* line 416, ../../sass/screen.scss */
+/* line 466, ../../sass/screen.scss */
select option {
padding: 3px;
white-space: pre-wrap;
}
-/* line 422, ../../sass/screen.scss */
+/* line 472, ../../sass/screen.scss */
select optgroup option {
padding-left: 10px;
}
-/* line 425, ../../sass/screen.scss */
+/* line 475, ../../sass/screen.scss */
select optgroup:before {
font-weight: bold;
}
-/* line 431, ../../sass/screen.scss */
+/* line 481, ../../sass/screen.scss */
input[type="submit"], .btn {
font: 19px "Dosis", sans-serif;
background-color: #8fcc33;
color: #fff;
- border: 1px solid #648f24;
+ border: 1px solid #395214;
border-radius: 5px;
padding: 8px 12px;
display: inline-block;
}
-/* line 441, ../../sass/screen.scss */
+/* line 491, ../../sass/screen.scss */
p.submits {
text-align: right;
}
-/* line 445, ../../sass/screen.scss */
+/* line 495, ../../sass/screen.scss */
form .commentaire {
font-style: italic;
}
-/* line 449, ../../sass/screen.scss */
+/* line 499, ../../sass/screen.scss */
.edit-btn {
border-color: #706c00;
color: #000;
@@ -867,14 +920,14 @@ form .commentaire {
background-origin: content-box;
background-size: contain;
}
-/* line 457, ../../sass/screen.scss */
+/* line 507, ../../sass/screen.scss */
.edit-btn:after {
content: "";
width: 30px;
display: inline-block;
}
-/* line 464, ../../sass/screen.scss */
+/* line 514, ../../sass/screen.scss */
textarea, div.tinymce {
font-family: "Lato", sans-serif;
border: none;
@@ -884,20 +937,20 @@ textarea, div.tinymce {
transition: border 1s ease-out, background 1s ease-out;
}
-/* line 473, ../../sass/screen.scss */
+/* line 523, ../../sass/screen.scss */
textarea {
height: 200px;
resize: vertical;
}
-/* line 481, ../../sass/screen.scss */
+/* line 531, ../../sass/screen.scss */
form .field {
margin: 5px 0;
display: flex;
background: #fff;
padding: 10px;
}
-/* line 487, ../../sass/screen.scss */
+/* line 537, ../../sass/screen.scss */
form .field label, form .field .label {
display: inline-block;
width: 250px;
@@ -906,48 +959,48 @@ form .field label, form .field .label {
padding-top: 5px;
flex-shrink: 0;
}
-/* line 495, ../../sass/screen.scss */
+/* line 545, ../../sass/screen.scss */
form .field label.required:before, form .field .label.required:before {
margin-right: 5px;
content: "*";
color: #f70978;
}
-/* line 501, ../../sass/screen.scss */
+/* line 551, ../../sass/screen.scss */
form .field label {
font-family: Alegreya, serif;
font-weight: bold;
}
-/* line 505, ../../sass/screen.scss */
+/* line 555, ../../sass/screen.scss */
form .field .help_text {
font-style: italic;
font-size: 0.9em;
}
-/* line 509, ../../sass/screen.scss */
+/* line 559, ../../sass/screen.scss */
form .field .input {
display: inline-block;
flex-grow: 1;
margin-right: 10px;
}
-/* line 519, ../../sass/screen.scss */
+/* line 569, ../../sass/screen.scss */
ul.as-selections,
.selectize-control.multi {
display: flex;
flex-wrap: wrap;
}
-/* line 524, ../../sass/screen.scss */
+/* line 574, ../../sass/screen.scss */
ul.as-selections li,
.selectize-control.multi li {
display: inline-block;
}
-/* line 527, ../../sass/screen.scss */
+/* line 577, ../../sass/screen.scss */
ul.as-selections .selectize-input, ul.as-selections .selectize-dropdown,
.selectize-control.multi .selectize-input,
.selectize-control.multi .selectize-dropdown {
font-size: 100%;
line-height: 1.1;
}
-/* line 531, ../../sass/screen.scss */
+/* line 581, ../../sass/screen.scss */
ul.as-selections .as-selection-item,
ul.as-selections .selectize-input > div,
.selectize-control.multi .as-selection-item,
@@ -959,7 +1012,7 @@ ul.as-selections .selectize-input > div,
border-radius: 2px;
font-weight: 500;
}
-/* line 540, ../../sass/screen.scss */
+/* line 590, ../../sass/screen.scss */
ul.as-selections .as-selection-item a.as-close,
ul.as-selections .selectize-input > div a.as-close,
.selectize-control.multi .as-selection-item a.as-close,
@@ -969,51 +1022,51 @@ ul.as-selections .selectize-input > div a.as-close,
cursor: pointer;
margin-right: 5px;
}
-/* line 547, ../../sass/screen.scss */
+/* line 597, ../../sass/screen.scss */
ul.as-selections .as-selection-item.selected,
ul.as-selections .selectize-input > div.selected,
.selectize-control.multi .as-selection-item.selected,
.selectize-control.multi .selectize-input > div.selected {
background: #8fcc33;
}
-/* line 552, ../../sass/screen.scss */
+/* line 602, ../../sass/screen.scss */
ul.as-selections .as-original,
.selectize-control.multi .as-original {
flex-grow: 1;
min-width: 200px;
}
-/* line 556, ../../sass/screen.scss */
+/* line 606, ../../sass/screen.scss */
ul.as-selections .as-original input,
.selectize-control.multi .as-original input {
width: 100%;
}
-/* line 562, ../../sass/screen.scss */
+/* line 612, ../../sass/screen.scss */
div.as-results {
position: relative;
z-index: 2;
}
-/* line 566, ../../sass/screen.scss */
+/* line 616, ../../sass/screen.scss */
div.as-results ul {
position: absolute;
width: 100%;
background: #fff;
border: 1px solid #d2ebad;
}
-/* line 573, ../../sass/screen.scss */
+/* line 623, ../../sass/screen.scss */
div.as-results ul li {
padding: 3px 5px;
}
-/* line 579, ../../sass/screen.scss */
+/* line 629, ../../sass/screen.scss */
div.as-results ul li.as-result-item.active {
background: #fddeb5;
}
-/* line 584, ../../sass/screen.scss */
+/* line 634, ../../sass/screen.scss */
div.as-results ul li.as-message {
font-style: italic;
}
-/* line 594, ../../sass/screen.scss */
+/* line 644, ../../sass/screen.scss */
.window {
display: none;
position: fixed;
@@ -1024,11 +1077,11 @@ div.as-results ul li.as-message {
left: 0;
z-index: 50;
}
-/* line 604, ../../sass/screen.scss */
+/* line 654, ../../sass/screen.scss */
.window.visible {
display: block;
}
-/* line 608, ../../sass/screen.scss */
+/* line 658, ../../sass/screen.scss */
.window .window-bg {
background: #000;
opacity: 0.7;
@@ -1039,7 +1092,7 @@ div.as-results ul li.as-message {
top: 0;
z-index: -1;
}
-/* line 619, ../../sass/screen.scss */
+/* line 669, ../../sass/screen.scss */
.window .window-content {
position: relative;
margin: 0 auto;
@@ -1053,11 +1106,11 @@ div.as-results ul li.as-message {
max-height: 100%;
overflow: auto;
}
-/* line 633, ../../sass/screen.scss */
+/* line 683, ../../sass/screen.scss */
.window .window-content form label, .window .window-content form .label {
width: 150px;
}
-/* line 639, ../../sass/screen.scss */
+/* line 689, ../../sass/screen.scss */
.window .window-closer {
position: absolute;
top: 0;
@@ -1065,65 +1118,65 @@ div.as-results ul li.as-message {
padding: 12px;
z-index: 3;
}
-/* line 645, ../../sass/screen.scss */
+/* line 695, ../../sass/screen.scss */
.window .window-closer:after {
content: "×";
}
-/* line 656, ../../sass/screen.scss */
+/* line 706, ../../sass/screen.scss */
#lieu_widget .window-content {
max-width: 800px;
}
-/* line 660, ../../sass/screen.scss */
+/* line 710, ../../sass/screen.scss */
#lieu_widget .lieu-ui {
position: relative;
width: 100%;
min-width: 150px;
flex: 2;
}
-/* line 666, ../../sass/screen.scss */
+/* line 716, ../../sass/screen.scss */
#lieu_widget .lieu-ui .map {
height: 400px;
width: 100%;
}
-/* line 670, ../../sass/screen.scss */
+/* line 720, ../../sass/screen.scss */
#lieu_widget .lieu-ui.hidden {
display: none;
}
-/* line 673, ../../sass/screen.scss */
+/* line 723, ../../sass/screen.scss */
#lieu_widget .lieu-ui .masked {
visibility: hidden;
}
-/* line 678, ../../sass/screen.scss */
+/* line 728, ../../sass/screen.scss */
#lieu_widget .lieu-choixmodif, #lieu_widget .lieu-options {
display: none;
}
-/* line 682, ../../sass/screen.scss */
+/* line 732, ../../sass/screen.scss */
#lieu_widget .lieu-global {
display: flex;
width: 100%;
flex-wrap: wrap;
}
-/* line 687, ../../sass/screen.scss */
+/* line 737, ../../sass/screen.scss */
#lieu_widget .lieu-global.with-options .lieu-options {
display: block;
}
-/* line 694, ../../sass/screen.scss */
+/* line 744, ../../sass/screen.scss */
#lieu_widget.modif .lieu-global.with-options .lieu-options, #lieu_widget.edit .lieu-global.with-options .lieu-options {
display: none;
}
-/* line 699, ../../sass/screen.scss */
+/* line 749, ../../sass/screen.scss */
#lieu_widget .lieu-options {
padding: 7px;
max-width: 350px;
flex: 3;
}
-/* line 704, ../../sass/screen.scss */
+/* line 754, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions {
max-height: 300px;
overflow-y: auto;
}
-/* line 708, ../../sass/screen.scss */
+/* line 758, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li {
position: relative;
background: #fff;
@@ -1131,64 +1184,64 @@ div.as-results ul li.as-message {
padding: 4px;
font-size: 0.9em;
}
-/* line 714, ../../sass/screen.scss */
+/* line 764, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li:hover {
background: #ccc;
}
-/* line 717, ../../sass/screen.scss */
+/* line 767, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li p {
margin: 2px 0;
}
-/* line 720, ../../sass/screen.scss */
+/* line 770, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li .lieu-nom {
font-weight: bold;
}
-/* line 723, ../../sass/screen.scss */
+/* line 773, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li .lieu-infos {
font-size: 0.8em;
display: flex;
width: 100%;
justify-content: space-between;
}
-/* line 729, ../../sass/screen.scss */
+/* line 779, ../../sass/screen.scss */
#lieu_widget .lieu-options .lieu-suggestions li .lieu-infos span {
display: inline-block;
text-overflow: ellipsis;
overlow: hidden;
}
-/* line 740, ../../sass/screen.scss */
+/* line 790, ../../sass/screen.scss */
#lieu_widget.modif .lieu-choixmodif {
display: unset;
}
-/* line 745, ../../sass/screen.scss */
+/* line 795, ../../sass/screen.scss */
#lieu_widget.modif .lieu-ui, #lieu_widget.attente .lieu-ui {
display: none;
}
-/* line 752, ../../sass/screen.scss */
+/* line 802, ../../sass/screen.scss */
#lieu_widget.edit .lieu-ui .lieu-acinput {
display: none;
}
-/* line 755, ../../sass/screen.scss */
+/* line 805, ../../sass/screen.scss */
#lieu_widget.edit .lieu-ui .map {
height: 200px;
}
-/* line 761, ../../sass/screen.scss */
+/* line 811, ../../sass/screen.scss */
#lieu_widget #avis_lieu_vide {
display: none;
}
-/* line 765, ../../sass/screen.scss */
+/* line 815, ../../sass/screen.scss */
#lieu_widget .message {
background: #fddeb5;
padding: 5px;
font-style: italic;
font-size: 0.9em;
}
-/* line 771, ../../sass/screen.scss */
+/* line 821, ../../sass/screen.scss */
#lieu_widget .message.hidden {
display: none;
}
-/* line 777, ../../sass/screen.scss */
+/* line 827, ../../sass/screen.scss */
a.lieu-change {
color: #fff;
background: #f99b20;
@@ -1201,25 +1254,25 @@ a.lieu-change {
border-radius: 5px;
margin-right: 7px;
}
-/* line 789, ../../sass/screen.scss */
+/* line 839, ../../sass/screen.scss */
a.lieu-change.ajout:before {
content: "+";
margin-right: 5px;
}
-/* line 795, ../../sass/screen.scss */
+/* line 845, ../../sass/screen.scss */
#stages-map {
width: 100%;
height: 600px;
max-height: 90vh;
}
-/* line 802, ../../sass/screen.scss */
+/* line 852, ../../sass/screen.scss */
#id_stage-thematiques {
display: none;
}
-/* line 808, ../../sass/screen.scss */
+/* line 858, ../../sass/screen.scss */
.homeh1 {
display: flex;
justify-content: space-between;
@@ -1229,26 +1282,26 @@ a.lieu-change.ajout:before {
border-bottom: 3px solid #000;
margin-bottom: 15px;
}
-/* line 817, ../../sass/screen.scss */
+/* line 867, ../../sass/screen.scss */
.homeh1 h1 {
margin-bottom: 3px;
}
-/* line 821, ../../sass/screen.scss */
+/* line 871, ../../sass/screen.scss */
.homeh1 > * {
display: inline-block;
}
-/* line 824, ../../sass/screen.scss */
+/* line 874, ../../sass/screen.scss */
.homeh1 p {
text-align: right;
}
-/* line 829, ../../sass/screen.scss */
+/* line 879, ../../sass/screen.scss */
.betacadre {
background: #fa6cae;
padding: 10px;
}
-/* line 834, ../../sass/screen.scss */
+/* line 884, ../../sass/screen.scss */
.entrer {
background: #fff;
max-width: 500px;
@@ -1256,7 +1309,7 @@ a.lieu-change.ajout:before {
text-align: center;
margin: 15px auto;
}
-/* line 841, ../../sass/screen.scss */
+/* line 891, ../../sass/screen.scss */
.entrer .archicubes {
border-top: 2px solid #1a82dd;
margin-top: 5px;
@@ -1264,84 +1317,84 @@ a.lieu-change.ajout:before {
font-size: 0.9em;
}
-/* line 849, ../../sass/screen.scss */
+/* line 899, ../../sass/screen.scss */
article.promo {
display: block;
font-size: 1.1em;
}
-/* line 853, ../../sass/screen.scss */
+/* line 903, ../../sass/screen.scss */
article.promo .explications {
display: table;
}
-/* line 856, ../../sass/screen.scss */
+/* line 906, ../../sass/screen.scss */
article.promo .explications:first-child {
direction: rtl;
}
-/* line 858, ../../sass/screen.scss */
+/* line 908, ../../sass/screen.scss */
article.promo .explications:first-child > * {
direction: ltr;
}
-/* line 863, ../../sass/screen.scss */
+/* line 913, ../../sass/screen.scss */
article.promo .explications > div {
display: table-cell;
vertical-align: middle;
text-align: center;
}
-/* line 868, ../../sass/screen.scss */
+/* line 918, ../../sass/screen.scss */
article.promo .explications > div p {
margin: 15px 15px;
}
-/* line 876, ../../sass/screen.scss */
+/* line 926, ../../sass/screen.scss */
.faq-toc {
font-family: "Lato", sans-serif;
display: block;
max-width: 700px;
margin: 0 auto;
}
-/* line 881, ../../sass/screen.scss */
+/* line 931, ../../sass/screen.scss */
.faq-toc ul {
margin: 20px;
}
-/* line 885, ../../sass/screen.scss */
+/* line 935, ../../sass/screen.scss */
.faq-toc ul li a {
color: #000;
display: block;
padding: 5px;
}
-/* line 891, ../../sass/screen.scss */
+/* line 941, ../../sass/screen.scss */
.faq-toc ul li.toc-h1 {
display: none;
}
-/* line 895, ../../sass/screen.scss */
+/* line 945, ../../sass/screen.scss */
.faq-toc ul li.toc-h2 a {
background: #fcc883;
}
-/* line 899, ../../sass/screen.scss */
+/* line 949, ../../sass/screen.scss */
.faq-toc ul li.toc-h3 a {
padding-left: 10px;
background: #fff;
font-weight: normal;
}
-/* line 905, ../../sass/screen.scss */
+/* line 955, ../../sass/screen.scss */
.faq-toc ul li a:hover {
color: #395214;
background: #bce085 !important;
}
-/* line 914, ../../sass/screen.scss */
+/* line 964, ../../sass/screen.scss */
.faq article {
background: #fff;
padding: 15px;
}
-/* line 917, ../../sass/screen.scss */
+/* line 967, ../../sass/screen.scss */
.faq article h2 {
background-color: #fcc883;
color: #ae6505;
margin: -15px;
padding: 15px;
}
-/* line 924, ../../sass/screen.scss */
+/* line 974, ../../sass/screen.scss */
.faq article h3 {
color: #0f4c82;
background-color: #9dcbf3;
@@ -1349,19 +1402,19 @@ article.promo .explications > div p {
margin-top: 30px;
padding: 10px 15px;
}
-/* line 931, ../../sass/screen.scss */
+/* line 981, ../../sass/screen.scss */
.faq article h3:nth-child(2) {
margin-top: 0;
}
-/* line 936, ../../sass/screen.scss */
+/* line 986, ../../sass/screen.scss */
.faq article ul {
padding-left: 20px;
}
-/* line 938, ../../sass/screen.scss */
+/* line 988, ../../sass/screen.scss */
.faq article ul li {
list-style: initial;
}
-/* line 943, ../../sass/screen.scss */
+/* line 993, ../../sass/screen.scss */
.faq article p, .faq article ul {
font-family: "Lato", sans-serif;
font-size: 18px;
@@ -1370,20 +1423,20 @@ article.promo .explications > div p {
margin-right: 5%;
}
-/* line 957, ../../sass/screen.scss */
+/* line 1007, ../../sass/screen.scss */
table.stats {
width: 100%;
background: #fff;
margin: 20px 0;
cellspacing: 1px;
}
-/* line 962, ../../sass/screen.scss */
+/* line 1012, ../../sass/screen.scss */
table.stats th {
font-weight: bold;
border-top: 1px solid #000;
border-bottom: 1px solid #999;
}
-/* line 967, ../../sass/screen.scss */
+/* line 1017, ../../sass/screen.scss */
table.stats td, table.stats th {
padding: 5px 3px;
text-align: center;
@@ -1971,14 +2024,14 @@ body.recherche.vue-hybride.vue-details .recherche-liste.recherche-details {
display: block;
text-align: left;
font-size: 0.95em;
- color: #c77c1a;
+ color: #ae6505;
margin-top: 0;
width: auto;
}
/* line 185, ../../sass/_responsive.scss */
form .field .help_text {
text-align: right;
- color: #395214;
+ color: black;
}
/* line 190, ../../sass/_responsive.scss */
form .field .input {
diff --git a/avisstage/templates/avisstage/compte/aconfirmer.html b/avisstage/templates/avisstage/compte/aconfirmer.html
new file mode 100644
index 0000000..bbe6398
--- /dev/null
+++ b/avisstage/templates/avisstage/compte/aconfirmer.html
@@ -0,0 +1,19 @@
+{% extends "avisstage/base.html" %}
+{% load staticfiles %}
+
+{% block title %}Confirmation requise - ExperiENS{% endblock %}
+
+{% block content %}
+
Confirmation requise
+
+
+ {% if object.confirmed_at %}
+ L'adresse {{ object.email }} a déjà été confirmée.
+ {% else %}
+ Un mail de confirmation vous a été envoyé à l'adresse {{ object.email }} pour la vérifier.
+ Merci de cliquer sur le lien inclus pour confirmer qu'elle est correcte.
+ Si vous ne recevez rien, vérifier dans vos indésirables.
+ {% endif %}
+ Retour
+
+{% endblock %}
diff --git a/avisstage/templates/avisstage/compte/edit_mdp.html b/avisstage/templates/avisstage/compte/edit_mdp.html
new file mode 100644
index 0000000..ff07aae
--- /dev/null
+++ b/avisstage/templates/avisstage/compte/edit_mdp.html
@@ -0,0 +1,29 @@
+{% extends "avisstage/base.html" %}
+{% load staticfiles %}
+
+{% block content %}
+ Définir un mot de passe
+
+{% endblock %}
diff --git a/avisstage/templates/avisstage/compte/email_supprime.html b/avisstage/templates/avisstage/compte/email_supprime.html
new file mode 100644
index 0000000..494d27a
--- /dev/null
+++ b/avisstage/templates/avisstage/compte/email_supprime.html
@@ -0,0 +1,18 @@
+{% extends "avisstage/base.html" %}
+{% load staticfiles %}
+
+{% block title %}Supprimer une adresse mail - ExperiENS{% endblock %}
+
+{% block content %}
+ Supprimer une adresse mail
+
+
+
+
+{% endblock %}
diff --git a/avisstage/templates/avisstage/compte/parametres.html b/avisstage/templates/avisstage/compte/parametres.html
new file mode 100644
index 0000000..36a9547
--- /dev/null
+++ b/avisstage/templates/avisstage/compte/parametres.html
@@ -0,0 +1,76 @@
+{% extends "avisstage/base.html" %}
+{% load staticfiles %}
+
+{% block title %}Mes paramètres - ExperiENS{% endblock %}
+
+{% block content %}
+ Mes paramètres
+
+
+ Adresses e-mail
+
+ {% for email in request.user.email_address_set.all %}
+
+ {{ email.email }}
+ {{ email.confirmed_at|yesno:"✓,✗"|safe }}
+ {% if email.confirmed_at %}
+
+ {% if email.email == user.email %}
+ Principale
+ {% else %}
+
+ {% endif %}
+
+
+ {% else %}
+
+
+
+ {% endif %}
+
+ {% if not email.email == user.email %}
+ Supprimer
+ {% endif %}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+ Mot de passe
+
+ {% if request.user.password and request.user.has_usable_password %}
+ Un mot de passe interne est déjà défini pour ce compte.
+ {% else %}
+ Aucun mot de passe n'est défini pour ce compte. Créez-en un pour pouvoir vous connecter après la fin de votre scolarité à l'ENS.
+ {% endif %}
+
+ En cliquant sur ce bouton, un lien unique vous sera envoyé à votre adresse e-mail principale ({{ request.user.email }}) qui vous donnera accès au formulaire d'édition du mot de passe.
+
+
+{% endblock %}
diff --git a/avisstage/templates/avisstage/formulaires/profil.html b/avisstage/templates/avisstage/formulaires/profil.html
index e5ac89d..7d1fce0 100644
--- a/avisstage/templates/avisstage/formulaires/profil.html
+++ b/avisstage/templates/avisstage/formulaires/profil.html
@@ -18,6 +18,13 @@
{% endfor %}
-
+
+
{% endblock %}
diff --git a/avisstage/templates/avisstage/mails/reinit_mdp.html b/avisstage/templates/avisstage/mails/reinit_mdp.html
new file mode 100644
index 0000000..f9e3c98
--- /dev/null
+++ b/avisstage/templates/avisstage/mails/reinit_mdp.html
@@ -0,0 +1,8 @@
+Bonjour,
+
+Pour créer ou modifier le mot de passe associé à votre compte {{ user.get_username }}, merci de cliquer sur le lien suivant ou de le copier dans votre navigateur :
+
+ {{ protocol }}://{{ domain }}{% url 'avisstage:mdp_edit' uidb64=uid token=token %}
+
+Cordialement,
+L'équipe ExperiENS
diff --git a/avisstage/templates/avisstage/mails/reinit_mdp.txt b/avisstage/templates/avisstage/mails/reinit_mdp.txt
new file mode 100644
index 0000000..cc5a9de
--- /dev/null
+++ b/avisstage/templates/avisstage/mails/reinit_mdp.txt
@@ -0,0 +1 @@
+[ExperiENS] Définition du mot de passe
diff --git a/avisstage/templates/avisstage/perso.html b/avisstage/templates/avisstage/perso.html
index adf992a..32f816f 100644
--- a/avisstage/templates/avisstage/perso.html
+++ b/avisstage/templates/avisstage/perso.html
@@ -8,34 +8,38 @@
Mon compte
-
- {% if user.profil.en_scolarite %}
- Statut : En scolarité
- Vous pouvez accéder à l'ensemble du site, et aux fiches de stages.
- Quand vous n'aurez plus de compte clipper (après votre scolarité), votre accès sera restreint à vos propres expériences, que vous pourrez ajouter, modifier, supprimer.
- Pensez à renseigner une adresse e-mail non-ENS pour conserver cet accès, et permettre aux futur⋅e⋅s normalien⋅ne⋅s de toujours vous contacter !
- {% else %}
- Statut : Archicube
- Vous ne pouvez plus accéder qu'à vos propres expériences pour les modifier, et tenir à jour votre profil.
- Si vous êtes encore en scolarité, merci de vous reconnecter en passant par le serveur d'authentification de l'ENS pour mettre à jour votre statut.
- {% endif %}
- Le statut est mis à jour automatiquement chaque année selon le mode de connexion que vous utilisez.
-
-
- Adresse e-mail
- {% if not user.profil.has_nonENS_email %}Vous n'avez pas renseigné d'adresse mail autre que celle de l'ENS. Pensez à le faire, pour que les générations futures puissent toujours vous contacter !
{% endif %}
- Gérer les adresses e-mail liées à mon compte
-
-
- Mode de connexion
- {% if user.profil.en_scolarite %}En scolarité, utilisez le serveur central d'authentification pour vous connecter. Quand vous n'aurez plus de compte clipper, vous devrez vous connecter directement via l'accès archicubes, avec votre login {{ user.cas_account.cas_login }} et le mot de passe spécifique à ExperiENS que vous aurez défini.
{% endif %}
- {% if not user.password or not user.has_usable_password %}Vous n'avez pas créé de mot de passe interne à ExperiENS. Pensez-y pour garder l'accès au site quand vous n'aurez plus de compte clipper !
{% endif %}
- Créer / changer mon mot de passe ExperiENS
+
+
+ {% if user.profil.en_scolarite %}
+ Statut : En scolarité
+ Vous pouvez accéder à l'ensemble du site, et aux fiches de stages.
+ Quand vous n'aurez plus de compte clipper (après votre scolarité), votre accès sera restreint à vos propres expériences, que vous pourrez ajouter, modifier, supprimer.
+ Pensez à renseigner une adresse e-mail non-ENS pour conserver cet accès, et permettre aux futur⋅e⋅s normalien⋅ne⋅s de toujours vous contacter !
+ {% else %}
+ Statut : Archicube
+ Vous ne pouvez plus accéder qu'à vos propres expériences pour les modifier, et tenir à jour votre profil.
+ Si vous êtes encore en scolarité, merci de vous reconnecter en passant par le serveur d'authentification de l'ENS pour mettre à jour votre statut.
+ {% endif %}
+
+ Le statut est mis à jour automatiquement chaque année selon le mode de connexion que vous utilisez.
+
+
+ Connexion
+ Adresse e-mail principale : {{ user.email }}
+ {% if not user.profil.has_nonENS_email %}Vous n'avez pas renseigné d'adresse mail autre que celle de l'ENS. Pensez à le faire, pour que les générations futures puissent toujours vous contacter !
{% endif %}
+
+
+ Mot de passe interne : {% if user.password and user.has_usable_password %}Défini{% else %}Non défini{% endif %}
+ {% if not user.password or not user.has_usable_password %}Pensez à définir un mot de passe propre à ExperiENS pour garder l'accès au site quand vous n'aurez plus de compte clipper !
{% endif %}
+ {% if user.profil.en_scolarite %}En scolarité, utilisez le serveur central d'authentification pour vous connecter. Quand vous n'aurez plus de compte clipper, vous devrez vous connecter directement via l'accès archicubes, avec votre login {{ user.username }} et le mot de passe spécifique à ExperiENS que vous aurez défini.
{% endif %}
+
+ Gérer mes paramètres de connexion
+
-
+
{% with object=user.profil %}
diff --git a/avisstage/urls.py b/avisstage/urls.py
index 94bab54..93f0978 100644
--- a/avisstage/urls.py
+++ b/avisstage/urls.py
@@ -24,6 +24,23 @@ urlpatterns = [
path('profil/show//', views.ProfilView.as_view(),
name='profil'),
path('profil/edit/', views.ProfilEdit.as_view(), name='profil_edit'),
+ path('profil/parametres/', views.MesParametres.as_view(), name='parametres'),
+ path('profil/emails//aconfirmer/',
+ views.AdresseAConfirmer.as_view(), name="emails_aconfirmer"),
+ path('profil/emails//supprime/', views.SupprimeAdresse.as_view(),
+ name="emails_supprime"),
+ path('profil/emails//reconfirme/',
+ views.ReConfirmeAdresse.as_view(),
+ name="emails_reconfirme"),
+ path('profil/emails//principal/',
+ views.RendAdressePrincipale.as_view(), name="emails_principal"),
+ path('profil/emails/confirme//', views.ConfirmeAdresse.as_view(),
+ name="emails_confirme"),
+ path('profil/mdp/demande/',
+ views.EnvoieLienMotDePasse.as_view(), name="mdp_demande"),
+ path('profil/mdp///',
+ views.DefinirMotDePasse.as_view(), name="mdp_edit"),
+
path('recherche/', views.recherche, name='recherche'),
path('recherche/resultats/', views.recherche_resultats,
name='recherche_resultats'),
diff --git a/avisstage/views.py b/avisstage/views.py
index 2bcb19c..897b124 100644
--- a/avisstage/views.py
+++ b/avisstage/views.py
@@ -2,21 +2,31 @@
from django.shortcuts import render, redirect, get_object_or_404
-from django.views.generic import DetailView, ListView
-from django.views.generic.edit import UpdateView, CreateView
+from django.views.generic import (
+ DetailView, ListView, UpdateView, CreateView, TemplateView, DeleteView,
+ FormView, View
+)
+from django.views.generic.detail import SingleObjectMixin
from django import forms
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
+from django.contrib.auth.tokens import default_token_generator
+from django.contrib.auth.views import PasswordResetConfirmView
+from django.contrib import messages
from braces.views import LoginRequiredMixin
from django.http import JsonResponse, HttpResponseForbidden, Http404
from django.core.mail import send_mail
from django.db.models import Q, Count
from collections import Counter, defaultdict
+from simple_email_confirmation.models import EmailAddress
from .models import Normalien, Stage, Lieu, AvisLieu, AvisStage
-from .forms import StageForm, LieuForm, AvisStageForm, AvisLieuForm, FeedbackForm
+from .forms import (
+ StageForm, LieuForm, AvisStageForm, AvisLieuForm, FeedbackForm, AdresseEmailForm,
+ ReinitMdpForm
+)
from .utils import en_scolarite
from .views_search import *
@@ -343,3 +353,126 @@ def statistiques(request):
'num_lieux_utiles': nlieux,
'num_par_longueur': nbylength,
})
+
+#
+# Compte
+#
+
+class MesAdressesMixin(LoginRequiredMixin):
+ slug_url_kwarg = "email"
+ slug_field = "email"
+ confirmed_only = False
+
+ def get_queryset(self, *args, **kwargs):
+ qs = self.request.user.email_address_set.all()
+ if self.confirmed_only:
+ qs = qs.filter(confirmed_at__isnull=False)
+ return qs
+
+def _send_confirm_mail(email, request):
+ confirm_url = request.build_absolute_uri(
+ reverse("avisstage:emails_confirme", kwargs={"key": email.key}))
+ send_mail(
+ "[ExperiENS] Confirmez votre adresse a-mail",
+"""Bonjour,
+
+Vous venez d'ajouter cette adresse e-mail à votre compte ExperiENS.
+
+Pour la vérifier, merci de cliquer sur le lien suivant, ou de copier l'adresse dans votre navigateur :
+
+ {confirm_url}
+
+Cordialement,
+L'équipe ExperiENS""".format(confirm_url=confirm_url),
+ 'experiens-nepasrepondre@eleves.ens.fr',
+ [email.email],
+ fail_silently=False,
+ )
+ return redirect(reverse("avisstage:emails_aconfirmer",
+ kwargs={"email": email.email}))
+
+class MesParametres(LoginRequiredMixin, FormView):
+ model = EmailAddress
+ template_name = "avisstage/compte/parametres.html"
+ form_class = AdresseEmailForm
+
+ def get_form_kwargs(self, *args, **kwargs):
+ kwargs = super().get_form_kwargs(*args, **kwargs)
+ kwargs["_user"] = self.request.user
+ return kwargs
+
+ def form_valid(self, form):
+ new = EmailAddress.objects.create_unconfirmed(
+ form.cleaned_data["email"], self.request.user)
+ return _send_confirm_mail(new, self.request)
+
+class RendAdressePrincipale(MesAdressesMixin, SingleObjectMixin, View):
+ model = EmailAddress
+ confirmed_only = True
+
+ def post(self, *args, **kwargs):
+ if not hasattr(self, "object"):
+ self.object = self.get_object()
+ self.request.user.email = self.object.email
+ self.request.user.save()
+ return redirect(reverse("avisstage:parametres"))
+
+class AdresseAConfirmer(MesAdressesMixin, DetailView):
+ model = EmailAddress
+ template_name = "avisstage/compte/aconfirmer.html"
+
+class ReConfirmeAdresse(MesAdressesMixin, DetailView):
+ model = EmailAddress
+
+ def post(self, *args, **kwargs):
+ email = self.get_object()
+ if email.confirmed_at is None:
+ return _send_confirm_mail(email, self.request)
+ return redirect(reverse("avisstage:parametres"))
+
+class ConfirmeAdresse(LoginRequiredMixin, View):
+ def get(self, *args, **kwargs):
+ try:
+ email = EmailAddress.objects.confirm(self.kwargs["key"],
+ self.request.user, True)
+ except Exception as e:
+ raise Http404()
+ messages.add_message(
+ self.request, messages.SUCCESS,
+ "L'adresse email {email} a bien été confirmée".format(email=email.email))
+ return redirect(reverse("avisstage:parametres"))
+
+class SupprimeAdresse(MesAdressesMixin, DeleteView):
+ model = EmailAddress
+ template_name = "avisstage/compte/email_supprime.html"
+ success_url = reverse_lazy("avisstage:parametres")
+
+ def get_queryset(self, *args, **kwargs):
+ qs = super().get_queryset(*args, **kwargs)
+ return qs.exclude(email=self.request.user.email)
+
+class EnvoieLienMotDePasse(LoginRequiredMixin, View):
+ def post(self, *args, **kwargs):
+ form = ReinitMdpForm({"email": self.request.user.email})
+ form.is_valid()
+ form.save(
+ email_template_name = 'avisstage/mails/reinit_mdp.html',
+ from_email = 'experiens-nepasrepondre@eleves.ens.fr',
+ subject_template_name = 'avisstage/mails/reinit_mdp.txt',
+ )
+ messages.add_message(
+ self.request, messages.INFO,
+ "Un mail a été envoyé à {email}. Merci de vérifier vos indésirables si vous ne le recevez pas bientôt".format(email=self.request.user.email)
+ )
+ return redirect(reverse("avisstage:parametres"))
+
+class DefinirMotDePasse(PasswordResetConfirmView):
+ template_name = "avisstage/compte/edit_mdp.html"
+ success_url = reverse_lazy("avisstage:perso")
+
+ def get_user(self, *args, **kwargs):
+ user = super().get_user(*args, **kwargs)
+ if self.request.user.is_authenticated and user != self.request.user:
+ raise Http404("Ce token n'est pas valide pour votre compte")
+ return user
+
diff --git a/experiENS/settings_base.py b/experiENS/settings_base.py
index a4ba634..d03aec0 100644
--- a/experiENS/settings_base.py
+++ b/experiENS/settings_base.py
@@ -35,9 +35,9 @@ INSTALLED_APPS = [
'django_elasticsearch_dsl',
- #'allauth',
- #'allauth.account', # Uncomment for transition
- #'allauth.socialaccount', # Allauth -> Authens
+ #'allauth', # Uncomment that part when you
+ #'allauth.account', # apply migration
+ #'allauth.socialaccount', # Allauth -> AuthENS
'widget_tweaks',