Skip to content

Instantly share code, notes, and snippets.

@lvh
Created September 15, 2012 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lvh/3727373 to your computer and use it in GitHub Desktop.
Save lvh/3727373 to your computer and use it in GitHub Desktop.
Manhole and Axiom demo
from axiom import attributes, item, store
import jinja2
import sys
from twisted.cred import checkers, portal
from twisted.conch import manhole, manhole_ssh
from twisted.internet import reactor
from twisted.python import log
from twisted.web import resource, server
class Link(item.Item):
title = attributes.text(allowNone=False)
url = attributes.bytes(allowNone=False)
votes = attributes.integer(default=0)
template = jinja2.Template("""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<h1>lvh's link farm!</h1>
<ul>
{% for link in links %}
<li>
<a href="{{ link.url }}">
{{ link.title }}
</a>
({{ link.votes }} votes)
</li>
{% endfor %}
</ul>
</body>
</html>
""")
class DemoResource(resource.Resource):
isLeaf = True
def __init__(self, store):
self.store = store
def render_GET(self, request):
links = self.store.query(Link, sort=Link.votes.descending)
return template.render(links=links).encode("utf-8")
demoStore = store.Store("myAxiomStore")
demoResource = DemoResource(demoStore)
# These are the globals we'll make available to people logging in.
shellGlobals = {
"demoStore": demoStore,
"Link": Link
}
# Although you *could* dynamically figure out which globals you want to add,
# defining them declaratively is a lot simpler and more common.
def makeManhole(_ign):
return manhole.ColoredManhole(shellGlobals)
# Enter the Cred parts. A realm is a thing that gives authenticated clients
# some object. In this case, we'll be creating terminal sessions.
realm = manhole_ssh.TerminalRealm()
realm.chainedProtocolFactory.protocolFactory = makeManhole
# Yes, it says "don't use" -- that's just for security reasons. There are
# other interesting checkers in that module, probably most interestingly
# a PAM checker so you can plug straight into your system's native auth :)
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(abc="xyz")
# A portal is just a thing that glues a realm + checkers together.
manholePortal = portal.Portal(realm, [checker])
manholeFactory = manhole_ssh.ConchFactory(manholePortal)
log.startLogging(sys.stdout)
reactor.listenTCP(9080, server.Site(demoResource))
reactor.listenTCP(9022, manholeFactory)
reactor.run()
from axiom import attributes, item, store, upgrade
import jinja2
import sys
from twisted.application import service
from twisted.cred import checkers, portal
from twisted.conch import manhole, manhole_ssh
from twisted.internet import reactor
from twisted.python import log
from twisted.web import resource, server
class Link(item.Item):
schemaVersion = 2
title = attributes.text(allowNone=False)
url = attributes.bytes(allowNone=False)
votes = attributes.integer(default=0)
color = attributes.bytes(default="#FF0000")
# This is easy since we're just appending to the schema. The general API is
# registerUpgrader, this is just a shorthand that copies existing attrs.
upgrade.registerAttributeCopyingUpgrader(Link, 1, 2)
template = jinja2.Template("""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<h1>lvh's link farm!</h1>
<ul>
{% for link in links %}
<li>
<a style="color: {{ link.color }}" href="{{ link.url }}">
{{ link.title }}
</a>
({{ link.votes }} votes)
</li>
{% endfor %}
</ul>
</body>
</html>
""")
class DemoResource(resource.Resource):
isLeaf = True
def __init__(self, store):
self.store = store
def render_GET(self, request):
links = self.store.query(Link, sort=Link.votes.descending)
return template.render(links=links).encode("utf-8")
demoStore = store.Store("myAxiomStore")
# This starts all of the store's IServices: including scheduling and upgrading
service.IService(demoStore).startService()
demoResource = DemoResource(demoStore)
# These are the globals we'll make available to people logging in.
shellGlobals = {
"demoStore": demoStore,
"Link": Link
}
# Although you *could* dynamically figure out which globals you want to add,
# defining them declaratively is a lot simpler and more common.
def makeManhole(_ign):
return manhole.ColoredManhole(shellGlobals)
# Enter the Cred parts. A realm is a thing that gives authenticated clients
# some object. In this case, we'll be creating terminal sessions.
realm = manhole_ssh.TerminalRealm()
realm.chainedProtocolFactory.protocolFactory = makeManhole
# Yes, it says "don't use" -- that's just for security reasons. There are
# other interesting checkers in that module, probably most interestingly
# a PAM checker so you can plug straight into your system's native auth :)
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(abc="xyz")
# A portal is just a thing that glues a realm + checkers together.
manholePortal = portal.Portal(realm, [checker])
manholeFactory = manhole_ssh.ConchFactory(manholePortal)
log.startLogging(sys.stdout)
reactor.listenTCP(9080, server.Site(demoResource))
reactor.listenTCP(9022, manholeFactory)
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment