#!/usr/bin/env python # ============================================================================ # This file is part of Pwman3. # # Pwman3 is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2 # as published by the Free Software Foundation; # # Pwman3 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Pwman3; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ============================================================================ # Copyright (C) 2012-2014 Oz Nahum # ============================================================================ from __future__ import print_function from bottle import route, run, debug, template, request, redirect, static_file from pwman.util.crypto_engine import CryptoEngine import pwman.data.factory from pwman.data.nodes import Node from pwman import parser_options, get_conf_options from pkg_resources import resource_filename import sys from signal import SIGTERM import os import json templates_path = [resource_filename('pwman', 'ui/templates')] statics = [resource_filename('pwman', 'ui/templates/static')][0] AUTHENTICATED = False TAGS = None DB = None # BUG: Error: SQLite: Incorrect number of bindings supplied. # The current statement uses 2, and there are 1 supplied. # When issuing multiple times filter # WEB GUI shows multiple tags as one tag! @route('/exit', method=['GET']) def exit(): os.kill(os.getpid(), SIGTERM) def require_auth(fn): def check_auth(**kwargs): if AUTHENTICATED: return fn(**kwargs) else: redirect("/auth") return check_auth @route('/node/:no') @require_auth def view_node(no): global DB node = DB.getnodes([no]) node = DB.getnodes([no])[0] node = Node.from_encrypted_entries(node[1], node[2], node[3], node[4], node[5:]) return template("ajax.tpl", request=request, node=node, template_lookup=templates_path) @route('/_add_numbers') def add_numbers(): """Add two numbers server side, ridiculous but well...""" a = request.params.get('a', 0, type=int) b = request.params.get('b', 0, type=int) return json.dumps({'result': a+b}) @route('/static/') def send_static(filename): return static_file(filename, root=statics) def submit_node(id, request): # create new\update node based on request.params.items() redirect('/') @route('/new/', method=['GET', 'POST']) @route('/edit/:no', method=['GET', 'POST']) @require_auth def edit_node(no=None): global DB if 'POST' in request.method: submit_node(no, request) if no: node = DB.getnodes([no])[0] node = Node.from_encrypted_entries(node[1], node[2], node[3], node[4], node[5:]) output = template('edit.tpl', node=node, template_lookup=templates_path) return output @route('/forget', method=['GET', 'POST']) def forget(): global AUTHENTICATED AUTHENTICATED = False enc = CryptoEngine.get() enc.forget() redirect('/auth') @route('/auth', method=['GET', 'POST']) def is_authenticated(): global AUTHENTICATED crypto = CryptoEngine.get() if request.method == 'POST': key = request.POST.get('pwd', '') while True: try: crypto.authenticate(key) break except Exception: redirect('/auth') AUTHENTICATED = True redirect('/') else: return template("login.tpl", template_lookup=templates_path, request=request) @route('/auth', method=['GET', 'POST']) def is_authenticated(): crypto = CryptoEngine.get() crypto.authenticate('foobar') global AUTHENTICATED AUTHENTICATED = True redirect('/') @route('/', method=['GET', 'POST']) @require_auth def listnodes(apply=['require_login']): global AUTHENTICATED, TAGS, DB _filter = None if 'POST' in request.method: _filter = request.POST.get('tag') if _filter: DB._filtertags = [] if _filter == 'None': DB._filtertags = [] nodeids = DB.listnodes() raw_nodes = DB.getnodes(nodeids) _nodes_inst = [] for node in raw_nodes: _nodes_inst.append(Node.from_encrypted_entries( node[1], node[2], node[3], node[4], node[5:])) _nodes_inst[-1]._id = node[0] nodesd = _nodes_inst ce = CryptoEngine.get() tags = [ce.decrypt(t).decode() for t in DB.listtags()] html_nodes = template("index.tpl", nodes=nodesd, tags=tags, request=request, template_lookup=[resource_filename('pwman', 'ui/templates')]) return html_nodes @route('/static/') def server_static(filepath): return static_file(filepath, root=statics) class Pwman3WebDaemon(object): def __enter__(self): return self def run(self): global AUTHENTICATED, TAGS, DB OSX = False print(sys.argv) args = parser_options().parse_args() xselpath, dburi, configp = get_conf_options(args, OSX) DB = pwman.data.factory.createdb(dburi, None) DB.open() print(dburi) print(dir(DB)) CryptoEngine.get() debug(True) run(port=9030) def __exit__(self, type, value, traceback): return isinstance(value, TypeError) if __name__ == '__main__': with Pwman3WebDaemon() as webui: webui.run()