IssueUserFolder.py :  » Issue-Tracker » IssueTracker » IssueTrackerProduct » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Issue Tracker » IssueTracker 
IssueTracker » IssueTrackerProduct » IssueUserFolder.py
# IssueTrackerProduct
#
# www.issuetrackerproduct.com
# Peter Bengtsson <mail@peterbe.com>
# License: ZPL
#

__version__='0.0.8'

# python

# Zope
from AccessControl import User,AuthEncoding
from App.Dialogs import MessageDialog
from AccessControl import ClassSecurityInfo
from AccessControl.Role import DEFAULTMAXLISTUSERS

try:
    # >= Zope 2.12
    from App.special_dtml import DTMLFile
    from Persistence import Persistent
except ImportError:
    # < Zope 2.12
    from Globals import DTMLFile,Persistent

# Product
import Utils
from I18N import _
from Constants import *
from Permissions import IssueTrackerManagerRole,IssueTrackerUserRole,VMS

#----------------------------------------------------------------------------

manage_addIssueUserFolderForm=DTMLFile('dtml/addIssueUserFolder', globals())

def manage_addIssueUserFolder(self, title='', webmaster_email='',
                              keep_usernames=None, REQUEST=None):
    """ ads  """
    id="acl_users"
    webmaster_email = str(webmaster_email).strip()
    old_users = None
    if keep_usernames and id in self.objectIds('User Folder'):
        old_users = self.manage_getUsersToConvert(withpasswords=True)
        self.manage_delObjects([id])
        
    
    i=IssueUserFolder(webmaster_email)
    self._setObject(id,i)
    userfolder = self._getOb(id)

    for role in [IssueTrackerManagerRole, IssueTrackerUserRole]:
        # only add these roles if they don't already exist
        if role not in self.valid_roles():
            #self.REQUEST.set('role', role)
            #self.manage_defined_roles(submit='Add Role', REQUEST=self.REQUEST)
            aq_self = self.this()
            roles = list(aq_self.__ac_roles__)
            roles.append(role)
            aq_self.__ac_roles__ = tuple(roles)
            

    if old_users and REQUEST is not None:
        old_users_dict = {}
        for user in old_users:
            old_users_dict[user['username'].replace(' ','')] = user

        keys = REQUEST.get('keys')
        for key in keys:
            username = REQUEST.get('username_%s'%key)
            if key not in keep_usernames:
                continue
            if not username:
                raise "IllegalValue", 'A username must be specified'
            password = old_users_dict[key]['__']
            fullname = REQUEST.get('fullname_%s'%key)
            if not fullname:
                fullname = username
            email = REQUEST.get('email_%s'%key)
            if not Utils.ValidEmailAddress(email):
                raise "InvalidEmail", "Email (%r) not valid email address"%email
            roles = REQUEST.get('roles_%s'%key)
            domains = REQUEST.get('domains_%s'%key)
            if domains and not self.domainSpecValidate(domains):
                raise "IllegalValue", 'Illegal domain specification'

            userfolder._doAddUser(username, password, roles, domains,
                                  email=email,
                                  fullname=fullname)
                                  
    if REQUEST:
        return self.manage_main(self, REQUEST)


def _uniqify(somelist):
    d={}
    for i in somelist:
        d[i]=1
    return d.keys()

def _merge_dicts_nicely(dict1, dict2):
    """ make all dict values into lists
    into one dict """
    new = {}
    for k,v in (dict1.items()+dict2.items()):
        if new.has_key(k):
            # that we haven't seen before
            if type(v)==type([]):
                new[k].extend(v)
            else:
                new[k].append(v)
        else:
            if type(v)==type([]):
                new[k] = v
            else:
                new[k] = [v]
    for k,v in new.items():
        thatlist = _uniqify(v)
        thatlist.sort()
        new[k] = thatlist
    return new

def _find_issuetrackers(context):
    issuetrackers = []
    for object in context.objectValues():
        if object.meta_type == ISSUETRACKER_METATYPE:
            issuetrackers.append(object)
        elif object.isPrincipiaFolderish:
            issuetrackers.extend(_find_issuetrackers(object))
    return issuetrackers

def manage_getUsersToConvert(self, withpasswords=False):
    """ find all the users in the acl_users folder here, and
    try to find a suitable name and email address. """
    if not 'acl_users' in self.objectIds('User Folder'):
        # just double checking that we have a old user folder here
        return []
    
    old_user_folder = self.acl_users
    old_users = []

    issuetrackers = _find_issuetrackers(self)
    if self.meta_type == ISSUETRACKER_METATYPE:
        if self not in issuetrackers:
            issuetrackers.append(self)
            
    acl_cookienames = acl_cookieemails = {}
    for issuetracker in issuetrackers:
        _cookienames = issuetracker.getACLCookieNames()
        
        if _cookienames:
            acl_cookienames = _merge_dicts_nicely(acl_cookienames, _cookienames)

        _cookieemails = issuetracker.getACLCookieEmails()
        if _cookieemails:
            acl_cookieemails = _merge_dicts_nicely(acl_cookieemails, _cookieemails)
        
    for user in old_user_folder.getUsers():
        fullname = acl_cookienames.get(str(user), [])
        email = acl_cookieemails.get(str(user),[])
        
        if not fullname and email:
            _email1 = email[0].split('@')[0]
            if len(_email1.split('.'))>1:
                fullname = [x.capitalize() \
                             for x in _email1.split('.')]
                fullname = ' '.join(fullname)
                
            elif len(_email1.split('_'))>1:
                fullname = [x.capitalize() \
                            for x in _email1.split('_')]
                fullname = ' '.join(fullname)
                
            else:
                fullname = str(user).capitalize()

        d = {'username':str(user),
             'domains':user.domains,
             'roles':user.roles,
             'fullname':fullname,
             'email':email}
        
        if email and email[0] and Utils.ValidEmailAddress(email[0]):
            d['invalid_email'] = False
        else:
            d['invalid_email'] = True
            
        if withpasswords:
            d['__'] = user.__
        old_users.append(d)
        
    return old_users
    
#----------------------------------------------------------------------------

class IssueUserFolder(User.UserFolder):
    """ user folder for managing IssueUsers """

    meta_type = ISSUEUSERFOLDER_METATYPE

    ## these variables need to be in the new class so they are used in the
    ## correct context and won't be taken from the base class and consequently 
    ## from the wrong directory
    _mainUser = DTMLFile('dtml/mainIssueUser', globals())
    _mainUser._setName('_mainUser')
    
    manage = _mainUser
    manage_main = _mainUser

    _add_User = DTMLFile('dtml/addIssueUser', globals())
    _editUser = DTMLFile('dtml/editIssueUser', globals())
    _passwordReminder = DTMLFile('dtml/passwordReminder', globals())
    
    _userFolderProperties = DTMLFile('dtml/userFolderProps', globals())
    
    
    security = ClassSecurityInfo()

    def __init__(self, webmaster_email=''):
        """ Same as inherited but a possible webmaster_email attribute """
        self.webmaster_email = webmaster_email
        apply(User.UserFolder.__init__, (self,), {})
        

    def manage_setUserFolderProperties(self, encrypt_passwords=0,
                                       update_passwords=0,
                                       maxlistusers=DEFAULTMAXLISTUSERS,
                                       webmaster_email=None,
                                       REQUEST=None):
        """ wrapper on manage_setUserFolderProperties() from base class
        that also sets webmaster_email """
        
        if webmaster_email is not None:
            self.webmaster_email = webmaster_email.strip()
        return User.UserFolder.manage_setUserFolderProperties(self,
                                               encrypt_passwords=encrypt_passwords,
                                               update_passwords=update_passwords,
                                               maxlistusers=maxlistusers,
                                               REQUEST=REQUEST)
        
        
    def _addUser(self, name, password, confirm, roles, domains, REQUEST=None):
        if not name:
            return MessageDialog(
                title  ='Illegal value', 
                message='A username must be specified',
                action ='manage_main')
        if not password or not confirm:
            if not domains:
                return MessageDialog(
                    title  ='Illegal value', 
                    message='Password and confirmation must be specified',
                    action ='manage_main')
        if self.getUser(name) or (self._emergency_user and
                                  name == self._emergency_user.getUserName()):
            return MessageDialog(
                title  ='Illegal value', 
                message='A user with the specified name already exists',
                action ='manage_main')
        if (password or confirm) and (password != confirm):
            return MessageDialog(
            title  ='Illegal value', 
            message='Password and confirmation do not match',
            action ='manage_main')
        
        if not roles: roles=[]
        if not domains: domains=[]

        if domains and not self.domainSpecValidate(domains):
            return MessageDialog(
                title  ='Illegal value', 
                message='Illegal domain specification',
                action ='manage_main')
        if not Utils.ValidEmailAddress(REQUEST['email']):
            return MessageDialog(
                title  ='Illegal value',
                message='Not a valid email address',
                action ='manage_main')
        if not REQUEST.get('fullname',''):
            REQUEST.set('fullname',name)
        self._doAddUser(name, password, roles, domains,
                        email=REQUEST['email'],
                        fullname=REQUEST['fullname'],
                        must_change_password=REQUEST.get('must_change_password', False),
                        display_format=REQUEST.get('display_format',''),
                        )
        if REQUEST: return self._mainUser(self, REQUEST)


    def _changeUser(self,name,password,confirm,roles,domains,REQUEST=None):
        if password == 'password' and confirm == 'pconfirm':
            # Protocol for editUser.dtml to indicate unchanged password
            password = confirm = None
        if not name:
            return MessageDialog(
                           title  ='Illegal value', 
                           message='A username must be specified',
                           action ='manage_main')
        if password == confirm == '':
            if not domains:
                return MessageDialog(
                    title  ='Illegal value', 
                    message='Password and confirmation must be specified',
                    action ='manage_main')
        if not self.getUser(name):
            return MessageDialog(
                           title  ='Illegal value', 
                           message='Unknown user',
                           action ='manage_main')
        if (password or confirm) and (password != confirm):
            return MessageDialog(
                           title  ='Illegal value', 
                           message='Password and confirmation do not match',
                           action ='manage_main')

        if not roles: roles=[]
        if not domains: domains=[]

        if domains and not self.domainSpecValidate(domains):
            return MessageDialog(
                           title  ='Illegal value', 
                          message='Illegal domain specification',
                           action ='manage_main')
        if REQUEST.get('email') and not Utils.ValidEmailAddress(REQUEST['email']):
            return MessageDialog(
                title  ='Illegal value',
                message='Not a valid email address',
                action ='manage_main')
        self._doChangeUser(name, password, roles, domains,
                           email=REQUEST.get('email'),
                           fullname=REQUEST.get('fullname'),
                           must_change_password=REQUEST.get('must_change_password'))
        if REQUEST:
            return self._mainUser(self, REQUEST)

    def _changeUserDetails(self, name, fullname, email, REQUEST=None):
        """ Simple method that does what _changeUser() does but without
        password and roles """
        fullname = fullname.strip()
        email = email.strip()
        if not fullname:
            raise "NoFullname", "Full name must be specified"
        if not email:
            raise "NoEmail", "Email must be specified"
        elif not Utils.ValidEmailAddress(email):
            raise "InvalidEmail", "Email not valid email address"

        self._doChangeUserDetails(name, fullname, email)

        if REQUEST:
            return self._mainUser(self, REQUEST)

    def _doChangeUserDetails(self, name, fullname, email,
                             must_change_password=None):
        user = self.data[name]
        user.fullname = fullname
        user.email = email
        if must_change_password is not None:
            user.must_change_password = must_change_password
        self.data[name] = user
            
        
    def _doAddUser(self, name, password, roles, domains, **kw):
        """Create a new user"""
        email=kw['email']
        fullname=kw['fullname']
        must_change_password=kw.get('must_change_password',False)
        display_format = kw.get('display_format','')
        if password is not None and self.encrypt_passwords:
            password = self._encryptPassword(password)
        self.data[name]=IssueUser(name, password, roles, domains,
                                  email, fullname, must_change_password,
                                  display_format)

    def _doChangeUser(self, name, password, roles, domains, **kw):
        user = self.data[name]
        if password is not None:
            if self.encrypt_passwords:
                password = self._encryptPassword(password)
            user.__ = password
        user.roles = roles
        user.domains = domains
        if kw.get('email'):
            email=kw['email']
            user.email = email
        if kw.get('fullname'):
            fullname=kw['fullname']
            user.fullname = fullname
        if kw.get('display_format'):
            display_format=kw['display_format']
            user.display_format = display_format
        user.must_change_password=kw.get('must_change_password', False)
        self.data[name]=user

    def getIssueTrackerRoot(self):
        """ Try to return the IssueTracker instance root or None """
        try:
            root = self.getRoot() # from aquisition
            if root.meta_type == ISSUETRACKER_METATYPE:
                return root
            else:
                return None
        except:
            # Means it's deploy outside an issuetracker
            return None
            
    def getWebmasterEmail(self):
        """ return webmaster_email or try to find a IssueTracker instance """
        # returns None if not found
        issuetrackerroot = self.getIssueTrackerRoot() 
        if issuetrackerroot:
            wherefrom = "Issue Tracker"
            email = issuetrackerroot.getSitemasterEmail()
        else:
            wherefrom = "Issue User Folder"
            email = self.webmaster_email
        if not Utils.ValidEmailAddress(email):
            m = "Webmaster email (%s) taken from %s invalid"
            m = m%(email, wherefrom)
            raise "InvalidWebmasterEmail", m

    def getIssueUserFolderPath(self):
        """ return the absolute real path of this object parent """
        return '/'.join(self.getPhysicalPath())
    
    
    security.declareProtected(VMS, 'manage_sendReminder')
    def manage_sendReminder(self, name, email_from, email_subject,
                            remindertext):
        """ actually send the password reminder """
        try:
            user = self.getUser(name)
        except:
            return MessageDialog(
                            title  ='Illegal value',
                            message='The specified user does not exist',
                            action ='manage_main')
                            
        issuetrackerroot = self.getIssueTrackerRoot()
        
        if not email_from:
            raise "NoEmailFromError", "You must specify a from email address"
        elif not self.webmaster_email:
            self.webmaster_email = email_from

        email_to = user.getEmail()
        if not email_to or email_to and not Utils.ValidEmailAddress(email_to):
            raise "NoEmailToError", "User does not have a valid email address"
            
            
        replacement_key = "<password shown here>"
        if remindertext.find(replacement_key) == -1:
            raise "NoPasswordReplacementError",\
                  "No place to put the password reminder"
                  
        if self.encrypt_passwords:
            # generate a new password and save it
            password = Utils.getRandomString(length=6, loweronly=1)
            user.__ = password
        
        else:
            password = user.__
        
        if not email_subject:
            email_subject = "Issue Tracker password reminder"
        
        remindertext = remindertext.replace(replacement_key, password)
        
        # send it!
        

        if issuetrackerroot:
            # send via the issuetracker
            issuetrackerroot.sendEmail(remindertext, email_to, email_from, 
               email_subject, swallowerrors=False)
        else:
            body = '\r\n'.join(['From: %s'%email_from, 'To: %s'%email_to,
                                'Subject: %s'%email_subject, "", remindertext])
                            
            # Expect a mailhost object. Note that here we're outside the Issuetracker
            try:
                mailhost = self.MailHost
            except:
                try:
                    mailhost = self.SecureMailHost
                except:
                    try:
                        mailhost = self.superValues('MailHost')[0]
                    except IndexError:
                        raise "NoMailHostError", "No 'MailHost' available to send from"
            if hasattr(mailhost, 'secureSend'):
                mailhost.secureSend(remindertext, email_to, email_from, email_subject)
            else:
                mailhost.send(body, email_to, email_from, email_subject)
            
        m = "Password reminder sent to %s" % email_to
        return self.manage_main(self, self.REQUEST, manage_tabs_message=m)

        
        
    
    security.declareProtected(VMS, 'manage_passwordReminder')
    def manage_passwordReminder(self, name):
        """ wrap up a template """
        try:
            user = self.getUser(name)
        except:
            return MessageDialog(
                            title  ='Illegal value',
                            message='The specified user does not exist',
                            action ='manage_main')
                            
        issuetrackerroot = self.getIssueTrackerRoot()
        
        if self.webmaster_email:
            from_field = self.webmaster_email
        elif issuetrackerroot:
            from_field = issuetrackerroot.getSitemasterFromField()
        else:
            from_field = ""
            
        
        subject = _("Password reminder")
        
        if issuetrackerroot is not None:
            subject = "%s: %s" % (issuetrackerroot.getTitle(), subject)
            
        
        msg = "Dear %(fullname)s,\n\n"
        msg += "This is a password reminder for you to use on %(url)s.\n"
        if self.encrypt_passwords:
            msg += "Since your previous password was encrypted we have had "\
                   "to recreate a new password for you.\n"
        msg += "Your username is still: %(username)s\nand your password is: "\
               "<password shown here>"
        msg += "\n\n"
        msg += "PS. The administrator sending this password reminder will"\
               " not able to read your password at any time."
        #if issuetrackerroot is not None:
        #    msg += "Now you can go to %s and log in"%(issuetrackerroot.absolute_url()
            
        d = {'fullname':user.getFullname(),
             'username':name}
        if issuetrackerroot is not None:
            d['url'] = issuetrackerroot.absolute_url()
        else:
            d['url'] = self.absolute_url().replace('/acl_users','')
             
        msg = msg % d
            
        return self._passwordReminder(self, self.REQUEST, user=user,
                username=name,
                subject=subject, message=msg, from_field=from_field)
            
#----------------------------------------------------------------------------

class IssueUser(User.SimpleUser, Persistent):
    """ User with additional email property """

    misc_properties = {} # backwardcompatability
    
    def __init__(self, name, password, roles, domains,
                 email, fullname, must_change_password=False,
                 display_format='', use_accesskeys=False,
                 remember_savedfilter_persistently=False,
                 show_nextactions=False):
        """ constructor method """
        self.name = name
        self.__ = password
        self.roles = roles
        self.domains = domains
        self.email = email
        self.fullname = fullname
        self.must_change_password = must_change_password
        self.display_format = display_format
        self.use_accesskeys = use_accesskeys
        self.remember_savedfilter_persistently = remember_savedfilter_persistently
        self.show_nextactions = show_nextactions

        self._user_lists = None # For the User page. if None, not set
        #self._user_display_format = None

        self.misc_properties = {}


    def getIssueUserPath(self):
        """ return the absolute real path of this object parent """
        return '/'.join(self.getPhysicalPath())

    def getIssueUserIdentifier(self):
        """ return the parents physical path and username """
        return self.getIssueUserPath(), self.name
    
    def getIssueUserIdentifierString(self):
        """ return getIssueUserIdentifier() as a comma separated
        string. """
        return ','.join(self.getIssueUserIdentifier())

    def getIssueUserIdentifierstring(self):
        """ return getIssueUserIdentifier() as one string """
        path, name = self.getIssueUserIdentifier()
        return "%s,%s"%(path, name)
    
    def getEmail(self):
        """ returns the user's email """
        return self.email

    def getFullname(self):
        """ returns the fullname """
        return self.fullname

    def getUserLists(self):
        """ return _user_lists """
        if not hasattr(self, '_user_lists'): 
            self._user_lists = None           
            return None                      
        return self._user_lists

    def setUserLists(self, lists):
        """ add these lists """
        was = self.getUserLists()
        if was is None:
            was = []
        new = was+lists
        self._user_lists = Utils.uniqify(new)

    def getDisplayFormat(self):
        """ return prefered displayformat """
        if hasattr(self, 'display_format'):
            return getattr(self, 'display_format')
        else:
            # old bad code
            return getattr(self, '_user_display_format', None)

    def setDisplayFormat(self, displayformat):
        """ set prefered displayformat """
        self.display_format = displayformat
        
    def useAccessKeys(self, default=False):
        """ return prefered displayformat """
        return getattr(self, 'use_accesskeys', default)
    
    def rememberSavedfilterPersistently(self, default=False):
        """ return if last savedfilter id should be remembered persistently
        (for more info read rememberSavedfilterPersistently() in IssueTracker.py) 
        """
        return getattr(self, 'remember_savedfilter_persistently', default)
    
    def showNextActionIssues(self, default=False):
        """ return if 'Your next action issues' should be shown on the homepage
        """
        return getattr(self, 'show_nextactions', default)

    def useIssueNotes(self, default=False):
        """return if 'Use Issue notes' should be shown on the homepage
        """
        return getattr(self, 'use_issuenotes', default)

    def setRememberSavedfilterPersistently(self, toggle):
        """ set to saved last savedfilter id persistently or not """
        self.remember_savedfilter_persistently = not not toggle
        
    def setUseNextActionIssues(self, toggle):
        """ set to saved last savedfilter id persistently or not """
        self.show_nextactions = not not toggle

    def setUseIssueNotes(self, toggle):
        """enable issue notes"""
        self.use_issuenotes = not not toggle

    def setAccessKeys(self, toggle):
        """ set prefered displayformat """
        self.use_accesskeys = not not toggle # makes sure it's bool type

    def getMiscProperty(self, key, default=None):
        """ return from misc_properties """
        return self.misc_properties.get(key, default)

    def hasMiscProperty(self, key):
        """ do we have it in misc_properties """
        return self.misc_properties.has_key(key)
        #if not hasattr(self, 'misc_properties'):
        #    return False
        #else:
            

    def setMiscProperty(self, key, value):
        """ set in misc_properties dict """
        was = self.misc_properties
        was[key] = value
        self.misc_properties = was
        
    def debugInfo(self):
        """ return the misc_properties """
        if DEBUG: # from Constants
            out = []
            out.append("misc_properties:%s" % self.misc_properties)
            out.append("must_change_password:%s" % self.must_change_password)
            out.append("display_format:%s" % self.display_format)
            out.append("use_accesskeys:%s" % getattr(self, 'use_accesskeys', False))
            out.append("remember_savedfilter_persistently:%s" % getattr(self, 'remember_savedfilter_persistently', False))
            
            out.append("_user_lists:%s" % self._user_lists)
            return ', '.join(out)
        else:
            return "Not in debug mode"

    def mustChangePassword(self):
        """ return if 'self.must_change_password' is True """
        if not hasattr(self, 'must_change_password'):
            self.must_change_password = False # default
        return self.must_change_password

    def _unmust_mustChangePassword(self):
        """ toggle the boolean value """
        newvalue = False
        self.must_change_password = newvalue

    def sendPasswordReminder(self):
        """ will send the password in an email """
        raise "DeprecatedError"
    
        if self.encrypt_passwords:
            m = "Password reminders disabled since passwords are encrypted"
            raise "PasswordsEncrypted", m
        S = "Issue User Password Reminder"
        M = "Dear %s,\nYour password is: "%self.getFullname()
        M += self.__
        M += '\n'

        F = self.getWebmasterEmail()
        T = self.getEmail()

        # Find the nearest MailHost object
        mailhost = self.MailHost

        mailhost.send(M, T, F, S)

        page = self.manage_main
        m = "Email password reminder sent to %s"%T
        return page(self, self.REQUEST, manage_tabs_message=m)




www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.