Commit c69b4e86 authored by Sebastien Robin's avatar Sebastien Robin

fabien finished to implement authentication, and he added tests for it

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14439 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 999e908f
...@@ -129,11 +129,6 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -129,11 +129,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
xml = self.convertToXml(xml) xml = self.convertToXml(xml)
LOG('addNode',0,'xml_reconstitued: %s' % str(xml)) LOG('addNode',0,'xml_reconstitued: %s' % str(xml))
# In the case where this new node is a object to add # In the case where this new node is a object to add
LOG('addNode',0,'object.id: %s' % object.getId())
LOG('addNode',0,'xml.nodeName: %s' % xml.nodeName)
LOG('addNode',0,'getSubObjectDepth: %i' % self.getSubObjectDepth(xml))
LOG('addNode',0,'isHistoryAdd: %i' % self.isHistoryAdd(xml))
LOG('addNode xml',0,repr(xml.toxml()))
if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and self.getSubObjectDepth(xml)==0: if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and self.getSubObjectDepth(xml)==0:
if self.isHistoryAdd(xml)!=-1: # bad hack XXX to be removed if self.isHistoryAdd(xml)!=-1: # bad hack XXX to be removed
for element in self.getXupdateElementList(xml): for element in self.getXupdateElementList(xml):
...@@ -216,7 +211,6 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -216,7 +211,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
object_id = self.getAttribute(xml,'id') object_id = self.getAttribute(xml,'id')
elif self.getSubObjectDepth(xml)==1: elif self.getSubObjectDepth(xml)==1:
object_id = self.getSubObjectId(xml) object_id = self.getSubObjectId(xml)
#LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
elif self.getSubObjectDepth(xml)==2: elif self.getSubObjectDepth(xml)==2:
# we have to call delete node on a subsubobject # we have to call delete node on a subsubobject
sub_object_id = self.getSubObjectId(xml) sub_object_id = self.getSubObjectId(xml)
...@@ -706,14 +700,11 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -706,14 +700,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
for subnode in self.getElementNodeList(xml): for subnode in self.getElementNodeList(xml):
if not(subnode.nodeName in self.NOT_EDITABLE_PROPERTY): if not(subnode.nodeName in self.NOT_EDITABLE_PROPERTY):
keyword_type = self.getPropertyType(subnode) keyword_type = self.getPropertyType(subnode)
LOG('newObject',0,str(subnode.childNodes))
# This is the case where the property is a list # This is the case where the property is a list
keyword=str(subnode.nodeName) keyword=str(subnode.nodeName)
if len(subnode.childNodes) > 0: # We check that this tag is not empty if len(subnode.childNodes) > 0: # We check that this tag is not empty
data = subnode.childNodes[0].data data = subnode.childNodes[0].data
args[keyword]=data args[keyword]=data
LOG('newObject',0,'keyword: %s' % str(keyword))
LOG('newObject',0,'keywordtype: %s' % str(keyword_type))
#if args.has_key(keyword): #if args.has_key(keyword):
# LOG('newObject',0,'data: %s' % str(args[keyword])) # LOG('newObject',0,'data: %s' % str(args[keyword]))
if args.has_key(keyword): if args.has_key(keyword):
...@@ -722,8 +713,6 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -722,8 +713,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
self.addNode(object=object,xml=subnode, force=1) self.addNode(object=object,xml=subnode, force=1)
# We should first edit the object # We should first edit the object
args = self.getFormatedArgs(args=args) args = self.getFormatedArgs(args=args)
LOG('newObject',0,"object.getphyspath: %s" % str(object.getPhysicalPath()))
LOG('newObject',0,"args: %s" % str(args))
# edit the object with a dictionnary of arguments, # edit the object with a dictionnary of arguments,
# like {"telephone_number":"02-5648"} # like {"telephone_number":"02-5648"}
#object._edit(**args) #object._edit(**args)
...@@ -885,7 +874,6 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -885,7 +874,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
dict_list = map(lambda x:x.split(':'),data[1:-1].split(',')) dict_list = map(lambda x:x.split(':'),data[1:-1].split(','))
data = map(lambda (x,y):(x.replace(' ','').replace("'",''),int(y)),dict_list) data = map(lambda (x,y):(x.replace(' ','').replace("'",''),int(y)),dict_list)
data = dict(data) data = dict(data)
LOG('convertXmlValue',0,'data: %s' % str(data))
return data return data
# XXX is it the right place ? It should be in XupdateUtils, but here we # XXX is it the right place ? It should be in XupdateUtils, but here we
...@@ -997,7 +985,6 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -997,7 +985,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
add_action = self.isWorkflowActionAddable(object=object, add_action = self.isWorkflowActionAddable(object=object,
status=status,wf_tool=wf_tool, status=status,wf_tool=wf_tool,
wf_id=wf_id,xml=xml) wf_id=wf_id,xml=xml)
#LOG('addNode, workflow_history wf_conflict_list:',0,wf_conflict_list)
LOG('addNode, workflow_history add_action:',0,add_action) LOG('addNode, workflow_history add_action:',0,add_action)
if add_action and not simulate: if add_action and not simulate:
LOG('addNode, setting status:',0,'ok') LOG('addNode, setting status:',0,'ok')
......
...@@ -152,7 +152,9 @@ class Publication(Subscription): ...@@ -152,7 +152,9 @@ class Publication(Subscription):
constructors = (addPublication,) constructors = (addPublication,)
# Constructor # Constructor
def __init__(self, id, title, publication_url, destination_path, query, xml_mapping, conduit, gpg_key): def __init__(self, id, title, publication_url, destination_path,
query, xml_mapping, conduit, gpg_key, auth_required=False,
authentication_format='', authentication_type=''):
""" """
constructor constructor
""" """
...@@ -169,6 +171,9 @@ class Publication(Subscription): ...@@ -169,6 +171,9 @@ class Publication(Subscription):
self.setConduit(conduit) self.setConduit(conduit)
Folder.__init__(self, id) Folder.__init__(self, id)
self.title = title self.title = title
self.auth_required = auth_required
self.authentication_format = authentication_format
self.authentication_type = authentication_type
def getPublicationUrl(self): def getPublicationUrl(self):
""" """
...@@ -189,6 +194,42 @@ class Publication(Subscription): ...@@ -189,6 +194,42 @@ class Publication(Subscription):
""" """
self.publication_url = publication_url self.publication_url = publication_url
def isAuthenticationRequired(self):
"""
return False if authentication not required, True else
"""
return getattr(self, 'auth_required', False)
def setAuthentication(self, auth):
"""
set the value of the authentication requirement
"""
self.auth_required = auth
def getAuthenticationFormat(self):
"""
return the format of authentication
"""
return getattr(self, 'authentication_format', '')
def getAuthenticationType(self):
"""
return the type of authentication
"""
return getattr(self, 'authentication_type', '')
def setAuthenticationFormat(self, authentication_format):
"""
set the format of authentication
"""
self.authentication_format = authentication_format
def setAuthenticationType(self, authentication_type):
"""
set the type of authentication
"""
self.authentication_type = authentication_type
def addSubscriber(self, subscriber): def addSubscriber(self, subscriber):
""" """
Add a new subscriber to the publication Add a new subscriber to the publication
......
...@@ -34,6 +34,10 @@ from xml.dom.minidom import parse, parseString ...@@ -34,6 +34,10 @@ from xml.dom.minidom import parse, parseString
from XMLSyncUtils import XMLSyncUtils from XMLSyncUtils import XMLSyncUtils
from Conduit.ERP5Conduit import ERP5Conduit from Conduit.ERP5Conduit import ERP5Conduit
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.ERP5Security.ERP5UserManager import ERP5UserManager
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
from AccessControl.SecurityManagement import newSecurityManager
import commands import commands
from zLOG import LOG from zLOG import LOG
...@@ -43,7 +47,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -43,7 +47,7 @@ class PublicationSynchronization(XMLSyncUtils):
""" """
def PubSyncInit(self, publication=None, xml_client=None, subscriber=None, def PubSyncInit(self, publication=None, xml_client=None, subscriber=None,
sync_type=None, auth_required=0): sync_type=None):
""" """
Read the client xml message Read the client xml message
Send the first XML message from the server Send the first XML message from the server
...@@ -52,8 +56,10 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -52,8 +56,10 @@ class PublicationSynchronization(XMLSyncUtils):
#the session id is set at the same value of those of the client #the session id is set at the same value of those of the client
subscriber.setSessionId(self.getSessionId(xml_client)) subscriber.setSessionId(self.getSessionId(xml_client))
# for a new session, the message Id must be reset #same for the message id
subscriber.resetMessageId() subscriber.setMessageId(self.getMessageId(xml_client))
#at the begining of the synchronization the subscriber is not authenticated
subscriber.setAuthenticated(False)
#the last_message_id is 1 because the message that #the last_message_id is 1 because the message that
#we are about to send is the message 1 #we are about to send is the message 1
subscriber.initLastMessageId(1) subscriber.initLastMessageId(1)
...@@ -67,7 +73,8 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -67,7 +73,8 @@ class PublicationSynchronization(XMLSyncUtils):
alert_code = self.getAlertCode(xml_client) alert_code = self.getAlertCode(xml_client)
cred = self.checkCred(xml_client) cred = self.checkCred(xml_client)
#XXX this is in developement, it's just for tests #XXX this is in developement, it's just for tests
if not cred and auth_required: if publication.isAuthenticationRequired():
if not cred:
LOG('PubSyncInit',0,'authentication required') LOG('PubSyncInit',0,'authentication required')
# Prepare the xml message for the Sync initialization package # Prepare the xml message for the Sync initialization package
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
...@@ -76,14 +83,15 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -76,14 +83,15 @@ class PublicationSynchronization(XMLSyncUtils):
xml('<SyncML>\n') xml('<SyncML>\n')
# syncml header # syncml header
xml(self.SyncMLHeader(subscriber.getSessionId(), xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(), subscriber.getMessageId(), subscriber.getSubscriptionUrl(),
publication.getPublicationUrl())) publication.getPublicationUrl()))
# syncml body # syncml body
xml(' <SyncBody>\n') xml(' <SyncBody>\n')
# chal message # chal message
xml(self.SyncMLChal(cmd_id, "SyncHdr", publication.getPublicationUrl(), xml(self.SyncMLChal(cmd_id, "SyncHdr",
subscriber.getSubscriptionUrl(), "b64", "syncml:auth-basic", publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
self.UNAUTHORIZED)) publication.getAuthenticationFormat(),
publication.getAuthenticationType(), self.AUTH_REQUIRED))
cmd_id += 1 cmd_id += 1
xml(' </SyncBody>\n') xml(' </SyncBody>\n')
...@@ -92,8 +100,56 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -92,8 +100,56 @@ class PublicationSynchronization(XMLSyncUtils):
xml_a = ''.join(xml_list) xml_a = ''.join(xml_list)
self.sendResponse(from_url=publication.getPublicationUrl(), self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(),sync_id=publication.getTitle(), to_url=subscriber.getSubscriptionUrl(),
xml=xml_a,domain=publication) sync_id=publication.getTitle(), xml=xml_a, domain=publication)
else:#(if the subscriber begin the session with a cred) -> to be tested
(authentication_format, authentication_type, data) = self.getCred(xml_client)
#at the begining, the code is initialised at UNAUTHORIZED
auth_code=self.UNAUTHORIZED
if authentication_format == publication.getAuthenticationFormat():
if authentication_type == publication.getAuthenticationType():
decoded = subscriber.decode(authentication_format, data)
if decoded not in ('', None) and decoded.__contains__(':'):
(login, password) = decoded.split(':')
uf = self.getPortalObject().acl_users
for plugin_name, plugin in uf._getOb('plugins').listPlugins(
IAuthenticationPlugin ):
if plugin.authenticateCredentials(
{'login':login, 'password':password}) is not None:
subscriber.setAuthenticated(True)
auth_code=self.AUTH_ACCEPTED
#here we must log in with the user authenticated :
user = uf.getUserById(login).__of__(uf)
newSecurityManager(None, user)
subscriber.setUser(login)
break
#in all others cases, the auth_code is set to UNAUTHORIZED
# Prepare the xml message for the Sync initialization package
cmd_id = 1 # specifies a SyncML message-unique command identifier
xml_list = []
xml = xml_list.append
xml('<SyncML>\n')
# syncml header
xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.getMessageId(),
subscriber.getSubscriptionUrl(),
publication.getPublicationUrl()))
# syncml body
xml(' <SyncBody>\n')
xml(self.SyncMLStatus(cmd_id, subscriber.getSubscriptionUrl(),
publication.getPublicationUrl(), auth_code))
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(),
sync_id=publication.getTitle(), xml=xml_a, domain=publication)
else : else :
# If slow sync, then resend everything # If slow sync, then resend everything
if alert_code == self.SLOW_SYNC: if alert_code == self.SLOW_SYNC:
...@@ -103,8 +159,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -103,8 +159,7 @@ class PublicationSynchronization(XMLSyncUtils):
# Check if the last time synchronization is the same as the client one # Check if the last time synchronization is the same as the client one
mess='\nsubscriber.getNextAnchor:\t%s\nsubscriber.getLastAnchor:\t%s\ mess='\nsubscriber.getNextAnchor:\t%s\nsubscriber.getLastAnchor:\t%s\
\nlast_anchor:\t\t\t%s\nnext_anchor:\t\t\t%s' % (subscriber.getNextAnchor(), \nlast_anchor:\t\t\t%s\nnext_anchor:\t\t\t%s' % (subscriber.getNextAnchor(), subscriber.getLastAnchor(), last_anchor, next_anchor)
subscriber.getLastAnchor(), last_anchor, next_anchor)
LOG('PubSyncInit',0,mess) LOG('PubSyncInit',0,mess)
if subscriber.getNextAnchor() != last_anchor: if subscriber.getNextAnchor() != last_anchor:
...@@ -112,8 +167,8 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -112,8 +167,8 @@ class PublicationSynchronization(XMLSyncUtils):
LOG('PubSyncInit',0,'anchor null') LOG('PubSyncInit',0,'anchor null')
raise ValueError, "Sorry, the anchor was null" raise ValueError, "Sorry, the anchor was null"
else: else:
message = "bad anchors in PubSyncInit! " + subscriber.getNextAnchor() + \ message = "bad anchors in PubSyncInit! " + \
" and " + last_anchor subscriber.getNextAnchor() + " and " + last_anchor
LOG('PubSyncInit',0,message) LOG('PubSyncInit',0,message)
else: else:
subscriber.setNextAnchor(next_anchor) subscriber.setNextAnchor(next_anchor)
...@@ -123,8 +178,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -123,8 +178,7 @@ class PublicationSynchronization(XMLSyncUtils):
# We have started the sync from the server (may be for a conflict resolution) # We have started the sync from the server (may be for a conflict resolution)
pass pass
if alert is not None and auth_required==0: if alert is not None and not publication.isAuthenticationRequired():
#if 1:
# Prepare the xml message for the Sync initialization package # Prepare the xml message for the Sync initialization package
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
xml_list = [] xml_list = []
...@@ -202,6 +256,14 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -202,6 +256,14 @@ class PublicationSynchronization(XMLSyncUtils):
alert_code in (self.TWO_WAY,self.SLOW_SYNC): alert_code in (self.TWO_WAY,self.SLOW_SYNC):
result = self.PubSyncInit(publication=publication, result = self.PubSyncInit(publication=publication,
xml_client=xml_client, subscriber=subscriber, sync_type=alert_code) xml_client=xml_client, subscriber=subscriber, sync_type=alert_code)
else:
#we log the user authenticated to do the synchronization with him
if publication.isAuthenticationRequired():
if subscriber.isAuthenticated():
uf = self.getPortalObject().acl_users
user = uf.getUserById(subscriber.getUser()).__of__(uf)
newSecurityManager(None, user)
result = self.PubSyncModif(publication, xml_client)
else: else:
result = self.PubSyncModif(publication, xml_client) result = self.PubSyncModif(publication, xml_client)
elif subscriber is not None: elif subscriber is not None:
......
...@@ -41,6 +41,11 @@ from zLOG import LOG ...@@ -41,6 +41,11 @@ from zLOG import LOG
import md5 import md5
try:
from base64 import b64encode, b64decode
except ImportError:
from base64 import encodestring as b64encode, decodestring as b64decode
#class Conflict(SyncCode, Implicit): #class Conflict(SyncCode, Implicit):
class Conflict(SyncCode, Base): class Conflict(SyncCode, Base):
""" """
...@@ -53,8 +58,8 @@ class Conflict(SyncCode, Base): ...@@ -53,8 +58,8 @@ class Conflict(SyncCode, Base):
isIndexable = 0 isIndexable = 0
isPortalContent = 0 # Make sure RAD generated accessors at the class level isPortalContent = 0 # Make sure RAD generated accessors at the class level
def __init__(self, object_path=None, keyword=None, xupdate=None, publisher_value=None,\ def __init__(self, object_path=None, keyword=None, xupdate=None,
subscriber_value=None, subscriber=None): publisher_value=None, subscriber_value=None, subscriber=None):
self.object_path=object_path self.object_path=object_path
self.keyword = keyword self.keyword = keyword
self.setLocalValue(publisher_value) self.setLocalValue(publisher_value)
...@@ -614,8 +619,8 @@ class Subscription(Folder, SyncCode): ...@@ -614,8 +619,8 @@ class Subscription(Folder, SyncCode):
isPortalContent = 1 isPortalContent = 1
isRADContent = 1 isRADContent = 1
icon = None icon = None
isIndexable = 0 isIndexable = 0
user = None
# Declarative properties # Declarative properties
property_sheets = ( PropertySheet.Base property_sheets = ( PropertySheet.Base
...@@ -635,7 +640,8 @@ class Subscription(Folder, SyncCode): ...@@ -635,7 +640,8 @@ class Subscription(Folder, SyncCode):
) )
# Constructor # Constructor
def __init__(self, id, title, publication_url, subscription_url, destination_path, query, xml_mapping, conduit, gpg_key): def __init__(self, id, title, publication_url, subscription_url, destination_path, query, xml_mapping, conduit, gpg_key, login, password,
authentication_format='', authentication_type=''):
""" """
We need to create a dictionnary of We need to create a dictionnary of
signatures of documents which belong to the synchronisation signatures of documents which belong to the synchronisation
...@@ -652,6 +658,10 @@ class Subscription(Folder, SyncCode): ...@@ -652,6 +658,10 @@ class Subscription(Folder, SyncCode):
#self.signatures = PersistentMapping() #self.signatures = PersistentMapping()
self.last_anchor = '00000000T000000Z' self.last_anchor = '00000000T000000Z'
self.next_anchor = '00000000T000000Z' self.next_anchor = '00000000T000000Z'
self.login=login
self.password=password
self.authentication_format=authentication_format
self.authentication_type=authentication_type
self.domain_type = self.SUB self.domain_type = self.SUB
self.gpg_key = gpg_key self.gpg_key = gpg_key
self.setGidGenerator(None) self.setGidGenerator(None)
...@@ -714,28 +724,28 @@ class Subscription(Folder, SyncCode): ...@@ -714,28 +724,28 @@ class Subscription(Folder, SyncCode):
We will see if the last session id was the same We will see if the last session id was the same
wich means that the same message was sent again wich means that the same message was sent again
return 1 if the session id was not seen, 0 if already seen return True if the session id was not seen, False if already seen
""" """
last_session_id = getattr(self,'last_session_id',None) last_session_id = getattr(self,'last_session_id',None)
if last_session_id == session_id: if last_session_id == session_id:
return 0 return False
self.last_session_id = session_id self.last_session_id = session_id
return 1 return True
def checkCorrectRemoteMessageId(self, message_id): def checkCorrectRemoteMessageId(self, message_id):
""" """
We will see if the last message id was the same We will see if the last message id was the same
wich means that the same message was sent again wich means that the same message was sent again
return 1 if the message id was not seen, 0 if already seen return True if the message id was not seen, False if already seen
""" """
last_message_id = getattr(self,'last_message_id',None) last_message_id = getattr(self,'last_message_id',None)
# LOG('checkCorrectRemoteMessageId last_message_id =',0,last_message_id) # LOG('checkCorrectRemoteMessageId last_message_id =',0,last_message_id)
# LOG('checkCorrectRemoteMessageId message_id =',0,message_id) # LOG('checkCorrectRemoteMessageId message_id =',0,message_id)
if last_message_id == message_id: if last_message_id == message_id:
return 0 return False
self.last_message_id = message_id self.last_message_id = message_id
return 1 return True
def initLastMessageId(self, last_message_id=None): def initLastMessageId(self, last_message_id=None):
""" """
...@@ -872,25 +882,74 @@ class Subscription(Folder, SyncCode): ...@@ -872,25 +882,74 @@ class Subscription(Folder, SyncCode):
""" """
return self.gid_generator return self.gid_generator
def getLogin(self):
"""
This method return the login of this subscription
"""
return getattr(self, 'login', '')
def setLogin(self, new_login):
"""
set the login at new_login
"""
self.login=new_login
def getPassword(self):
"""
This method return the password of this subscription
"""
return getattr(self, 'password', '')
def setPassword(self, new_password):
"""
set the password at new_password
"""
self.password=new_password
def setAuthentication(self, auth):
"""
set the value of the authentication requirement
"""
self.auth_required = auth
def getAuthenticationFormat(self):
"""
return the format of authentication
"""
return getattr(self, 'authentication_format', '')
def getAuthenticationType(self):
"""
return the type of authentication
"""
return getattr(self, 'authentication_type', '')
def setAuthenticationFormat(self, authentication_format):
"""
set the format of authentication
"""
self.authentication_format = authentication_format
def setAuthenticationType(self, authentication_type):
"""
set the type of authentication
"""
self.authentication_type = authentication_type
def getGidFromObject(self, object): def getGidFromObject(self, object):
""" """
""" """
o_base = aq_base(object) o_base = aq_base(object)
o_gid = None o_gid = None
# LOG('getGidFromObject',0,'gidgenerator : _%s_' % repr(self.getGidGenerator()))
gid_gen = self.getGidGenerator() gid_gen = self.getGidGenerator()
if callable(gid_gen): if callable(gid_gen):
# LOG('getGidFromObject gid_generator',0,'is callable')
o_gid=gid_gen(object) o_gid=gid_gen(object)
# LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid))
elif getattr(o_base, gid_gen, None) is not None: elif getattr(o_base, gid_gen, None) is not None:
# LOG('getGidFromObject',0,'there is the gid generator on o_base')
generator = getattr(object, gid_gen) generator = getattr(object, gid_gen)
o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant
# LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid))
elif gid_gen is not None: elif gid_gen is not None:
# It might be a script python # It might be a script python
# LOG('getGidFromObject',0,'there is the gid generator')
generator = getattr(object,gid_gen) generator = getattr(object,gid_gen)
o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant
# LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid)) # LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid))
...@@ -911,7 +970,6 @@ class Subscription(Folder, SyncCode): ...@@ -911,7 +970,6 @@ class Subscription(Folder, SyncCode):
# LOG('getObjectFromGid oject_list',0,object_list) # LOG('getObjectFromGid oject_list',0,object_list)
if signature is not None and signature.getId() is not None: if signature is not None and signature.getId() is not None:
o_id = signature.getId() o_id = signature.getId()
# LOG('getObjectFromGid o_id',0,o_id)
o = None o = None
try: try:
o = destination._getOb(o_id) o = destination._getOb(o_id)
...@@ -920,7 +978,6 @@ class Subscription(Folder, SyncCode): ...@@ -920,7 +978,6 @@ class Subscription(Folder, SyncCode):
if o is not None and o in object_list: if o is not None and o in object_list:
return o return o
for o in object_list: for o in object_list:
# LOG('getObjectFromGid',0,'working on : %s' % repr(o))
o_gid = self.getGidFromObject(o) o_gid = self.getGidFromObject(o)
if o_gid == gid: if o_gid == gid:
return o return o
...@@ -1074,6 +1131,12 @@ class Subscription(Folder, SyncCode): ...@@ -1074,6 +1131,12 @@ class Subscription(Folder, SyncCode):
""" """
self.message_id = 0 self.message_id = 0
def setMessageId(self, message_id):
"""
set the message id to message_id
"""
self.message_id = message_id
def getLastAnchor(self): def getLastAnchor(self):
""" """
return the id of the last synchronisation return the id of the last synchronisation
...@@ -1230,3 +1293,67 @@ class Subscription(Folder, SyncCode): ...@@ -1230,3 +1293,67 @@ class Subscription(Folder, SyncCode):
o.setTempXML(None) o.setTempXML(None)
self.setRemainingObjectPathList(None) self.setRemainingObjectPathList(None)
def isAuthenticated(self):
"""
return True if the subscriber is authenticated for this session, False
in other case
"""
return self.is_authenticated
def setAuthenticated(self, value):
"""
set at True or False the value of is_authenticated is the subscriber
is authenticated for this session or not
"""
self.is_authenticated = value
def encode(self, format, string_to_encode):
"""
return the string_to_encode encoded with format format
"""
if format in ('', None):
return string_to_encode
if format == 'b64':
return b64encode(string_to_encode)
#elif format is .... put here the other formats
else:#if there is no format corresponding with format, raise an error
LOG('encode : unknown or not implemented format :', 0, format)
raise ValueError, "Sorry, the format %s is unknow or not implemented" % format
def decode(self, format, string_to_decode):
"""
return the string_to_decode decoded with format format
"""
string_to_decode = string_to_decode.encode('utf-8')
if format in ('', None):
return string_to_decode
if format == 'b64':
return b64decode(string_to_decode)
#elif format is .... put here the other formats
else:#if there is no format corresponding with format, raise an error
LOG('decode : unknown or not implemented format :', 0, format)
raise ValueError, "Sorry, the format %s is unknow or not implemented" % format
def isDecodeEncodeTheSame(self, string_encoded, string_decoded, format):
"""
return True if the string_encoded is equal to string_decoded encoded
in format
"""
isTheSame=False
if self.encode(format, string_decoded) == string_encoded:
isTheSame=True
return isTheSame
def setUser(self, user):
"""
save the user logged in to log him on each transaction
"""
self.user=user
def getUser(self):
"""
retrun the user logged in
"""
return self.user
...@@ -44,6 +44,8 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -44,6 +44,8 @@ class SubscriptionSynchronization(XMLSyncUtils):
""" """
LOG('SubSyncInit',0,'starting....') LOG('SubSyncInit',0,'starting....')
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
subscription.NewAnchor()
subscription.initLastMessageId()
xml_list = [] xml_list = []
xml = xml_list.append xml = xml_list.append
xml('<SyncML>\n') xml('<SyncML>\n')
...@@ -54,8 +56,6 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -54,8 +56,6 @@ class SubscriptionSynchronization(XMLSyncUtils):
# syncml body # syncml body
xml(' <SyncBody>\n') xml(' <SyncBody>\n')
subscription.NewAnchor()
subscription.initLastMessageId()
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscription.startSynchronization() subscription.startSynchronization()
...@@ -100,7 +100,21 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -100,7 +100,21 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml_client = msg xml_client = msg
if isinstance(xml_client, str) or isinstance(xml_client, unicode): if isinstance(xml_client, str) or isinstance(xml_client, unicode):
xml_client = parseString(xml_client) xml_client = parseString(xml_client)
response = self.SubSyncModif(self.getSubscription(id),xml_client) next_status = self.getNextSyncBodyStatus(xml_client, None)
#LOG('readResponse, next status :',0,next_status)
if next_status is not None:
status_code = self.getStatusCode(next_status)
#LOG('readResponse status code :',0,status_code)
if status_code == self.AUTH_REQUIRED:
#LOG('readResponse', 0, 'Authentication required')
response = self.SubSyncCred(id, xml_client)
elif status_code == self.UNAUTHORIZED:
#LOG('readResponse', 0, 'Bad authentication')
return {'has_response':0,'xml':xml_client}
else:
response = self.SubSyncModif(self.getSubscription(id), xml_client)
else:
response = self.SubSyncModif(self.getSubscription(id), xml_client)
if RESPONSE is not None: if RESPONSE is not None:
...@@ -108,6 +122,53 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -108,6 +122,53 @@ class SubscriptionSynchronization(XMLSyncUtils):
else: else:
return response return response
def SubSyncCred (self, id, msg=None, RESPONSE=None):
"""
This method send crendentials
"""
LOG('SubSyncCred',0,'starting... id: %s' % str(id))
LOG('SubSyncCred',0,'starting... msg: %s' % str(msg))
cmd_id = 1 # specifies a SyncML message-unique command identifier
subscription = self.getSubscription(id)
xml_list = []
xml = xml_list.append
xml('<SyncML>\n')
# syncml header
data = "%s:%s" % (subscription.getLogin(), subscription.getPassword())
data=subscription.encode(subscription.getAuthenticationFormat(), data)
xml(self.SyncMLHeader(subscription.getSessionId(),
subscription.incrementMessageId(), subscription.getPublicationUrl(),
subscription.getSubscriptionUrl(), dataCred=data,
authentication_format=subscription.getAuthenticationFormat(),
authentication_type=subscription.getAuthenticationType()))
# syncml body
xml(' <SyncBody>\n')
# alert message
xml(self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(),
subscription.getPublicationUrl(),
subscription.getDestinationPath(),
subscription.getLastAnchor(),
subscription.getNextAnchor()))
cmd_id += 1
xml(' <Put>\n')
xml(' <CmdID>%s</CmdID>\n' % cmd_id)
cmd_id += 1
xml(' </Put>\n')
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
self.sendResponse(from_url=subscription.subscription_url,
to_url=subscription.publication_url, sync_id=subscription.getTitle(),
xml=xml_a,domain=subscription)
return {'has_response':1,'xml':xml_a}
def SubSyncModif(self, subscription, xml_client): def SubSyncModif(self, subscription, xml_client):
""" """
Send the client modification, this happens after the Synchronization Send the client modification, this happens after the Synchronization
......
This diff is collapsed.
...@@ -47,7 +47,8 @@ from zLOG import LOG ...@@ -47,7 +47,8 @@ from zLOG import LOG
class XMLSyncUtilsMixin(SyncCode): class XMLSyncUtilsMixin(SyncCode):
def SyncMLHeader(self, session_id, msg_id, target, source, target_name=None, def SyncMLHeader(self, session_id, msg_id, target, source, target_name=None,
source_name=None): source_name=None, dataCred=None, authentication_format='b64',
authentication_type='syncml:auth-basic'):
""" """
Since the Header is always almost the same, this is the Since the Header is always almost the same, this is the
way to set one quickly. way to set one quickly.
...@@ -61,14 +62,22 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -61,14 +62,22 @@ class XMLSyncUtilsMixin(SyncCode):
xml(' <MsgID>%s</MsgID>\n' % msg_id) xml(' <MsgID>%s</MsgID>\n' % msg_id)
xml(' <Target>\n') xml(' <Target>\n')
xml(' <LocURI>%s</LocURI>\n' % target) xml(' <LocURI>%s</LocURI>\n' % target)
if target_name is not None: if target_name not in (None, ''):
xml(' <LocName>%s</LocName>\n' %target_name) xml(' <LocName>%s</LocName>\n' %target_name)
xml(' </Target>\n') xml(' </Target>\n')
xml(' <Source>\n') xml(' <Source>\n')
xml(' <LocURI>%s</LocURI>\n' % source) xml(' <LocURI>%s</LocURI>\n' % source)
if source_name is not None: if source_name not in (None, ''):
xml(' <LocName>%s</LocName>\n' % source_name) xml(' <LocName>%s</LocName>\n' % source_name)
xml(' </Source>\n') xml(' </Source>\n')
if dataCred not in (None, ''):
xml(' <Cred>\n')
xml(' <Meta>\n')
xml(' <Format>%s</Format>\n' % authentication_format)
xml(' <Type>%s</Type>\n' % authentication_type)
xml(' </Meta>\n')
xml(' <Data>%s</Data>\n' % dataCred)
xml(' </Cred>\n')
xml(' </SyncHdr>\n') xml(' </SyncHdr>\n')
xml_a = ''.join(xml_list) xml_a = ''.join(xml_list)
return xml_a return xml_a
...@@ -103,7 +112,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -103,7 +112,7 @@ class XMLSyncUtilsMixin(SyncCode):
return xml_a return xml_a
def SyncMLStatus(self, cmd_id, target_ref, source_ref, sync_code, def SyncMLStatus(self, cmd_id, target_ref, source_ref, sync_code,
next_anchor): next_anchor=None):
""" """
Since the Status section is always almost the same, this is the Since the Status section is always almost the same, this is the
way to set one quickly. way to set one quickly.
...@@ -115,6 +124,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -115,6 +124,7 @@ class XMLSyncUtilsMixin(SyncCode):
xml(' <TargetRef>%s</TargetRef>\n' % target_ref) xml(' <TargetRef>%s</TargetRef>\n' % target_ref)
xml(' <SourceRef>%s</SourceRef>\n' % source_ref) xml(' <SourceRef>%s</SourceRef>\n' % source_ref)
xml(' <Data>%s</Data>\n' % sync_code) xml(' <Data>%s</Data>\n' % sync_code)
if next_anchor is not None:
xml(' <Item>\n') xml(' <Item>\n')
xml(' <Data>\n') xml(' <Data>\n')
xml(' <Anchor xmlns=\'syncml:metinf\'>\n') xml(' <Anchor xmlns=\'syncml:metinf\'>\n')
...@@ -416,27 +426,6 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -416,27 +426,6 @@ class XMLSyncUtilsMixin(SyncCode):
return int(subnode.childNodes[0].data) return int(subnode.childNodes[0].data)
return None return None
#def getStatusCode(self, xml):
# """
# Return the value of the alert code inside the xml_stream
# """
# # Get informations from the body
# first_node = xml.childNodes[0]
# if first_node.nodeName != "SyncML":
# print "This is not a SyncML message"
#
# client_body = first_node.childNodes[3]
# if client_body.nodeName != "SyncBody":
# print "This is not a SyncML Body"
#
# for subnode in client_body.childNodes:
# if subnode.nodeName=='Status':
# for subnode2 in subnode.childNodes:
# if subnode2.nodeType == subnode.ELEMENT_NODE and subnode2.nodeName == 'Data':
# return int(subnode2.childNodes[0].data)
# return None
def getStatusCommand(self, xml): def getStatusCommand(self, xml):
""" """
Return the value of the command inside the xml_stream Return the value of the command inside the xml_stream
...@@ -448,6 +437,44 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -448,6 +437,44 @@ class XMLSyncUtilsMixin(SyncCode):
return subnode.childNodes[0].data return subnode.childNodes[0].data
return None return None
def getCred(self, xml):
"""
return the credential information : type, format and data
"""
format=''
type=''
data=''
first_node = xml.childNodes[0]
if first_node.nodeName != "SyncML":
print "This is not a SyncML message"
# Get informations from the header
xml_header = first_node.childNodes[1]
if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Cred':
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Meta':
for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == 'Format':
if len(subnode3.childNodes) > 0:
format=subnode3.childNodes[0].data
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == 'Type':
if len(subnode3.childNodes) > 0:
type=subnode3.childNodes[0].data
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Data':
if len(subnode2.childNodes) > 0:
data=subnode2.childNodes[0].data
return (format, type, data)
def getAlertCode(self, xml_stream): def getAlertCode(self, xml_stream):
""" """
Return the value of the alert code inside the full syncml message Return the value of the alert code inside the full syncml message
...@@ -739,13 +766,13 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -739,13 +766,13 @@ class XMLSyncUtilsMixin(SyncCode):
# object_gid = gid_generator() # object_gid = gid_generator()
force = 0 force = 0
if syncml_data.count('\n') < self.MAX_LINES and not object.id.startswith('.'): # If not we have to cut if syncml_data.count('\n') < self.MAX_LINES and not object.id.startswith('.'): # If not we have to cut
LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping)) #LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping))
LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml))) #LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml)))
LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list)) #LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list))
LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid))) #LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid)))
LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC)) #LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC))
signature = subscriber.getSignature(object_gid) signature = subscriber.getSignature(object_gid)
LOG('getSyncMLData',0,'current object: %s' % str(object.getId())) #LOG('getSyncMLData',0,'current object: %s' % str(object.getId()))
# Here we first check if the object was modified or not by looking at dates # Here we first check if the object was modified or not by looking at dates
if signature is not None: if signature is not None:
signature.checkSynchronizationNeeded(object) signature.checkSynchronizationNeeded(object)
...@@ -774,7 +801,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -774,7 +801,7 @@ class XMLSyncUtilsMixin(SyncCode):
rest_string = xml_string[len(short_string):] rest_string = xml_string[len(short_string):]
#LOG('XMLSyncUtils',0,'rest_string: %s' % str(rest_string)) #LOG('XMLSyncUtils',0,'rest_string: %s' % str(rest_string))
i += 1 i += 1
LOG('getSyncMLData',0,'setPartialXML with: %s' % str(rest_string)) #LOG('getSyncMLData',0,'setPartialXML with: %s' % str(rest_string))
signature.setPartialXML(rest_string) signature.setPartialXML(rest_string)
status =self.PARTIAL status =self.PARTIAL
signature.setAction('Add') signature.setAction('Add')
...@@ -787,8 +814,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -787,8 +814,8 @@ class XMLSyncUtilsMixin(SyncCode):
elif signature.getStatus()==self.NOT_SYNCHRONIZED \ elif signature.getStatus()==self.NOT_SYNCHRONIZED \
or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet
xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping) xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping)
LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object))) #LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object)))
LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus())) #LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus()))
if signature.getStatus()==self.PUB_CONFLICT_MERGE: if signature.getStatus()==self.PUB_CONFLICT_MERGE:
xml_confirmation += self.SyncMLConfirmation(cmd_id,object.id, xml_confirmation += self.SyncMLConfirmation(cmd_id,object.id,
self.CONFLICT_MERGE,'Replace') self.CONFLICT_MERGE,'Replace')
...@@ -821,7 +848,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -821,7 +848,7 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
# Now we can apply the xupdate from the subscriber # Now we can apply the xupdate from the subscriber
subscriber_xupdate = signature.getSubscriberXupdate() subscriber_xupdate = signature.getSubscriberXupdate()
LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate) #LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate)
if subscriber_xupdate is not None: if subscriber_xupdate is not None:
old_xml = signature.getXML() old_xml = signature.getXML()
conduit.updateNode(xml=subscriber_xupdate, object=object, conduit.updateNode(xml=subscriber_xupdate, object=object,
...@@ -1080,7 +1107,6 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1080,7 +1107,6 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if xml_header.nodeName != "SyncHdr": if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header') LOG('PubSyncModif',0,'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header" raise ValueError, "Sorry, This is not a SyncML Header"
return
subscriber = domain # If we are the client, this is fine subscriber = domain # If we are the client, this is fine
simulate = 0 # used by applyActionList, should be 0 for client simulate = 0 # used by applyActionList, should be 0 for client
...@@ -1103,11 +1129,12 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1103,11 +1129,12 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if last_xml != '': if last_xml != '':
has_response = 1 has_response = 1
if domain.domain_type == self.PUB: # We always reply if domain.domain_type == self.PUB: # We always reply
self.sendResponse(from_url=domain.publication_url, to_url=subscriber.subscription_url, self.sendResponse(from_url=domain.publication_url,
sync_id=domain.getTitle(), xml=last_xml,domain=domain) to_url=subscriber.subscription_url, sync_id=domain.getTitle(),
xml=last_xml,domain=domain)
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
self.sendResponse(from_url=domain.subscription_url, to_url=domain.publication_url, self.sendResponse(from_url=domain.subscription_url,
sync_id=domain.getTitle(), xml=last_xml,domain=domain) to_url=domain.publication_url, sync_id=domain.getTitle(), xml=last_xml,domain=domain)
return {'has_response':has_response,'xml':last_xml} return {'has_response':has_response,'xml':last_xml}
subscriber.setLastSentMessage('') subscriber.setLastSentMessage('')
...@@ -1135,7 +1162,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1135,7 +1162,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
subscriber=subscriber, subscriber=subscriber,
remote_xml=remote_xml, remote_xml=remote_xml,
conduit=conduit, simulate=simulate) conduit=conduit, simulate=simulate)
LOG('SyncModif, has_next_action:',0,has_next_action) #LOG('SyncModif, has_next_action:',0,has_next_action)
xml_list = [] xml_list = []
xml = xml_list.append xml = xml_list.append
......
...@@ -127,6 +127,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -127,6 +127,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="gid_generator" value="<dtml-var getGidGenerator>" size="40" /> <input type="text" name="gid_generator" value="<dtml-var getGidGenerator>" size="40" />
</td> </td>
</tr> </tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Authentication Required
</label></div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="auth_required" value="1" <dtml-if expr="isAuthenticationRequired()">CHECKED</dtml-if>>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Format authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_format" value="<dtml-var getAuthenticationFormat>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Type authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_type" value="<dtml-var getAuthenticationType>" size="40" />
</td>
</tr>
</table> </table>
<table> <table>
<tr> <tr>
......
...@@ -137,6 +137,46 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -137,6 +137,46 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="gid_generator" value="<dtml-var getGidGenerator>" size="40" /> <input type="text" name="gid_generator" value="<dtml-var getGidGenerator>" size="40" />
</td> </td>
</tr> </tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Login
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="login" value="<dtml-var getLogin>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Password
</label></div>
</td>
<td align="left" valign="top">
<input type="password" name="password" value="<dtml-var getPassword>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Format authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_format" value="<dtml-var getAuthenticationFormat>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Type authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_type" value="<dtml-var getAuthenticationType>" size="40" />
</td>
</tr>
</table> </table>
<table> <table>
<tr> <tr>
......
...@@ -123,6 +123,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -123,6 +123,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="gid_generator" size="40" /> <input type="text" name="gid_generator" size="40" />
</td> </td>
</tr> </tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Authentication Required
</label></div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="auth_required" value="1">
</td>
</tr>
<tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Format authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_format" size="40" />
</td>
</tr>
<td align="left" valign="top">
<div class="form-label">
Type authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_type" size="40" />
</td>
</tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
</td> </td>
......
...@@ -133,6 +133,45 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -133,6 +133,45 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="gid_generator" size="40" /> <input type="text" name="gid_generator" size="40" />
</td> </td>
</tr> </tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Login
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="login" size="40" /> </td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Password
</label></div>
</td>
<td align="left" valign="top">
<input type="password" name="password" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Format authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_format" size="40" />
</td>
</tr>
<td align="left" valign="top">
<div class="form-label">
Type authentication
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="authentication_type" size="40" />
</td>
</tr>
<tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
</td> </td>
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment