0001-association-failure-handled-9415.patch
.gitignore | ||
---|---|---|
3 | 3 |
*.log |
4 | 4 |
*.sh |
5 | 5 |
*.swp |
6 | ||
7 |
./static |
|
6 |
*.patch |
|
7 |
local_settings* |
|
8 |
cookies.txt |
|
9 |
./static/ |
|
8 | 10 |
uwsgi* |
9 | 11 |
*.sqlite3 |
mandayejs/do_login.js | ||
---|---|---|
33 | 33 | |
34 | 34 |
page.open(input.address, function() { |
35 | 35 |
page.onLoadFinished = function() { |
36 |
if (page.injectJs(input.auth_checker)){ |
|
37 |
input.auth_success = page.evaluate(function(){ |
|
38 |
return auth_success(); |
|
39 |
}); |
|
40 |
} |
|
41 |
|
|
42 |
if (!input.auth_success){ |
|
43 |
console.log(JSON.stringify({'result': 'failure', 'reason': 'authentication failed'})); |
|
44 |
phantom.exit(); |
|
45 |
} |
|
36 | 46 |
page.render('login.png'); |
37 | 47 |
console.log(JSON.stringify({'result': 'ok', 'cookies': page.cookies, 'headers': headers_list, 'url': page.frameUrl})); |
38 | 48 |
phantom.exit(); |
39 | 49 |
} |
40 |
page.injectJs('static/js/jquery.min.js');
|
|
50 |
page.injectJs('jquery.min.js'); |
|
41 | 51 |
page.evaluate(function(input) { |
42 | 52 |
var locators = input.locators; |
43 | 53 |
for ( var i=0; i < locators.length; i++ ) { |
mandayejs/locale/fr/LC_MESSAGES/django.po | ||
---|---|---|
8 | 8 |
msgstr "" |
9 | 9 |
"Project-Id-Version: PACKAGE VERSION\n" |
10 | 10 |
"Report-Msgid-Bugs-To: \n" |
11 |
"POT-Creation-Date: 2015-12-17 17:16+0000\n"
|
|
11 |
"POT-Creation-Date: 2015-12-23 14:02+0000\n"
|
|
12 | 12 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
13 | 13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 |
"Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | |
22 | 22 |
msgid "locators" |
23 | 23 |
msgstr "selecteurs" |
24 | 24 | |
25 |
#: mandayejs/mandaye/models.py:25 |
|
26 |
#, fuzzy |
|
27 |
#| msgid "associate" |
|
28 |
msgid "associated" |
|
29 |
msgstr "associer mon compte" |
|
30 | ||
25 | 31 |
#: mandayejs/mandaye/templates/mandaye/panel.html:10 |
26 | 32 |
msgid "dissociate" |
27 | 33 |
msgstr "dissocier mon compte" |
... | ... | |
31 | 37 |
msgid "associate" |
32 | 38 |
msgstr "associer mon compte" |
33 | 39 | |
34 |
#: mandayejs/mandaye/views.py:56
|
|
40 |
#: mandayejs/mandaye/views.py:60
|
|
35 | 41 |
msgid "login" |
36 | 42 |
msgstr "se connecter" |
37 | 43 | |
38 |
#: mandayejs/mandaye/views.py:57
|
|
44 |
#: mandayejs/mandaye/views.py:61
|
|
39 | 45 |
msgid "logout" |
40 | 46 |
msgstr "se déconnecter" |
41 | 47 | |
42 |
#: mandayejs/mandaye/views.py:100 |
|
48 |
#: mandayejs/mandaye/views.py:108 |
|
49 |
msgid "wrong user credentials" |
|
50 |
msgstr "codes d'accès invalides" |
|
51 | ||
52 |
#: mandayejs/mandaye/views.py:111 |
|
43 | 53 |
msgid "submit" |
44 | 54 |
msgstr "valider" |
45 | 55 | |
46 |
#: mandayejs/mandaye/views.py:101
|
|
56 |
#: mandayejs/mandaye/views.py:112
|
|
47 | 57 |
msgid "associate your account" |
48 | 58 |
msgstr "associer mon compte" |
mandayejs/mandaye/migrations/0006_usercredentials_linked.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import models, migrations |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('mandaye', '0005_auto_20151126_1413'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AddField( |
|
15 |
model_name='usercredentials', |
|
16 |
name='linked', |
|
17 |
field=models.BooleanField(default=True, verbose_name='associated'), |
|
18 |
preserve_default=True, |
|
19 |
), |
|
20 |
] |
mandayejs/mandaye/models.py | ||
---|---|---|
22 | 22 |
class UserCredentials(models.Model): |
23 | 23 |
user = models.ForeignKey('auth.User') |
24 | 24 |
locators = JSONField(_('locators'), default={}, blank=True) |
25 |
linked = models.BooleanField(_('associated'), default=True, blank=True) |
|
25 | 26 | |
26 | 27 |
class Meta: |
27 | 28 |
unique_together = ('user',) |
28 | 29 | |
29 | 30 |
def __str__(self): |
30 |
return self.user.email
|
|
31 |
return self.user.get_full_name() or self.user.email or self.user.username
|
|
31 | 32 | |
32 | 33 |
def to_login_info(self): |
33 | 34 |
return {'#'+k : v for k,v in self.locators.items() if k != 'csrfmiddlewaretoken' } |
35 | ||
36 |
def is_linked(self,): |
|
37 |
return self.linked |
mandayejs/mandaye/templates/mandaye/associate.html | ||
---|---|---|
9 | 9 |
<body> |
10 | 10 |
<div id="main-div"> |
11 | 11 |
<h1>{{ associate|capfirst }}</h1> |
12 |
{%if messages %} |
|
13 |
<ul class="messages"> |
|
14 |
{%for message in messages%} |
|
15 |
<li>{{message}}</li> |
|
16 |
{%endfor%} |
|
17 |
</ul> |
|
18 |
{%endif%} |
|
12 | 19 |
<form id='associate' method="post"> |
13 | 20 |
{% csrf_token %} |
14 | 21 |
{{ form.as_p }} |
mandayejs/mandaye/templates/mandaye/post-login.html | ||
---|---|---|
2 | 2 |
<html> |
3 | 3 |
<head> |
4 | 4 |
<script src="{% xstatic 'jquery' 'jquery.min.js' %}"></script> |
5 |
<script src="{% static 'mandaye.post.js' %}"></script> |
|
6 |
<script type='text/javascript'> |
|
7 |
var url = "{{ address }}" ; |
|
8 |
</script> |
|
9 | 5 |
</head> |
10 | 6 |
<body> |
11 | 7 |
Please wait... |
mandayejs/mandaye/utils.py | ||
---|---|---|
13 | 13 |
# |
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | ||
17 | ||
16 |
import os |
|
17 |
import json |
|
18 |
import subprocess |
|
18 | 19 |
from django.conf import settings |
19 | 20 | |
20 | 21 |
import urlparse |
21 | 22 |
from Cookie import SimpleCookie |
22 | 23 | |
23 | 24 | |
25 |
def exec_phantom(data): |
|
26 |
phantom = subprocess.Popen(['/usr/bin/phantomjs', |
|
27 |
'--ignore-ssl-errors=yes', |
|
28 |
'--ssl-protocol=any', |
|
29 |
'--cookies-file=cookies.txt', |
|
30 |
os.path.join(settings.BASE_DIR, 'mandayejs', 'do_login.js')], |
|
31 |
close_fds=True, |
|
32 |
stdin=subprocess.PIPE, |
|
33 |
stdout=subprocess.PIPE) |
|
34 |
stdout, stderr = phantom.communicate(json.dumps(data)) |
|
35 |
result = json.loads(stdout) |
|
36 |
return result |
|
37 | ||
24 | 38 |
def cookie_builder(headers): |
25 | 39 |
"""Build Cookies from list of headers |
26 | 40 |
""" |
mandayejs/mandaye/views.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from __future__ import absolute_import |
|
18 | ||
17 | 19 |
import os |
18 | 20 |
import json |
19 | 21 |
import logging |
20 |
import subprocess |
|
21 | 22 |
import urlparse |
22 | 23 |
import urllib |
23 | 24 | |
... | ... | |
26 | 27 |
from django.contrib.auth import logout as auth_logout |
27 | 28 |
from django.contrib.auth import get_user_model |
28 | 29 |
from django.contrib.auth.decorators import login_required |
30 |
from django.contrib import messages |
|
29 | 31 |
from django.forms import PasswordInput |
30 | 32 |
from django.forms import models as model_forms |
31 | 33 |
from django.http import HttpResponseRedirect, HttpResponse |
... | ... | |
35 | 37 |
from django.views.decorators.csrf import csrf_exempt |
36 | 38 |
from django.db import IntegrityError |
37 | 39 |
from django.utils.translation import ugettext_lazy as _ |
40 |
from django.template import RequestContext, Template |
|
38 | 41 | |
39 | 42 |
from .models import UserCredentials |
40 | 43 |
from mandayejs.mandaye.forms import FormFactory |
41 |
from mandayejs.mandaye.utils import cookie_builder, get_location |
|
44 |
from mandayejs.mandaye.utils import exec_phantom, cookie_builder, get_location |
|
45 | ||
46 |
logger = logging.getLogger(__name__) |
|
42 | 47 | |
43 | 48 |
def login(request, *args, **kwargs): |
44 | 49 |
return auth_views.login(request, *args, **kwargs) |
... | ... | |
63 | 68 |
def is_account_linked(self): |
64 | 69 |
"""Check if user account is associated |
65 | 70 |
""" |
66 |
try: |
|
67 |
UserCredentials.objects.get(user=self.request.user) |
|
68 |
return True |
|
69 |
except : |
|
71 |
try: |
|
72 |
User = get_user_model() |
|
73 |
user = User.objects.get(username=self.request.user.username) |
|
74 |
return user.usercredentials_set.get().linked |
|
75 |
except (User.DoesNotExist, UserCredentials.DoesNotExist) as e: |
|
70 | 76 |
return False |
71 | 77 | |
72 | 78 | |
... | ... | |
75 | 81 |
@login_required |
76 | 82 |
def post_login(request, *args, **kwargs): |
77 | 83 |
try: |
84 |
user = get_user_model().objects.get(username=request.user.username) |
|
85 |
logger.debug(user) |
|
78 | 86 |
credentials = UserCredentials.objects.get( |
79 |
user=request.user) |
|
80 |
except UserCredentials.DoesNotExist: |
|
87 |
user=user, |
|
88 |
linked=True) |
|
89 |
logger.debug(credentials) |
|
90 |
except (UserCredentials.DoesNotExist,): |
|
81 | 91 |
return HttpResponseRedirect(resolve_url('associate')) |
82 | 92 | |
83 | 93 |
context = {} |
... | ... | |
88 | 98 |
@csrf_exempt |
89 | 99 |
def associate(request, *args, **kwargs): |
90 | 100 |
if request.POST: |
91 |
credentials = UserCredentials() |
|
92 |
credentials.user = request.user |
|
101 |
credentials, created = UserCredentials.objects.get_or_create(user=request.user) |
|
93 | 102 |
credentials.locators = request.POST |
103 |
credentials.linked = True |
|
104 |
credentials.save() |
|
94 | 105 |
form = FormFactory(request.POST, auto_id=True, locators=settings.SITE_LOCATORS) |
95 | 106 |
else: |
96 | 107 |
form = FormFactory(auto_id=True, locators=settings.SITE_LOCATORS) |
97 | 108 |
if not form.is_valid(): |
98 |
return render(request, 'mandaye/associate.html', {
|
|
109 |
response = render(request, 'mandaye/associate.html', {
|
|
99 | 110 |
'form': form, |
100 | 111 |
'submit': _('submit'), |
101 | 112 |
'associate': _('associate your account'), |
... | ... | |
103 | 114 |
'SITE_ASSOCIATE_STATIC', |
104 | 115 |
{'css':'', 'js':''}) |
105 | 116 |
}) |
106 |
try: |
|
107 |
credentials.save() |
|
108 |
except (IntegrityError,) as e: |
|
109 |
pass |
|
110 | ||
117 |
return response |
|
118 |
|
|
111 | 119 |
return HttpResponseRedirect(resolve_url('post-login')) |
112 | 120 | |
113 | 121 |
@login_required |
114 | 122 |
def dissociate(request, *args, **kwargs): |
115 | 123 |
try: |
116 |
User = get_user_model() |
|
117 |
User.objects.get(username=request.user).delete() |
|
124 |
c_user = UserCredentials.objects.get( |
|
125 |
user__username=request.user.username) |
|
126 |
c_user.linked = False |
|
127 |
c_user.save() |
|
118 | 128 |
return HttpResponseRedirect(resolve_url('mellon_logout')) |
119 |
except (User.DoesNotExist,) as e:
|
|
129 |
except (UserCredentials.DoesNotExist,):
|
|
120 | 130 |
return HttpResponseRedirect(resolve_url('associate')) |
121 | 131 | |
122 | 132 |
@login_required |
... | ... | |
125 | 135 |
login_info = { |
126 | 136 |
'address': request.build_absolute_uri(settings.SITE_LOGIN_PATH), |
127 | 137 |
'cookies': [], |
128 |
'locators': [ credentials.to_login_info() ] |
|
138 |
'locators': [ credentials.to_login_info() ], |
|
139 |
'homepath': getattr(settings, 'SITE_HOME_PATH', '/'), |
|
140 |
'auth_checker': os.path.join(settings.STATIC_ROOT, getattr(settings, 'SITE_AUTH_CHECKER')) |
|
129 | 141 |
} |
142 |
logger.debug(login_info) |
|
130 | 143 |
result = exec_phantom(login_info) |
144 |
logger.debug(result) |
|
131 | 145 |
if result.get('result') != 'ok': |
132 |
return HttpResponseRedirect('/') |
|
133 |
location = get_location(result.get('url','/')) |
|
134 |
response = HttpResponseRedirect(location) |
|
135 |
response.cookies = cookie_builder(result.get('headers')) |
|
146 |
logger.debug('authentication failed') |
|
147 |
User = get_user_model() |
|
148 |
user = User.objects.get(username=request.user.username) |
|
149 |
c_user = user.usercredentials_set.get() |
|
150 |
c_user.linked = False |
|
151 |
c_user.save() |
|
152 |
logger.debug("redirecting to {}".format(resolve_url('associate'))) |
|
153 |
messages.error(request, _('wrong user credentials')) |
|
154 |
url = resolve_url('associate') |
|
155 |
else: |
|
156 |
url = getattr(settings, 'SITE_HOME_PATH', '/') |
|
157 | ||
158 |
template = Template('<script type="text/javascript">\ |
|
159 |
window.top.location = "{{url}}";</script>') |
|
160 |
context = RequestContext(request, {'url': url}) |
|
161 |
response = HttpResponse(template.render(context)) |
|
162 |
if result.get('headers',None): |
|
163 |
response.cookies = cookie_builder(result.get('headers')) |
|
164 | ||
136 | 165 |
return response |
137 | 166 | |
138 |
def exec_phantom(data): |
|
139 |
phantom = subprocess.Popen(['/usr/bin/phantomjs', |
|
140 |
'--ignore-ssl-errors=yes', |
|
141 |
'--ssl-protocol=any', |
|
142 |
'--cookies-file=cookies.txt', |
|
143 |
os.path.join(settings.BASE_DIR,'mandayejs/do_login.js')], |
|
144 |
close_fds=True, |
|
145 |
stdin=subprocess.PIPE, |
|
146 |
stdout=subprocess.PIPE) |
|
147 |
stdout, stderr = phantom.communicate(json.dumps(data)) |
|
148 |
result = json.loads(stdout) |
|
149 |
return result |
mandayejs/sites/vincennes/static/css/vincennes_associate.css | ||
---|---|---|
13 | 13 |
font-size: x-small; |
14 | 14 |
} |
15 | 15 | |
16 |
.messages { |
|
17 |
font-size: small; |
|
18 |
text-align: left; |
|
19 |
postion: relative; |
|
20 |
margin-left: 90px; |
|
21 |
color: red; |
|
22 |
} |
|
23 | ||
24 |
.messages li { list-style-type: none } |
|
25 | ||
16 | 26 |
.errorlist { |
17 | 27 |
font-size: small; |
18 | 28 |
text-align: left; |
mandayejs/sites/vincennes/static/js/vincennes_auth_checker.js | ||
---|---|---|
1 |
$(function(){ |
|
2 |
window.auth_success = function(){ |
|
3 |
var found = $("body").text().indexOf('Les informations de connexion'); |
|
4 |
if (found == -1) |
|
5 |
return true; |
|
6 |
return false; |
|
7 |
}; |
|
8 |
}); |
|
0 |
- |