[rhmessaging-commits] rhmessaging commits: r1727 - in mgmt: cumin/python/cumin and 2 other directories.
rhmessaging-commits at lists.jboss.org
rhmessaging-commits at lists.jboss.org
Tue Feb 26 11:42:17 EST 2008
Author: justi9
Date: 2008-02-26 11:42:17 -0500 (Tue, 26 Feb 2008)
New Revision: 1727
Added:
mgmt/cumin/bin/cumin-admin
Removed:
mgmt/cumin/bin/cumin-database
Modified:
mgmt/cumin/bin/cumin
mgmt/cumin/python/cumin/__init__.py
mgmt/cumin/python/cumin/page.py
mgmt/cumin/python/cumin/page.strings
mgmt/cumin/python/wooly/__init__.py
mgmt/cumin/python/wooly/server.py
mgmt/notes/justin-todo.txt
Log:
Adds user auth to cumin.
Introduces a CuminServer class that performs the authorization.
Replaces cumin-database with a new tool, cumin-admin, that now does
both schema operations and adds and removes users.
Restores the current user UI (for real this time) and implements log
out.
Modified: mgmt/cumin/bin/cumin
===================================================================
--- mgmt/cumin/bin/cumin 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/bin/cumin 2008-02-26 16:42:17 UTC (rev 1727)
@@ -1,7 +1,6 @@
#!/usr/bin/env python
-import sys, os
-from wooly.server import WebServer
+import sys, os, socket
from cumin import *
from cumin.util import *
@@ -33,12 +32,11 @@
app.init()
- server = WebServer(app, port)
+ host = socket.gethostname()
+ server = CuminServer(app, host, port)
try:
server.start()
- except KeyboardInterrupt:
- server.stop()
except:
server.stop()
raise
@@ -70,4 +68,7 @@
do_main(home, data, port, debug)
if __name__ == "__main__":
- main()
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
Added: mgmt/cumin/bin/cumin-admin
===================================================================
--- mgmt/cumin/bin/cumin-admin (rev 0)
+++ mgmt/cumin/bin/cumin-admin 2008-02-26 16:42:17 UTC (rev 1727)
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+
+import sys, os
+from sqlobject import connectionForURI
+from traceback import print_exc
+from getpass import getpass
+from random import sample
+from crypt import crypt
+from mint import MintDatabase, ConsoleUser
+
+from cumin.util import *
+
+def usage():
+ print """Usage: cumin-admin [OPTIONS...] COMMAND
+Options:
+ -h, --help Print this message
+ --data URL Connect to database at URL
+ (default postgesql://cumin@localhost/cumin)
+ --force yes Don't complain and just do it
+Commands:
+ create-schema Create the database schema
+ drop-schema Drop the database schema; requires "--force yes"
+
+ add-user NAME Add user called NAME
+ remove-user NAME Remove user called NAME; requires "--force yes"
+ list-users List existing users
+"""
+ sys.exit(1)
+
+def parse_command_args():
+ args = list()
+ parg = ""
+
+ for arg in sys.argv[1:]:
+ if not arg.startswith("--") and not parg.startswith("--"):
+ args.append(arg)
+
+ parg = arg
+
+ return args
+
+def main():
+ if "-h" in sys.argv or "--help" in sys.argv:
+ usage()
+
+ home = os.environ.get("CUMIN_HOME")
+
+ if not home:
+ home = os.path.normpath("/usr/share/cumin")
+
+ config = Config()
+ config.add_param("data", "s", "postgresql://cumin@localhost/cumin")
+ config.add_param("force", "b", False)
+
+ config.load_file(os.path.join(home, "etc", "cumin.conf"))
+ config.load_file(os.path.join(os.path.expanduser("~"), ".cumin.conf"))
+ config.load_args(sys.argv)
+
+ config.prt()
+
+ home = os.environ["CUMIN_HOME"]
+ data = config.get("data")
+ force = config.get("force")
+
+ args = parse_command_args()
+
+ if not args:
+ print "Error: no command found"
+ usage()
+
+ command = args[0]
+
+ database = MintDatabase(data)
+ database.check()
+ database.init()
+
+ if command == "create-schema":
+ main = os.path.join(home, "sql", "schema.sql")
+ indexes = os.path.join(home, "sql", "indexes.sql")
+
+ database.createSchema((main, indexes))
+ elif command == "drop-schema":
+ if force:
+ database.dropSchema()
+ else:
+ print "Error: command create-schema requires --force yes"
+ usage()
+ elif command == "add-user":
+ if len(args) != 2:
+ print "Error: no user name given"
+ usage()
+
+ password = getpass()
+
+ chs = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ ch0, ch1 = sample(chs, 2)
+
+ user = ConsoleUser()
+ user.name = args[1]
+ user.password = crypt(password, ch0 + ch1)
+ user.syncUpdate()
+ elif command == "remove-user":
+ if force:
+ if len(args) != 2:
+ print "Error: no user name given"
+ usage()
+
+ accounts = ConsoleUser.selectBy(name=args[1])
+
+ if accounts.count():
+ for account in accounts:
+ account.destroySelf()
+ return
+ else:
+ print "Error: no such user '%s'" % args[1]
+ else:
+ print "Error: command remove-user requires --force yes"
+ usage()
+
+ elif command == "list-users":
+ accounts = ConsoleUser.select(orderBy='name')
+
+ for account in accounts:
+ print "%4i %s" % (account.id, account.name)
+
+ count = accounts.count()
+ print "(%i user%s found)" % (count, ess(count))
+ else:
+ print "Error: command '%s' not recognized" % command
+ usage()
+
+if __name__ == "__main__":
+ try:
+ main()
+ except SystemExit, e:
+ raise e
+ except:
+ print_exc()
+ sys.exit(1)
Property changes on: mgmt/cumin/bin/cumin-admin
___________________________________________________________________
Name: svn:executable
+ *
Deleted: mgmt/cumin/bin/cumin-database
===================================================================
--- mgmt/cumin/bin/cumin-database 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/bin/cumin-database 2008-02-26 16:42:17 UTC (rev 1727)
@@ -1,90 +0,0 @@
-#!/usr/bin/env python
-
-import sys, os
-from sqlobject import connectionForURI
-from traceback import print_exc
-from mint import MintDatabase
-
-from cumin.util import *
-
-def usage():
- print """Usage: cumin-database [OPTIONS...] COMMAND
-Options:
- -h, --help Print this message
- --data URL Connect to database at URL
- (default postgesql://cumin@localhost/cumin)
- --force yes Don't complain and just do it
-Commands:
- create-schema Create the database schema; requires --force
- drop-schema Drop the database schema; requires --force
-"""
- sys.exit(1)
-
-def parse_command():
- parg = ""
-
- for arg in sys.argv[1:]:
- if not arg.startswith("--") and not parg.startswith("--"):
- return arg
-
- parg = arg
-
-def main():
- if "-h" in sys.argv or "--help" in sys.argv:
- usage()
-
- home = os.environ.get("CUMIN_HOME")
-
- if not home:
- home = os.path.normpath("/usr/share/cumin")
-
- config = Config()
- config.add_param("data", "s", "postgresql://cumin@localhost/cumin")
- config.add_param("force", "b", False)
-
- config.load_file(os.path.join(home, "etc", "cumin.conf"))
- config.load_file(os.path.join(os.path.expanduser("~"), ".cumin.conf"))
- config.load_args(sys.argv)
-
- config.prt()
-
- home = os.environ["CUMIN_HOME"]
- data = config.get("data")
- force = config.get("force")
-
- command = parse_command()
-
- if command is None:
- print "Error: no command found"
- usage()
-
- database = MintDatabase(data)
- database.checkConnection()
-
- if command == "create-schema":
- if force:
- main = os.path.join(home, "sql", "schema.sql")
- indexes = os.path.join(home, "sql", "indexes.sql")
-
- database.createSchema((main, indexes))
- else:
- print "Command create-schema requires --force yes"
- sys.exit(1)
- elif command == "drop-schema":
- if force:
- database.dropSchema()
- else:
- print "Command create-schema requires --force yes"
- sys.exit(1)
- else:
- print "Error: command '%s' not recognized" % command
- usage()
-
-if __name__ == "__main__":
- try:
- main()
- except SystemExit, e:
- raise e
- except:
- print_exc()
- sys.exit(1)
Modified: mgmt/cumin/python/cumin/__init__.py
===================================================================
--- mgmt/cumin/python/cumin/__init__.py 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/python/cumin/__init__.py 2008-02-26 16:42:17 UTC (rev 1727)
@@ -1,4 +1,4 @@
-import sys, os, socket
+import sys, os
from random import randint
from wooly import Application, Session, Page
@@ -10,6 +10,8 @@
from time import sleep
from threading import Thread, Event
from traceback import print_exc
+from base64 import decodestring
+from crypt import crypt
from model import CuminModel, ModelPage
from demo import DemoData
@@ -90,3 +92,35 @@
reg.connect(self.model.data)
self.event.wait(10)
+
+class CuminServer(WebServer):
+ def authorized(self, session):
+ name = session.credentials.get("name")
+ password = session.credentials.get("password")
+
+ if name:
+ try:
+ user = ConsoleUser.selectBy(name=name)[0]
+ except IndexError:
+ return False
+
+ if user:
+ crypted = user.password
+
+ if crypted and crypt(password, crypted) == crypted:
+ lch = user.lastChallenged
+
+ if lch:
+ timeout = timedelta(seconds=3600)
+ now = datetime.now()
+
+ if now - lch < timeout:
+ lout = user.lastLoggedOut
+
+ if lout is None or lout < lch:
+ return True
+
+ user.lastChallenged = datetime.now()
+ user.syncUpdate()
+
+ return False
Modified: mgmt/cumin/python/cumin/page.py
===================================================================
--- mgmt/cumin/python/cumin/page.py 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/python/cumin/page.py 2008-02-26 16:42:17 UTC (rev 1727)
@@ -1,6 +1,7 @@
from wooly import *
from wooly.widgets import *
from wooly.resources import *
+from time import sleep
from broker import *
from brokergroup import *
@@ -58,6 +59,9 @@
def __init__(self, app, name):
super(MainFrame, self).__init__(app, name)
+ self.__logout = BooleanParameter(app, "logout")
+ self.add_parameter(self.__logout)
+
self.__frame_tmpl = Template(self, "frame_html")
self.__tabs = MainFrameTabs(app, "tabs")
@@ -95,6 +99,14 @@
def get_title(self, session, object):
return "Main"
+ def render_user_name(self, session, object):
+ return session.credentials.get("name")
+
+ def render_logout_href(self, session, object):
+ branch = session.branch()
+ self.__logout.set(branch, True)
+ return branch.marshal()
+
def render_frames(self, session, object):
self.__object.set(session, object)
writer = Writer()
@@ -163,6 +175,31 @@
frame.set_object(session, system)
return self.page().set_current_frame(session, frame)
+ def do_process(self, session, object):
+ if self.__logout.get(session):
+ self.__logout.set(session, False)
+
+ name = session.credentials.get("name")
+
+ try:
+ user = ConsoleUser.selectBy(name=name)[0]
+ except IndexError:
+ pass
+
+ if user:
+ user.lastLoggedOut = datetime.now()
+ user.syncUpdate()
+
+ # XXX boy, this sucks. necessary because the
+ # resolution of TimestampCol (lastLoggedOut) is too
+ # coarse for the subsequent comparison of
+ # lastLoggedOut and lastChallenged
+ sleep(1)
+
+ self.page().set_redirect_url(session, session.marshal())
+
+ super(MainFrame, self).do_process(session, object)
+
class MainFrameTabs(LinkSet):
def __init__(self, app, name):
super(MainFrameTabs, self).__init__(app, name)
Modified: mgmt/cumin/python/cumin/page.strings
===================================================================
--- mgmt/cumin/python/cumin/page.strings 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/python/cumin/page.strings 2008-02-26 16:42:17 UTC (rev 1727)
@@ -708,12 +708,10 @@
[MainFrame.html]
<div id="head">
<div>
- <!--
<ul id="user">
- <li>Hi, <strong>user</strong></li>
- <li><a class="nav" href="">Log Out</a></li>
+ <li>Hi, <strong>{user_name}</strong></li>
+ <li><a class="nav" onclick="wooly.clearUpdates()" href="{logout_href}">Log Out</a></li>
</ul>
- -->
{tabs}
</div>
Modified: mgmt/cumin/python/wooly/__init__.py
===================================================================
--- mgmt/cumin/python/wooly/__init__.py 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/python/wooly/__init__.py 2008-02-26 16:42:17 UTC (rev 1727)
@@ -518,6 +518,7 @@
self.trunk = trunk
self.page = None
self.values = dict()
+ self.credentials = dict()
if self.app.debug:
self.debug = self.Debug(self)
Modified: mgmt/cumin/python/wooly/server.py
===================================================================
--- mgmt/cumin/python/wooly/server.py 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/cumin/python/wooly/server.py 2008-02-26 16:42:17 UTC (rev 1727)
@@ -1,7 +1,7 @@
-from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from traceback import print_exc
from datetime import datetime
from time import strptime
+from base64 import decodestring
from wooly import *
from devel import DevelPage
@@ -10,12 +10,13 @@
class WebServer(object):
http_date = "%a, %d %b %Y %H:%M:%S %Z"
- def __init__(self, app, port=8080):
+ def __init__(self, app, host, port):
self.app = app
+ self.host = host
self.port = port
- addr = ("localhost", self.port)
- apps = [("", self.wsgi_app)]
+ addr = (self.host, self.port)
+ apps = [("", self.service)]
self.__server = CherryPyWSGIServer(addr, apps)
self.__server.ssl_certificate = None # "/tmp/localhost.crt"
self.__server.ssl_private_key = None # "/tmp/localhost.key"
@@ -23,13 +24,11 @@
def start(self):
self.__server.start()
- print "Web server started on port %s" % (self.port)
-
def stop(self):
self.__server.stop()
- def wsgi_app(self, env, respond):
- if env["PATH_INFO"].endswith(".html"):
+ def service(self, env, respond):
+ if False and env["PATH_INFO"].endswith(".html"):
print "------------------------------------"
for key in sorted(env):
print key, env[key]
@@ -38,6 +37,17 @@
session.unmarshal_page(env["PATH_INFO"])
session.unmarshal_url_vars(env["QUERY_STRING"])
+ if "HTTP_AUTHORIZATION" in env:
+ str = env["HTTP_AUTHORIZATION"].split(" ")[1]
+ name, password = decodestring(str).split(":", 1)
+ session.credentials["name"] = name
+ session.credentials["password"] = password
+
+ if not self.authorized(session):
+ headers = [("WWW-Authenticate", "Basic realm=\"MRG Management\"")]
+ respond("401 Unauthorized", headers)
+ return ()
+
if env["REQUEST_METHOD"] == "POST":
if env["CONTENT_TYPE"] == "application/x-www-form-urlencoded":
length = int(env["CONTENT_LENGTH"])
@@ -101,6 +111,9 @@
return response
+ def authorized(self, session):
+ return False
+
def error(self, session, respond):
respond("500 Error", [("Content-Type", "text/plain")])
Modified: mgmt/notes/justin-todo.txt
===================================================================
--- mgmt/notes/justin-todo.txt 2008-02-26 16:34:01 UTC (rev 1726)
+++ mgmt/notes/justin-todo.txt 2008-02-26 16:42:17 UTC (rev 1727)
@@ -16,8 +16,12 @@
* Add broker reg name unique constraint and validation
+ * Add unique constraint to user name, and deal with it in cumin-admin
+
Deferred
+ * Blow up if we try to call set_redirect_url twice in a session
+
* Need to add cherrypy bsd license to binary dist?
* See if we can't avoid the app.add_parameter in Parameter; adding to
More information about the rhmessaging-commits
mailing list