# -*- coding: utf-8 # $Id$ # # # Copyright 2001, 2002 by IVA Team and contributors # # This file is part of IVA. # # IVA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # IVA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with IVA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Contains class UserManager, which is the holder and factory object for FLE users.""" __version__ = "$Revision$"[11:-2] from time import time import types, Errors from urllib import quote_plus import re import string import Globals import OFS from Globals import Persistent, Acquisition, PersistentMapping from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2 from OFS.Image import Image from AccessControl import ClassSecurityInfo from TraversableWrapper import TraversableWrapper from Cruft import Cruft from UserDict import UserDict from UserInfo import UserInfo from Webtop import Webtop from common import get_url, \ make_action, get_roles, get_local_roles, translate from common import perm_view, perm_edit, perm_manage, perm_add_lo, perm_access from input_checks import is_valid_title, is_valid_id from Products.ZCatalog.ZCatalog import ZCatalog try: from Products.ZWiki.ZWikiPage import ZWikiPage USE_ZWIKI = 1 except: USE_ZWIKI = 0 from zope.interface import implements from interfaces import IUserManager from zope.component import adapter from zope.app.container.interfaces import IObjectAddedEvent # Instance of this class is FLE/fle_users and contains # all UserInfo objects. # This class contains factory methods for creating and removing users. # User editing is in the UserInfo class. class UserManager( TraversableWrapper, Cruft, Persistent, BTreeFolder2, OFS.SimpleItem.Item, ): """FLE user manager.""" meta_type = 'UserManager' implements(IUserManager) security = ClassSecurityInfo() security.declareObjectPublic() # No additional comments. def __init__(self, id, title): """Construct FLE User Manager.""" self.id = id self.title = title BTreeFolder2.__init__(self, id) self.groups = [] # Groups are stored in a list. security.declarePrivate('add_group') def add_group(self, name): """Add a new group.""" if name not in self.groups: self.groups.append(name) # No additional comments. security.declarePrivate('remove_group') def remove_group(self, name): """Remove a group.""" if name in self.groups: self.groups.remove(name) # No additional comments. security.declarePrivate('get_groups') def get_groups(self): """Get list of groups.""" return self.groups[:] security.declarePublic('has_user_global_role') def has_user_global_role(self, uname, role): """Has given user given role.""" return role in get_roles(self.parent(),uname) security.declarePublic('is_power_user') def is_power_user(self, uname): """Is user a power user?""" if not type(uname) is types.StringType: # Try to convert uname to string (it is a REQUEST.AUTHENTICATED_USER) uname = str(uname) return self.get_user_info(uname).has_any_role(('IVAAdmin', 'Manager', 'Staff')) return getattr(self.fle_users,uname).has_any_role(('IVAAdmin', 'Manager', 'Staff')) security.declarePrivate('is_nickname_free') def is_nickname_free(self, nickname): """Checks that given nick name is not already take by somebody else. Note that case doesn't matter: if somebody is 'foo' nobody can take 'Foo'.""" return not self.acl_users.getUser(nickname) return nickname.lower() not in \ [o.lower() for o in self.acl_users.getUserNames()] # Called from coursemanager's course_selection.dtml security.declarePublic('is_valid_uname') def is_valid_uname(self, uname): """Public valid uname checking. Checks if the given user name exists.""" return self.acl_users.getUser(uname) security.declareProtected(perm_edit, 'pakuKasutajaleNimi') def pakuKasutajaleNimi(self, algnimi="stud"): """Proovitakse nimesid. Kui algne nimi sobib, siis jäetakse see, muul juhul asutakse numbreid lisama. kuni leitakse vaba""" if not self.kasKasutajaOlemas(algnimi): return algnimi nr=1 while self.kasKasutajaOlemas(algnimi+str(nr)): nr=nr+1 return algnimi+str(nr) security.declareProtected(perm_edit, 'kasKasutajaOlemas') def kasKasutajaOlemas(self, nimi): "Vaadatakse läbi kuni leitakse või jõutakse juurikast kõrgemale" obj=self while hasattr(obj, 'acl_users'): try: if nimi in obj.acl_users.getUserNames(): return 1 except AttributeError: pass try: obj=obj.aq_parent except: return 0 return 0 def leiaKasutajaKataloog(self, nimi): "Kui leitakse siis väljastatakse, muul juhul 0" obj=self while 1: if hasattr(obj, 'acl_users'): if obj.acl_users.getUser(nimi): return obj.acl_users try: obj=obj.aq_parent except: return 0 def kasutajanimedeLoetelu(self): "leitavate nimede nimistu" obj=self loetelu=[] while 1: if hasattr(obj, 'acl_users'): try: for nimi in obj.acl_users.getUserNames(): if nimi not in loetelu: loetelu.append(nimi) except AttributeError: pass try: obj=obj.aq_parent except: break return loetelu security.declareProtected(perm_edit, 'lisaKasutaja') def lisaKasutaja(self, nimi, parool): "Kasutaja lisamine" if self.kasKasutajaOlemas(nimi): return 0 self.acl_users._doAddUser(nimi, parool, list(), ()) self.add_user_fle(nimi, tuple()) return "Kasutaja lisatud" security.declareProtected(perm_edit, 'looParool') def looParool(self): import random, string passwd = "" chars = string.ascii_lowercase for x in range(3): nr = 95 while chr(nr) not in chars: nr = random.randint(65,122) passwd += chr(nr) return passwd+str(int(random.random()*10))+str(int(random.random()*10))+str(int(random.random()*10)) # security.declareProtected(perm_edit, 'looKasutaja') # def looKasutaja(self, kasutajanimi): # "Nimi kohandatakse, luuakse parool, väljastatakse mõlemad" # nimi=self.pakuKasutajaleNimi(kasutajanimi) # parool=self.looParool() # if self.lisaKasutaja(nimi, parool): # return (nimi, parool) # return None security.declareProtected(perm_manage,'manage_addIvaUsers_handler') def manage_addIvaUsers_handler(self, REQUEST,eesnimi=None, perenimi=None, kasutajanimi=None, affiliation=-1, fail=None, contB=None): """ adds one user, upper form """ if not contB: return "viga" if fail: lines = fail.readlines() fnames = [] lnames = [] unames = [] for line in lines: person = line.split(',') if len(person) != 3: continue # invalid line fnames.append(unicode(person[0].strip(),'iso-8859-1').encode('utf-8')) lnames.append(unicode(person[1].strip(),'iso-8859-1').encode('utf-8')) unames.append(unicode(person[2].strip(),'iso-8859-1').encode('utf-8')) else: eesnimi=eesnimi.strip() perenimi=perenimi.strip() kasutajanimi=kasutajanimi.strip() if len(eesnimi)==0 or len(perenimi)==0 or len(kasutajanimi)==0: return self.restrictedTraverse('message_dialog.html')(title="Error", message="Please fill all fields!", action="manage_addIvaUsers") fnames = [eesnimi,] lnames = [perenimi,] unames = [kasutajanimi,] return self.manage_addingUsers_handler(REQUEST,fnames,lnames,unames,affiliation) security.declareProtected(perm_manage,'manage_addingUsers_handler') def manage_addingUsers_handler(self,REQUEST,fnames=[], lnames=[], unames=[], affiliation=-1): """ handles usercreation """ #ok if type(fnames)==types.StringType: fnames=[fnames,] lnames=[lnames,] unames=[unames,] namelist = self.kasutajanimedeLoetelu() namelist.sort() retur = {} i = 1 recycle = 0 for x in unames: viga = 0 error = "username taken" nr = unames.index(x) if self.kasKasutajaOlemas(x): viga = 1 if x in namelist: viga = 1 if len(x)<3: viga = 1 error = "username too short" if viga: recycle = 1 retur[i] = {'fName':fnames[nr], 'lName':lnames[nr],'uName':x,'Error':error} else: retur[i] = {'fName':fnames[nr], 'lName':lnames[nr],'uName':x,'Error':'OK'} i = i + 1 if recycle: return self.unrestrictedTraverse('manage_addingUsers.html')(unamelist=retur,affiliation=affiliation,stat_text='Status',theEnd='',htitle="make corrections...") else: passwordlist = self._addingUsers(REQUEST,fnames,lnames,unames,affiliation) return self.unrestrictedTraverse('manage_addingUsers.html')(unamelist=passwordlist,affiliation=affiliation,stat_text='Password',theEnd="true", htitle="make notes, you don't see that page again") security.declareProtected(perm_manage, '_addingUsers') def _addingUsers(self, REQUEST, enimi, pnimi, knimi, eriala='-1'): paroolid={} e=self.getAffiliations() for x in knimi: nr = knimi.index(x) parool=self.looParool() # paroolid.append(parool) # XXX: duplicate function lisaKasutaja, should use add_user self.lisaKasutaja(x, parool) nu = self.get_user_info(x) if int(eriala)>=0: nu.edit_info(enimi[nr], pnimi[nr], organization=e[int(eriala)]) else: nu.edit_info(enimi[nr], pnimi[nr]) paroolid[x] = {'fName':enimi[nr], 'lName':pnimi[nr], 'uName':x, 'Error':parool} return paroolid security.declareProtected(perm_view, 'getAffiliations') def getAffiliations(self): """ Erialade loetelu, kasutajainfos organization """ return getattr(self, 'erialad', {}) security.declareProtected(perm_view, 'getAffiliation') def getAffiliation(self, code): """ get affiliation name """ return self.erialad[code] security.declareProtected(perm_edit, 'addAffiliation') def addAffiliation(self, name): """ add affiliation """ name = name.strip() tt = str(time()) tt = int(re.sub('\.','',tt)) while self.erialad.has_key(tt): tt = str(time()) tt = int(re.sub('\.','',tt)) self.erialad[tt] = name self._p_changed = True return 0 def erialadeKombo(self, REQUEST, kastinimi='eriala',vaikimisiID='-1',opt=''): """ Kombo opt == full siis koht edit_user_info """ e=self.getAffiliations() try: kasutaja=self.get_user_info(self.get_current_user(REQUEST)) except: kasutaja = None if len(e)>0: tulemus="" return tulemus return "" security.declareProtected(perm_manage,'manage_affiliations_handler') def manage_affiliations_handler(self, REQUEST,addButton='',affName='', uploadB='',affCodesTxt='', deleteB='', affCode=''): "Leht" e=self.getAffiliations() if addButton and affName: tt = str(time()) tt = int(re.sub('\.','',tt)) e[tt] = affName if uploadB and affCodesTxt: loetelu=affCodesTxt.readlines() for x in loetelu: y = re.sub('\r\n','',x) tt = str(time()) tt = int(re.sub('\.','',tt)) e[tt] = y if deleteB and affCode: for ac in affCode: try: e.pop(ac) except KeyError: pass self.erialad=e self._p_changed = True return REQUEST.RESPONSE.redirect('manage_affiliations.html') security.declarePrivate('add_user') # uname: User account name # # password: The password # # roles: List of (FLE-wide) roles the user should have # # domains: List of domains from which the user is allowed to login. def add_user(self, uname, password, roles, domains=()): """Add user to UserManager.""" # If the user has no roles and no password, we'll just skip. if not password and not roles: return if self.acl_users.getUser(uname): raise 'FLE Error', "Trying to add user that already exists in acl_users! (%s)" % (uname) try: self.acl_users._doAddUser(uname, password, [], list(domains)) except: import sys if sys.exc_type=='NotImplemented': raise Errors.FleError("The user folder is implemented partially and does not support adding users.") raise try: user = self.add_user_fle(uname,roles) except: # In case of exception, get rid of user in acl_users. try: self.acl_users._doDelUsers((uname,)) except KeyError: pass except: import sys if sys.exc_type=='NotImplemented': raise Errors.FleError("The user folder is implemented partially and does not support removing users.") raise # FIXME: this will result in an error when adding user failed: UnboundLocalError: local variable 'user' referenced before assignment return user def add_user_fle(self, uname, roles, uniq_id=None): if uniq_id is None: suffix = '_'+str(int(time())) uniq_id = self.generateId(prefix='user',suffix=suffix, rand_ceiling=99999999999) uname = str(uname) user = UserInfo(uname, uniq_id) user.perm_org = self.fle_root().def_not_aff user.perm_pass = self.fle_root().def_not_change user.perm_must_change = self.fle_root().def_passwd #user.id=uname #XXX:FIX: BadRequest: The id "Jõgi" contains characters illegal in URLs. self._setObject(uname, user) # A clever loop to get to the actual acl_user folder which contains # the authenticated user (because it might not be the closest one!) obj=self while 1: # TODO: XXX: checkme! try: acl_user_obj = obj.acl_users.getUser(uname) if acl_user_obj: acl_user_obj=acl_user_obj.__of__(obj.acl_users) break obj=obj.aq_parent except AttributeError: break # Get the user object from acl_users, and set it as the # owner of the newly created UserInfo object. user.changeOwnership(acl_user_obj) # Set the userthingy as a owner (local role) to the # newly created UserInfo object. user.manage_delLocalRoles(user.get_valid_userids()) user.manage_setLocalRoles(uname, ('Owner',)) # Set the user's FLE-global roles to the FLE root object. #self.parent().manage_setLocalRoles(uname,roles) return user def _create_a_random_string(self): """Create a random string (used to authenticate invited users).""" from common import random, a_char import sha secret = '' m = sha.new() for i in range(5): secret = secret + str(random()) m.update(secret) hash = m.digest() secret = '' for i in hash: secret = secret + a_char(ord(i)) return secret # FIXME: How to handle all the objects that the user owns and that have # links to user's information (like user's name or photo)? security.declareProtected(perm_manage, 'remove_user') def remove_user(self, uname): """Remove user.""" if not uname in self.objectIds(): raise 'FLE Error', 'Given user does not exist.' try: acl_users = self.acl_users acl_users._doDelUsers((uname,)) self._delObject(uname) except: import sys if sys.exc_type=='NotImplemented': raise Errors.FleError("The user folder is implemented partially and does not support removing users.") raise security.declareProtected(perm_manage, 'manage_userPerhandler') def manage_userPerhandler(self, REQUEST, nimed='',perm_org='', perm_pass='', perm_must_change=''): """ change user permissions """ # kasutajanimed = string.split(nimed,',') # XXX: weird... kasutajanimed = eval(nimed) if type(perm_org)==types.StringType: perm_org=(perm_org,) if type(perm_pass)==types.StringType: perm_pass=(perm_pass,) if type(perm_must_change)==types.StringType: perm_must_change=(perm_must_change,) # Vaatame kas kasutajale lubatakse ogranisatsiooni vahetamist voi mitte # print kasutajanimed for kas_kasutaja in kasutajanimed: if kas_kasutaja != '': lipuke = 0 viga = 0 for abc in perm_org: if abc != '': kasutaja = self.get_user_info(abc) if kas_kasutaja == str(kasutaja.get_uname()): lipuke = 1 kasutaja.perm_org = 1 else: viga = 1 if lipuke==0: kasutaja = self.get_user_info(kas_kasutaja) kasutaja.perm_org = 0 # Vaatame kas kasutajale lubatakse parooli vahetamist voi mitte for kas_kasutaja in kasutajanimed: if kas_kasutaja != '': lipuke = 0 viga = 0 for abc in perm_pass: if abc != '': kasutaja = self.get_user_info(abc) if kas_kasutaja == str(kasutaja.get_uname()): lipuke = 1 kasutaja.perm_pass = 1 else: viga = 1 if lipuke==0: kasutaja = self.get_user_info(kas_kasutaja) kasutaja.perm_pass = 0 # Vaatame kas kasutajale sunnitakse parooli vahetamine for kas_kasutaja in kasutajanimed: if kas_kasutaja != '': lipuke = 0 viga = 0 for abc in perm_must_change: if abc != '': kasutaja = self.get_user_info(abc) if kas_kasutaja == str(kasutaja.get_uname()): lipuke = 1 kasutaja.perm_must_change = 1 else: viga = 1 if lipuke==0: kasutaja = self.get_user_info(kas_kasutaja) kasutaja.perm_must_change = 0 return self.restrictedTraverse('manage_userPermissions.html')(users=kasutajanimed) #REQUEST.RESPONSE.redirect('kasutajaotsing') security.declareProtected(perm_manage, 'manage_ivaUsers_csv') def manage_ivaUsers_csv(self,REQUEST): """ gives a csv file with userpasswords """ csv = "" for x in self.get_users(): if not x.get_organization().strip(): org = '' else: org = x.get_organization() csv += x.get_first_name()+","+x.get_last_name()+","+x.get_uname()+","+org+","+x.global_last_active_time(REQUEST)+"\n" return csv security.declareProtected(perm_manage, 'manage_ivaUsers_handler') def manage_ivaUsers_handler(self, REQUEST, unames=[], delete = '', permission = '',archive = '', changeAff='',organization='', reset=''): """ Kasutajate kustutamine """ if len(unames)==0: return self.restrictedTraverse('message_dialog_error.html')( title='Error: select some user', message="You didn't select any users", action="manage_ivaUsers" ) if type(unames)==types.StringType: unames=(unames,) if delete: errors = [] for uname in unames: kasutaja=self.get_user_info(uname) for kursus in kasutaja.user_courses(): kursus.getObject().remove_person(uname) kasutaja.unindex_object() self.remove_user(uname) if errors: return self.restrictedTraverse('message_dialog_error.html')(title='Error', message='Deletion of following users failed'+'
'.join(errors), action='manage_ivaUsers') else: return self.restrictedTraverse('message_dialog_error.html')(title='Success!', message='All selected users deleted successfully', action='manage_ivaUsers') elif permission: nimed = [] for kasutajanimi in unames: nimed.append(kasutajanimi) return self.restrictedTraverse('manage_userPermissions.html')(users=nimed) elif changeAff: for kasutajanimi in unames: try: self.get_user_info(kasutajanimi).set_organization(self.getAffiliations()[int(organization)]) except KeyError: self.get_user_info(kasutajanimi).set_organization('') self.get_user_info(kasutajanimi).reindex_object() elif archive: return self.archive_user(REQUEST,unames) elif reset: mess = "" for user in unames: mess += "
"+user return self.restrictedTraverse('message_dialog2.html')(title = 'Confirm action', message = translate(self, "Are you sure you want to reset password for following users?")+mess, extra_value_name = 'users', extra_values = unames, option1_value = 'Cancel', option1_name = 'cancel', option2_value = 'Ok', option2_name = 'reset', handler = 'reset_password') else: raise 'FLE error', 'unknown button in manage_ivaUsers' if delete: REQUEST.RESPONSE.redirect('manage_ivaUsers') security.declareProtected(perm_manage, 'reset_password') def reset_password(self, REQUEST, cancel='', reset='',users=[]): """ reset users password - generate new password and send it via email """ if cancel or not reset: return REQUEST.RESPONSE.redirect('manage_ivaUsers.html') for x in users: user = self.get_user_info(x) new_password = self.looParool() user.set_password(new_password) message = "" tmp = translate(self,'Message from IVA server') message += "\n"+tmp message += "\n"+translate(self,'IVA server aadress:')+" "+self.fle_root().absolute_url() message += "\n"+translate(self,'Your password has been reset, below are you credentials') message += "\n"+translate(self,'Username:')+" "+x message += "\n"+translate(self,'Password:')+" " message += new_password self.saadaEmail(user.get_email(), tmp, message, user.get_email()) return REQUEST.RESPONSE.redirect('manage_ivaUsers.html') # Country list lives in this method. security.declarePublic('get_countries') def get_countries(self): """Return list of all(?) countries in the world (in English)""" from countries import country_list return country_list security.declarePublic('get_user_info') def get_user_info(self, uname): """Return a the uname UserInfo object.""" from types import StringType if not type(uname) is StringType: raise 'FLE Error', 'Argument uname is not string type! (and this is the wrong place to convert it).' # Get user info object from fle_users folder return self.get_child(uname) try: return self.get_child(uname) except AttributeError: return None except KeyError: return None security.declarePublic('get_users') def get_users(self): """Return a list of UserInfo objects.""" return self.get_children('UserInfo') security.declareProtected(perm_view, 'get_users_sorted_by_uname') def get_users_sorted_by_uname(self): """Return a list of UserInfo objects sorted by uname""" def uname_comp(x,y): a = x.get_uname() b = y.get_uname() if a < b: return -1 elif a == b: return 0 else: return 1 retval = self.get_children('UserInfo') retval.sort(uname_comp) return retval security.declareProtected(perm_edit, 'make_temp_user') def make_temp_user(self, uname): """Make temporary user from existing user.""" return self.fle_root().temp_objects.add_object( self.get_child(uname)) security.declareProtected(perm_manage, 'manage_registering_users') def manage_registering_users(self, REQUEST, acceptB='', rejectB='', suser=[]): """ manages pending users(at registration) """ #XXX: emailing if acceptB: for x in suser: passwd = self.looParool() # XXX: do username checking # XXX: create user # XXX:FIX: language and translation if not self.is_nickname_free(getattr(REQUEST,x)): return "kasutajanimi %s ei ole vaba" % getattr(REQUEST, x) ou = self.add_user(getattr(REQUEST,x), passwd, list()) ou.set_first_name(self.get_pending_details(x)['fname']) ou.set_last_name(self.get_pending_details(x)['lname']) ou.set_email(self.get_pending_details(x)['email']) ou.set_language(self.get_pending_details(x)['preflang']) fuse = self.get_user_info(REQUEST.get(x)) fuse.reindex_object() # send an email message = translate(self,"register_accept", target=self.get_pending_details(x)['preflang']) self.saadaEmail(self.get_pending_details(x)['email'],"registration confirmed", message+"\n\n%s, %s, %s" % (self.fle_root().absolute_url(), getattr(REQUEST, x), passwd )) # unqueue self.unqueue_user(x) elif rejectB: #XXX: do we send email if rejecting user registration? #XXX: we do it now for x in suser: message = translate(self,"register_reject", target=self.get_pending_details(x)['preflang']) self.saadaEmail(self.get_pending_details(x)['email'], "registration rejected", message) self.unqueue_user(x) return REQUEST.RESPONSE.redirect('manage_ivaUsers.html?managepending=') security.declareProtected(perm_manage, 'cleanup_webtops') def cleanup_webtops(self): """Sets webtop items' owners to be the webtop owners.""" for user in self.get_users(): print "Cleaning for user %s..." % user.get_uname() self.set_owner_of_webtop(user.webtop,user.get_uname()) def set_owner_of_webtop(self,folder,uname): tlist = ('WebtopFolder','WebtopFile','WebtopLink','WebtopMemo') if self.isFeatureEnabled('sqi'): tlist += ('WebtopProxyFile',) if self.isFeatureEnabled('scorm'): tlist += ('SCORMFile',) for item in folder.objectValues(tlist): print "Cleaning %s" % item.get_id() item.set_author(uname) if item.meta_type=='WebtopFolder': self.set_owner_of_webtop(item,uname) def getCurrentUserObj(self, uname): """ return current user object. This had some error if was in zpt """ try: return getattr(self, uname) except AttributeError: return None security.declareProtected(perm_manage, 'archive_user') def archive_user(self, REQUEST=None,selected_users=[]): """ archives users, with documents """ #XXX: not finished! from ExportIMS import Kirjutus from ExportIMS import kirjutaYldM import tempfile, os, shutil filelist = '' for x in selected_users: yld = kirjutaYldM(userArchive=1) failinimi = tempfile.mktemp() events_wrote = False ui = self.get_user_info(x) kasutaja = ((ui),) courses_list = ui.user_courses() course_list = [] for cls in courses_list: if cls not in course_list: course_list.append(cls) for y in course_list: k = Kirjutus(self.fle_root(), y.get_id()) k.looKursuseFail() #XXX: handle user events so that they end up in a yld instance! k.kirjutaKasutajaWebtop(kasutaja) self.export_users(REQUEST, failinimi=failinimi, kursusega=y.get_id(), palju="[self.get_user_info('"+x+"'),]") k.kirjutaItem(k.organization, tiitel='KURSUSE KASUTAJAD') k.kirjutaResource(k.resources, 'imsent_xmlv1p1', 'users.xml') k.kirjutaKasutajaBlog(kasutaja) if not events_wrote: # FIXME: user doesn't have events anymore... k.kirjutaKasutajaSyndmus(kasutaja) events_wrote = True yld.kirjutaYldmanifest(y.get_id(),y.get_description(),base=str(y.get_id())+"/",uniq_id=y.getUniqId()) k.pakiKursusFaili(failinimi) #XXX: every single user must end in a different zip yld.lisaFaili(failinimi) name = 'user_'+re.sub('[^a-zA-Z0-9]', '_', self.firstAndLastNG(x)) name2 = name number = 1 while os.path.isfile(os.path.join(Globals.INSTANCE_HOME,'var',name+'.zip')): number = number + 1 name = name2+'_ver'+str(number) name += '.zip' shutil.move(failinimi,os.path.join(Globals.INSTANCE_HOME,'var',name)) filelist += "
" + os.path.join(Globals.INSTANCE_HOME,'var',name) #file = open(failinimi,"rb") #export_data=file.read() #file.close() #os.remove(failinimi) #REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=ivaexport.zip') #REQUEST.RESPONSE.setHeader('content-type','application/zip') if REQUEST: return self.restrictedTraverse('message_dialog.html')( message = translate(self, 'Users are archived to following places:')+ filelist, action = 'manage_ivaUsers') else: return 0 security.declareProtected(perm_manage, 'export_users') def export_users(self, REQUEST,failinimi='user_export.zip',kursusega='',palju='all'): """ expordi kasutajad """ from ExportIMS import User_export import tempfile, os abc = User_export() if palju == 'all': # for user in self.filtreeriKasutajad(REQUEST, self.fle_root().fle_users.get_users()): for user in self.fle_root().fle_users.get_users(): abc.kirjutaKasutaja(user) else: kursus=getattr(self.fle_root().courses, kursusega) user_collection = eval(palju) for user in user_collection: abc.kirjutaKasutaja(user,kursus) abc.kirjutaKursusGrupina(kursus) abc.kirjutaMembership(kursus, users=user_collection) for krupp in kursus.subgroups.objectValues('GroupFolder'): abc.kirjutaSisegrupid(kursus,krupp) abc.kirjutaMembership(krupp,'krupp', users=user_collection) abc.lisaMembership() abc.pakiFaili(str(kursusega)+"/",failinimi) # kui tuleme course.py-st et exportida kursus koos kasutajatega if kursusega: return file = open(failinimi,"rb") export_data=file.read() file.close() os.remove(failinimi) REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=user_export.zip') REQUEST.RESPONSE.setHeader('content-type','application/zip') return export_data security.declareProtected(perm_manage, 'fix_webtop_permissions') def fix_webtop_permissions(self): """ fix webtop permissions """ for x in self.get_users(): try: wt = getattr(x.aq_inner, 'webtop') except AttributeError: print "kasutajal %s puudub webtop" % x acl = self.leiaKasutajaKataloog(x.get_uname()) acl_user = acl.aq_inner.getUser(x.get_uname()).__of__(acl) for wtp in wt.objectValues('WebtopFolder'): # course webtops wtp.changeOwnership(acl_user, 1) return "done" security.declareProtected(perm_manage, 'migrate_portfolio') def migrate_portfolio(self): """ move Webtop* stuff from portfolio to webtop """ for x in self.get_users(): # users try: wt = getattr(x.aq_inner, 'webtop') except AttributeError: print "kasutajal %s puudub webtop" % x for c in wt.objectValues('WebtopFolder'): # course webtops try: p = getattr(c.aq_inner, 'portfolio') except AttributeError: continue print "scanning items" for item in p.objectValues(): try: if item.meta_type == 'AssignmentProxy': continue original_id = item.id print "Z>",c.absolute_url(), p.absolute_url(), item.absolute_url() while getattr(c.aq_self, item.id, None): item.id = item.id+'x' c._setObject(item.id, item) p._delObject(original_id) o = getattr(c, item.id) o.manage_delLocalRoles((x.get_uname(),)) o.manage_setLocalRoles(x.get_uname(), ('Owner',)) acl = self.leiaKasutajaKataloog(x.get_uname()) acl_user = acl.aq_inner.getUser(x.get_uname()).__of__(acl) o.changeOwnership(acl_user) except: pass for x in self.fle_root().courses.get_courses(): course = x.getObject() sg = course.subgroups for y in sg.objectValues(): #subgroup if y.meta_type != 'Subgroup': # weird folder continue portfolio = getattr(y, 'portfolio', None) if portfolio is None: continue owner = portfolio.getOwnerTuple()[1] if portfolio.meta_type == 'Portfolio': continue if portfolio.meta_type != 'Portfolio': try: print "pole Portfolio, on", portfolio.meta_type for item in portfolio.objectValues(): original_id = item.id old_roles = item.get_local_roles() while getattr(y.aq_self, item.id, None): item.id = item.id+'x' y._setObject(item.id, item) portfolio._delObject(original_id) o = getattr(portfolio, item.id) o.manage_delLocalRoles((owner,)) for r in old_roles: o.manage_setLocalRoles(r[0], r[1]) acl = self.leiaKasutajaKataloog(owner) acl_user = acl.aq_inner.getUser(owner).__of__(acl) item.changeOwnership(acl_user) y._delObject('portfolio') except: pass return "done" Globals.InitializeClass(UserManager) @adapter(IUserManager, IObjectAddedEvent) def added(obj, event): """Set default permissions for roles.""" # ZCatalog for userinfo if not hasattr(obj, 'userinfo_zcatalog'): class largs: def __init__(self, **kw): self.__dict__.update(kw) catalog = ZCatalog('userinfo_zcatalog', 'ZCatalog for UserInfo') from Products.PluginIndexes.TextIndex.Vocabulary import Vocabulary vocabulary = Vocabulary('Vocabulary', 'Vocabulary', globbing=1) catalog._setObject('Vocabulary', vocabulary) # indexes catalog.addIndex('get_email', 'TextIndex') catalog.addIndex('get_first_name', 'TextIndex') catalog.addIndex('get_last_name', 'TextIndex') catalog.addIndex('get_uname', 'TextIndex') catalog.addIndex('meta_type', 'FieldIndex') catalog.addIndex('get_organization', 'FieldIndex') catalog.addIndex('has_photo', 'FieldIndex') catalog.addIndex('userid', 'FieldIndex', extra = largs(indexed_attrs = 'get_uname')) #metadata catalog.addColumn('absolute_url') catalog.addColumn('get_email') catalog.addColumn('get_first_name') catalog.addColumn('get_last_name') catalog.addColumn('get_uname') catalog.addColumn('has_photo') # XXX: not working correctly catalog.addColumn('meta_type') catalog.addColumn('get_organization') catalog.addColumn('get_photo_tag') obj._setObject('userinfo_zcatalog', catalog) obj._p_changed = 1 # EOF