Skip to content
This repository has been archived by the owner on Apr 16, 2022. It is now read-only.

Commit

Permalink
ADDED:RPCAuth files
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Bernard committed May 23, 2006
1 parent b2636d2 commit bd5ec74
Show file tree
Hide file tree
Showing 9 changed files with 441 additions and 0 deletions.
10 changes: 10 additions & 0 deletions web/ryzom_com/RPCAuth/CHANGLOG.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version 0.0.1 Initial release: works for me

version 0.0.2 Changed detection in modifyRequest to check Content-Type
and Request-Method

version 0.0.3 Added add, list, remove methods so product coders can
register their functions to avoid prefixing username and passwords.
Changed modifyRequest to not check Content-Type.

version 0.4 Zope 2.7 support. Work if unicode path is passed in.
66 changes: 66 additions & 0 deletions web/ryzom_com/RPCAuth/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
NAME=RPCAuth
MAJOR_VERSION=0.1
MINOR_VERSION=0
RELEASE_TAG=final
PACKAGE_NAME=${NAME}-${MAJOR_VERSION}.${MINOR_VERSION}_${RELEASE_TAG}

PYTHON="/usr/bin/python"
TMPDIR=~/tmp

CURDIR=~/src/collective/RPCAuth
BASE_DIR=${CURDIR}/..
SOFTWARE_HOME=~/src/zope/2_7/lib/python
INSTANCE_HOME=~/src/instance/head
PACKAGES=RPCAuth


RM=rm -f
RMRF=rm -rf
FIND=find
XARGS=xargs
CD=cd
LN=ln -sfn
CP=cp
TAR=tar
MKDIR=mkdir -p

.PHONY : clean test reindent reindent_clean sdist
.PHONY : default

# default: The default step (invoked when make is called without a target)
default: clean test

clean :
find . \( -name '*~' -o -name '*.py[co]' -o -name '*.bak' \) -exec rm {} \; -print

reindent :
~/src/reindent.py -r -v .

test :
export INSTANCE_HOME=${INSTANCE_HOME}; export SOFTWARE_HOME=${SOFTWARE_HOME}; \
cd ${CURDIR}/tests && ${PYTHON} runalltests.py


# sdist: Create a source distribution file (implies clean).
#
sdist: reindent clean sdist_tgz

# sdist_tgz: Create a tgz archive file as a source distribution.
#
sdist_tgz:
echo -n "${MAJOR_VERSION}.${MINOR_VERSION}-${RELEASE_TAG}" >\
${CURDIR}/version.txt
${MKDIR} ${TMPDIR}/${PACKAGE_NAME}
${CD} ${TMPDIR}/${PACKAGE_NAME} && \
for package in ${PACKAGES}; do ${LN} ${BASE_DIR}/$$package .; done && \
${CD} ${TMPDIR} && ${TAR} czfh ${BASE_DIR}/${PACKAGE_NAME}.tgz ${PACKAGE_NAME} \
--exclude=${PACKAGE_NAME}.tgz\
--exclude=CVS \
--exclude=.cvsignore \
--exclude=makefile \
--exclude=Makefile \
--exclude=*.pyc \
--exclude=TAGS \
--exclude=*~ \
--exclude=.#*
${RMRF} ${TMPDIR}/${PACKAGE_NAME}
6 changes: 6 additions & 0 deletions web/ryzom_com/RPCAuth/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RPCAuth is a rip off of the great CookieCrumbler product. It is
designed to allow users of XML-RPC methods to pass their username and
password as arguments. It works on the same principle as the
CookieCrumbler allowing the transparent use of existing UserFolders,
just add a RPCAuth instance to the folder where your acl_users is
located.
Binary file added web/ryzom_com/RPCAuth/RPCAuth.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
223 changes: 223 additions & 0 deletions web/ryzom_com/RPCAuth/RPCAuth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
"""
RPCAuth is a pretraversal hook that checks for xmlrpc calls and
tries to extract a username and password from the arguements passed
"""

import sys
from base64 import encodestring
from urllib import quote, unquote
from os import path
import string
from DateTime import DateTime
from utils import SimpleItemWithProperties
from AccessControl import ClassSecurityInfo, Permissions
from ZPublisher import BeforeTraverse
import Globals
from zLOG import LOG, ERROR
from App.Common import package_home
from ZPublisher.HTTPRequest import HTTPRequest

# Constants.
ATTEMPT_DISABLED = -1
ATTEMPT_NONE = 0
ATTEMPT_LOGIN = 1
ATTEMPT_CONT = 2

ModifyRPCAuth = 'Change RPC Auth'


class RPCAuth(SimpleItemWithProperties):
'''
Reads xmlrpc args during traversal and simulates the HTTP
authentication headers.
'''
meta_type = 'RPC Auth'
security = ClassSecurityInfo()
security.declareProtected(ModifyRPCAuth,
'manage_editProperties',
'manage_changeProperties')
security.declareProtected(Permissions.view_management_screens,
'manage_propertiesForm')


_properties = ({'id':'uname_arg', 'type': 'string', 'mode':'w',
'label':'User name arguement prefix'},
{'id':'pword_arg', 'type': 'string', 'mode':'w',
'label':'User password arguement prefix'},
{'id':'remove_args','type':'boolean','mode':'w',
'label':'Remove password username arguements'},
)

def __init__(self):
self.remove_args = 1
self.uname_arg = 'zid'
self.pword_arg = 'zpw'
self._authProviders = {'absglob':{},'abs':{},'rel':{}}


security.declareProtected(ModifyRPCAuth,'addAuthProvider')
def addAuthProvider(self,objectPaths,function):
"""takes a list of paths and a function as an arguements"""
aps = getattr(self,'_authProviders',{'absglob':{},'abs':{},'rel':{}})
for name in list(objectPaths):
if name[-1] == '/' and name[0] == '/': # absolute glob
aps['absglob'][tuple(string.split(name,'/')[1:-1])] = function
if name[0] == '/': # absolute url
aps['abs'][tuple(string.split(name,'/')[1:])] = function
if name[0] != '/' and name[-1] != '/' and '/' in name: # relative
aps['rel'][tuple(string.split(name,'/'))] = function
self._authProviders = aps
self._p_changed = 1

security.declareProtected(ModifyRPCAuth,'listAuthProviders')
def listAuthProviders(self):
"""a list of objects with auth providers"""
aps = getattr(self,'_authProviders',{'absglob':{},'abs':{},'rel':{}})
return aps['absglob'].keys()+\
aps['abs'].keys()+\
aps['rel'].keys()

security.declareProtected(ModifyRPCAuth,'removeAuthProvider')
def removeAuthProvider(self,objectPaths):
"""remove auth providers objectPaths should be a list"""
for objectPath in list(objectPaths):
if type(objectPath) == type('s'):
objectPath = string.split(objectPath,'/')
while '' in objectPath: del objectPath[objectPath.index('')]
tuple(objectPath)
if objectPath in self._authProviders['absglob'].keys():
del self._authProviders['absglob'][objectPath]
elif objectPath in self._authProviders['abs'].keys():
del self._authProviders['abs'][objectPath]
elif objectPath in self._authProviders['rel'].keys():
del self._authProviders['rel'][objectPath]


def _identify(self,arg_tuple):
arg_list = list(arg_tuple)
zusername,zpassword = None,None
try:
for item in arg_tuple: #use the tuple here so we can delete items as we iterate
if type(item) == type('') and len(item) > len(self.uname_arg) and item[:len(self.uname_arg)] == self.uname_arg:
zusername = item[len(self.uname_arg):]
del arg_list[arg_list.index(item)]
continue
if type(item) == type('') and len(item) > len(self.uname_arg) and item[:len(self.pword_arg)] == self.pword_arg:
zpassword = item[len(self.pword_arg):]
del arg_list[arg_list.index(item)]
if zusername and zpassword:
arg_tuple = tuple(arg_list)
return zusername,zpassword,arg_tuple
else:
return None,None,None
except 'none':
return None

def _registryIdentify(self,targetPath):
targetPath = list(targetPath)
targetPath.reverse()
targetPath = [a.encode('utf-8') for a in targetPath]
targetPath = tuple(targetPath)
# first check absolute path cuz it's easy
if targetPath in self._authProviders['abs'].keys():
return self._authProviders['abs'][targetPath]
# check relative paths
relPath = targetPath[:]
while len(relPath) > 1:
if relPath in self._authProviders['rel'].keys():
return self._authProviders['rel'][relPath]
relPath= relPath[1:]
# check absolute globs
globPath = targetPath[:-1]
while len(globPath) > 1:
if globPath in self._authProviders['absglob'].keys():
return self._authProviders['absglob'][globPath]
globPath=globPath[:-1]
return None

security.declarePrivate('modifyRequest')
def modifyRequest(self, req, resp):
# Returns flags indicating what the user is trying to do.

if req.__class__ is not HTTPRequest:
return ATTEMPT_DISABLED

if not req._auth:
# Attempt to log in.
targetPath = tuple(req['TraversalRequestNameStack'])
authProvider = self._registryIdentify(targetPath)
if authProvider:
name,pw,arg_tuple = authProvider(req.args)
else:
name,pw,arg_tuple = self._identify(req.args)
if name and pw:
ac = encodestring('%s:%s' % (name, pw))
req._auth = 'basic %s' % ac
resp._auth = 1
if self.remove_args or authProvider: # if we set remove_args or an authProvider is used
req.args = arg_tuple
return ATTEMPT_LOGIN
return ATTEMPT_NONE

def __call__(self, container, req):
'''The __before_publishing_traverse__ hook.'''
resp = self.REQUEST['RESPONSE']
attempt = self.modifyRequest(req, resp)


def _cleanupResponse(self):
resp = self.REQUEST['RESPONSE']
try: del resp.unauthorized
except: pass
try: del resp._unauthorized
except: pass
return resp



security.declarePrivate('unauthorized')
def unauthorized(self):
resp.unauthorized()

def _unauthorized(self):
resp._unauthorized()


# Installation and removal of traversal hooks.

def manage_beforeDelete(self, item, container):
if item is self:
handle = self.meta_type + '/' + self.getId()
BeforeTraverse.unregisterBeforeTraverse(container, handle)

def manage_afterAdd(self, item, container):
if item is self:
handle = self.meta_type + '/' + self.getId()
container = container.this()
nc = BeforeTraverse.NameCaller(self.getId())
BeforeTraverse.registerBeforeTraverse(container, nc, handle)

Globals.InitializeClass(RPCAuth)

def manage_addRAForm(self):
"this is a form to get the id"
return """<html>
<head>
<title>Setup RPC Auth</title>
</head>
<body>
Please type the id of the RPC Auth:<br>
<form name="form" action="manage_addRPCAuth"><br>
<input type="text" name="id"><br>
<input type="submit" value="add">
</form>
</body>
</html>"""

def manage_addRPCAuth(self, id, REQUEST=None):
' '
ob = RPCAuth()
ob.id = id
self._setObject(id, ob)
if REQUEST is not None:
return self.manage_main(self, REQUEST)
9 changes: 9 additions & 0 deletions web/ryzom_com/RPCAuth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import RPCAuth

def initialize(context):
context.registerClass(
RPCAuth.RPCAuth,
constructors=(RPCAuth.manage_addRAForm,
RPCAuth.manage_addRPCAuth),
icon = 'RPCAuth.gif'
)
Empty file.
Loading

0 comments on commit bd5ec74

Please sign in to comment.