Mercurial > wikked
changeset 196:cbf7db1ff0d5
Better authentication handling:
- Not bundling user info with every response anymore.
- Ability to optionally bundle user info with the page read API endpoint.
- New API endpoint for current user info.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 09 Feb 2014 20:46:22 -0800 |
parents | 964fd28e9b39 |
children | 067eca50f8f7 |
files | wikked/assets/js/wikked/models.js wikked/assets/tpl/nav.html wikked/views/admin.py wikked/views/edit.py wikked/views/history.py wikked/views/read.py wikked/views/special.py |
diffstat | 7 files changed, 91 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/wikked/assets/js/wikked/models.js Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/assets/js/wikked/models.js Sun Feb 09 20:46:22 2014 -0800 @@ -13,12 +13,11 @@ var exports = {}; var NavigationModel = exports.NavigationModel = Backbone.Model.extend({ - idAttribute: 'path', defaults: function() { return { path: "", action: "read", - user: false + username: false }; }, initialize: function() { @@ -26,12 +25,15 @@ model._onChangePath(path); }); this._onChangePath(this.get('path')); - this.on('change:auth', function(model, auth) { - model._onChangeAuth(auth); + this.on('change:user', function(model, auth) { + model._onChangeUser(auth); }); - this._onChangeAuth(this.get('auth')); + this._onChangeUser(this.get('user')); return this; }, + url: function() { + return '/api/user/info'; + }, doPreviewSearch: function(query, callback) { if (this._isSearching) { this._pendingQuery = query; @@ -78,18 +80,16 @@ this.doPreviewSearch(q, c); } }, - _onChangeAuth: function(auth) { - if (auth) { + _onChangeUser: function(user) { + if (user) { this.set({ url_login: false, - url_logout: '/#/logout', - username: auth.username + url_logout: '/#/logout' }); } else { this.set({ url_login: '/#/login', - url_logout: false, - username: false + url_logout: false }); } } @@ -189,7 +189,7 @@ var MasterPageModel = exports.MasterPageModel = PageModel.extend({ initialize: function() { - this.nav = new NavigationModel({ id: this.id }); + this.nav = new NavigationModel({ path: this.id }); this.footer = new FooterModel(); MasterPageModel.__super__.initialize.apply(this, arguments); this.on('change:auth', function(model, auth) { @@ -253,10 +253,21 @@ -1, 'cog'); }, + url: function() { + var url = PageReadModel.__super__.url.apply(this, arguments); + if (!this.nav.get('user')) { + url += '?user'; + } + return url; + }, checkStatePath: function() { return this.get('path'); }, _onChange: function() { + if (this.get('user')) { + // Forward user info to the navigation model. + this.nav.set('user', this.get('user')); + } if (this.getMeta('redirect')) { // Handle redirects. var newPath = this.getMeta('redirect').replace(/^\//, "");
--- a/wikked/assets/tpl/nav.html Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/assets/tpl/nav.html Sun Feb 09 20:46:22 2014 -0800 @@ -24,8 +24,8 @@ <button type="submit" class="btn btn-sm btn-default">Search</button> </form> <ul class="nav navbar-nav navbar-right"> - {{#if username}} - <li><a href="{{url_profile}}"><span class="glyphicon glyphicon-cog"></span> {{username}}</a></li> + {{#if user}} + <li><a href="{{url_profile}}"><span class="glyphicon glyphicon-cog"></span> {{user.username}}</a></li> <li><a href="{{url_logout}}"><span class="glyphicon glyphicon-log-out"></span> Logout</a></li> {{else}} <li><a href="{{url_login}}"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
--- a/wikked/views/admin.py Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/views/admin.py Sun Feb 09 20:46:22 2014 -0800 @@ -1,6 +1,5 @@ -from flask import g, abort, request +from flask import g, jsonify, abort, request from flask.ext.login import login_user, logout_user, current_user -from wikked.views import (make_auth_response) from wikked.web import app, login_manager @@ -10,7 +9,7 @@ return login_manager.unauthorized() g.wiki.index.reset(g.wiki.getPages()) result = {'ok': 1} - return make_auth_response(result) + return jsonify(result) @app.route('/api/user/login', methods=['POST']) @@ -24,7 +23,7 @@ if app.bcrypt.check_password_hash(user.password, password): login_user(user, remember=bool(remember)) result = {'username': username, 'logged_in': 1} - return make_auth_response(result) + return jsonify(result) abort(401) @@ -32,7 +31,7 @@ def api_user_is_logged_in(): if current_user.is_authenticated(): result = {'logged_in': True} - return make_auth_response(result) + return jsonify(result) abort(401) @@ -40,13 +39,33 @@ def api_user_logout(): logout_user() result = {'ok': 1} - return make_auth_response(result) + return jsonify(result) + + +@app.route('/api/user/info') +def api_current_user_info(): + user = current_user + if user.is_authenticated(): + result = { + 'user': { + 'username': current_user.username, + 'groups': current_user.groups + } + } + return jsonify(result) + return jsonify({'user': False}) @app.route('/api/user/info/<name>') def api_user_info(name): user = g.wiki.auth.getUser(name) if user is not None: - result = {'username': user.username, 'groups': user.groups} - return make_auth_response(result) + result = { + 'user': { + 'username': user.username, + 'groups': user.groups + } + } + return jsonify(result) abort(404) +
--- a/wikked/views/edit.py Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/views/edit.py Sun Feb 09 20:46:22 2014 -0800 @@ -3,7 +3,7 @@ from flask.ext.login import current_user from wikked.page import Page, PageData from wikked.formatter import PageFormatter, FormattingContext -from wikked.views import (make_page_title, make_auth_response, get_page_or_none, +from wikked.views import (make_page_title, get_page_or_none, is_page_writable, get_page_meta, url_from_viewarg, split_url_from_viewarg) from wikked.web import app @@ -59,7 +59,7 @@ } if custom_data: result.update(custom_data) - return make_auth_response(result) + return jsonify(result) def do_edit_page(url, default_message): @@ -86,7 +86,7 @@ g.wiki.setPage(url, page_fields) result = {'saved': 1} - return make_auth_response(result) + return jsonify(result) @app.route('/api/edit/', methods=['GET', 'POST'])
--- a/wikked/views/history.py Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/views/history.py Sun Feb 09 20:46:22 2014 -0800 @@ -1,5 +1,5 @@ import os.path -from flask import g, request, abort +from flask import g, jsonify, request, abort from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import get_formatter_by_name @@ -7,7 +7,7 @@ from wikked.scm.base import ACTION_NAMES from wikked.utils import PageNotFoundError from wikked.views import (is_page_readable, get_page_meta, get_page_or_404, - make_auth_response, url_from_viewarg, + url_from_viewarg, CHECK_FOR_READ) from wikked.web import app @@ -64,7 +64,7 @@ history = g.wiki.getHistory(limit=limit) hist_data = get_history_data(history, needs_files=True) result = {'history': hist_data} - return make_auth_response(result) + return jsonify(result) @app.route('/api/history/<path:url>') @@ -73,7 +73,7 @@ history = page.getHistory() hist_data = get_history_data(history) result = {'url': url, 'meta': get_page_meta(page), 'history': hist_data} - return make_auth_response(result) + return jsonify(result) @app.route('/api/revision/<path:url>') @@ -85,7 +85,7 @@ page_rev = page.getRevision(rev) meta = dict(get_page_meta(page, True), rev=rev) result = {'meta': meta, 'text': page_rev} - return make_auth_response(result) + return jsonify(result) @app.route('/api/diff/<path:url>') @@ -105,7 +105,7 @@ else: meta = dict(get_page_meta(page, True), rev1=rev1, rev2=rev2) result = {'meta': meta, 'diff': diff} - return make_auth_response(result) + return jsonify(result) @app.route('/api/revert/<path:url>', methods=['POST']) @@ -128,5 +128,5 @@ } g.wiki.revertPage(url, page_fields) result = {'reverted': 1} - return make_auth_response(result) + return jsonify(result)
--- a/wikked/views/read.py Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/views/read.py Sun Feb 09 20:46:22 2014 -0800 @@ -1,8 +1,9 @@ import time import urllib -from flask import render_template, request, g +from flask import render_template, request, g, jsonify +from flask.ext.login import current_user from wikked.views import (get_page_meta, get_page_or_404, get_page_or_none, - is_page_readable, make_auth_response, + is_page_readable, url_from_viewarg, split_url_from_viewarg, CHECK_FOR_READ) from wikked.web import app @@ -43,7 +44,7 @@ pages = filter(is_page_readable, g.wiki.getPages(url_from_viewarg(url))) page_metas = [get_page_meta(page) for page in pages] result = {'path': url, 'pages': list(page_metas)} - return make_auth_response(result) + return jsonify(result) @app.route('/api/read/') @@ -53,7 +54,17 @@ @app.route('/api/read/<path:url>') def api_read_page(url): - #TODO: remove redundant quoting/spliting/unquoting around here. + additional_info = {} + if 'user' in request.args: + user = current_user + if user.is_authenticated(): + additional_info['user'] = { + 'username': user.username, + 'groups': user.groups + } + else: + additional_info['user'] = False + endpoint, value, path = split_url_from_viewarg(url) if endpoint is None: # Normal page. @@ -64,7 +75,8 @@ force_resolve=('force_resolve' in request.args)) result = {'meta': get_page_meta(page), 'text': page.text} - return make_auth_response(result) + result.update(additional_info) + return jsonify(result) # Meta listing page. meta_page_url = '%s:%s' % (endpoint, path) @@ -103,7 +115,8 @@ if info_page: result['meta'] = get_page_meta(info_page) - return make_auth_response(result) + result.update(additional_info) + return jsonify(result) @app.route('/api/raw/') @@ -115,7 +128,7 @@ def api_read_page_raw(url): page = get_page_or_404(url, check_perms=CHECK_FOR_READ) result = {'meta': get_page_meta(page), 'text': page.raw_text} - return make_auth_response(result) + return jsonify(result) @app.route('/api/query') @@ -126,7 +139,7 @@ 'query': query, 'pages': [get_page_meta(p) for p in pages] } - return make_auth_response(result) + return jsonify(result) @app.route('/api/state/') @@ -138,7 +151,7 @@ def api_get_state(url): page = get_page_or_404(url, check_perms=CHECK_FOR_READ) state = page.getState() - return make_auth_response({ + return jsonify({ 'meta': get_page_meta(page, True), 'state': STATE_NAMES[state] }) @@ -164,7 +177,7 @@ links.append({'url': link, 'missing': True}) result = {'meta': get_page_meta(page), 'out_links': links} - return make_auth_response(result) + return jsonify(result) @app.route('/api/inlinks/') @@ -187,5 +200,5 @@ links.append({'url': link, 'missing': True}) result = {'meta': get_page_meta(page), 'in_links': links} - return make_auth_response(result) + return jsonify(result)
--- a/wikked/views/special.py Thu Feb 06 22:00:32 2014 -0800 +++ b/wikked/views/special.py Sun Feb 09 20:46:22 2014 -0800 @@ -1,6 +1,5 @@ -from flask import g, request, abort -from wikked.views import (is_page_readable, get_page_meta, get_page_or_none, - make_auth_response) +from flask import g, jsonify, request, abort +from wikked.views import is_page_readable, get_page_meta, get_page_or_none from wikked.web import app @@ -22,7 +21,7 @@ app.logger.error(" %s" % e) result = {'orphans': orphans} - return make_auth_response(result) + return jsonify(result) @@ -40,7 +39,7 @@ readable_hits.append({'url': h.url, 'title': h.title, 'text': h.hl_text}) result = {'query': query, 'hit_count': len(readable_hits), 'hits': readable_hits} - return make_auth_response(result) + return jsonify(result) @app.route('/api/searchpreview') @@ -57,5 +56,5 @@ readable_hits.append({'url': h.url, 'title': h.title}) result = {'query': query, 'hit_count': len(readable_hits), 'hits': readable_hits} - return make_auth_response(result) + return jsonify(result)