Flask-Login mit CouchDB

Code-Stücke können hier veröffentlicht werden.
Antworten
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Hier mal ein kleines Beispiel, wie man Flask-Login mit CouchDB verwenden kann. Verbesserungsvorschläge willkommen, Verwendung auf eigene Gefahr.

Es basiert auf dem Flask-Login Example. Zunächst das Beispiel von Bitbucket herunterladen.

Diesen Sourcecode im Verzeichnis /example unter einem beliebigen Namen abspeichern

Code: Alles auswählen

# -*- coding: utf-8 -*-
"""
Flask-Login example
===================
This is a small application that provides a trivial demonstration of
Flask-Login, including remember me functionality.

:copyright: (C) 2011 by Matthew Frazier.
:license:   MIT/X11, see LICENSE for more details.
"""
from flask import Flask, request, render_template, redirect, url_for, flash
from flaskext.login import (LoginManager, current_user, login_required,
                            login_user, logout_user, UserMixin, AnonymousUser,
                            confirm_login, fresh_login_required)

from couchdb.mapping import TextField, BooleanField, Document
from flaskext.couchdb import *

class User(Document):
    name = TextField()
    active = BooleanField(default=True)
    password = TextField()

    def is_active(self):
        return self.active
        
    def is_anonymous(self):
        return False
        
    def is_authenticated(self):
        return True

    def get_id(self):
        try:
            return unicode(self.name)
        except AttributeError:
            raise NotImplementedError("No `id` attribute - override get_id")



class Anonymous(AnonymousUser):
    name = u"Anonymous"

app = Flask(__name__)
app.config.from_object('config')

couch_manager = CouchDBManager()
couch_manager.setup(app)

login_manager = LoginManager()
login_manager.anonymous_user = Anonymous
login_manager.login_view = "login"
login_manager.login_message = u"Please log in to access this page."
login_manager.refresh_view = "reauth"
login_manager.setup_app(app)

@login_manager.user_loader
def load_user(id):
    return User.load(id)

@app.route("/")
def index():
    return render_template("index.html")


@app.route("/secret")
@fresh_login_required
def secret():
    return render_template("secret.html")


@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST" and "username" in request.form and "passwd" in request.form:
        username = request.form["username"]
        passwd = request.form["passwd"]
        user = User.load(username)
        if user and user.password == passwd:
            remember = request.form.get("remember", "no") == "yes"
            if login_user(user, remember=remember):
                flash("Logged in!")
                return redirect(request.args.get("next") or url_for("index"))
            else:
                flash("Sorry, but you could not log in.")
        else:
            flash(u"Invalid username or password.")
    return render_template("login.html")


@app.route("/reauth", methods=["GET", "POST"])
@login_required
def reauth():
    if request.method == "POST":
        confirm_login()
        flash(u"Reauthenticated.")
        return redirect(request.args.get("next") or url_for("index"))
    return render_template("reauth.html")


@app.route("/logout")
@login_required
def logout():
    logout_user()
    flash("Logged out.")
    return redirect(url_for("index"))

if __name__ == "__main__":
    app.run(host='0.0.0.0')
Die Konfigurationsdaten im Verzeichnis /example unter dem Namen config.py abspeichern.

Code: Alles auswählen

COUCHDB_SERVER = "http://localhost:5984"
COUCHDB_DATABASE = "mydb"

SECRET_KEY = "yeah, not actually a secret"
DEBUG = True
Diese Datei dient lediglich dazu, die Demo Daten auf dem Server zu speichern

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import couchdb
from couchdb.mapping import TextField, BooleanField, Document


from uuid import uuid4

class User(Document):
    name = TextField()
    active = BooleanField(default=True)
    password = TextField()
    type = TextField(default="User")


couch = couchdb.Server()

try:
    db = couch.delete("mydb")
    db = couch.create("mydb")
except:
    db = couch.create("mydb")

u=User(name = u"Notch", password = u"ü")
u.id = u"Notch"
u.store(db)
u=User(name = u"Steve", password = u"b")
u.id = u"Steve"
u.store(db)
u=User(name = u"Creeper", active = False, password = u"c")
u.id = u"Creeper"
u.store(db)
Das Template login.html wurde um ein Passwort erweitert

Code: Alles auswählen

{% extends "layout.html" %}

{% block body %}
  <h2>Login</h2>
  <form action="" method=post>
    <dl>
      <dt>Username:
      <dd><input type=text name=username>
      <dt>Password:
      <dd><input type=text name=passwd>
      <dt>Remember Me:
      <dd><input type=checkbox name=remember value=yes>
      <dd><input type=submit value=Login>
    </dl>
  </form>
{% endblock %}
Das schwierigste beim Programmieren ist, sinnvolle Variablen- und Funktionsnamen zu finden :lol:
Lenzer
User
Beiträge: 9
Registriert: Dienstag 13. Dezember 2011, 04:20

Danke für den ausführlichen Beitrag
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Lenzer hat geschrieben:Danke für den ausführlichen Beitrag
Gibt es eigentlich einen Grund dafür, dass dein Forenbeiträge ausschließlich darin bestehen, dass du Wochen oder Monate nach dem letzten Posting in einem Thread diesen mit Antworten der Sorte "Danke für den (Link|Tipp|Beitrag)" wieder ausgräbst?

Sollte Lenzer vielleicht ein Bot-Experiment sein? :shock:
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@/me: Um der Facebook-Generation gerecht zu werden, muss halt einfach mal ein "Gefällt mir"-Button eingeführt werden. ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

snafu hat geschrieben:@/me: Um der Facebook-Generation gerecht zu werden, muss halt einfach mal ein "Gefällt mir"-Button eingeführt werden. ;)
Ein intelligentes Voting könnte immerhin bei Code-Beiträgen dafür sorgen, dass Beiträge gewisser Streiter für Freiheit im Sinne von Artikel 5 GG eine geringe Bewertung bekommen und somit von Anfängern sofort als unbrauchbar wahrgenommen würden ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@hyperion: Es würde reichen, wenn ihn einfach niemand mehr beachten würde, dann würde ihm sein Kreuzzug schon bald langweilig werden [1]. Aber solange sich noch im x-ten Thread jemand findet, der diese Angelegenheit unbedingt erneut ausdiskutieren muss, erhält er immer wieder die Aufmerksamkeit, nach welcher sein Ego offenbar dürstet, und wird mithin auch nicht müde, seinen Kreuzzug fortzusetzen.

Und sag jetzt nicht, dass man ja die armen Anfänger vor ihm bewahren müsste. ;) Wer sich halbwegs für Python und Programmierung interessiert, erkennt guten Quelltext schon selbst. Und was den hausaufgabenabschreibenden Rest angeht... nun, da ist ohnehin schon alles verloren, so dass selbst diese gewisse Person nichts mehr verderben kann.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben: Und sag jetzt nicht, dass man ja die armen Anfänger vor ihm bewahren müsste. ;) Wer sich halbwegs für Python und Programmierung interessiert, erkennt guten Quelltext schon selbst.
Hm... als (Programmier-)Anfänger kann man das imho nicht - und da ist ein Hinweis auf die Qualität sicherlich angebracht. Ob man sich dabei über die Art, die Ziele oder das Auftreten eines berüchtigten Users muckieren muss, ist sicherlich fraglich. Aber hey, ab und an ist es einfach auch amüsant ;-)
lunar hat geschrieben: Und was den hausaufgabenabschreibenden Rest angeht... nun, da ist ohnehin schon alles verloren, so dass selbst diese gewisse Person nichts mehr verderben kann.
Da hast Du recht; für diese macht das aber ja auch keiner, oder?
Das Problem dabei erkannte schon Henry Ford, der sinngemäß sagte:
"50% meiner Werbeausgaben sind weggeworfenes Geld - ich weiß aber nicht welche 50%!"
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Es würde reichen, wenn ihn einfach niemand mehr beachten würde, dann würde ihm sein Kreuzzug schon bald langweilig werden [1].
Und wo ist [1] nun? Und hier nochmal in Memeform: "Scumbag lunar: cites reference, does not include it" SCNR ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

@Leonidas: Vor Dem "Und sag jetzt nicht,...". Siehst Du's etwa nicht? Schlechtes Zeichen ;)

@Hyperion: Wenn man sich dafür interessiert, versucht man auch als Anfänger den gezeigten Quelltext zu verstehen. Versteht man Quelltext, kann man auch als Anfänger über dessen Qualität urteilen. Schließlich sind interessierte Anfänger in der Regel keine Vollidioten.
BlackJack

@lunar: Anfänger haben naturgemäss keine Ahnung von der Materie und dementsprechend können sie die Qualität eben nicht wirklich beurteilen, solange die Lösung halbwegs funktioniert. Die umständlichsten Algorithmen mit quadratischer Laufzeit oder schlimmer können für sie verständlich und einleuchtend aussehen, wo eine qualitativ bessere Lösung mit linearer Laufzeit und/oder kürzer und verständlicher formuliert werden kann. `input()` und `eval()` können einem Anfänger als ganz tolle Funktionen vorkommen. Gerade mit `eval()` kann alles so schön einfach lösen. ;-)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich denke nicht, dass ein Anfänger ohne Weiteres beurteilen könnte, dass `zahl % 10 != 5` grundsätzlich sinnvoller ist als `str(zahl).endswith('5')`.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:@Leonidas: Vor Dem "Und sag jetzt nicht,...". Siehst Du's etwa nicht? Schlechtes Zeichen ;)
Offenbar :?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten