# -*- 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
# 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'
security = ClassSecurityInfo()
security.declareObjectPublic()
# security.declareProtected(perm_edit, 'edit_user_form')
## def __bobo_traverse__(self,request,entry_name=None):
## if entry_name in self.objectIds('UserInfo'):
## return getattr(self.UserInfo,entry_name)
## return getattr(self,entry_name)
def index_html(self,REQUEST):
" index_html to fle_users "
return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url())
# No additional comments.
def __init__(self, id, title):
"""Construct FLE User Manager."""
self.id = id
self.title = title
BTreeFolder2.__init__(self, id)
self.groups = []
security.declarePrivate('manage_afterAdd')
def manage_afterAdd(self, item, container):
"""Set default permissions for roles."""
from common import roles_admin, roles_staff, roles_user
self.manage_permission(perm_access,('IVAAdmin','Manager','Member','Owner'),0)
self.manage_permission(perm_edit,('IVAAdmin','Manager','Owner'),0)
self.manage_permission(perm_view,('IVAAdmin','Manager','Member','Owner'),0)
# ZCatalog for userinfo
if not hasattr(self, 'userinfo_zcatalog'):
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')
#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')
self._setObject('userinfo_zcatalog', catalog)
self._p_changed = 1
# 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)
if not self.acl_users.getUser(uname):
return 0
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 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 uname in self.acl_users.getUserNames()
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'):
if nimi in obj.acl_users.getUserNames():
return 1
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'):
for nimi in obj.acl_users.getUserNames():
if nimi not in loetelu:
loetelu.append(nimi)
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, ['Member',], ())
self.add_user_fle(nimi, ('Member',))
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.message_dialog(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.manage_addingUsers(unamelist=retur,affiliation=affiliation,stat_text='Status',theEnd='',htitle="make corrections...")
else:
passwordlist = self._addingUsers(REQUEST,fnames,lnames,unames,affiliation)
return self.manage_addingUsers(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')
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 uname in self.acl_users.getUserNames():
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)
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:
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
# 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.manage_userPermissions(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.message_dialog_error(
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.remove_person(uname)
kasutaja.unindex_object()
self.remove_user(uname)
if errors:
return self.message_dialog_error(title='Error',
message='Deletion of following users failed'+' '.join(errors),
action='manage_ivaUsers')
else:
return self.message_dialog_error(title='Success!', message='All selected users deleted successfully', action='manage_ivaUsers')
elif permission:
nimed = []
for kasutajanimi in unames:
nimed.append(kasutajanimi)
return self.manage_userPermissions(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.message_dialog2(title = 'Confirm action',
message = translate(self, "Are you sure you want to reset password for following users?", target=self.giveLanguage(REQUEST))+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')
for x in users:
user = self.get_user_info(x)
new_password = self.looParool()
user.set_password(new_password)
message = ""
lang = self.giveLanguage(REQUEST)
tmp = translate(self,'Message from IVA server',target=lang)
message += "\n"+tmp
message += "\n"+translate(self,'IVA server aadress:',target=lang)+" "+self.fle_root().absolute_url()
message += "\n"+translate(self,'Your password has been reset, below are you credentials', target=lang)
message += "\n"+translate(self,'Username:',target=lang)+" "+x
message += "\n"+translate(self,'Password:',target=lang)+" "
message += new_password
self.saadaEmail(user.get_email(), tmp, message, user.get_email())
return REQUEST.RESPONSE.redirect('manage_ivaUsers')
# 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
try:
return self.get_child(uname)
except AttributeError:
raise Errors.FleError('No such FLE user: %s' % (uname))
except:
return None
# No additional comments.
security.declareProtected(perm_edit, 'form_handler')
def form_handler(
self,
REQUEST,
users = '',
freeze = '', # submit buttons
unfreeze = '', #
remove = '', #
):
"""Handle input from the fle_users/index_html form."""
if type(users) is types.StringType:
users = [users,]
if freeze:
for user in users:
self.freeze_user(user)
REQUEST.RESPONSE.redirect('index_html')
return
elif unfreeze:
for user in users:
self.unfreeze_user(user)
REQUEST.RESPONSE.redirect('index_html')
return
elif remove:
user_string = users[0]
for user in users[1:]:
user_string += "%20" + user
REQUEST.RESPONSE.redirect('remove_users_confirm?user_string=%s' % user_string)
return
else:
# This code should never be reached.
raise 'FLE Error', 'Unknown button'
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()
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 ))
# 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, ['Member'])
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'])
self.unqueue_user(x)
fuse = self.get_user_info(REQUEST.get(x))
fuse.reindex_object()
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?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',)
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 ImportExportIMS import Kirjutus
from ImportExportIMS 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.firstAndLast(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.message_dialog(
message = translate(self, 'Users are archived to following places:', target=self.giveLanguage(REQUEST))+ 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 ImportExportIMS 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, '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)
# EOF