Projet

Général

Profil

« Précédent | Suivant » 

Révision cacbe34d

Ajouté par Josué Kouka il y a plus de 8 ans

handle association failure (#9415)

Voir les différences:

.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
README
76 76
            'help': ''
77 77
        },
78 78
    ]
79

  
79 80
    # List of javascript scripts running on every pages 
80 81
    # loaded in panel.html
81 82
    SITE_SCRIPTS = [
82 83
        'js/example.com.js',
83 84
    ]
84 85

  
86
    # JS Script asserting authentication through phantomjs
87
    # The authentication assertion function must be into 
88
    # a var such as :
89
    #
90
    # window.auth_success = function(){
91
    #       // your code 
92
    #    }
93
    #   
94
    SITE_AUTH_CHECKER = 'js/vincennes_auth_checker.js'
95

  
96
    # JS/CSS for the association page (/_mandaye/associate)
85 97
    SITE_ASSOCIATE_STATIC = {
86 98
        'css': 'css/example_associate.css',
87 99
        'js': 'js/example_associate.js',
......
95 107
    ]
96 108
    
97 109
    MELLON_VERIFY_SSL_CERTIFICATE = False
98

  
99

  
110
 
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');
41 50
  page.evaluate(function(input) {
42 51
      var locators = input.locators;
43 52
      for ( var i=0; i < locators.length; i++ ) { 
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

  
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
});

Formats disponibles : Unified diff