forked from ib-lundgren/flask-oauthprovider
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from ryepdx/master
Added MongoDB example
- Loading branch information
Showing
17 changed files
with
761 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from flask import Flask, request | ||
from provider import ExampleProvider | ||
from models import AccessToken, ResourceOwner as User | ||
|
||
app = Flask(__name__) | ||
app.config.update( | ||
DATABASE_URI="", | ||
SECRET_KEY="debugging key" | ||
) | ||
|
||
provider = ExampleProvider(app) | ||
|
||
# Imported to setup views | ||
import login | ||
|
||
@app.route('/callback') | ||
def callback(): | ||
return str(request.__dict__) | ||
|
||
@app.route("/protected") | ||
@provider.require_oauth() | ||
def protected_view(): | ||
token = request.oauth.resource_owner_key | ||
access_token = AccessToken.get_collection().find_one({'token':token}) | ||
user = User.find_one({'_id':access_token['resource_owner_id']}) | ||
return user['name'] | ||
|
||
|
||
@app.route("/protected_realm") | ||
@provider.require_oauth(realm="secret") | ||
def protected_realm_view(): | ||
token = request.oauth.resource_owner_key | ||
access_token = AccessToken.get_collection().find_one({'token':token}) | ||
user = User.find_one({'_id':access_token['resource_owner_id']}) | ||
return user['email'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# -*- coding: utf-8 -*- | ||
from mongo_demoprovider import app | ||
from models import ResourceOwner as User | ||
from flask import g, session, render_template, request, redirect, flash | ||
from flask import abort, url_for | ||
from flask.ext.openid import OpenID | ||
|
||
# setup flask-openid | ||
oid = OpenID(app) | ||
|
||
|
||
@app.before_request | ||
def before_request(): | ||
g.user = None | ||
if 'openid' in session: | ||
user_dict = User.find_one({'openid':session['openid']}) | ||
|
||
if user_dict: | ||
g.user = User() | ||
g.user.update(user_dict) | ||
|
||
|
||
@app.route('/') | ||
def index(): | ||
return render_template('index.html') | ||
|
||
|
||
@app.route('/login', methods=['GET', 'POST']) | ||
@oid.loginhandler | ||
def login(): | ||
"""Does the login via OpenID. Has to call into `oid.try_login` | ||
to start the OpenID machinery. | ||
""" | ||
# if we are already logged in, go back to were we came from | ||
if g.user is not None: | ||
return redirect(oid.get_next_url()) | ||
if request.method == 'POST': | ||
openid = request.form.get('openid') | ||
if openid: | ||
return oid.try_login(openid, ask_for=['email', 'fullname', | ||
'nickname']) | ||
return render_template('login.html', next=oid.get_next_url(), | ||
error=oid.fetch_error()) | ||
|
||
|
||
@oid.after_login | ||
def create_or_login(resp): | ||
"""This is called when login with OpenID succeeded and it's not | ||
necessary to figure out if this is the users's first login or not. | ||
This function has to redirect otherwise the user will be presented | ||
with a terrible URL which we certainly don't want. | ||
""" | ||
session['openid'] = resp.identity_url | ||
user = User.get_collection().find_one({'openid':resp.identity_url}) | ||
if user is not None: | ||
flash(u'Successfully signed in') | ||
g.user = user | ||
return redirect(oid.get_next_url()) | ||
return redirect(url_for('create_profile', next=oid.get_next_url(), | ||
name=resp.fullname or resp.nickname, | ||
email=resp.email)) | ||
|
||
|
||
@app.route('/create-profile', methods=['GET', 'POST']) | ||
def create_profile(): | ||
"""If this is the user's first login, the create_or_login function | ||
will redirect here so that the user can set up his profile. | ||
""" | ||
if g.user is not None or 'openid' not in session: | ||
return redirect(url_for('index')) | ||
if request.method == 'POST': | ||
name = request.form['name'] | ||
email = request.form['email'] | ||
if not name: | ||
flash(u'Error: you have to provide a name') | ||
elif '@' not in email: | ||
flash(u'Error: you have to enter a valid email address') | ||
else: | ||
flash(u'Profile successfully created') | ||
User.get_collection().insert(User(name, email, session['openid'])) | ||
return redirect(oid.get_next_url()) | ||
return render_template('create_profile.html', next_url=oid.get_next_url()) | ||
|
||
|
||
@app.route('/profile', methods=['GET', 'POST']) | ||
def edit_profile(): | ||
"""Updates a profile""" | ||
if g.user is None: | ||
abort(401) | ||
form = dict(name=g.user.name, email=g.user.email) | ||
if request.method == 'POST': | ||
if 'delete' in request.form: | ||
User.get_collection().remove(g.user) | ||
session['openid'] = None | ||
flash(u'Profile deleted') | ||
return redirect(url_for('index')) | ||
form['name'] = request.form['name'] | ||
form['email'] = request.form['email'] | ||
if not form['name']: | ||
flash(u'Error: you have to provide a name') | ||
elif '@' not in form['email']: | ||
flash(u'Error: you have to enter a valid email address') | ||
else: | ||
flash(u'Profile successfully created') | ||
g.user.name = form['name'] | ||
g.user.email = form['email'] | ||
uid = User.get_collection().save(g.user) | ||
return redirect(url_for('edit_profile')) | ||
return render_template('edit_profile.html', form=form) | ||
|
||
|
||
@app.route('/logout') | ||
def logout(): | ||
session.pop('openid', None) | ||
flash(u'You have been signed out') | ||
return redirect(oid.get_next_url()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import pymongo | ||
|
||
|
||
def get_connection(): | ||
return pymongo.MongoClient().demo_oauth_provider | ||
|
||
|
||
class Model(dict): | ||
@classmethod | ||
def get_collection(cls): | ||
conn = get_connection() | ||
return conn[cls.table] | ||
|
||
@classmethod | ||
def find_one(cls, attrs): | ||
return cls.get_collection().find_one(attrs) | ||
|
||
@classmethod | ||
def insert(cls, obj): | ||
return cls.get_collection().insert(obj) | ||
|
||
@classmethod | ||
def save(cls, obj): | ||
return cls.get_collection().save(obj) | ||
|
||
def __getattr__(self, attr): | ||
return self[attr] | ||
|
||
def __setattr__(self, attr, value): | ||
self[attr] = value | ||
|
||
|
||
|
||
class ResourceOwner(Model): | ||
table = "users" | ||
|
||
def __init__(self, name="", email="", openid=""): | ||
self.name = name | ||
self.email = email | ||
self.openid = openid | ||
self.request_tokens = [] | ||
self.access_tokens = [] | ||
self.client_ids = [] | ||
|
||
def __repr__(self): | ||
return "<ResourceOwner (%s, %s)>" % (self.name, self.email) | ||
|
||
|
||
class Client(Model): | ||
table = "clients" | ||
|
||
def __init__(self, client_key, name, description, secret=None, pubkey=None): | ||
self.client_key = client_key | ||
self.name = name | ||
self.description = description | ||
self.secret = secret | ||
self.pubkey = pubkey | ||
self.request_tokens = [] | ||
self.access_tokens = [] | ||
self.callbacks = [] | ||
self.resource_owner_id = "" | ||
|
||
def __repr__(self): | ||
return "<Client (%s, %s)>" % (self.name, self.id) | ||
|
||
|
||
class Nonce(Model): | ||
table = "nonces" | ||
|
||
def __init__(self, nonce, timestamp): | ||
self.nonce = nonce | ||
self.timestamp = timestamp | ||
self.client_id = "" | ||
self.request_token_id = "" | ||
self.access_token_id = "" | ||
|
||
def __repr__(self): | ||
return "<Nonce (%s, %s, %s, %s)>" % (self.nonce, self.timestamp, self.client, self.resource_owner) | ||
|
||
|
||
class RequestToken(Model): | ||
table = "requestTokens" | ||
|
||
def __init__(self, token, callback, secret=None, verifier=None, realm=None): | ||
self.token = token | ||
self.secret = secret | ||
self.verifier = verifier | ||
self.realm = realm | ||
self.callback = callback | ||
self.client_id = "" | ||
self.resource_owner_id = "" | ||
|
||
|
||
def __repr__(self): | ||
return "<RequestToken (%s, %s, %s)>" % (self.token, self.client, self.resource_owner) | ||
|
||
|
||
class AccessToken(Model): | ||
table = "accessTokens" | ||
|
||
def __init__(self, token, secret=None, verifier=None, realm=None): | ||
self.token = token | ||
self.secret = secret | ||
self.verifier = verifier | ||
self.realm = realm | ||
self.client_id = "" | ||
self.resource_owner_id = "" | ||
|
||
def __repr__(self): | ||
return "<AccessToken (%s, %s, %s)>" % (self.token, self.client, self.resource_owner) |
Oops, something went wrong.