| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | #!/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 <nahumoz@gmail.com># ============================================================================from __future__ import print_functionfrom bottle import route, run, debug, template, request, redirect, static_filefrom pwman.util.crypto import CryptoEngineimport pwman.data.factoryfrom pwman.data.tags import TagNewfrom pwman import parser_options, get_conf_optionsfrom daemon import Daemonfrom pkg_resources import resource_filenameimport itertoolsimport argparseimport sysfrom os.path import expanduser, jointemplates_path = [resource_filename('pwman', 'ui/templates')]statics = [resource_filename('pwman', 'ui/templates/static')][0]AUTHENTICATED = FalseTAGS = NoneDB = 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!def require_auth(fn):    def check_auth(**kwargs):        if AUTHENTICATED:            return fn(**kwargs)        else:            redirect("/auth")    return check_auth@route('/node/:no')@require_authdef view_node(no):    global DB    node = DB.getnodes([no])    output = template("view.tpl", node=node[0], template_lookup=templates_path)    return outputdef 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_authdef edit_node(no=None):    global DB    if 'POST' in request.method:        submit_node(no, request)    if no:        node = DB.getnodes([no])[0]    else:        class Node(object):            def __init__(self):                self._id = None                self.username = ''                self.password = ''                self.url = ''                self.notes = ''                self.tags = ''        node = Node()    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(dbver=0.5)    if request.method == 'POST':        key = request.POST.get('pwd', '')        crypto.auth(key)        AUTHENTICATED = True        redirect('/')    else:        return template("login.tpl", template_lookup=templates_path)@route('/', method=['GET', 'POST'])@require_authdef listnodes(apply=['require_login']):    global AUTHENTICATED, TAGS, DB    _filter = None    if 'POST' in request.method:        _filter = request.POST.get('tag')        if _filter:            DB._filtertags = [TagNew(_filter.strip())]        if _filter == 'None':            DB._filtertags = []    nodeids = DB.listnodes()    nodes = DB.getnodes(nodeids)    nodesd = [''] * len(nodes)    for idx, node in enumerate(nodes):        ntags = [t.strip() for t in filter(None, node.tags)]        nodesd[idx] = ('@'.join((node.username, node.url)),                       ', '.join(ntags))    if not TAGS:        t = [node.tags for node in nodes]        t1 = list(itertools.chain.from_iterable(t))        TAGS = list(set(t1))        TAGS.sort()        TAGS.insert(0, 'None')    html_nodes = template("main.tpl", nodes=nodes, tags=TAGS,                          template_lookup=[resource_filename('pwman',                                                             'ui/templates')])    return html_nodes@route('/static/<filepath:path>')def server_static(filepath):    return static_file(filepath, root=statics)class Pwman3WebDaemon(Daemon):    def startd(self):        """        Start the daemon        """        # Check for a pidfile to see if the daemon already runs        self.exit_running()        #if not os.path.exists(self.pidfile):        # Start the daemon        self.daemonize()        # after self.daemonize()        # all output is redirected        print(open(self.pidfile).read())        self.run()    def run(self):        global AUTHENTICATED, TAGS, DB        OSX = False        sys.argv = []        args = parser_options().parse_args()        xselpath, dbtype = get_conf_options(args, OSX)        dbver = 0.5        DB = pwman.data.factory.create(dbtype, dbver)        DB.open(dbver=0.5)        print(dir(DB))        CryptoEngine.get(dbver=0.5)        print(pwman.config._conf)        debug(True)        run(port=9030)if __name__ == '__main__':    parser = argparse.ArgumentParser(        description="Start the webui of pwman3",        usage='%(prog)s start|stop|restart|status [-p|-d]\n',        )    parser.add_argument('-D', '--NoDaemon',                        help='Do not fork, start in foreground',                        action="store_true", default=False)    ext_usage = ("{prog} start - starts the webui."                 "{prog} stop - stops the webui."                 "{prog} status - check if the process is already running."                 "".format(prog=parser.prog))    if len(sys.argv) == 1:        parser.print_help()        sys.exit(1)    action = sys.argv[1]    if action not in ['start', 'stop', 'restart', 'status']:        parser.print_help()        print(ext_usage)        sys.exit(1)    sys.argv = sys.argv[1:]    path = join(expanduser("~"), '.pwman')    daemon = Pwman3WebDaemon(parser.prog, join(path, '%s.pid' % parser.prog),                             noisy=True)    args = parser.parse_args()    if action == 'status':        running = daemon.check_proc()        if running:            print("%s already runs with pid: %d" % (parser.prog, running))    if action == 'start' and args.NoDaemon:        try:            daemon.start()        except KeyboardInterrupt:            daemon.set_level("auto")            daemon.stop()    if action == 'start' and not args.NoDaemon:        daemon.startd()    if action == "restart":        daemon.restart()    if action == "stop":        daemon.stop()
 |