Gestion des accès et interface

This commit is contained in:
Evarin 2018-12-28 23:46:24 +01:00
parent 52f574678d
commit 2b94a28670
16 changed files with 304 additions and 202 deletions

View file

@ -0,0 +1,20 @@
from allauth.account.adapter import DefaultAccountAdapter
from allauth_ens.adapter import LongTermClipperAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def is_open_for_signup(self, request):
return False
class SocialAccountAdapter(LongTermClipperAccountAdapter):
def is_open_for_signup(self, request, sociallogin):
# sociallogin.account is a SocialAccount instance.
# See https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/models.py
if sociallogin.account.provider == 'clipper':
return True
# It returns AccountAdapter.is_open_for_signup().
# See https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/adapter.py
return super().is_open_for_signup(request, sociallogin)

12
avisstage/decorators.py Normal file
View file

@ -0,0 +1,12 @@
from functools import wraps
from django.urls import reverse
from django.shortcuts import redirect
def en_scolarite_required(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if request.user.profil.en_scolarite:
return view_func(request, *args, **kwargs)
return redirect(reverse("avisstage:403-archicubes"))
return _wrapped_view

View file

@ -3,7 +3,6 @@
from __future__ import unicode_literals
from allauth.account.models import EmailAddress
from allauth.socialaccount.models import SocialAccount
from django.db import models
from django.db.models.signals import post_save
@ -19,7 +18,7 @@ from django.utils.html import strip_tags
from taggit_autosuggest.managers import TaggableManager
from tinymce.models import HTMLField as RichTextField
from .utils import choices_length
from .utils import choices_length, en_scolarite
from .statics import DEPARTEMENTS_DEFAUT, PAYS_OPTIONS, TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, TYPE_LIEU_DICT, TYPE_STAGE_DICT, NIVEAU_SCOL_OPTIONS, NIVEAU_SCOL_DICT
import ldap
@ -53,64 +52,49 @@ class Normalien(models.Model):
@property
def en_scolarite(self):
return SocialAccount.objects.filter(user_id=self.user_id,
provider="clipper").exists()
return en_scolarite(self.user_id)
def has_nonENS_email(self):
a = EmailAddress.objects.filter(user_id=self.user_id,
verified=True) \
.exclude(email__endswith="ens.fr")
print(a)
verified=True) \
.exclude(email__endswith="ens.fr")
return a.exists()
@property
def preferred_email(self):
a = EmailAddress.objects.filter(user_id=self.user_id,
verified=True) \
.exclude(email__endswith="ens.fr")\
.order_by('-primary')
if len(a) == 0:
a = EmailAddress.objects.filter(user_id=self.user_id,
verified=True) \
.order_by('-primary')
if len(a) == 0:
return ""
else:
return a[0].email
# Hook à la création d'un nouvel utilisateur : récupération de ses infos par LDAP
def create_user_profile(sender, instance, created, **kwargs):
if created:
profil, created = Normalien.objects.get_or_create(user=instance)
try:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
l = ldap.initialize("ldaps://ldap.spi.ens.fr:636")
l.set_option(ldap.OPT_REFERRALS, 0)
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
l.set_option(ldap.OPT_X_TLS_DEMAND, True)
l.set_option(ldap.OPT_DEBUG_LEVEL, 255)
l.set_option(ldap.OPT_NETWORK_TIMEOUT, 10)
l.set_option(ldap.OPT_TIMEOUT, 10)
info = l.search_s('dc=spi,dc=ens,dc=fr',
ldap.SCOPE_SUBTREE,
('(uid=%s)' % (instance.username,)),
[str("cn"),
str("mailRoutingAddress"),
str("homeDirectory")])
# Si des informations sont disponibles
if len(info) > 0:
infos = info[0][1]
# Nom
profil.nom = infos.get('cn', [''])[0]
# Parsing du homeDirectory pour la promotion
if 'homeDirectory' in infos:
dirs = infos['homeDirectory'][0].split('/')
if dirs[1] == 'users':
annee = dirs[2]
dep = dirs[3]
dep = dict(DEPARTEMENTS_DEFAUT).get(dep.lower(), '')
profil.promotion = u'%s %s' % (dep, annee)
# Mail
pmail = infos.get('mailRoutingAddress',
['%s@clipper.ens.fr'%instance.username])
if len(pmail) > 0:
profil.mail = pmail[0]
profil.save()
except ldap.LDAPError:
pass
#post_save.connect(create_user_profile, sender=User)
saccount = SocialAccount.objects.get(user=instance,
provider="clipper")
except SocialAccount.DoesNotExist:
return
edata = saccount.extra_data.get("ldap", {})
dep = ""
if "department_code" in edata:
dep = dict(DEPARTEMENTS_DEFAUT).get(
edata["department_code"].lower(), '')
profil.promotion = "%s %s" % (dep, edata["entrance_year"])
profil.nom = edata.get("name", "")
profil.save()
post_save.connect(create_user_profile, sender=User)
#
# Lieu de stage

View file

@ -161,6 +161,13 @@ header {
}
}
p.warning {
background-color: #c20;
font-weight: bold;
color: #fff;
padding: 3px;
}
// Liste des stages condensée sur le profil
.condensed-stages {

View file

@ -229,29 +229,37 @@ header h1 {
color: #fff;
}
/* line 167, ../../sass/screen.scss */
/* line 164, ../../sass/screen.scss */
p.warning {
background-color: #c20;
font-weight: bold;
color: #fff;
padding: 3px;
}
/* line 174, ../../sass/screen.scss */
.condensed-stages li {
display: table;
width: 100%;
background: #fff;
margin: 12px;
}
/* line 174, ../../sass/screen.scss */
/* line 181, ../../sass/screen.scss */
.condensed-stages li > *, .condensed-stages li:before {
display: table-cell;
vertical-align: middle;
padding: 15px;
}
/* line 179, ../../sass/screen.scss */
/* line 186, ../../sass/screen.scss */
.condensed-stages li a {
width: auto;
}
/* line 181, ../../sass/screen.scss */
/* line 188, ../../sass/screen.scss */
.condensed-stages li a:hover {
background: #e08206;
color: #fff;
}
/* line 186, ../../sass/screen.scss */
/* line 193, ../../sass/screen.scss */
.condensed-stages li:before {
content: "";
text-align: right;
@ -259,77 +267,77 @@ header h1 {
opacity: 0.8;
color: #000;
}
/* line 193, ../../sass/screen.scss */
/* line 200, ../../sass/screen.scss */
.condensed-stages li.stage-brouillon:before {
content: "Brouillon";
background: #f93a93;
}
/* line 197, ../../sass/screen.scss */
/* line 204, ../../sass/screen.scss */
.condensed-stages li.stage-publie:before {
content: "Publié";
background: #419be9;
}
/* line 201, ../../sass/screen.scss */
/* line 208, ../../sass/screen.scss */
.condensed-stages li.stage-ajout:before {
content: "+";
color: #000;
}
/* line 209, ../../sass/screen.scss */
/* line 216, ../../sass/screen.scss */
.stage-liste li {
display: block;
position: relative;
}
/* line 213, ../../sass/screen.scss */
/* line 220, ../../sass/screen.scss */
.stage-liste li.date-maj {
font-weight: 300;
font-size: 0.9em;
padding: 3px 0;
font-style: italic;
}
/* line 219, ../../sass/screen.scss */
/* line 226, ../../sass/screen.scss */
.stage-liste li.stage {
padding: 10px;
background: #fff;
margin: 10px;
border-left: 5px solid #f99b20;
}
/* line 225, ../../sass/screen.scss */
/* line 232, ../../sass/screen.scss */
.stage-liste li.stage h3 {
font-size: 1.4em;
padding-left: 5px;
}
/* line 229, ../../sass/screen.scss */
/* line 236, ../../sass/screen.scss */
.stage-liste li.stage h3 > a {
color: #0f4c82;
}
/* line 233, ../../sass/screen.scss */
/* line 240, ../../sass/screen.scss */
.stage-liste li.stage h3 .auteur {
font-size: 0.8em;
}
/* line 236, ../../sass/screen.scss */
/* line 243, ../../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 243, ../../sass/screen.scss */
/* line 250, ../../sass/screen.scss */
.stage-liste li .misc-hdr {
margin-bottom: 10px;
}
/* line 247, ../../sass/screen.scss */
/* line 254, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates > span {
display: table-cell;
vertical-align: middle;
}
/* line 251, ../../sass/screen.scss */
/* line 258, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates .year {
padding-left: 8px;
}
/* line 254, ../../sass/screen.scss */
/* line 261, ../../sass/screen.scss */
.stage-liste li .misc-hdr .dates svg text {
font-size: 0.8;
}
/* line 260, ../../sass/screen.scss */
/* line 267, ../../sass/screen.scss */
.stage-liste li a.hoverlink {
position: absolute;
display: block;
@ -340,7 +348,7 @@ header h1 {
z-index: 2;
}
/* line 272, ../../sass/screen.scss */
/* line 279, ../../sass/screen.scss */
ul.infos {
margin: 0 -3px;
padding: 0;
@ -349,7 +357,7 @@ ul.infos {
justify-content: space-between;
width: 100;
}
/* line 280, ../../sass/screen.scss */
/* line 287, ../../sass/screen.scss */
ul.infos li {
display: inline-block;
padding: 5px;
@ -361,28 +369,28 @@ ul.infos li {
text-align: center;
background-color: #ddd;
}
/* line 291, ../../sass/screen.scss */
/* line 298, ../../sass/screen.scss */
ul.infos li.thematique {
color: #0d3f6b;
background-color: #86bff1;
}
/* line 295, ../../sass/screen.scss */
/* line 302, ../../sass/screen.scss */
ul.infos li.matiere {
color: #395214;
background-color: #c7e699;
}
/* line 299, ../../sass/screen.scss */
/* line 306, ../../sass/screen.scss */
ul.infos li.lieu {
color: #7c043c;
background-color: #fb84bc;
}
/* line 303, ../../sass/screen.scss */
/* line 310, ../../sass/screen.scss */
ul.infos li.year {
background-color: #950548;
color: #fff;
display: none;
}
/* line 308, ../../sass/screen.scss */
/* line 315, ../../sass/screen.scss */
ul.infos li.avis-len {
background-color: transparent;
border: 1px solid #eee;
@ -390,29 +398,29 @@ ul.infos li.avis-len {
padding: 4px;
padding-bottom: 2px;
}
/* line 315, ../../sass/screen.scss */
/* line 322, ../../sass/screen.scss */
ul.infos li.avis-len.avis-vide {
border-bottom-color: #ddd;
}
/* line 318, ../../sass/screen.scss */
/* line 325, ../../sass/screen.scss */
ul.infos li.avis-len.avis-court {
border-bottom-color: #ffff66;
}
/* line 321, ../../sass/screen.scss */
/* line 328, ../../sass/screen.scss */
ul.infos li.avis-len.avis-moyen {
border-bottom-color: #86bff1;
}
/* line 324, ../../sass/screen.scss */
/* line 331, ../../sass/screen.scss */
ul.infos li.avis-len.avis-long {
border-bottom-color: #a5d65c;
}
/* line 330, ../../sass/screen.scss */
/* line 337, ../../sass/screen.scss */
ul.infos:after {
content: "";
flex: 1000;
}
/* line 336, ../../sass/screen.scss */
/* line 343, ../../sass/screen.scss */
section.profil {
background: #fff;
max-width: 600px;
@ -420,7 +428,7 @@ section.profil {
margin: 5px auto;
margin-bottom: 15px;
}
/* line 343, ../../sass/screen.scss */
/* line 350, ../../sass/screen.scss */
section.profil div.infos {
border-bottom: 3px solid #1a82dd;
display: flex;
@ -712,7 +720,7 @@ article.stage .section-wrapper .toc .toc-active a {
border: 1px solid #ad0654;
}
/* line 364, ../../sass/screen.scss */
/* line 371, ../../sass/screen.scss */
input, textarea, select, div.tinymce, option, optgroup:before {
background: #fff;
font-size: 1em;
@ -722,13 +730,13 @@ input, textarea, select, div.tinymce, option, optgroup:before {
padding: 5px;
text-align: left;
}
/* line 373, ../../sass/screen.scss */
/* line 380, ../../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 380, ../../sass/screen.scss */
/* line 387, ../../sass/screen.scss */
input[type='text'], input[type='password'],
input[type='email'], input[type='number'], textarea, select {
border: none;
@ -738,7 +746,7 @@ input[type='email'], input[type='number'], textarea, select {
transition: border 1s ease-out, background 1s ease-out;
}
/* line 389, ../../sass/screen.scss */
/* line 396, ../../sass/screen.scss */
select {
-moz-appearance: none;
appearance: none;
@ -752,21 +760,21 @@ select {
background-color: #fff;
background-size: contain;
}
/* line 402, ../../sass/screen.scss */
/* line 409, ../../sass/screen.scss */
select option {
padding: 3px;
white-space: pre-wrap;
}
/* line 408, ../../sass/screen.scss */
/* line 415, ../../sass/screen.scss */
select optgroup option {
padding-left: 10px;
}
/* line 411, ../../sass/screen.scss */
/* line 418, ../../sass/screen.scss */
select optgroup:before {
font-weight: bold;
}
/* line 417, ../../sass/screen.scss */
/* line 424, ../../sass/screen.scss */
input[type="submit"], .btn {
font: 19px "Dosis", sans-serif;
background-color: #8fcc33;
@ -777,17 +785,17 @@ input[type="submit"], .btn {
display: inline-block;
}
/* line 427, ../../sass/screen.scss */
/* line 434, ../../sass/screen.scss */
p.submits {
text-align: right;
}
/* line 431, ../../sass/screen.scss */
/* line 438, ../../sass/screen.scss */
form .commentaire {
font-style: italic;
}
/* line 435, ../../sass/screen.scss */
/* line 442, ../../sass/screen.scss */
.edit-btn {
border-color: #706c00;
color: #000;
@ -796,14 +804,14 @@ form .commentaire {
background-origin: content-box;
background-size: contain;
}
/* line 443, ../../sass/screen.scss */
/* line 450, ../../sass/screen.scss */
.edit-btn:after {
content: "";
width: 30px;
display: inline-block;
}
/* line 450, ../../sass/screen.scss */
/* line 457, ../../sass/screen.scss */
textarea, div.tinymce {
font-family: "Lato", sans-serif;
border: none;
@ -813,20 +821,20 @@ textarea, div.tinymce {
transition: border 1s ease-out, background 1s ease-out;
}
/* line 459, ../../sass/screen.scss */
/* line 466, ../../sass/screen.scss */
textarea {
height: 200px;
resize: vertical;
}
/* line 467, ../../sass/screen.scss */
/* line 474, ../../sass/screen.scss */
form .field {
margin: 5px 0;
display: flex;
background: #fff;
padding: 10px;
}
/* line 473, ../../sass/screen.scss */
/* line 480, ../../sass/screen.scss */
form .field label, form .field .label {
display: inline-block;
width: 250px;
@ -835,39 +843,39 @@ form .field label, form .field .label {
padding-top: 5px;
flex-shrink: 0;
}
/* line 481, ../../sass/screen.scss */
/* line 488, ../../sass/screen.scss */
form .field label.required:before, form .field .label.required:before {
margin-right: 5px;
content: "*";
color: #f70978;
}
/* line 487, ../../sass/screen.scss */
/* line 494, ../../sass/screen.scss */
form .field label {
font-family: Alegreya, serif;
font-weight: bold;
}
/* line 491, ../../sass/screen.scss */
/* line 498, ../../sass/screen.scss */
form .field .help_text {
font-style: italic;
font-size: 0.9em;
}
/* line 495, ../../sass/screen.scss */
/* line 502, ../../sass/screen.scss */
form .field .input {
display: inline-block;
flex-grow: 1;
margin-right: 10px;
}
/* line 505, ../../sass/screen.scss */
/* line 512, ../../sass/screen.scss */
ul.as-selections {
display: flex;
flex-wrap: wrap;
}
/* line 509, ../../sass/screen.scss */
/* line 516, ../../sass/screen.scss */
ul.as-selections li {
display: inline-block;
}
/* line 513, ../../sass/screen.scss */
/* line 520, ../../sass/screen.scss */
ul.as-selections .as-selection-item {
padding: 0 5px;
background: #f99b20;
@ -876,53 +884,53 @@ ul.as-selections .as-selection-item {
border-radius: 2px;
font-weight: 500;
}
/* line 521, ../../sass/screen.scss */
/* line 528, ../../sass/screen.scss */
ul.as-selections .as-selection-item a.as-close {
color: #fff;
-webkit-cursor: pointer;
cursor: pointer;
margin-right: 5px;
}
/* line 528, ../../sass/screen.scss */
/* line 535, ../../sass/screen.scss */
ul.as-selections .as-selection-item.selected {
background: #8fcc33;
}
/* line 533, ../../sass/screen.scss */
/* line 540, ../../sass/screen.scss */
ul.as-selections .as-original {
flex-grow: 1;
min-width: 200px;
}
/* line 537, ../../sass/screen.scss */
/* line 544, ../../sass/screen.scss */
ul.as-selections .as-original input {
width: 100%;
}
/* line 543, ../../sass/screen.scss */
/* line 550, ../../sass/screen.scss */
div.as-results {
position: relative;
z-index: 2;
}
/* line 547, ../../sass/screen.scss */
/* line 554, ../../sass/screen.scss */
div.as-results ul {
position: absolute;
width: 100%;
background: #fff;
border: 1px solid #d2ebad;
}
/* line 554, ../../sass/screen.scss */
/* line 561, ../../sass/screen.scss */
div.as-results ul li {
padding: 3px 5px;
}
/* line 560, ../../sass/screen.scss */
/* line 567, ../../sass/screen.scss */
div.as-results ul li.as-result-item.active {
background: #fddeb5;
}
/* line 565, ../../sass/screen.scss */
/* line 572, ../../sass/screen.scss */
div.as-results ul li.as-message {
font-style: italic;
}
/* line 575, ../../sass/screen.scss */
/* line 582, ../../sass/screen.scss */
.window {
display: none;
position: fixed;
@ -933,11 +941,11 @@ div.as-results ul li.as-message {
left: 0;
z-index: 50;
}
/* line 585, ../../sass/screen.scss */
/* line 592, ../../sass/screen.scss */
.window.visible {
display: block;
}
/* line 589, ../../sass/screen.scss */
/* line 596, ../../sass/screen.scss */
.window .window-bg {
background: #000;
opacity: 0.7;
@ -948,7 +956,7 @@ div.as-results ul li.as-message {
top: 0;
z-index: -1;
}
/* line 600, ../../sass/screen.scss */
/* line 607, ../../sass/screen.scss */
.window .window-content {
position: relative;
margin: 0 auto;
@ -962,11 +970,11 @@ div.as-results ul li.as-message {
max-height: 100%;
overflow: auto;
}
/* line 614, ../../sass/screen.scss */
/* line 621, ../../sass/screen.scss */
.window .window-content form label, .window .window-content form .label {
width: 150px;
}
/* line 620, ../../sass/screen.scss */
/* line 627, ../../sass/screen.scss */
.window .window-closer {
position: absolute;
top: 0;
@ -974,65 +982,65 @@ div.as-results ul li.as-message {
padding: 12px;
z-index: 3;
}
/* line 626, ../../sass/screen.scss */
/* line 633, ../../sass/screen.scss */
.window .window-closer:after {
content: "×";
}
/* line 637, ../../sass/screen.scss */
/* line 644, ../../sass/screen.scss */
#lieu_widget .lieu-ui {
position: relative;
}
/* line 639, ../../sass/screen.scss */
/* line 646, ../../sass/screen.scss */
#lieu_widget .lieu-ui .map {
height: 400px;
width: 100%;
}
/* line 643, ../../sass/screen.scss */
/* line 650, ../../sass/screen.scss */
#lieu_widget .lieu-ui.hidden {
display: none;
}
/* line 646, ../../sass/screen.scss */
/* line 653, ../../sass/screen.scss */
#lieu_widget .lieu-ui .masked {
visibility: hidden;
}
/* line 651, ../../sass/screen.scss */
/* line 658, ../../sass/screen.scss */
#lieu_widget .lieu-choixmodif {
display: none;
}
/* line 656, ../../sass/screen.scss */
/* line 663, ../../sass/screen.scss */
#lieu_widget.modif .lieu-choixmodif {
display: unset;
}
/* line 661, ../../sass/screen.scss */
/* line 668, ../../sass/screen.scss */
#lieu_widget.modif .lieu-ui, #lieu_widget.attente .lieu-ui {
display: none;
}
/* line 668, ../../sass/screen.scss */
/* line 675, ../../sass/screen.scss */
#lieu_widget.edit .lieu-ui .lieu-acinput {
display: none;
}
/* line 671, ../../sass/screen.scss */
/* line 678, ../../sass/screen.scss */
#lieu_widget.edit .lieu-ui .map {
height: 200px;
}
/* line 677, ../../sass/screen.scss */
/* line 684, ../../sass/screen.scss */
#lieu_widget #avis_lieu_vide {
display: none;
}
/* line 681, ../../sass/screen.scss */
/* line 688, ../../sass/screen.scss */
#lieu_widget .message {
background: #fddeb5;
padding: 5px;
font-style: italic;
font-size: 0.9em;
}
/* line 687, ../../sass/screen.scss */
/* line 694, ../../sass/screen.scss */
#lieu_widget .message.hidden {
display: none;
}
/* line 693, ../../sass/screen.scss */
/* line 700, ../../sass/screen.scss */
a.lieu-change {
color: #fff;
background: #f99b20;
@ -1045,25 +1053,25 @@ a.lieu-change {
border-radius: 5px;
margin-right: 7px;
}
/* line 705, ../../sass/screen.scss */
/* line 712, ../../sass/screen.scss */
a.lieu-change.ajout:before {
content: "+";
margin-right: 5px;
}
/* line 711, ../../sass/screen.scss */
/* line 718, ../../sass/screen.scss */
#stages-map {
width: 100%;
height: 600px;
max-height: 90vh;
}
/* line 718, ../../sass/screen.scss */
/* line 725, ../../sass/screen.scss */
#id_stage-thematiques {
display: none;
}
/* line 724, ../../sass/screen.scss */
/* line 731, ../../sass/screen.scss */
.homeh1 {
display: flex;
justify-content: space-between;
@ -1073,26 +1081,26 @@ a.lieu-change.ajout:before {
border-bottom: 3px solid #000;
margin-bottom: 15px;
}
/* line 733, ../../sass/screen.scss */
/* line 740, ../../sass/screen.scss */
.homeh1 h1 {
margin-bottom: 3px;
}
/* line 737, ../../sass/screen.scss */
/* line 744, ../../sass/screen.scss */
.homeh1 > * {
display: inline-block;
}
/* line 740, ../../sass/screen.scss */
/* line 747, ../../sass/screen.scss */
.homeh1 p {
text-align: right;
}
/* line 745, ../../sass/screen.scss */
/* line 752, ../../sass/screen.scss */
.betacadre {
background: #fa6cae;
padding: 10px;
}
/* line 750, ../../sass/screen.scss */
/* line 757, ../../sass/screen.scss */
.entrer {
background: #fff;
max-width: 500px;
@ -1101,84 +1109,84 @@ a.lieu-change.ajout:before {
margin: 15px auto;
}
/* line 758, ../../sass/screen.scss */
/* line 765, ../../sass/screen.scss */
article.promo {
display: block;
font-size: 1.1em;
}
/* line 762, ../../sass/screen.scss */
/* line 769, ../../sass/screen.scss */
article.promo .explications {
display: table;
}
/* line 765, ../../sass/screen.scss */
/* line 772, ../../sass/screen.scss */
article.promo .explications:first-child {
direction: rtl;
}
/* line 767, ../../sass/screen.scss */
/* line 774, ../../sass/screen.scss */
article.promo .explications:first-child > * {
direction: ltr;
}
/* line 772, ../../sass/screen.scss */
/* line 779, ../../sass/screen.scss */
article.promo .explications > div {
display: table-cell;
vertical-align: middle;
text-align: center;
}
/* line 777, ../../sass/screen.scss */
/* line 784, ../../sass/screen.scss */
article.promo .explications > div p {
margin: 15px 15px;
}
/* line 785, ../../sass/screen.scss */
/* line 792, ../../sass/screen.scss */
.faq-toc {
font-family: "Lato", sans-serif;
display: block;
max-width: 700px;
margin: 0 auto;
}
/* line 790, ../../sass/screen.scss */
/* line 797, ../../sass/screen.scss */
.faq-toc ul {
margin: 20px;
}
/* line 794, ../../sass/screen.scss */
/* line 801, ../../sass/screen.scss */
.faq-toc ul li a {
color: #000;
display: block;
padding: 5px;
}
/* line 800, ../../sass/screen.scss */
/* line 807, ../../sass/screen.scss */
.faq-toc ul li.toc-h1 {
display: none;
}
/* line 804, ../../sass/screen.scss */
/* line 811, ../../sass/screen.scss */
.faq-toc ul li.toc-h2 a {
background: #fcc883;
}
/* line 808, ../../sass/screen.scss */
/* line 815, ../../sass/screen.scss */
.faq-toc ul li.toc-h3 a {
padding-left: 10px;
background: #fff;
font-weight: normal;
}
/* line 814, ../../sass/screen.scss */
/* line 821, ../../sass/screen.scss */
.faq-toc ul li a:hover {
color: #395214;
background: #bce085 !important;
}
/* line 823, ../../sass/screen.scss */
/* line 830, ../../sass/screen.scss */
.faq article {
background: #fff;
padding: 15px;
}
/* line 826, ../../sass/screen.scss */
/* line 833, ../../sass/screen.scss */
.faq article h2 {
background-color: #fcc883;
color: #ae6505;
margin: -15px;
padding: 15px;
}
/* line 833, ../../sass/screen.scss */
/* line 840, ../../sass/screen.scss */
.faq article h3 {
color: #0f4c82;
background-color: #9dcbf3;
@ -1186,19 +1194,19 @@ article.promo .explications > div p {
margin-top: 30px;
padding: 10px 15px;
}
/* line 840, ../../sass/screen.scss */
/* line 847, ../../sass/screen.scss */
.faq article h3:nth-child(2) {
margin-top: 0;
}
/* line 845, ../../sass/screen.scss */
/* line 852, ../../sass/screen.scss */
.faq article ul {
padding-left: 20px;
}
/* line 847, ../../sass/screen.scss */
/* line 854, ../../sass/screen.scss */
.faq article ul li {
list-style: initial;
}
/* line 852, ../../sass/screen.scss */
/* line 859, ../../sass/screen.scss */
.faq article p, .faq article ul {
font-family: "Lato", sans-serif;
font-size: 18px;
@ -1207,20 +1215,20 @@ article.promo .explications > div p {
margin-right: 5%;
}
/* line 866, ../../sass/screen.scss */
/* line 873, ../../sass/screen.scss */
table.stats {
width: 100%;
background: #fff;
margin: 20px 0;
cellspacing: 1px;
}
/* line 871, ../../sass/screen.scss */
/* line 878, ../../sass/screen.scss */
table.stats th {
font-weight: bold;
border-top: 1px solid #000;
border-bottom: 1px solid #999;
}
/* line 876, ../../sass/screen.scss */
/* line 883, ../../sass/screen.scss */
table.stats td, table.stats th {
padding: 5px 3px;
text-align: center;

View file

@ -0,0 +1,13 @@
{% extends "avisstage/base.html" %}
{% load staticfiles %}
{% block title %}Page non trouvée{% endblock %}
{% block content %}
<article>
<section>
<h1>Page non trouvée</h1>
<p>Cette page n'existe pas, ou peut-être que vous n'y avez pas accès.</p>
</section>
</article>
{% endblock %}

View file

@ -0,0 +1,14 @@
{% extends "avisstage/base.html" %}
{% load staticfiles %}
{% block title %}Accès interdit{% endblock %}
{% block content %}
<article>
<section>
<h1>Accès réservé aux personnes en scolarité</h1>
<p>Vous pouvez pas consulter cette page : après la fin de votre scolarité, vous ne pouvez accéder qu'à votre profil et vos fiches de stages pour les tenir à jour.</p>
<p><a href="{% url "avisstage:perso" %}">Aller à mon tableau de bord</a></p>
</section>
</article>
{% endblock %}

View file

@ -27,7 +27,9 @@
<ul id="menu">
{% if user.is_authenticated %}
<li><a href="{% url 'avisstage:perso' %}">Mon expérience</a></li>
<li><a href="{% url 'avisstage:recherche' %}">Recherche</a></li>
{% if user.profil.en_scolarite %}
<li><a href="{% url 'avisstage:recherche' %}">Recherche</a></li>
{% endif %}
{% endif %}
<li><a href="{% url 'avisstage:faq' %}">FAQ</a></li>
{% if user.is_staff %}

View file

@ -18,7 +18,7 @@
<p class="promo">Promotion : <b>{{ object.promotion }}</b></p>
<p class="contact">
{% if object.contactez_moi %}
Contact : <a href="mailto:{{ object.mail }}">{{ object.mail }}</a>
Contact : <a href="mailto:{{ object.preferred_email }}">{{ object.preferred_email }}</a>
{% endif %}
</p>
</div>

View file

@ -11,8 +11,9 @@
{% if not user.is_authenticated %}
<div class="entrer">
<p><a href="{% url "account_login" %}" class="btn">Connexion</a></p>
<p class="helptext">Connexion via le serveur central d'authentification ENS (identifiants clipper)</p>
<p><a href="{% url "clipper_login" %}" class="btn">Connexion</a></p>
<p class="helptext">Connexion via le serveur central d'authentification ENS <br />(identifiants clipper)</p>
<p><a href="{% url "account_login" %}">Accès archicubes</a> <i>Pour continuer à tenir à jour ses fiches, sans voir celles des autres</i></p>
</div>
{% endif %}
@ -23,7 +24,13 @@
</div>
<div>
<p>Ne partez plus en stage en terre inconnue : nourrissez-vous des {{ num_stages }} expériences de séjours effectués par la communauté normalienne, repérez les bons plans, et ne faites pas les mêmes erreurs&nbsp;!</p>
{% if user.is_authenticated %}<p><a href="{% url 'avisstage:recherche' %}" class="btn">Rechercher des stages</a></p>{% endif %}
{% if user.is_authenticated %}
{% if user.profil.en_scolarite %}
<p><a href="{% url 'avisstage:recherche' %}" class="btn">Rechercher des stages</a></p>
{% else %}
<p><i>Accès restreint aux personnes en scolarité</i></p>
{% endif %}
{% endif %}
</div>
</div>
<div class="explications">

View file

@ -10,22 +10,28 @@
<h2>Mon compte</h2>
<section class="profil">
{% if user.profil.en_scolarite %}
<p class="scolarite">Statut : En scolarité</p>
<h3 class="scolarite">Statut : En scolarité</h3>
<p>Vous pouvez accéder à l'ensemble du site, et aux fiches de stages.</p>
<p>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.</p>
<p>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 !</p>
{% else %}
<p class="scolarite">Statut : Archicube</p>
<h3 class="scolarite">Statut : Archicube</h3>
<p>Vous ne pouvez plus accéder qu'à vos propres expériences pour les modifier, et tenir à jour votre profil.</p>
<p>Si vous êtes encore en scolarité, merci de vous <a href="{% url "clipper_login" %}">reconnecter en passant par le serveur d'authentification de l'ENS</a> pour mettre à jour votre statut.</p>
{% endif %}
<p><i>Le statut est mis à jour automatiquement chaque année selon le mode de connexion que vous utilisez.</i></p>
</section>
<section class="profil">
<h3>Adresses e-mail</h3>
{% if not user.profil.has_nonENS_email %}<p align="center" class="warning">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 !</p>{% endif %}
<p><a href="{% url "account_email" %}">Gérer les adresses e-mail liées à mon compte</a></p>
</section>
<section class="profil">
<h3>Mode de connexion</h3>
{% if user.profil.en_scolarite %}<p>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 l'identifiant {{ user.username }}</p>{% endif %}
{% if not user.password %}<p class="warning" align="center">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 !</p>{% endif %}
<p><a href="{% url "account_change_password" %}">Créer / changer mon mot de passe ExperiENS</a></p>
</section>
<p class="help_text">Le statut est mis à jour automatiquement chaque année selon le mode de connexion que vous utilisez.</p>
{% if not user.profil.has_nonENS_email %}<p class="warning">Vous n'avez pas renseigné d'adresse mail autre que celle de l'ENS. Pensez à le faire !</p>{% endif %}
<p><a href="{% url "account_email" %}">Gérer les adresses e-mail liées à mon compte</a></p>
{% if not user.password %}<p class="warning">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 !</p>{% endif %}
<p><a href="{% url "account_change_password" %}">Changer mon mot de passe ExperiENS</a></p>
<p>Votre nom d'utilisateur pour la connexion directement sur ExperiENS est <tt>{{ user.username }}</tt>.</p>
</article>
<article>
@ -36,7 +42,7 @@
<p class="promo">Promotion : <b>{{ object.promotion }}</b></p>
<p class="contact">
{% if object.contactez_moi %}
Contact : {{ object.mail }}
Contact : {{ object.preferred_email }}
{% endif %}
</p>
</div>

View file

@ -14,15 +14,18 @@ urlpatterns = [
url(r'^stage/nouveau/$', views.manage_stage, name='stage_ajout'),
url(r'^stage/(?P<pk>\w+)/$', views.StageView.as_view(), name='stage'),
url(r'^stage/(?P<pk>\w+)/edit/$', views.manage_stage, name='stage_edit'),
url(r'^stage/(?P<pk>\w+)/publication/$', views.publier_stage, name='stage_publication'),
url(r'^stages/majs/$', views.StageListe.as_view(), name='stage_majs'),
url(r'^stage/(?P<pk>\w+)/publication/$', views.publier_stage,
name='stage_publication'),
url(r'^403/archicubes/$', views.archicubes_interdits,
name='403-archicubes'),
url(r'^lieu/save/$', views.save_lieu, name='lieu_ajout'),
url(r'^profil/show/(?P<username>[\w@]+)/$', views.ProfilView.as_view(),
name='profil'),
url(r'^profil/edit/$', views.ProfilEdit.as_view(), name='profil_edit'),
url(r'^recherche/$', views.recherche, name='recherche'),
url(r'^recherche/resultats/$', views.recherche_resultats, name='recherche_resultats'),
url(r'^recherche/resultats/$', views.recherche_resultats,
name='recherche_resultats'),
url(r'^recherche/items/$', views.stage_items, name='stage_items'),
url(r'^feedback/$', views.feedback, name='feedback'),
url(r'^moderation/$', views.statistiques, name='moderation'),

View file

@ -1,6 +1,15 @@
# coding: utf-8
from allauth.socialaccount.models import SocialAccount
from functools import reduce
def choices_length (choices):
return reduce (lambda m, choice: max (m, len (choice[0])), choices, 0)
def en_scolarite(user_or_id):
if isinstance(user_or_id, int):
user_id = user_or_id
else:
user_id = user_or_id.id
return SocialAccount.objects.filter(user_id=user_id,
provider="clipper").exists()

View file

@ -9,14 +9,16 @@ from django.urls import reverse
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
from braces.views import LoginRequiredMixin
from django.http import JsonResponse, HttpResponseForbidden
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 avisstage.models import Normalien, Stage, Lieu, AvisLieu, AvisStage
from avisstage.forms import StageForm, LieuForm, AvisStageForm, AvisLieuForm, FeedbackForm
from avisstage.views_search import *
from .models import Normalien, Stage, Lieu, AvisLieu, AvisStage
from .forms import StageForm, LieuForm, AvisStageForm, AvisLieuForm, FeedbackForm
from .utils import en_scolarite
from .views_search import *
import random, math
@ -35,6 +37,11 @@ def index(request):
def perso(request):
return render(request, 'avisstage/perso.html')
# 403 Archicubes
@login_required
def archicubes_interdits(request):
return render(request, 'avisstage/403-archicubes.html')
# Profil
#login_required
class ProfilView(LoginRequiredMixin, DetailView):
@ -43,7 +50,14 @@ class ProfilView(LoginRequiredMixin, DetailView):
# Récupération du profil
def get_object(self):
return Normalien.objects.get(user__username=self.kwargs.get('username'))
# Restriction d'accès pour les archicubes
if (en_scolarite(self.request.user) or
self.kwargs.get('username') == self.request.user.username):
return Normalien.objects.get(user__username=
self.kwargs.get('username'))
else:
raise Http404
# Stage
#login_required
@ -53,19 +67,15 @@ class StageView(LoginRequiredMixin, DetailView):
# Restriction aux stages publics ou personnels
def get_queryset(self):
filtre = Q(auteur__user_id=self.request.user.id) | Q(public=True)
filtre = Q(auteur__user_id=self.request.user.id)
# Restriction d'accès pour les archicubes
if en_scolarite(self.request.user):
filtre |= Q(public=True)
return Stage.objects.filter(filtre)
# Liste des stages par dernière modification
#login_required
class StageListe(LoginRequiredMixin, ListView):
model = Stage
template_name = 'avisstage/recherche/stage.html'
def get_queryset(self):
return Stage.objects.filter(public=True).order_by('-date_maj')
# FAQ
def faq(request):
return render(request, 'avisstage/faq.html')
@ -78,7 +88,7 @@ def faq(request):
#login_required
class ProfilEdit(LoginRequiredMixin, UpdateView):
model = Normalien
fields = ['nom', 'promotion', 'mail', 'contactez_moi', 'bio']
fields = ['nom', 'promotion', 'contactez_moi', 'bio']
template_name = 'avisstage/formulaires/profil.html'
# Limitation à son propre profil

View file

@ -14,6 +14,7 @@ import json
import logging
from .documents import StageDocument
from .decorators import en_scolarite_required
from .models import Stage
from .statics import TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, NIVEAU_SCOL_OPTIONS
@ -131,12 +132,14 @@ def cherche(**kwargs):
return resultat, tri
@login_required
@en_scolarite_required
def recherche(request):
form = SearchForm()
return render(request, 'avisstage/recherche/recherche.html',
{"form": form})
@login_required
@en_scolarite_required
def recherche_resultats(request):
stages = []
tri = ''
@ -203,6 +206,7 @@ def recherche_resultats(request):
"tri": tri, "vue": vue, "lieux": lieux})
@login_required
@en_scolarite_required
def stage_items(request):
try:
stageids = [int(a) for a in request.GET.get("ids", "").split(';')]

View file

@ -123,11 +123,14 @@ CAS_REDIRECT_URL = reverse_lazy('avisstage:perso')
CAS_EMAIL_FORMAT = "%s@clipper.ens.fr"
CAS_FORCE_CHANGE_USERNAME_CASE = "lower"
CAS_VERSION = 'CAS_2_SAML_1_0'
SOCIALACCOUNT_ADAPTER='allauth_ens.adapter.LongTermClipperAccountAdapter'
ACCOUNT_ADAPTER = 'avisstage.allauth_adapter.AccountAdapter'
SOCIALACCOUNT_ADAPTER = 'avisstage.allauth_adapter.SocialAccountAdapter'
LOGIN_URL = reverse_lazy('account_login')
LOGOUT_URL = reverse_lazy('account_logout')
LOGIN_REDIRECT_URL = reverse_lazy('avisstage:perso')
ACCOUNT_HOME_URL = reverse_lazy('avisstage:index')
LOGGING = {
'version': 1,