# -*- 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, 'isExistingUser')
def isExistingUser(self, nimi):
"Vaadatakse läbi kuni leitakse või jõutakse juurikast kõrgemale"
if self.acl_users.getUser(nimi) is not None or hasattr(self, nimi):
return True
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
security.declareProtected(perm_edit, 'lisaKasutaja')
def lisaKasutaja(self, nimi, parool):
""" Kasutaja lisamine """
if self.isExistingUser(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_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,]
retur = {}
i = 1
recycle = 0
for x in unames:
viga = 0
error = "username taken"
nr = unames.index(x)
if self.isExistingUser(x): 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
uuser = acl_users.searchUsers(id = uname)
if len(uuser) != 1:
raise
uuser = uuser[0]
tm = getattr(acl_users.aq_base, uuser.get('pluginid'))
tm.removeUser(uname)
#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():
# TODO: XXX: TypeError: 'str' object is not callable
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('Subgroup'):
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