Anonymous avatar Anonymous committed fee4946

Examples, tweaks, fixes, distribution stuff

Comments (0)

Files changed (9)

 syntax: glob
 *.pyc
+.ropeproject
+dist
+build
+*egg-info

LICENSE

-Copyright (c) 2011 by Lars.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright
-  notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the following
-  disclaimer in the documentation and/or other materials provided
-  with the distribution.
-
-* The names of the contributors may not be used to endorse or
-  promote products derived from this software without specific
-  prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2011 by Lars.
+
+Some rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the following
+  disclaimer in the documentation and/or other materials provided
+  with the distribution.
+
+* The names of the contributors may not be used to endorse or
+  promote products derived from this software without specific
+  prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+include LICENSE.txt
+recursive-include docs *.html *.css *.js *.png
+recursive-include examples *.py
+recursive-exclude flaskext *.pyc
+recursive-exclude examples *.pyc

examples/no_db_persistence.py

+from flask import Flask, request, g, redirect, url_for
+app = Flask(__name__)
+
+from flaskext.auth import Auth, AuthUser, login_required, logout
+auth = Auth(app)
+
+@app.before_request
+def init_users():
+    """
+    Initializing users by hardcoding password. Another use case is to read
+    usernames from an external file (like /etc/passwd).
+    """
+    admin = AuthUser(username='admin')
+    # Setting and encrypting the hardcoded password.
+    admin.set_and_encrypt_password('password', password_hash='123')
+    # Persisting users for this request.
+    g.users = {'admin': admin}
+
+@login_required()
+def admin():
+    return 'Admin! Excellent!'
+
+def index():
+    if request.method == 'POST':
+        username = request.form['username']
+        if username in g.users:
+            # Authenticate and log in!
+            if g.users[username].authenticate(request.form['password']):
+                return redirect(url_for('admin'))
+        return 'Failure :('
+    return '''
+            <form method="POST">
+                Username: <input type="text" name="username"/><br/>
+                Password: <input type="password" name="password"/><br/>
+                <input type="submit" value="Log in"/>
+            </form>
+        '''
+
+def logout_view():
+    user = logout()
+    if user is None:
+        return 'No user to log out.'
+    return 'Logged out user {0}.'.format(user.username)
+
+# URLs
+app.add_url_rule('/', 'index', index, methods=['GET', 'POST'])
+app.add_url_rule('/admin/', 'admin', admin)
+app.add_url_rule('/logout/', 'logout', logout_view)
+
+# Secret key needed to use sessions.
+app.secret_key = 'N4BUdSXUzHxNoO8g'
+
+if __name__ == '__main__':
+    app.run(debug=True)

examples/sqlalchemy_model.py

+import datetime
+from flask import Flask, request, redirect, url_for
+from flaskext.sqlalchemy import SQLAlchemy
+from flaskext.auth import Auth, AuthUser, login_required, logout
+
+app = Flask(__name__)
+app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
+db = SQLAlchemy(app)
+auth = Auth(app)
+
+def now():
+    return datetime.datetime.now()
+
+class User(db.Model, AuthUser):
+    """
+    Implementation of User for SQLAlchemy.
+    """
+    id = db.Column(db.Integer, primary_key=True)
+    username = db.Column(db.String(80), unique=True, nullable=False)
+    password = db.Column(db.String(120), nullable=False)
+    password_hash = db.Column(db.String(80))
+    role = db.Column(db.String(80))
+    created = db.Column(db.DateTime(), default=now)
+    modified = db.Column(db.DateTime())
+
+    def __init__(self, *args, **kwargs):
+        super(User, self).__init__(*args, **kwargs)
+        password = kwargs.get('password')
+        if password is not None and not self.id:
+            self.created = datetime.datetime.utcnow()
+            # Initialize and encrypt password before first save.
+            self.set_and_encrypt_password(password)
+
+@login_required()
+def admin():
+    return 'Admin! Excellent!'
+
+def index():
+    if request.method == 'POST':
+        username = request.form['username']
+        user = User.query.filter(User.username==username).one()
+        if user is not None:
+            # Authenticate and log in!
+            if user.authenticate(request.form['password']):
+                return redirect(url_for('admin'))
+        return 'Failure :('
+    return '''
+            <form method="POST">
+                Username: <input type="text" name="username"/><br/>
+                Password: <input type="password" name="password"/><br/>
+                <input type="submit" value="Log in"/>
+            </form>
+        '''
+
+def user_create():
+    if request.method == 'POST':
+        username = request.form['username']
+        if User.query.filter(User.username==username).first():
+            return 'User already exists.'
+        password = request.form['password']
+        user = User(username=username, password=password)
+        db.session.add(user)
+        db.session.commit()
+        return redirect(url_for('index'))
+    return '''
+            <form method="POST">
+                Username: <input type="text" name="username"/><br/>
+                Password: <input type="password" name="password"/><br/>
+                <input type="submit" value="Create"/>
+            </form>
+        '''
+
+def logout_view():
+    user = logout()
+    if user is None:
+        return 'No user to log out.'
+    return 'Logged out user {0}.'.format(user.username)
+
+# URLs
+app.add_url_rule('/', 'index', index, methods=['GET', 'POST'])
+app.add_url_rule('/admin/', 'admin', admin)
+app.add_url_rule('/users/create/', 'user_create', user_create, methods=['GET', 'POST'])
+app.add_url_rule('/logout/', 'logout', logout_view)
+
+# Secret key needed to use sessions.
+app.secret_key = 'N4BUdSXUzHxNoO8g'
+
+if __name__ == '__main__':
+    try:
+        open('/tmp/flask_auth_test.db')
+    except IOError:
+        db.create_all()
+    app.run(debug=True)

flaskext/auth/auth.py

         - username:
             Username of the user.
         - password: 
-            Password of the user. By default not encrypted. The set_password()
-            method sets and encrypts the password.
+            Password of the user. By default not encrypted. The
+            set_and_encrypt_password() method sets and encrypts the password.
         - password_hash: 
             Hash used for the encrytion of the password.
         - role:
 
     role = None
 
-    def __init__(self, username, password, password_hash, role):
+    def __init__(self, username, password=None, password_hash=None, role=None):
         self.username = username
         # Encryption of the password should happen explicitly.
         self.password = password
         self.password_hash = password_hash
         self.role = role
 
-    def set_password(self, password, password_hash=str(int(time.time()))):
+    def set_and_encrypt_password(self, password, password_hash=str(int(time.time()))):
         """
         Encrypts and sets the password. If no password_hash is provided, a new
         one is generated.
             return True
         return False
 
-def encrypt(password, password_hash=None):
+def encrypt(password, password_hash=None, hash_algorithm=None):
     """Encrypts a password based on the hashing algorithm."""
     to_encrypt = password
     if password_hash is not None:

flaskext/auth/sqlalchemy.py

+"""
+Module to provide plug-and-play authentication support for Google App Engine
+using flask-auth.
+"""
+
+from flaskext.auth import AuthUser
+
+db = None
+'''
+def username_exists(username):
+    if bool(User.query().filter('username =', username).fetch(limit=1)):
+        raise db.ValidationError('User with this username already exists.')
+'''
+class User(AuthUser):
+    """
+    Implementation of User for persistence in Google's App Engine datastore.
+    """
+    id = db.Column(db.Integer, primary_key=True)
+    username = db.Column(db.String(80))
+    '''
+    password = db.StringProperty(required=True)
+    password_hash = db.StringProperty()
+    role = db.StringProperty()
+    created = db.DateTimeProperty(auto_now_add=True)
+    modified = db.DateTimeProperty(auto_now=True)
+    '''
+    def __init__(self, *args, **kwargs):
+        super(User, self).__init__(*args, **kwargs)
+        password = kwargs.get('password')
+        if password is not None and not self.has_key():
+            # Initialize and encrypt password before first save.
+            self.set_password(password)
 ----------
 
 Database-agnostic extension for Flask to support role-based authentication of
-users. Contains plug-and-play models for SQLAlchemy and Google App Engine.
+users.
 
 Links
 `````
 setup(
     name='Flask-Auth',
     version='0.6',
-    url='>',
+    url='http://bitbucket.org/Shotca/flask-auth/',
     license='BSD',
     author='Lars de Ridder',
     author_email='shotcage@gmail.com',
     description='Auth extension for Flask.',
     long_description=__doc__,
-    packages=['flaskext'],
+    packages=['flaskext', 'flaskext.auth'],
     namespace_packages=['flaskext'],
     zip_safe=False,
     platforms='any',
         'License :: OSI Approved :: BSD License',
         'Operating System :: OS Independent',
         'Programming Language :: Python',
+        'Framework :: Flask',
         'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
         'Topic :: Software Development :: Libraries :: Python Modules'
     ]
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.