diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d79b2df --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Change Log +All notable changes to this project will be documented in this file. + +## 0.2.0 - 2015-02-07 +### Changed +- Started keeping a changelog! +- Added a separate 'authenticate' flow to provide explicit support for + calling out to indieauth without requesting any sort of access + token. +- Redirect_url is now determined automatically based on the + authenticated_handler or authorized_handler annotations diff --git a/README.md b/README.md index 54a2fe0..096b2b5 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,48 @@ A Flask extension to support IndieAuth and Micropub clients. +## Authentication + +Authentication uses the +[IndieAuth](https://indiewebcamp.com/IndieAuth) flow to confirm a user +controls a particular URL, without requesting any sort of permissions +or access token. Annotate an endpoint with +`@micropub.authenticated_handler` and then call +`micropub.authenticate` to initiate the login. + +## Authorization + +Authorization uses the full +[Micropub](https://indiewebcamp.com/Micropub) flow to authenticate a +user and then request an access token with which to make micropub +requests. Annotate an endpoint with `@micropub.authorized_handler` and +then call `micropub.authorize` to initiate the login. + +## CSRF + +MicropubClient provides a simple mechanism to deter Cross-Site Request +Forgery. Based on +[this Flask snippet](http://flask.pocoo.org/snippets/3/), we generate +a random string, pass it to the indieauth service via the state +parameter, and then confirm we get the same random string back later. + +This helps prevent malicious sites from sending users to your +indieauth endpoint against their will. + +## Example ```python from flask import Flask, request, url_for -from flask.ext.micropub import Micropub +from flask.ext.micropub import MicropubClient app = Flask(__name__) -micropub = Micropub(app) +micropub = MicropubClient(app) @app.route('/login') def login(): return micropub.authorize( - me, redirect_url=url_for('micropub_callback', _external=True), - scope=request.args.get('scope')) + me, scope=request.args.get('scope')) @app.route('/micropub-callback') @@ -25,4 +53,6 @@ def micropub_callback(resp): ``` -See details at https://indiewebcamp.com/IndieAuth and https://indiewebcamp.com/Micropub +See example.py for a more thorough example. Protocol details at +https://indiewebcamp.com/IndieAuth and +https://indiewebcamp.com/Micropub diff --git a/example.py b/example.py index b137c91..f87ad6c 100644 --- a/example.py +++ b/example.py @@ -7,6 +7,61 @@ app.config['SECRET_KEY'] = 'my super secret key' micropub = MicropubClient(app) +@app.route('/') +def index(): + return """ + + + +
+ + +
+
+ + + +
+ + + """ + + +@app.route('/authenticate') +def authenticate(): + return micropub.authenticate( + request.args.get('me'), next_url=url_for('index')) + + +@app.route('/authorize') +def authorize(): + return micropub.authorize( + request.args.get('me'), next_url=url_for('index'), + scope=request.args.get('scope')) + + +@app.route('/indieauth-callback') +@micropub.authenticated_handler +def indieauth_callback(resp): + return """ + + + + Authenticated: + + + + """.format(resp.me, resp.next_url, resp.error) + + @app.route('/micropub-callback') @micropub.authorized_handler def micropub_callback(resp): @@ -14,6 +69,7 @@ def micropub_callback(resp): + Authorized: