class FronterExport(LMSExport): """Class for handling export to Fronter.""" STATUS_ADD = 1 STATUS_UPDATE = 2 STATUS_DELETE = 3 ROLE_READ = '01' ROLE_WRITE = '02' ROLE_DELETE = '03' ROLE_CHANGE = '07' def __init__(self, output=None, include_password=True): LMSExport.__init__(self) self.output = output self.xml = XMLWriter(output) self.xml.startDocument(encoding='UTF-8') self.rootEl = 'enterprise' self.DataSource = 'Cerebrum' self.include_password = include_password #self.cf_id = self.fronter.fronter_host # TODO: Get this somewhere else logger.debug("Fronterexport initialized") def pwd(self, p): pwtype, password = p.split(":") type_map = {'md5': 1, 'unix': 2, 'nt': 3, 'plain': 4, 'ldap': 5} ret = {'pwencryptiontype': type_map['ldap']} if password: ret['password'] = password return ret def useraccess(self, access): # TODO: move to config section mapping = { # Not allowed to log in 0: 'None', # Normal user 'viewmygroups': 'User', 'allowlogin': '******', # Admin 'administrator': 'SysAdmin', } return mapping[access] def start_xml_file(self, kurs): self.xml.comment("Eksporterer data om følgende emner:\n " + "\n ".join(kurs)) self.xml.startTag(self.rootEl) self.xml.startTag('properties') self.xml.dataElement('datasource', self.DataSource) self.xml.dataElement('target', "ClassFronter/")#%s" % self.cf_id) # :TODO: Tell Fronter (again) that they need to define the set of # codes for the TYPE element. # self.xml.dataElement('TYPE', "REFRESH") self.xml.dataElement('datetime', time.strftime("%F %T %z")) self.xml.endTag('properties') begin = start_xml_file def user_to_XML(self, id, recstatus, data): """Lager XML for en person""" self.xml.startTag('person', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') if self.include_password: self.xml.dataElement('userid', id, self.pwd(data['PASSWORD'])) self.xml.startTag('name') self.xml.dataElement('fn', " ".join([x for x in (data['GIVEN'], data['FAMILY']) if x])) self.xml.startTag('n') self.xml.dataElement('family', data['FAMILY']) self.xml.dataElement('given', data['GIVEN']) self.xml.endTag('n') self.xml.endTag('name') self.xml.dataElement('email', data['EMAIL']) self.xml.emptyTag('systemrole', {'systemroletype': self.useraccess(data['USERACCESS'])}) self.xml.startTag('extension') self.xml.emptyTag('emailsettings', {'mail_username': id, 'mail_password': '******', 'description': 'UiO-email', 'mailserver': 'imap.uio.no', 'mailtype': 'imap', 'imap_serverdirectory': 'INBOX.', 'imap_sentfolder': 'Sent', 'imap_draftfolder': 'Drafts', 'imap_trashfolder': 'Trash', 'use_ssl': 1, 'defaultmailbox': 'INBOX', 'on_delete_action': 'trash', 'is_primary': 1, }) self.xml.endTag('extension') self.xml.endTag('person') def group_to_XML(self, id, recstatus, data): # Lager XML for en gruppe self.xml.startTag('group', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'FronterStructure1.0') allow_room = data.get('allow_room', 0) allow_contact = data.get('allow_contact', 0) # Convert booleans allow_room and allow_contact to bits allow_room = allow_room and 1 or 0 allow_contact = allow_contact and 2 or 0 self.xml.emptyTag('typevalue', {'level': allow_room | allow_contact}) self.xml.endTag('grouptype') self.xml.startTag('description') if (len(data['title']) > 60): self.xml.emptyTag('short') self.xml.dataElement('long', data['title']) else: self.xml.dataElement('short', data['title']) self.xml.endTag('description') self.xml.startTag('relationship', {'relation': 1}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', data['parent']) self.xml.endTag('sourcedid') self.xml.emptyTag('label') self.xml.endTag('relationship') self.xml.endTag('group') def room_to_XML(self, id, recstatus, data): # Lager XML for et rom # # Gamle rom skal aldri slettes automatisk. if recstatus == FronterExport.STATUS_DELETE: return self.xml.startTag('group', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'FronterStructure1.0') self.xml.emptyTag('typevalue', {'level': 4}) self.xml.endTag('grouptype') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'Roomprofile1.0') self.xml.emptyTag('typevalue', {'level': data['profile']}) self.xml.endTag('grouptype') self.xml.startTag('description') if (len(data['title']) > 60): self.xml.emptyTag('short') self.xml.dataElement('long', data['title']) else: self.xml.dataElement('short', data['title']) self.xml.endTag('description') self.xml.startTag('relationship', {'relation': 1}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', data['parent']) self.xml.endTag('sourcedid') self.xml.emptyTag('label') self.xml.endTag('relationship') self.xml.endTag('group') def personmembers_to_XML(self, gid, recstatus, members): # lager XML av medlemer self.xml.startTag('membership') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', gid) self.xml.endTag('sourcedid') for uname in members: self.xml.startTag('member') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', uname) self.xml.endTag('sourcedid') # This is a person member (as opposed to a group). self.xml.dataElement('idtype', '1') self.xml.startTag('role', {'recstatus': recstatus, 'roletype': FronterExport.ROLE_READ}) self.xml.dataElement('status', '1') self.xml.startTag('extension') # Member of group, not room. self.xml.emptyTag('memberof', {'type': 1}) self.xml.endTag('extension') self.xml.endTag('role') self.xml.endTag('member') self.xml.endTag('membership') def acl_to_XML(self, node, recstatus, groups): self.xml.startTag('membership') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', node) self.xml.endTag('sourcedid') for gname in groups.keys(): self.xml.startTag('member') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', gname) self.xml.endTag('sourcedid') # The following member ids are groups. self.xml.dataElement('idtype', '2') acl = groups[gname] if acl.has_key('role'): self.xml.startTag('role', {'recstatus': recstatus, 'roletype': acl['role']}) self.xml.dataElement('status', '1') self.xml.startTag('extension') self.xml.emptyTag('memberof', {'type': 2}) # Member of room. else: self.xml.startTag('role', {'recstatus': recstatus}) self.xml.dataElement('status', '1') self.xml.startTag('extension') self.xml.emptyTag('memberof', {'type': 1}) # Member of group. self.xml.emptyTag('groupaccess', {'contactAccess': acl['gacc'], 'roomAccess': acl['racc']}) self.xml.endTag('extension') self.xml.endTag('role') self.xml.endTag('member') self.xml.endTag('membership') def end(self): self.xml.endTag(self.rootEl) self.xml.endDocument()
class FronterExport(LMSExport): """Class for handling export to Fronter.""" STATUS_ADD = 1 STATUS_UPDATE = 2 STATUS_DELETE = 3 ROLE_READ = '01' ROLE_WRITE = '02' ROLE_DELETE = '03' ROLE_CHANGE = '07' def __init__(self, output=None, include_password=True): LMSExport.__init__(self) self.output = output self.xml = XMLWriter(output) self.xml.startDocument(encoding='UTF-8') self.rootEl = 'enterprise' self.DataSource = 'Cerebrum' self.include_password = include_password #self.cf_id = self.fronter.fronter_host # TODO: Get this somewhere else logger.debug("Fronterexport initialized") def pwd(self, p): pwtype, password = p.split(":") type_map = {'md5': 1, 'unix': 2, 'nt': 3, 'plain': 4, 'ldap': 5} ret = {'pwencryptiontype': type_map['ldap']} if password: ret['password'] = password return ret def useraccess(self, access): # TODO: move to config section mapping = { # Not allowed to log in 0: 'None', # Normal user 'viewmygroups': 'User', 'allowlogin': '******', # Admin 'administrator': 'SysAdmin', } return mapping[access] def start_xml_file(self, kurs): self.xml.comment("Eksporterer data om følgende emner:\n " + "\n ".join(kurs)) self.xml.startTag(self.rootEl) self.xml.startTag('properties') self.xml.dataElement('datasource', self.DataSource) self.xml.dataElement('target', "ClassFronter/") #%s" % self.cf_id) # :TODO: Tell Fronter (again) that they need to define the set of # codes for the TYPE element. # self.xml.dataElement('TYPE', "REFRESH") self.xml.dataElement('datetime', time.strftime("%F %T %z")) self.xml.endTag('properties') begin = start_xml_file def user_to_XML(self, id, recstatus, data): """Lager XML for en person""" self.xml.startTag('person', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') if self.include_password: self.xml.dataElement('userid', id, self.pwd(data['PASSWORD'])) self.xml.startTag('name') self.xml.dataElement( 'fn', " ".join([x for x in (data['GIVEN'], data['FAMILY']) if x])) self.xml.startTag('n') self.xml.dataElement('family', data['FAMILY']) self.xml.dataElement('given', data['GIVEN']) self.xml.endTag('n') self.xml.endTag('name') self.xml.dataElement('email', data['EMAIL']) self.xml.emptyTag( 'systemrole', {'systemroletype': self.useraccess(data['USERACCESS'])}) self.xml.startTag('extension') self.xml.emptyTag( 'emailsettings', { 'mail_username': id, 'mail_password': '******', 'description': 'UiO-email', 'mailserver': 'imap.uio.no', 'mailtype': 'imap', 'imap_serverdirectory': 'INBOX.', 'imap_sentfolder': 'Sent', 'imap_draftfolder': 'Drafts', 'imap_trashfolder': 'Trash', 'use_ssl': 1, 'defaultmailbox': 'INBOX', 'on_delete_action': 'trash', 'is_primary': 1, }) self.xml.endTag('extension') self.xml.endTag('person') def group_to_XML(self, id, recstatus, data): # Lager XML for en gruppe self.xml.startTag('group', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'FronterStructure1.0') allow_room = data.get('allow_room', 0) allow_contact = data.get('allow_contact', 0) # Convert booleans allow_room and allow_contact to bits allow_room = allow_room and 1 or 0 allow_contact = allow_contact and 2 or 0 self.xml.emptyTag('typevalue', {'level': allow_room | allow_contact}) self.xml.endTag('grouptype') self.xml.startTag('description') if (len(data['title']) > 60): self.xml.emptyTag('short') self.xml.dataElement('long', data['title']) else: self.xml.dataElement('short', data['title']) self.xml.endTag('description') self.xml.startTag('relationship', {'relation': 1}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', data['parent']) self.xml.endTag('sourcedid') self.xml.emptyTag('label') self.xml.endTag('relationship') self.xml.endTag('group') def room_to_XML(self, id, recstatus, data): # Lager XML for et rom # # Gamle rom skal aldri slettes automatisk. if recstatus == FronterExport.STATUS_DELETE: return self.xml.startTag('group', {'recstatus': recstatus}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', id) self.xml.endTag('sourcedid') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'FronterStructure1.0') self.xml.emptyTag('typevalue', {'level': 4}) self.xml.endTag('grouptype') self.xml.startTag('grouptype') self.xml.dataElement('scheme', 'Roomprofile1.0') self.xml.emptyTag('typevalue', {'level': data['profile']}) self.xml.endTag('grouptype') self.xml.startTag('description') if (len(data['title']) > 60): self.xml.emptyTag('short') self.xml.dataElement('long', data['title']) else: self.xml.dataElement('short', data['title']) self.xml.endTag('description') self.xml.startTag('relationship', {'relation': 1}) self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', data['parent']) self.xml.endTag('sourcedid') self.xml.emptyTag('label') self.xml.endTag('relationship') self.xml.endTag('group') def personmembers_to_XML(self, gid, recstatus, members): # lager XML av medlemer self.xml.startTag('membership') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', gid) self.xml.endTag('sourcedid') for uname in members: self.xml.startTag('member') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', uname) self.xml.endTag('sourcedid') # This is a person member (as opposed to a group). self.xml.dataElement('idtype', '1') self.xml.startTag('role', { 'recstatus': recstatus, 'roletype': FronterExport.ROLE_READ }) self.xml.dataElement('status', '1') self.xml.startTag('extension') # Member of group, not room. self.xml.emptyTag('memberof', {'type': 1}) self.xml.endTag('extension') self.xml.endTag('role') self.xml.endTag('member') self.xml.endTag('membership') def acl_to_XML(self, node, recstatus, groups): self.xml.startTag('membership') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', node) self.xml.endTag('sourcedid') for gname in groups.keys(): self.xml.startTag('member') self.xml.startTag('sourcedid') self.xml.dataElement('source', self.DataSource) self.xml.dataElement('id', gname) self.xml.endTag('sourcedid') # The following member ids are groups. self.xml.dataElement('idtype', '2') acl = groups[gname] if acl.has_key('role'): self.xml.startTag('role', { 'recstatus': recstatus, 'roletype': acl['role'] }) self.xml.dataElement('status', '1') self.xml.startTag('extension') self.xml.emptyTag('memberof', {'type': 2}) # Member of room. else: self.xml.startTag('role', {'recstatus': recstatus}) self.xml.dataElement('status', '1') self.xml.startTag('extension') self.xml.emptyTag('memberof', {'type': 1}) # Member of group. self.xml.emptyTag('groupaccess', { 'contactAccess': acl['gacc'], 'roomAccess': acl['racc'] }) self.xml.endTag('extension') self.xml.endTag('role') self.xml.endTag('member') self.xml.endTag('membership') def end(self): self.xml.endTag(self.rootEl) self.xml.endDocument()