Commit 16eecc36 authored by alexandre's avatar alexandre

First implementation of login/logout views

parent 52b12ad6
...@@ -27,6 +27,8 @@ INSTALLED_APPS = [ ...@@ -27,6 +27,8 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'rest_framework', 'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'playground', 'playground',
] ]
...@@ -100,6 +102,16 @@ USE_TZ = True ...@@ -100,6 +102,16 @@ USE_TZ = True
ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value. ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.
# cf <https://stackoverflow.com/questions/30871033/django-rest-framework-remove-csrf>
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
# 'rest_framework.authentication.TokenAuthentication',
'playground.authentication.CsrfExemptSessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
)
}
try: try:
LOCAL_SETTINGS LOCAL_SETTINGS
except NameError: except NameError:
......
...@@ -31,6 +31,7 @@ urlpatterns = [ ...@@ -31,6 +31,7 @@ urlpatterns = [
url(r'^api/', include(router.urls)), url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^', include('playground.urls')), url(r'^', include('playground.urls')),
] ]
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
# cf <https://stackoverflow.com/questions/30871033/django-rest-framework-remove-csrf>
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
...@@ -835,4 +835,45 @@ section.hidden { ...@@ -835,4 +835,45 @@ section.hidden {
.score-edit { .score-edit {
margin: 1em 0 1em 0; margin: 1em 0 1em 0;
} }
\ No newline at end of file
.modalDialog {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99999;
transition: opacity 400ms ease-in;
}
.modalDialog > div {
width: 400px;
position: relative;
margin: 10% auto;
padding: 5px 20px 13px 20px;
background: #fff;
}
.close {
background: #606061;
color: #FFFFFF;
line-height: 25px;
position: absolute;
right: -12px;
text-align: center;
top: -10px;
width: 24px;
text-decoration: none;
font-weight: bold;
border-radius: 12px;
box-shadow: 1px 1px 3px #000;
}
.close:hover {
background: #00d9ff;
}
...@@ -10,7 +10,9 @@ window.W = window.W || {}; ...@@ -10,7 +10,9 @@ window.W = window.W || {};
region: 'body', region: 'body',
onStart: function(options) { onStart: function(options) {
this.showView(new W.BaseView()); var userModel = new W.UserModel();
this.showView(new W.BaseView({model: userModel}));
userModel.fetch();
var router = new W.ScoreRouter({application: this}); var router = new W.ScoreRouter({application: this});
......
...@@ -6,6 +6,22 @@ window.W = window.W || {}; ...@@ -6,6 +6,22 @@ window.W = window.W || {};
(function (undefined) { (function (undefined) {
'use strict'; 'use strict';
W.UserModel = Backbone.Model.extend({
urlRoot: '/rest-auth/user/',
defaults: {
username: ""
},
url: function () {
var original_url = Backbone.Model.prototype.url.call(this);
var parsed_url = original_url + (original_url.charAt(original_url.length - 1) == '/' ? '' : '/');
return parsed_url;
},
});
W.ScoreModel = Backbone.RelationalModel.extend({ W.ScoreModel = Backbone.RelationalModel.extend({
defaults: { defaults: {
title: "Untitled", title: "Untitled",
...@@ -87,7 +103,6 @@ window.W = window.W || {}; ...@@ -87,7 +103,6 @@ window.W = window.W || {};
// console.log(data); // console.log(data);
return data; return data;
}, },
}); });
......
...@@ -1453,6 +1453,99 @@ window.W = window.W || {}; ...@@ -1453,6 +1453,99 @@ window.W = window.W || {};
}); });
/**
* User views
*/
W.LoginView = Backbone.Marionette.View.extend({
template: '#login-template',
ui: {
'close': '.btn-close',
'submit': '.btn-submit'
},
triggers: {
'click @ui.close': 'hide:modal',
'click @ui.submit': 'submit',
},
onSubmit: function (foo, event) {
event.preventDefault();
var model = this.model;
var that = this;
var form = this.$el.find("form");
var data = form.serialize();
$.ajax({
type: "POST",
url: form.attr('action'),
data: form.serialize(),
success: function(data, textStatus, jqXHR) {
model.fetch();
that.trigger('hide:modal');
},
error: function(xhr, ajaxOptions, thrownError){
alert('login failed - please try again');
},
});
}
});
W.LogoutView = Backbone.Marionette.View.extend({
template: '#logout-template',
ui: {
'close': '.btn-close',
'submit': '.btn-submit'
},
triggers: {
'click @ui.close': 'hide:modal',
'click @ui.submit': 'submit'
},
onSubmit: function (foo, event) {
event.preventDefault();
var that = this;
var model = this.model;
var form = this.$el.find("form");
$.ajax({
type: "POST",
url: form.attr('action'),
success: function(data, textStatus, jqXHR){
that.trigger('hide:modal');
alert("ok");
model.set(model.defaults);
},
error: function(xhr, ajaxOptions, thrownError){
alert('logout failed - please try again');
// that.trigger('hide:modal');
// model.clear();
},
});
}
});
W.RegisterView = Backbone.Marionette.View.extend({
template: '#register-template',
ui: {
'close': '.btn-close'
},
triggers: {
'click @ui.close': 'hide:modal',
},
});
/** /**
* Other views * Other views
*/ */
...@@ -1510,15 +1603,25 @@ window.W = window.W || {}; ...@@ -1510,15 +1603,25 @@ window.W = window.W || {};
ui: { ui: {
'toggle': '.btn-hamburger', 'toggle': '.btn-hamburger',
'login': '.btn-login',
'logout': '.btn-logout',
'register': '.btn-register',
}, },
triggers: { triggers: {
'click @ui.toggle': 'toggle', 'click @ui.toggle': 'toggle',
'click @ui.login': 'show:login',
'click @ui.logout': 'show:logout',
'click @ui.register': 'show:register',
},
initialize: function () {
this.listenTo(this.model, 'change', this.render);
}, },
onToggle: function() { onToggle: function() {
this.$el.toggleClass('main-header--collapsed'); this.$el.toggleClass('main-header--collapsed');
} },
}); });
...@@ -1541,11 +1644,38 @@ window.W = window.W || {}; ...@@ -1541,11 +1644,38 @@ window.W = window.W || {};
main: { main: {
el: '.main-area', el: '.main-area',
// replaceElement: true // replaceElement: true
},
modal: {
el: '.modal',
// replaceElement: true
} }
}, },
childViewEvents: {
'show:login': 'showLogin',
'show:register': 'showRegister',
'show:logout': 'showLogout',
'hide:modal': 'hideModal'
},
onRender: function () { onRender: function () {
this.showChildView('header', new W.HeaderView()); this.showChildView('header', new W.HeaderView({model: this.model}));
} },
showLogin: function(event) {
this.showChildView('modal', new W.LoginView({model: this.model}));
},
showLogout: function(event) {
this.showChildView('modal', new W.LogoutView({model: this.model}));
},
showRegister: function(event) {
this.showChildView('modal', new W.RegisterView());
},
hideModal: function(event) {
this.detachChildView('modal');
},
}); });
})(); })();
...@@ -26,6 +26,18 @@ ...@@ -26,6 +26,18 @@
{% include "playground/underscore/about.mtpl" %} {% include "playground/underscore/about.mtpl" %}
</script> </script>
<script id="login-template" type="text/template">
{% include "playground/underscore/login.mtpl" %}
</script>
<script id="logout-template" type="text/template">
{% include "playground/underscore/logout.mtpl" %}
</script>
<script id="register-template" type="text/template">
{% include "playground/underscore/register.mtpl" %}
</script>
<script id="score-list-template" type="text/template"> <script id="score-list-template" type="text/template">
{% include "playground/underscore/score-list.mtpl" %} {% include "playground/underscore/score-list.mtpl" %}
</script> </script>
......
<header class="main-header"></header> <header class="main-header"></header>
<main class="main-area"></main> <main class="main-area"></main>
<div class="modal"></div>
...@@ -9,14 +9,19 @@ ...@@ -9,14 +9,19 @@
<div class="btn-hamburger js-collapse">☰</div> <div class="btn-hamburger js-collapse">☰</div>
<nav> <nav>
Bienvenue {{ user.username }} <% if (username) { %>
Bienvenue <%- username %>
<% } else { %>
Bienvenue anonymous
<% } %>
<ul> <ul>
{% if user.is_authenticated %}
<li><a href="{% url 'auth_logout' %}">Se déconnecter</a></li> <% if (username) { %>
{% else %} <li><a href="{% url 'auth_logout' %}" class="btn-logout">Se déconnecter</a></li>
<li><a href="{% url 'auth_login' %}">Se connecter</a></li> <% } else { %>
<li><a href="{% url 'registration_register' %}">S'inscrire</a></li> <li><a href="{% url 'auth_login' %}" class="btn-login">Se connecter</a></li>
{% endif %} <li><a href="{% url 'registration_register' %}" class="btn-register">S'inscrire</a></li>
<% } %>
</ul> </ul>
</nav> </nav>
......
<div id="openModal" class="modalDialog">
<div> <a href="#close" title="Close" class="btn-close">X</a>
<h2>Log in (new)</h2>
<form method="post" action="/rest-auth/login/">
<p><label for="id_username">Username:</label> <input autofocus="" id="id_username" maxlength="254" name="username" type="text" required /></p>
<p><label for="id_password">Password:</label> <input id="id_password" name="password" type="password" required /></p>
<input type="submit" class="btn-submit" value="Log in" />
</form>
<!-- <p>Forgot your password? <a href="/accounts/password/reset/">Reset it</a>.</p> -->
<!-- <p>Not a member? <a href="/accounts/register/">Register</a>.</p> -->
</div>
</div>
<div id="openModal" class="modalDialog">
<div> <a href="#close" title="Close" class="btn-close">X</a>
<h2>Etes-vous sur de vouloir vous deconnecter?</h2>
<form method="post" action="/rest-auth/logout/">
<p><input class="btn-submit" type="submit" value="ok"></input></p>
</form>
</div>
</div>
<div id="openModal" class="modalDialog">
<div> <a href="#close" title="Close" class="btn-close">X</a>
<h2>Register</h2>
<form method="post" action="">
<input type="hidden" name="csrfmiddlewaretoken" value="DlQBl1CbGROA9YeL2VUa4lOn0d41iyKBJO2qYw469dnJVEJ7KD3XSTUF4tKSYESL">
<p><label for="id_username">Username:</label> <input autofocus="" id="id_username" maxlength="150" name="username" type="text" required=""> <span class="helptext">Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.</span></p>
<p><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" required=""> <span class="helptext">email address</span></p>
<p><label for="id_password1">Password:</label> <input id="id_password1" name="password1" type="password" required=""></p>
<p><label for="id_password2">Password confirmation:</label> <input id="id_password2" name="password2" type="password" required=""> <span class="helptext">Enter the same password as before, for verification.</span></p>
<input type="submit" value="Submit">
</form>
</div>
</div>
...@@ -2,4 +2,5 @@ django>=1.10,<1.11 ...@@ -2,4 +2,5 @@ django>=1.10,<1.11
django-registration django-registration
djangorestframework djangorestframework
djangorestframework-recursive djangorestframework-recursive
django-rest-auth
psycopg2 psycopg2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment