Initial package (WIP)
This commit is contained in:
parent
5bc1446dd3
commit
916b08374a
36 changed files with 5463 additions and 0 deletions
3
allauth_ens/__init__.py
Normal file
3
allauth_ens/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
__version__ = '0.0.1.dev0'
|
||||
|
||||
default_app_config = 'allauth_ens.apps.ENSAllauthAppConfig'
|
7
allauth_ens/apps.py
Normal file
7
allauth_ens/apps.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class ENSAllauthAppConfig(AppConfig):
|
||||
name = 'allauth_ens'
|
||||
verbose_name = _("ENS Authentication")
|
0
allauth_ens/providers/__init__.py
Normal file
0
allauth_ens/providers/__init__.py
Normal file
0
allauth_ens/providers/clipper/__init__.py
Normal file
0
allauth_ens/providers/clipper/__init__.py
Normal file
0
allauth_ens/providers/clipper/models.py
Normal file
0
allauth_ens/providers/clipper/models.py
Normal file
42
allauth_ens/providers/clipper/provider.py
Normal file
42
allauth_ens/providers/clipper/provider.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from allauth.account.models import EmailAddress
|
||||
from allauth.socialaccount.providers.base import ProviderAccount
|
||||
|
||||
from allauth_cas.providers import CASProvider
|
||||
|
||||
|
||||
class ClipperAccount(ProviderAccount):
|
||||
pass
|
||||
|
||||
|
||||
class ClipperProvider(CASProvider):
|
||||
id = 'clipper'
|
||||
name = 'Clipper'
|
||||
account_class = ClipperAccount
|
||||
|
||||
def extract_email(self, data):
|
||||
username, _, _ = data
|
||||
return '{}@clipper.ens.fr'.format(username)
|
||||
|
||||
def extract_common_fields(self, data):
|
||||
common = super(ClipperProvider, self).extract_common_fields(data)
|
||||
common['email'] = self.extract_email(data)
|
||||
return common
|
||||
|
||||
def extract_email_addresses(self, data):
|
||||
email = self.extract_email(data)
|
||||
return [
|
||||
EmailAddress(
|
||||
email=email,
|
||||
verified=True,
|
||||
primary=True,
|
||||
)
|
||||
]
|
||||
|
||||
def extract_extra_data(self, data):
|
||||
extra = super(ClipperProvider, self).extract_extra_data(data)
|
||||
extra['email'] = self.extract_email(data)
|
||||
return extra
|
||||
|
||||
|
||||
provider_classes = [ClipperProvider]
|
33
allauth_ens/providers/clipper/tests.py
Normal file
33
allauth_ens/providers/clipper/tests.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from allauth_cas.test.testcases import CASViewTestCase
|
||||
|
||||
|
||||
class ClipperViewsTests(CASViewTestCase):
|
||||
|
||||
def test_login_view(self):
|
||||
r = self.client.get('/accounts/clipper/login/')
|
||||
expected = (
|
||||
"https://cas.eleves.ens.fr/login?service=http%3A%2F%2Ftestserver"
|
||||
"%2Faccounts%2Fclipper%2Flogin%2Fcallback%2F"
|
||||
)
|
||||
self.assertRedirects(
|
||||
r, expected,
|
||||
fetch_redirect_response=False,
|
||||
)
|
||||
|
||||
def test_callback_view(self):
|
||||
self.patch_cas_response(valid_ticket='__all__')
|
||||
r = self.client.get('/accounts/clipper/login/callback/', {
|
||||
'ticket': '123456',
|
||||
})
|
||||
self.assertLoginSuccess(r)
|
||||
|
||||
def test_logout_view(self):
|
||||
r = self.client.get('/accounts/clipper/logout/')
|
||||
expected = (
|
||||
"https://cas.eleves.ens.fr/logout?service=http%3A%2F%2Ftestserver"
|
||||
"%2F"
|
||||
)
|
||||
self.assertRedirects(
|
||||
r, expected,
|
||||
fetch_redirect_response=False,
|
||||
)
|
6
allauth_ens/providers/clipper/urls.py
Normal file
6
allauth_ens/providers/clipper/urls.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from allauth_cas.urls import default_urlpatterns
|
||||
|
||||
from .provider import ClipperProvider
|
||||
|
||||
urlpatterns = default_urlpatterns(ClipperProvider)
|
15
allauth_ens/providers/clipper/views.py
Normal file
15
allauth_ens/providers/clipper/views.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from allauth_cas import views
|
||||
|
||||
from .provider import ClipperProvider
|
||||
|
||||
|
||||
class ClipperCASAdapter(views.CASAdapter):
|
||||
provider_id = ClipperProvider.id
|
||||
url = 'https://cas.eleves.ens.fr'
|
||||
version = 3
|
||||
|
||||
|
||||
login = views.CASLoginView.adapter_view(ClipperCASAdapter)
|
||||
callback = views.CASCallbackView.adapter_view(ClipperCASAdapter)
|
||||
logout = views.CASLogoutView.adapter_view(ClipperCASAdapter)
|
358
allauth_ens/scss/_base.scss
Normal file
358
allauth_ens/scss/_base.scss
Normal file
|
@ -0,0 +1,358 @@
|
|||
body {
|
||||
font-family: Roboto, Verdana;
|
||||
font-family: $font-family-base;
|
||||
line-height: 1.4;
|
||||
background: $gray-lightest;
|
||||
color: $gray;
|
||||
|
||||
@media (min-width: 576px) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
@include link;
|
||||
}
|
||||
|
||||
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* Layout structure *
|
||||
********************/
|
||||
|
||||
$main-max-width: 700px;
|
||||
|
||||
$divider-size: 2px;
|
||||
|
||||
.wrapper {
|
||||
max-width: $main-max-width;
|
||||
margin: 0 auto;
|
||||
|
||||
background: $white;
|
||||
box-shadow: 0 0 10px $gray-lighter;
|
||||
|
||||
}
|
||||
|
||||
@media (min-height: 400px) and (min-width: 576px) {
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-height: 500px) and (min-width: 576px) {
|
||||
.wrapper {
|
||||
position: relative;
|
||||
top: -5%;
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
|
||||
/* Blocks */
|
||||
|
||||
& > section {
|
||||
flex: 1 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
& > section {
|
||||
flex: 1 1 auto;
|
||||
width: 350px - $divider-size / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Divider */
|
||||
|
||||
& > .divider {
|
||||
display: none;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
content: " ";
|
||||
background: $gray-lighter;
|
||||
|
||||
height: $divider-size;
|
||||
width: $divider-size;
|
||||
}
|
||||
|
||||
@media (max-width: 575px) {
|
||||
& {
|
||||
flex: 100%;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
&::before { width: 100%; }
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
& {
|
||||
align-self: stretch;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
&::before { height: 100%; }
|
||||
}
|
||||
}
|
||||
|
||||
& > section + .divider {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
* Header *
|
||||
**********/
|
||||
|
||||
$header-bg: darken($red, 10%);
|
||||
$header-history-icon-size: 20px;
|
||||
|
||||
header {
|
||||
@include clearfix;
|
||||
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
|
||||
min-height: 60px;
|
||||
|
||||
background: $header-bg;
|
||||
color: $white;
|
||||
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
|
||||
button {
|
||||
width: 60px;
|
||||
cursor: pointer;
|
||||
|
||||
background: transparent;
|
||||
|
||||
@include hover-focus {
|
||||
background: lighten($header-bg, 5%);
|
||||
}
|
||||
|
||||
img {
|
||||
height: $header-history-icon-size;
|
||||
width: auto;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 15px 35px 15px 15px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
* Messages *
|
||||
************/
|
||||
|
||||
.messages-container {
|
||||
padding: 0 15px;
|
||||
|
||||
&::after {
|
||||
display: block;
|
||||
content: "";
|
||||
background-color: $gray-lighter;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.messages-list {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
& + .message {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&.warning { color: darken($orange, 15%); }
|
||||
&.error { color: $red; }
|
||||
}
|
||||
|
||||
|
||||
/***********
|
||||
* Content *
|
||||
***********/
|
||||
|
||||
section {
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Methods list */
|
||||
|
||||
$space-between: 15px;
|
||||
|
||||
.method-list {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
margin: - $space-between / 2;
|
||||
}
|
||||
|
||||
.method-wrapper {
|
||||
flex: 1 50%;
|
||||
padding: $space-between / 2;
|
||||
|
||||
a {
|
||||
@include btn;
|
||||
@include btn-primary-hov;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Connected accounts list */
|
||||
|
||||
.provider-list {
|
||||
|
||||
& > li {
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
|
||||
& > .heading > * {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********
|
||||
* Forms *
|
||||
*********/
|
||||
|
||||
$input-space-after: 10px;
|
||||
$input-wrapper-padding: 0;
|
||||
|
||||
|
||||
$input-border-color: rgba(0,0,0,0.12);
|
||||
$input-border-width: 1px;
|
||||
$input-border-width-lg: 2px;
|
||||
$input-padding: 2px;
|
||||
$input-font-size: 16px;
|
||||
$input-height: 30px;
|
||||
|
||||
$label-small-scale: 0.75;
|
||||
|
||||
$input-height-inner: $input-height - 2 * $input-padding;
|
||||
|
||||
$label-height: $input-height-inner;
|
||||
$label-small-top: $label-height * (1 - $label-small-scale);
|
||||
$label-top: $label-height + $input-wrapper-padding + $input-padding;
|
||||
|
||||
.input-wrapper {
|
||||
@include clearfix;
|
||||
|
||||
position: relative;
|
||||
display: block;
|
||||
margin: ($label-small-scale * $label-height) 0;
|
||||
padding: $input-wrapper-padding;
|
||||
|
||||
label {
|
||||
@include ellipsis;
|
||||
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
|
||||
padding-left: $input-wrapper-padding;
|
||||
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
height: $label-height;
|
||||
line-height: $label-height;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
color: rgba(0,0,0,0.38);
|
||||
font-size: $input-font-size;
|
||||
|
||||
transform: translate3d(0,$label-height + $input-padding,0) scale(1);
|
||||
transition: transform .4s cubic-bezier(.25,.8,.25,1);
|
||||
transform-origin: left top;
|
||||
}
|
||||
|
||||
input.field {
|
||||
height: $input-height;
|
||||
width: 100%;
|
||||
|
||||
padding: $input-padding $input-padding ($input-padding - $input-border-width);
|
||||
|
||||
background-color: $white;
|
||||
line-height: $input-height-inner;
|
||||
|
||||
border-bottom: $input-border-width solid $input-border-color;
|
||||
|
||||
font-size: $input-font-size;
|
||||
}
|
||||
|
||||
@mixin input-special($type, $color: $input-border-color) {
|
||||
&.input-#{$type} input.field {
|
||||
padding-bottom: $input-padding - $input-border-width-lg;
|
||||
border-width: $input-border-width-lg;
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
&.input-focused label,
|
||||
&.input-has-value label {
|
||||
transform: translate3d(0,$label-small-top,0) scale($label-small-scale);
|
||||
}
|
||||
|
||||
@include input-special('has-value', $green);
|
||||
@include input-special('error', $red);
|
||||
@include input-special('focused', $blue);
|
||||
|
||||
.infos-spacer {
|
||||
float: right;
|
||||
min-height: $input-space-after;
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[type=submit]:not(.link) {
|
||||
@include btn;
|
||||
@include btn-success-hov;
|
||||
}
|
||||
|
||||
[type=submit].link {
|
||||
@include link;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
|
||||
@include hover-focus {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
@include btn;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn-primary-hov {
|
||||
@include btn-primary-hov;
|
||||
}
|
86
allauth_ens/scss/_mixins.scss
Normal file
86
allauth_ens/scss/_mixins.scss
Normal file
|
@ -0,0 +1,86 @@
|
|||
@mixin hover {
|
||||
&:hover { @content }
|
||||
}
|
||||
|
||||
@mixin hover-focus {
|
||||
@if $enable-hover-media-query {
|
||||
&:focus { @content }
|
||||
@include hover { @content }
|
||||
} @else {
|
||||
&:focus,
|
||||
&:hover {
|
||||
@content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin clearfix() {
|
||||
&::after {
|
||||
display: block;
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin ellipsis($text-overflow: ellipsis) {
|
||||
& {
|
||||
overflow: hidden;
|
||||
text-overflow: $text-overflow;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin link {
|
||||
color: $link-color;
|
||||
font-size: inherit;
|
||||
text-decoration: $link-decoration;
|
||||
|
||||
@include hover-focus {
|
||||
color: $link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn {
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
|
||||
border: 0;
|
||||
padding: 15px 10px;
|
||||
|
||||
font-family: "Roboto Slab";
|
||||
font-size: 18px;
|
||||
|
||||
text-align:center;
|
||||
|
||||
transition: background .3s;
|
||||
|
||||
@include hover-focus {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-primary-hov {
|
||||
// background: $gray-lighter;
|
||||
color: $black;
|
||||
// border: 1px dashed $gray;
|
||||
// border-top: 2px solid transparent;
|
||||
// border-bottom: 2px solid darken($brand-primary, 15%);
|
||||
|
||||
@include hover-focus {
|
||||
background: darken($brand-primary, 15%);
|
||||
color: $white;
|
||||
// border: 1px solid darken($brand-primary, 15%);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-success-hov {
|
||||
background: $gray-lighter;
|
||||
color: $black;
|
||||
|
||||
@include hover-focus {
|
||||
background: darken($brand-success, 15%);
|
||||
color: $white;
|
||||
}
|
||||
}
|
24
allauth_ens/scss/_reset.scss
Normal file
24
allauth_ens/scss/_reset.scss
Normal file
|
@ -0,0 +1,24 @@
|
|||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
a, input, button {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input, button {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0 30px white inset;
|
||||
}
|
67
allauth_ens/scss/_variables.scss
Normal file
67
allauth_ens/scss/_variables.scss
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Colors
|
||||
|
||||
$white: #fff !default;
|
||||
$black: #000 !default;
|
||||
$red: #d9534f !default;
|
||||
$orange: #f0ad4e !default;
|
||||
$yellow: #ffd500 !default;
|
||||
$green: #5cb85c !default;
|
||||
$blue: #0275d8 !default;
|
||||
$teal: #5bc0de !default;
|
||||
$pink: #ff5b77 !default;
|
||||
$purple: #613d7c !default;
|
||||
|
||||
$gray-dark: #292b2c !default;
|
||||
$gray: #464a4c !default;
|
||||
$gray-light: #636c72 !default;
|
||||
$gray-lighter: #eceeef !default;
|
||||
$gray-lightest: #f7f7f9 !default;
|
||||
|
||||
$brand-primary: $blue !default;
|
||||
$brand-success: $green !default;
|
||||
$brand-info: $teal !default;
|
||||
$brand-warning: $orange !default;
|
||||
$brand-danger: $red !default;
|
||||
$brand-inverse: $gray-dark !default;
|
||||
|
||||
// Links
|
||||
|
||||
$link-color: $brand-primary !default;
|
||||
$link-decoration: none !default;
|
||||
$link-hover-color: darken($link-color, 15%) !default;
|
||||
$link-hover-decoration: underline !default;
|
||||
|
||||
|
||||
// Body
|
||||
|
||||
$body-bg: $white !default;
|
||||
$body-color: $gray-dark !default;
|
||||
|
||||
|
||||
// Fonts
|
||||
|
||||
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
|
||||
$font-family-monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
|
||||
$font-family-base: $font-family-sans-serif !default;
|
||||
|
||||
$font-size-base: 1rem !default;
|
||||
|
||||
$font-weight-normal: normal !default;
|
||||
$font-weight-bold: bold !default;
|
||||
|
||||
$font-weight-base: $font-weight-normal !default;
|
||||
$line-height-base: 1.5 !default;
|
||||
|
||||
$text-muted: $gray-light !default;
|
||||
|
||||
$dt-font-weight: $font-weight-bold !default;
|
||||
|
||||
|
||||
// Tables
|
||||
|
||||
$table-cell-padding: .75rem !default;
|
||||
|
||||
|
||||
// Options
|
||||
|
||||
$enable-hover-media-query: false !default;
|
5
allauth_ens/scss/ie.scss
Normal file
5
allauth_ens/scss/ie.scss
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Welcome to Compass. Use this file to write IE specific override styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <!--[if IE]>
|
||||
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
|
||||
* <![endif]--> */
|
3
allauth_ens/scss/print.scss
Normal file
3
allauth_ens/scss/print.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
/* Welcome to Compass. Use this file to define print styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */
|
17
allauth_ens/scss/screen.scss
Normal file
17
allauth_ens/scss/screen.scss
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* Welcome to Compass.
|
||||
* In this file you should write your main styles. (or centralize your imports)
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
|
||||
|
||||
// @import "vendor/normalize";
|
||||
// @import "reset";
|
||||
@import "compass/reset";
|
||||
@import "reset";
|
||||
|
||||
@import "font-awesome-compass";
|
||||
@import "font-awesome";
|
||||
|
||||
@import "variables";
|
||||
@import "mixins";
|
||||
|
||||
@import "base";
|
105
allauth_ens/static/allauth_ens/authens.js
Normal file
105
allauth_ens/static/allauth_ens/authens.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
|
||||
|
||||
/*************************
|
||||
* Input fields handlers *
|
||||
*************************/
|
||||
|
||||
function toggleWrapperClass(class_name, callable) {
|
||||
let func = function(bool) {
|
||||
if (bool === undefined)
|
||||
bool = callable.apply(this);
|
||||
this.wrapper.toggleClass(class_name, bool);
|
||||
};
|
||||
return func;
|
||||
}
|
||||
|
||||
let Input = function(field) {
|
||||
|
||||
this.dom_field = field;
|
||||
this.field = $(field);
|
||||
this.wrapper = $(field).closest('.input-wrapper');
|
||||
|
||||
// initialization
|
||||
this.update_focus();
|
||||
this.update_has_value();
|
||||
|
||||
// register event handlers
|
||||
this.field.focus( () => this.on_focus() );
|
||||
this.field.blur( () => this.on_blur() );
|
||||
this.field.on('change', () => this.on_change() );
|
||||
};
|
||||
|
||||
Input.prototype = {
|
||||
has_value: function() { return this.field.val() ? true : false; },
|
||||
has_focus: function() { return this.field.is(':focus'); },
|
||||
has_error: function() { return !this.has_value() && this.field.prop('required'); },
|
||||
|
||||
on_focus: function() { this.update_focus(true); },
|
||||
on_blur: function() { this.update_focus(false); },
|
||||
on_change: function() {
|
||||
this.update_has_value();
|
||||
this.update_error();
|
||||
}
|
||||
};
|
||||
|
||||
Object.assign(Input.prototype, {
|
||||
update_focus: toggleWrapperClass('input-focused', Input.prototype.has_focus),
|
||||
update_error: toggleWrapperClass('input-error', Input.prototype.has_error),
|
||||
update_has_value: toggleWrapperClass('input-has-value', Input.prototype.has_value),
|
||||
});
|
||||
|
||||
|
||||
$( function() {
|
||||
let fields = $('input.field');
|
||||
fields.map( function() { return new Input(this); });
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* History
|
||||
*/
|
||||
|
||||
$( function() {
|
||||
$('.history-back').click( () => history.back() );
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Keyboard shortcuts
|
||||
*
|
||||
* - A method can be selected by pressing Ctrl+Alt+(first letter of method name)
|
||||
* (or second if first is already used...)
|
||||
*/
|
||||
|
||||
function prepareShorcuts() {
|
||||
let shorcuts = {};
|
||||
|
||||
$('.method-wrapper a').each( function() {
|
||||
let name = $(this).text();
|
||||
|
||||
for (let i=0; i < name.length; i++) {
|
||||
let key = name[i].toLowerCase();
|
||||
if (key !== '' && shorcuts[key] === undefined) {
|
||||
shorcuts[key] = this;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.methodsShorcuts = shorcuts;
|
||||
}
|
||||
|
||||
$( function() {
|
||||
// Register shorcuts
|
||||
prepareShorcuts();
|
||||
|
||||
// Shorcuts handler
|
||||
$(document).keydown( function(e) {
|
||||
if (e.ctrlKey && e.altKey) {
|
||||
let methodLink = window.methodsShorcuts[e.key];
|
||||
if (methodLink !== undefined)
|
||||
methodLink.click();
|
||||
}
|
||||
});
|
||||
});
|
5
allauth_ens/static/allauth_ens/ie.css
Normal file
5
allauth_ens/static/allauth_ens/ie.css
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Welcome to Compass. Use this file to write IE specific override styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <!--[if IE]>
|
||||
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
|
||||
* <![endif]--> */
|
Binary file not shown.
After Width: | Height: | Size: 381 B |
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 -256 1792 1792"
|
||||
id="svg3013"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="chevron_left_font_awesome.svg">
|
||||
<metadata
|
||||
id="metadata3023">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs3021" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview3019"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.13169643"
|
||||
inkscape:cx="896"
|
||||
inkscape:cy="896"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3013" />
|
||||
<g
|
||||
transform="matrix(1,0,0,-1,387.25424,1338.5763)"
|
||||
id="g3015">
|
||||
<path
|
||||
d="M 742,-37 90,614 Q 53,651 53,704.5 53,758 90,795 l 652,651 q 37,37 90.5,37 53.5,0 90.5,-37 l 75,-75 q 37,-37 37,-90.5 0,-53.5 -37,-90.5 L 512,704 998,219 q 37,-38 37,-91 0,-53 -37,-90 L 923,-37 Q 886,-74 832.5,-74 779,-74 742,-37 z"
|
||||
id="path3017"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:currentColor" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
allauth_ens/static/allauth_ens/images/clipper.jpeg
Normal file
BIN
allauth_ens/static/allauth_ens/images/clipper.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
3
allauth_ens/static/allauth_ens/print.css
Normal file
3
allauth_ens/static/allauth_ens/print.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
/* Welcome to Compass. Use this file to define print styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */
|
4250
allauth_ens/static/allauth_ens/screen.css
Normal file
4250
allauth_ens/static/allauth_ens/screen.css
Normal file
File diff suppressed because it is too large
Load diff
9
allauth_ens/templates/account/base-login.html
Normal file
9
allauth_ens/templates/account/base-login.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "account/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Connexion" %} - {% project_name %}{% endblock %}
|
||||
{% block header-title %}{% trans "Connexion à" %} {% project_name %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>{% include "account/block-form.html" %}</section>
|
||||
{% endblock %}
|
11
allauth_ens/templates/account/base-logout.html
Normal file
11
allauth_ens/templates/account/base-logout.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% extends "authens/base.html" %}
|
||||
{% load authens i18n %}
|
||||
|
||||
{% block title %}{% trans "Déconnexion" %} - {% project_name %}{% endblock %}
|
||||
{% block header-title %}{% trans "Déconnexion de" %} {% project_name %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
{% trans "Vous êtes déjà déconnecté-e." %}
|
||||
</section>
|
||||
{% endblock %}
|
55
allauth_ens/templates/account/base.html
Normal file
55
allauth_ens/templates/account/base.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
{% load static %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
|
||||
{# Responsive UI #}
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{# CSS #}
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css?family=Roboto:400,700|Roboto+Slab:400">
|
||||
<link rel="stylesheet"
|
||||
href="{% static "allauth_ens/screen.css" %}">
|
||||
|
||||
{# JS #}
|
||||
<script type="text/javascript"
|
||||
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
|
||||
integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<script type="text/javascript"
|
||||
src="{% static "allauth_ens/authens.js" %}"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<header>
|
||||
<button type="button" class="history-back">
|
||||
<img src="{% static "allauth_ens/images/64px-Chevron_left_font_awesome.svg.png" %}">
|
||||
</button>
|
||||
<h1>{% block header-title %}{% endblock %}</h1>
|
||||
</header>
|
||||
|
||||
{% include "account/block-messages.html" %}
|
||||
|
||||
{% block messages-extra %}{% endblock %}
|
||||
|
||||
<div class="content-wrapper">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
20
allauth_ens/templates/account/block-form.html
Normal file
20
allauth_ens/templates/account/block-form.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% load i18n %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
<form action="{% url "account_login" %}" method="post">
|
||||
{% csrf_token %}
|
||||
<ul class="input-list">
|
||||
{% for field in form %}
|
||||
<li class="input-wrapper">
|
||||
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{% render_field field class+="field" autocomplete="off" autocapitalize="none" placeholder="" %}
|
||||
<div class="infos-spacer"></div>
|
||||
{% if field.help_text %}
|
||||
<p class="help">{{ field.help_text|safe }}</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<input type="submit" value="{% trans "Sign In" %}">
|
||||
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}">
|
||||
</form>
|
11
allauth_ens/templates/account/block-messages.html
Normal file
11
allauth_ens/templates/account/block-messages.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% if messages %}
|
||||
<div class="messages-container">
|
||||
<ul class="messages-list">
|
||||
{% for message in messages %}
|
||||
<li class="message {{ message.level_tag }}">
|
||||
{{ message }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
63
allauth_ens/templates/account/login.html
Normal file
63
allauth_ens/templates/account/login.html
Normal file
|
@ -0,0 +1,63 @@
|
|||
{% extends "account/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load account socialaccount %}
|
||||
|
||||
{% block title %}{% trans "Sign In" %} - {{ site.name }}{% endblock %}
|
||||
{% block header-title %}
|
||||
{% blocktrans with site.name as site_name %}
|
||||
Sign in {{ site_name }}
|
||||
{% endblocktrans %}
|
||||
{% endblock %}
|
||||
|
||||
{% block messages-extra %}
|
||||
{% if form.errors or user.is_authenticated %}
|
||||
<div class="messages-container">
|
||||
<ul class="messages-list">
|
||||
{% if form.errors %}
|
||||
<li class="message error">
|
||||
{% blocktrans %}
|
||||
Authentication failed. Please check your credentials and try again.
|
||||
{% endblocktrans %}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user.is_authenticated %}
|
||||
<li class="message warning">
|
||||
{% blocktrans %}
|
||||
You are unauthorized to view this page. Please sign in with an account
|
||||
with the required permissions.
|
||||
{% endblocktrans %}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% get_providers as socialaccount_providers %}
|
||||
|
||||
{% if socialaccount_providers %}
|
||||
<section>
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
Please sign in with one of your existing third party accounts, or with the
|
||||
form opposite.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<ul class="method-list">
|
||||
{% include "socialaccount/snippets/provider_list.html" with process="login" %}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{% include "socialaccount/snippets/login_extra.html" %}
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
<section>
|
||||
{% include "account/block-form.html" with form=form %}
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
28
allauth_ens/templates/account/logout.html
Normal file
28
allauth_ens/templates/account/logout.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% extends "account/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Sign Out" %} - {{ site.name }}{% endblock %}
|
||||
{% block header-title %}
|
||||
{% blocktrans with site.name as site_name %}
|
||||
Sign out {{ site_name }}
|
||||
{% endblocktrans %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<section>
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
Are you sure you want to sign out?
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<form action="{% url "account_logout" %}" method="post">
|
||||
{% csrf_token %}
|
||||
{% if redirect_field_value %}
|
||||
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}">
|
||||
{% endif %}
|
||||
<input type="submit" value="{% trans "Sign Out" %}">
|
||||
</form>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
32
allauth_ens/templates/account/settings.html
Normal file
32
allauth_ens/templates/account/settings.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
{% extends "account/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Account Preferences" %} - {{ request.site.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block header-title %}
|
||||
{% blocktrans with request.site.name as site_name %}
|
||||
Account Preferences - {{ site_name }}
|
||||
{% endblocktrans %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<section>
|
||||
|
||||
<ul class="method-list">
|
||||
<li class="method-wrapper">
|
||||
<a href="{% url "account_change_password" %}">{% trans "Change password" %}</a>
|
||||
</li>
|
||||
<li class="method-wrapper">
|
||||
<a href="{% url "account_email" %}">{% trans "Manage emails" %}</a>
|
||||
</li>
|
||||
<li class="method-wrapper">
|
||||
<a href="{% url "socialaccount_connections" %}">{% trans "Check account connections" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
73
allauth_ens/templates/socialaccount/connections.html
Normal file
73
allauth_ens/templates/socialaccount/connections.html
Normal file
|
@ -0,0 +1,73 @@
|
|||
{% extends "account/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load socialaccount %}
|
||||
{% load allauth_ens_social %}
|
||||
|
||||
{% block title %}{% trans "Account Connections" %} - {{ request.site.name }}{% endblock %}
|
||||
{% block header-title %}
|
||||
{% trans "Account Connections" %} - {{ request.site.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<section>
|
||||
<p>
|
||||
{% if form.accounts %}
|
||||
{% blocktrans %}
|
||||
You can sign in to your account using any of the following third party accounts:
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans %}
|
||||
You currently have no third party accounts connected to this account.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
<ul class="provider-list">
|
||||
{% get_providers_with_accounts user as providers_with_accounts %}
|
||||
|
||||
{% for provider in providers_with_accounts %}
|
||||
|
||||
<li class="provider">
|
||||
<ul class="heading">
|
||||
<li>
|
||||
<a class="connect"
|
||||
href="{% provider_login_url provider.provider.id process="connect" scope=scope auth_params=auth_params %}">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<b>{{ provider.provider.name }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% if provider.accounts %}
|
||||
|
||||
<ul class="connected-account-list">
|
||||
{% for base_account in provider.accounts %}
|
||||
<li>
|
||||
<span>
|
||||
<small style="font-size: 14px">
|
||||
{% firstof base_account.extra_data.name base_account.email %}
|
||||
</small>
|
||||
</span>
|
||||
<span>
|
||||
{% with base_account.get_provider_account as account %}
|
||||
<form action="{% url "socialaccount_connections" %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="account" value="{{ base_account.id }}">
|
||||
<input type="submit" class="link" value="{% trans "Remove" %}">
|
||||
</form>
|
||||
{% endwith %}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,26 @@
|
|||
{% load socialaccount %}
|
||||
|
||||
{% if not socialaccount_providers %}
|
||||
{% get_providers as socialaccount_providers %}
|
||||
{% endif %}
|
||||
|
||||
{% for provider in socialaccount_providers %}
|
||||
{% if provider.id == "openid" %}
|
||||
{% for brand in provider.get_brands %}
|
||||
<li class="method-wrapper">
|
||||
<a title="{{ brand.name }}"
|
||||
href="{% provider_login_url provider.id openid=brand.openid_url process=process %}"
|
||||
>
|
||||
{{ brand.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<li class="method-wrapper">
|
||||
<a title="{{ provider.name }}"
|
||||
href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_parms %}"
|
||||
>
|
||||
{{ provider.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
28
allauth_ens/templatetags/allauth_ens_social.py
Normal file
28
allauth_ens/templatetags/allauth_ens_social.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
import django
|
||||
from django import template
|
||||
|
||||
from allauth.socialaccount.templatetags import socialaccount as tt_social
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
if django.VERSION >= (1, 9):
|
||||
simple_tag = register.simple_tag
|
||||
else:
|
||||
simple_tag = register.assignment_tag
|
||||
|
||||
|
||||
@simple_tag
|
||||
def get_providers_with_accounts(user):
|
||||
providers = tt_social.get_providers()
|
||||
accounts = tt_social.get_social_accounts(user)
|
||||
|
||||
providers_with_accounts = [
|
||||
{
|
||||
'provider': provider,
|
||||
'accounts': accounts.get(provider.id, []),
|
||||
}
|
||||
for provider in providers
|
||||
]
|
||||
|
||||
return providers_with_accounts
|
8
allauth_ens/urls.py
Normal file
8
allauth_ens/urls.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from django.conf.urls import include, url
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^settings/$', views.account_settings,
|
||||
name="account_settings"),
|
||||
url(r'^', include('allauth.urls')),
|
||||
]
|
11
allauth_ens/views.py
Normal file
11
allauth_ens/views.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class SettingsAccount(TemplateView):
|
||||
template_name = 'account/settings.html'
|
||||
|
||||
|
||||
account_settings = SettingsAccount.as_view()
|
Loading…
Reference in a new issue