Browse Source

Add OpenID authentication in parallel with casual one

Arnaud Delcasse 12 years ago
parent
commit
4036f1d5d9
5 changed files with 42 additions and 7 deletions
  1. 21 3
      main.py
  2. 3 2
      schema.sql
  3. 6 0
      templates/admin_user_edit.html
  4. 7 1
      templates/admin_user_new.html
  5. 5 1
      templates/login.html

+ 21 - 3
main.py

@@ -3,6 +3,7 @@
 
 from flask import Flask, request, session, g, redirect, url_for, abort, \
     render_template, flash
+from flaskext.openid import OpenID
 import sqlite3
 from datetime import date, time, timedelta, datetime
 import time
@@ -21,12 +22,14 @@ DEBUG = True
 TITLE = u"Cavote FFDN"
 EMAIL = '"' + TITLE + '"' + ' <' + u"cavote@ffdn.org" + '>'
 VERSION = "cavote 0.1.1"
-SMTP_SERVER = "10.33.33.30"
+SMTP_SERVER = "127.0.0.1"
 PATTERNS = {u'Oui/Non': [u'Oui', u'Non'], u'Oui/Non/Blanc': [u'Oui', u'Non', u'Blanc'], u'Oui/Non/Peut-être': [u'Oui', u'Non', u'Peut-être']}
 
 app = Flask(__name__)
 app.config.from_object(__name__)
 
+oid = OpenID(app)
+
 def connect_db():
     return sqlite3.connect(app.config['DATABASE'])
 
@@ -98,11 +101,15 @@ def get_userid():
         return user.get('id')
 
 @app.route('/login', methods=['GET', 'POST'])
+@oid.loginhandler
 def login():
     if request.method == 'POST':
         user = valid_login(request.form['username'], request.form['password'])
         if user is None:
-            flash(u'Email ou mot de passe invalide.', 'error')
+            if request.form['openid']:
+                return oid.try_login(request.form['openid'], ask_for=['email', 'fullname', 'nickname'])
+            else:
+                flash(u'Email ou mot de passe invalide.', 'error')
         else:
             connect_user(user)
             flash(u'Vous êtes connecté. Bienvenue, %s !' % user['name'], 'success')
@@ -111,6 +118,16 @@ def login():
             return redirect(url_for('home'))
     return render_template('login.html')
 
+@oid.after_login
+def create_or_login(resp):
+    openid_url = resp.identity_url
+    user = query_db('select * from users where openid = ?', [openid_url], one=True)
+    if user is not None:
+        flash(u'Successfully signed in')
+        connect_user(user)
+        return redirect(oid.get_next_url())
+    return redirect(url_for('home'))
+
 @app.route('/logout')
 def logout():
     disconnect_user()
@@ -252,8 +269,9 @@ def admin_user_add():
                         if 'admin' in request.form.keys():
                             admin = 1
                         key = 'v%s' % keygen()
-                        g.db.execute('insert into users (email, name, organization, password, is_admin, key) values (?, ?, ?, ?, ?, ?)',
+                        g.db.execute('insert into users (email, openid, name, organization, password, is_admin, key) values (?, ?, ?, ?, ?, ?, ?)',
                                 [request.form['email'],
+                                    request.form['openid'],
                                     request.form['username'],
                                     request.form['organization'],
                                     '', admin, key])

+ 3 - 2
schema.sql

@@ -12,6 +12,7 @@ create table users (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
     email TEXT UNIQUE NOT NULL,
     password TEXT NOT NULL,
+    openid TEXT NOT NULL,
     name TEXT UNIQUE NOT NULL, 
     organization TEXT,
     is_admin BOOLEAN DEFAULT 0 NOT NULL,
@@ -83,8 +84,8 @@ create table user_choice (
 
 -- Test data
 
-INSERT INTO users (id, email, password, name, organization, is_admin, key)
-VALUES (1, "admin@admin.fr", "", "Toto (admin) Tata", "World corp", 1, "victory");
+INSERT INTO users (id, email, password, openid, name, organization, is_admin, key)
+VALUES (1, "admin@admin.fr", "", "", "Toto (admin) Tata", "World corp", 1, "victory");
 -- to login, go to /login/1/victory
 INSERT INTO groups (id, name, system) VALUES (1, "Tous", 1);
 INSERT INTO groups (name) VALUES ("CA");

+ 6 - 0
templates/admin_user_edit.html

@@ -12,6 +12,12 @@
         </div>
       </div>
       <div class="control-group">
+        <label class="control-label" for="openid">OpenID</label>
+        <div class="controls">
+          <input type="text" name="openid" id="openid" value="{{ user.openid }}" />
+        </div>
+      </div>
+      <div class="control-group">
           <label class="control-label" for="name">Nom</label>
           <div class="controls">
               <input type="text" name="name" id="name" value="{{ user.name }}" />

+ 7 - 1
templates/admin_user_new.html

@@ -20,9 +20,15 @@
     </div>
   </div>
   <div class="control-group">
+    <label class="control-label" for="openid">OpenID</label>
+    <div class="controls">
+      <input type="text" name="openid" id="openid" value="{{ request.form.openid }}" />
+    </div>
+  </div>
+  <div class="control-group">
     <label class="control-label" for="organization">Association</label>
     <div class="controls">
-      <input type="text" data-provide="typeahead" data-source='["FDN","Ilico","Aquilenet"]' size=30 name="organization" id="organization" value="{{ request.form.organization }}" />
+      <input type="text" data-provide="typeahead" data-source='["NDN","FDN","Ilico","Aquilenet"]' size=30 name="organization" id="organization" value="{{ request.form.organization }}" />
     </div>
   </div>
   <div class="control-group">

+ 5 - 1
templates/login.html

@@ -2,18 +2,22 @@
 {% block body %}
 <div class="row">
   <div class="span3 well offset1">
+    <p><a href="{{ url_for("password_lost") }}">Mot de passe perdu ?</a></p>
     <form action="{{ url_for('login', continue=request.args.continue) }}" method="post">
     <fieldset><legend>Connexion</legend>
       <label for="username">E-mail</label>
       <input type="text" name="username" id="username" value="{{ request.form.username }}"/>
       <label for="password">Mot de passe</label>
       <input type="password" name="password" id="password" />
+    </fieldset>
+    <fieldset><legend>OpenID</legend>
+      <label for="openid">OpenID</label>
+      <input type="text" name="openid" id="openid" value="{{ request.form.openid }}"/>
       <div class="form-actions">
         <input type="submit" class="btn btn-primary" value="Connexion" />
       </div>
     </fieldset>
     </form>
-    <p><a href="{{ url_for("password_lost") }}">Mot de passe perdu ?</a></p>
   </div>
 </div>
 {% endblock %}