manhole can now be opend/closed TTW
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1102 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
9f0cfba50d
commit
af872764f5
5 changed files with 137 additions and 58 deletions
|
@ -2,46 +2,3 @@
|
|||
$Id$
|
||||
"""
|
||||
|
||||
from twisted.internet import reactor, protocol
|
||||
from twisted.protocols import basic
|
||||
from twisted.cred import portal, checkers
|
||||
from twisted.conch import manhole, manhole_ssh
|
||||
try:
|
||||
from zope.app.publication.zopepublication import ZopePublication
|
||||
from zope.app.component.hooks import setSite
|
||||
hasZope = True
|
||||
except:
|
||||
hasZope = False
|
||||
import time
|
||||
import sys
|
||||
from cStringIO import StringIO
|
||||
|
||||
def getManholeFactory(namespace, **passwords):
|
||||
realm = manhole_ssh.TerminalRealm()
|
||||
def getManhole(_):
|
||||
return manhole.Manhole(namespace)
|
||||
realm.chainedProtocolFactory.protocolFactory = getManhole
|
||||
p = portal.Portal(realm)
|
||||
p.registerChecker(
|
||||
checkers.InMemoryUsernamePasswordDatabaseDontUse(**passwords))
|
||||
return manhole_ssh.ConchFactory(p)
|
||||
|
||||
def printTime():
|
||||
print 'twisted.manhole running:', time.strftime('%H:%M:%S')
|
||||
reactor.callLater(60, printTime)
|
||||
|
||||
#reactor.callLater(10, stopReactor)
|
||||
#reactor.listenTCP(5222, EchoServerFactory())
|
||||
|
||||
def startup(event=None):
|
||||
printTime()
|
||||
d = globals()
|
||||
#d['event'] = event
|
||||
if hasZope and event is not None:
|
||||
conn =event.database.open()
|
||||
root = conn.root()[ZopePublication.root_name]
|
||||
d.update(locals())
|
||||
reactor.listenTCP(5001, getManholeFactory(d, admin='aaa'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
startup()
|
|
@ -2,10 +2,17 @@
|
|||
|
||||
<configure
|
||||
xmlns="http://namespaces.zope.org/zope"
|
||||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
i18n_domain="zope"
|
||||
>
|
||||
|
||||
<subscriber handler="cybertools.twisted.manhole.startup"
|
||||
for="zope.app.appsetup.interfaces.IDatabaseOpenedEvent" />
|
||||
<browser:page
|
||||
for="zope.app.applicationcontrol.interfaces.IApplicationControl"
|
||||
name="manhole_control.html"
|
||||
template="manhole_control.pt"
|
||||
class=".manhole_control.ManholeControlView"
|
||||
permission="zope.ManageApplication"
|
||||
menu="zmi_views" title="Manhole Control"
|
||||
/>
|
||||
|
||||
</configure>
|
||||
|
|
|
@ -15,7 +15,10 @@ running the manhole script.
|
|||
|
||||
In order to use it with Zope copy the cybertools.twisted-configure.zcml
|
||||
to the etc/package-includes directory of your Zope instance and restart
|
||||
Zope. You can then log in with ssh like shown above, using the username
|
||||
Zope. Open the manhole via the "Manhole Control" Tab of the "Manage process"
|
||||
menu.
|
||||
|
||||
You can then log in with ssh like shown above, using the username
|
||||
and password of the zope.manager principal defined in your principals.zcml.
|
||||
|
||||
After logging in use the `help` command to get more information.
|
||||
|
@ -26,12 +29,15 @@ $Id$
|
|||
from twisted.internet import reactor, protocol, defer
|
||||
from twisted.protocols import basic
|
||||
from twisted.cred import portal, checkers, credentials, error as credError
|
||||
from twisted.conch import manhole, manhole_ssh
|
||||
from twisted.conch import manhole as manhole, manhole_ssh
|
||||
from zope.interface import implements
|
||||
try:
|
||||
from zope.app.publication.zopepublication import ZopePublication
|
||||
from zope.app.component.hooks import setSite
|
||||
from zope.app.security.principalregistry import principalRegistry
|
||||
from zope.app.security import settings
|
||||
from zope.app.security.interfaces import IAuthentication
|
||||
from zope.app.securitypolicy.principalrole import principalRoleManager
|
||||
from zope.app import zapi
|
||||
import transaction
|
||||
hasZope = True
|
||||
|
@ -41,10 +47,16 @@ import time
|
|||
import sys
|
||||
from cStringIO import StringIO
|
||||
|
||||
listener = None
|
||||
factory = None
|
||||
printLog = None
|
||||
port = 5001
|
||||
|
||||
|
||||
def getManholeFactory(namespace, **passwords):
|
||||
realm = manhole_ssh.TerminalRealm()
|
||||
def getManhole(_):
|
||||
#return manhole.ColoredManhole(namespace)
|
||||
return manhole.Manhole(namespace)
|
||||
realm.chainedProtocolFactory.protocolFactory = getManhole
|
||||
p = portal.Portal(realm)
|
||||
|
@ -60,18 +72,26 @@ class ZopeManagerChecker(object):
|
|||
credentialInterfaces = (credentials.IUsernamePassword,)
|
||||
|
||||
def requestAvatarId(self, credentials):
|
||||
manager = principalRegistry.getPrincipal('zope.manager')
|
||||
login = credentials.username
|
||||
password = credentials.password
|
||||
if login == manager.getLogin() and manager.validate(password):
|
||||
return defer.succeed(login)
|
||||
# TODO: This should be based on the official Zope API stuff, e.g. via:
|
||||
#principalRegistry = zapi.getUtility(IAuthentication)
|
||||
principal = principalRegistry.getPrincipalByLogin(login)
|
||||
if principal.validate(password):
|
||||
roles = principalRoleManager.getRolesForPrincipal(principal.id)
|
||||
for role, setting in roles:
|
||||
if role == 'zope.Manager' and setting == settings.Allow:
|
||||
return defer.succeed(login)
|
||||
return defer.fail(credError.UnauthorizedLogin(
|
||||
'Insufficient permissions'))
|
||||
return defer.fail(credError.UnauthorizedLogin(
|
||||
'User/password not correct'))
|
||||
|
||||
|
||||
def printTime():
|
||||
print 'twisted.manhole running:', time.strftime('%H:%M:%S')
|
||||
reactor.callLater(600, printTime)
|
||||
global printLog
|
||||
print '***', time.strftime('%H:%M:%S'), '- twisted.manhole open ***'
|
||||
printLog = reactor.callLater(600, printTime)
|
||||
|
||||
|
||||
class Help(object):
|
||||
|
@ -101,23 +121,32 @@ class Help(object):
|
|||
help = Help()
|
||||
|
||||
|
||||
def startup(event=None, port=5001):
|
||||
global hasZope
|
||||
def open(port=5001, request=None):
|
||||
global hasZope, factory, listener
|
||||
printTime()
|
||||
d = globals()
|
||||
if hasZope and event is not None:
|
||||
connection = event.database.open()
|
||||
if hasZope and request is not None:
|
||||
database = request.publication.db
|
||||
connection = database.open()
|
||||
root = connection.root()[ZopePublication.root_name]
|
||||
else:
|
||||
hasZope = False
|
||||
d.update(locals())
|
||||
namespace = {}
|
||||
for key in ('__builtins__', 'connection', 'event', 'setSite', 'hasZope',
|
||||
'zapi', 'transaction', 'root', '__doc__', 'help'):
|
||||
'zapi', 'transaction', 'root', '__doc__', 'help',
|
||||
'manholeFactory', 'context'):
|
||||
if key in d:
|
||||
namespace[key] = d[key]
|
||||
# TODO: get admin password from somewhere else or use a real checker.
|
||||
reactor.listenTCP(port, getManholeFactory(namespace, admin='aaa'))
|
||||
factory = getManholeFactory(namespace, admin='aaa')
|
||||
listener = reactor.listenTCP(port, factory)
|
||||
|
||||
def close():
|
||||
global listener
|
||||
listener.stopListening()
|
||||
listener = None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = 5001
|
||||
|
|
43
twisted/manhole_control.pt
Normal file
43
twisted/manhole_control.pt
Normal file
|
@ -0,0 +1,43 @@
|
|||
<html metal:use-macro="context/@@standard_macros/view"
|
||||
i18n:domain="zope">
|
||||
<head>
|
||||
<title i18n:translate="">ZODB Controller</title>
|
||||
</head>
|
||||
<body>
|
||||
<div metal:fill-slot="body">
|
||||
|
||||
<tal:update condition="view/update" />
|
||||
|
||||
<div class="row" tal:condition="view/isOpen">
|
||||
<div class="field" i18n:translate="">Manhole is open.</div>
|
||||
</div>
|
||||
<div class="row" tal:condition="not:view/isOpen">
|
||||
<div class="field" i18n:translate="">Manhole is closed.</div>
|
||||
</div>
|
||||
|
||||
<form action="." method="post" tal:attributes="action request/URL">
|
||||
<input type="hidden" name="form_submitted" value="true" />
|
||||
<div class="row">
|
||||
<span class="label"
|
||||
i18n:translate="">Port</span>:
|
||||
<input type="text" size="5" name="manhole.port"
|
||||
tal:attributes="value view/port" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<input type="checkbox" size="5" name="manhole.setting" value="true" />
|
||||
<span class="label" i18n:translate=""
|
||||
tal:condition="not:view/isOpen">Open manhole</span>
|
||||
<span class="label" i18n:translate=""
|
||||
tal:condition="view/isOpen">Close manhole</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="controls">
|
||||
<input type="submit" name="APPLY" value="Apply"
|
||||
i18n:attributes="value apply-button"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
43
twisted/manhole_control.py
Normal file
43
twisted/manhole_control.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
""" Manhole Control View
|
||||
|
||||
$Id$
|
||||
"""
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
from cybertools.twisted import manhole
|
||||
|
||||
class ManholeControlView(object):
|
||||
|
||||
def isOpen(self):
|
||||
return manhole.listener is not None
|
||||
|
||||
def toggleState(self):
|
||||
if self.isOpen():
|
||||
manhole.close()
|
||||
else:
|
||||
manhole.open(self.port(), self.request)
|
||||
|
||||
def port(self):
|
||||
return manhole.port
|
||||
|
||||
def update(self):
|
||||
if not self.request.get('form_submitted'):
|
||||
return
|
||||
port = self.request.get('manhole.port')
|
||||
if port:
|
||||
manhole.port = int(port)
|
||||
if self.request.get('manhole.setting', False):
|
||||
self.toggleState()
|
Loading…
Add table
Reference in a new issue