Ejemplo n.º 1
0
    def _send_notification(self, user):
        """
        Send account information to new user

        :param User user:
        :raises: TracError if email sending fails
        """
        data = {
            'system':conf.domain_name,
            'username':user.username,
            'password':user.password,
            'expires':user.expires
        }
        enotify = EmailNotifier(self.env, "New user account created", data)
        enotify.template_name = "local_account_created.txt"
        enotify.notify(user.mail)
Ejemplo n.º 2
0
    def _send_notification(self, user, server_name):
        """
        Send account information to new user

        :param User user:
        :raises: TracError if email sending fails
        """

        data = {
            'system': server_name,
            'username': user.username,
            'password': user.password,
            'expires': user.expires
        }
        enotify = EmailNotifier(self.env, "New user account created", data)
        enotify.template_name = "local_account_created.html"
        enotify.notify(user.mail)
Ejemplo n.º 3
0
    def process_request(self, req):
        """
        Takes the provided arguments and posts an email to author

        - username: User account whose password needs to be changed
        - token: Validation token generated by system

        """
        back_url = req.href()
        username = req.args.get('username', '')
        token = req.args.get('token', '')

        # Check if required parameters are set
        if not username or not token:
            add_warning(req, _('Invalid request'))
            return req.redirect(back_url)

        # Check if user really exists
        userstore = get_userstore()
        user = userstore.getUser(username)
        if not user:
            add_warning(req, _('Invalid request'))
            return req.redirect(back_url)

        # Check token
        if token != get_token(self.env, user):
            add_warning(req, _('Invalid request'))
            return req.redirect(back_url)

        # Construct and send email
        manage_url = self.env.abs_home_href(
            'admin/users/manage',
            username=user.username
        )
        data = {
            'user':user,
            'domain_name':self.env.config.get('multiproject', 'domain_name'),
            'manage_url':manage_url
        }

        # Get author email address
        author = userstore.get_user_author(user)
        if not author or not author.mail:
            add_warning(req, _('Author email not found - please contact service support instead'))
            return req.redirect(back_url)

        try:
            # Import module here so that multiproject.common.users can be imported easily/without circular dependencies
            from multiproject.common.notifications.email import EmailNotifier

            # Open home environment
            home_env = get_home(self.env)
            enotify = EmailNotifier(home_env, 'Password reset requested', data)
            enotify.template_name = 'multiproject_reset_password.txt'
            enotify.notify(author.mail)
            add_notice(req, _('Password reset requested - you will be informed about the new password once changed'))
        # Email sending failed
        except TracError:
            add_warning(req, _('Email sending failed - please try again later'))

        # Return back to homepage
        return req.redirect(back_url)
Ejemplo n.º 4
0
    def edit_user(self, req):
        """
        Handle user edit: view & save
        """
        changes = {}

        username = req.args.get('username')
        if not username:
            add_warning(req, _('Invalid username'))
            return self.list_users(req)

        # Load user being edited
        userstore = get_userstore()
        user = userstore.getUser(username)
        if not user:
            add_warning(req, _('Invalid username (or connection error)'))
            return self.list_users(req)

        # Load user who's doing the edit
        changed_by = userstore.getUser(req.authname)
        papi = Projects()

        # Check permissions and redirect to user listing (handy after editing the user)
        req.perm.require('USER_AUTHOR', Resource('user', id=user.id))

        data = req.args
        data['user'] = user
        data['author'] = userstore.getUserWhereId(user.author_id) if user.author_id else None
        data['base_path'] = req.base_path
        data['dateformats'] = DATEFORMATS
        data['is_local'] = userstore.is_local(user)
        data['now'] = datetime.utcnow()
        data['expired'] = user.expires and ((user.expires - datetime.utcnow()).days < 0)
        data['states'] = userstore.USER_STATUS_LABELS
        data['projects'] = papi.get_authored_projects(user)

        # Add javascript libraries for datepicker and autocomplete
        add_script(req, 'multiproject/js/jquery-ui.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_user_edit.js')

        # If get request show edit
        if req.method.upper() == 'GET':
            return 'admin_user_edit.html', data

        # Close pressed: get back to user listing
        if req.args.get('close'):
            return req.redirect(req.href('admin/users/manage'))

        # Handle save
        if 'limitexceeded' in req.args:
            add_warning(req, _('Picture you tried to upload was too big. Try a smaller one'))

        # Update author if changed
        author_id = req.args.get('author_id', None)

        # If id field is empty but name is not: manual input
        if not author_id and req.args.get('author_text'):
            add_warning(req, _('Author cannot be found'))
            return 'admin_user_edit.html', data

        # Check set reset the author
        if author_id:
            author = userstore.getUserWhereId(int(author_id))
            if not author:
                add_warning(req, _('Author cannot be found'))
                return 'admin_user_edit.html', data

            # Check if author is valid: has permission to author?
            perm = PermissionCache(self.env, author.username)
            if 'USER_AUTHOR' not in perm:
                add_warning(req, _('User %s cannot work as an author (does not have USER_AUTHOR permissions)' % author))
                return self.back(req)

            user.author_id = author.id
            changes['author'] = author
        else:
            user.author_id = None

        user.lastName = req.args.get('last')
        if not user.lastName:
            add_warning(req, _('Last name required'))
            return self.back(req)

        old_mail = user.mail
        user.mail = req.args.get('email')
        if not user.mail:
            add_warning(req, _('Email address required'))
            return self.back(req)

        if old_mail != user.mail:
            changes['email'] = user.mail
            org_store = CQDEOrganizationStore.instance()
            # TODO: is this correct?
            # When changing email, reset organizations to which the user belongs in
            user.organization_keys = org_store.get_organization_keys(user) or None

        # Update password if changed
        password = req.args.get('password')
        if password:
            if not userstore.is_local(user):
                add_warning(req, _("Can't change password for user that uses external authentication method"))
                return self.back(req)

            if len(password) < 7:
                add_warning(req, _("Password must be at least 7 characters long - please provide longer password"))
                return self.back(req)

            if password != req.args.get('confirmpw'):
                add_warning(req, _("Password do not match - please check"))
                return self.back(req)

        user.givenName = req.args.get('first')
        user.mobile = req.args.get('mobile')

        # Set or reset account expiration date
        expiration_str = req.args.get('expires', '')
        if expiration_str:
            try:
                # Parse date and set expiration time in the end of the day
                expires = datetime.strptime(expiration_str, DATEFORMATS['py'])
                expires += timedelta(hours=23, minutes=59, seconds=59)

                # If changed
                if expires != user.expires:
                    user.expires = expires
                    changes['expiration_date'] = user.expires.strftime(DATEFORMATS['py'])

            except Exception:
                self.log.exception('Date formatting failed')
                add_warning(req, _('Non-recognized expiration format'))
                pass

        # Remove expiration date
        elif user.expires:
            changes['expiration_date'] = 'Never expires'
            user.expires = None

        # Update status if set
        status = int(req.args.get('status', 0))
        if status and status in userstore.USER_STATUS_LABELS.keys() and user.status != status:
            changes['status'] = userstore.USER_STATUS_LABELS[status]
            user.status = status

        if req.args.get('removeicon'):
            user.icon = None
        else:
            icon = req.args.get('icon')
            if not isinstance(icon, unicode) and icon.filename:
                user.createIcon(req.args.get('icon'))

        self.log.info('Saving changes to user: %s' % user)
        ok = userstore.updateUser(user)
        if ok and password:
            changes['password'] = password
            ok = userstore.updatePassword(user, password)

        if not ok:
            add_warning(req, _("Could not save changes"))

        add_notice(req, _("User %s updated" % username))

        # Notify user about changes via email?
        if req.args.get('notify'):
            data = {
                'user':user,
                'changed_by':changed_by,
                'changes':changes
            }

            try:
                enotify = EmailNotifier(self.env, "Account updated", data)
                enotify.template_name = 'account_edited.txt'
                enotify.notify(user.mail)
                add_notice(req, _("Notified user about the changes"))
            except TracError:
                add_warning(req, _("Failed to send email notification - user changed anyway"))

        # Check if user has still (after modification) permission to modify user
        # NOTE: req.perm cannot be used here because it is not updated yet
        resource = Resource('user', id=user.id)
        perm = PermissionCache(self.env, username=req.authname)
        if perm.has_permission('USER_AUTHOR', resource):
            return self.back(req)

        add_notice(req, _('You have no longer permission to modify the account: %s' % user.username))
        return req.redirect(req.href('admin/users/manage'))
Ejemplo n.º 5
0
    def edit_user(self, req):
        """
        Handle user edit: view & save
        """
        changes = {}

        username = req.args.get('username')
        if not username:
            add_warning(req, _('Invalid username'))
            return self.list_users(req)

        # Load user being edited
        userstore = get_userstore()
        user = userstore.getUser(username)
        if not user:
            add_warning(req, _('Invalid username (or connection error)'))
            return self.list_users(req)

        # Load user who's doing the edit
        changed_by = userstore.getUser(req.authname)
        papi = Projects()

        # Check permissions and redirect to user listing (handy after editing the user)
        #req.perm.require('USER_AUTHOR', Resource('user', id=user.id))
        if self.check_author_and_deputies(changed_by.id,
            user.author_id, userstore.get_deputies(user.id), req, user.id) == False:
            add_warning(req, _("You don't have rights to edit user"))
            req.redirect(req.href("admin"))

        data = req.args
        data['user'] = user
        data['author'] = userstore.getUserWhereId(user.author_id) if user.author_id else None
        data['deputies'] = userstore.get_deputies(user.id)
        data['base_path'] = req.base_path
        data['dateformats'] = DATEFORMATS
        data['is_local'] = userstore.is_local(user)
        data['now'] = datetime.utcnow()
        data['expired'] = user.expires and ((user.expires - datetime.utcnow()).days < 0)
        data['states'] = userstore.USER_STATUS_LABELS
        data['projects'] = papi.get_authored_projects(user)

        # Add javascript libraries for datepicker and autocomplete
        add_script(req, 'multiproject/js/jquery-ui.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_user_edit.js')

        # If get request show edit
        if req.method.upper() == 'GET' and req.args.get('remove_deputy'):
            deputy = userstore.getUser(req.args.get('remove_deputy').strip())
            remove_res = userstore.remove_deputy(user.id, deputy.id)
            return req.send(remove_res, content_type='text/plain', status=200)
        elif req.method.upper() == 'GET':
            return 'admin_user_edit.html', data

        # Close pressed: get back to user listing
        if req.args.get('close'):
            return req.redirect(req.href('admin/users/manage'))

        if req.args.get('deputy_name'):
            deputy = userstore.getUser(req.args.get('deputy_name').strip())
            resource = Resource('user', id=deputy.id)
            perm = PermissionCache(self.env, username=deputy.username)
            if perm.has_permission('USER_AUTHOR', resource):
                if(userstore.add_deputy(user.id, deputy.username)):
                    add_notice(req, _("Deputy "+deputy.username+" added."))
                    return_url = 'home/admin/users/manage?username='******'home/admin/users/manage?username='******'t have enough rights"))
                return_url = 'home/admin/users/manage?username='******'limitexceeded' in req.args:
            add_warning(req, _('Picture you tried to upload was too big. Try a smaller one'))

        # Update author if changed
        author_id = req.args.get('author_id', None)

        # If id field is empty but name is not: manual input
        if not author_id and req.args.get('author_text'):
            add_warning(req, _('Author cannot be found'))
            return 'admin_user_edit.html', data

        # Check set reset the author
        if author_id:
            author = userstore.getUserWhereId(int(author_id))
            if not author:
                add_warning(req, _('Author cannot be found'))
                return 'admin_user_edit.html', data

            # Check if author is valid: has permission to author?
            perm = PermissionCache(self.env, author.username)
            if 'USER_AUTHOR' not in perm:
                add_warning(req, _('User %s cannot work as an author (does not have USER_AUTHOR permissions)' % author))
                return self.back(req)

            user.author_id = author.id
            changes['author'] = author
        else:
            user.author_id = None

        user.lastName = req.args.get('last')
        if not user.lastName:
            add_warning(req, _('Last name required'))
            return self.back(req)

        old_mail = user.mail
        user.mail = req.args.get('email')
        if not user.mail:
            add_warning(req, _('Email address required'))
            return self.back(req)

        if old_mail != user.mail:
            changes['email'] = user.mail
            org_store = CQDEOrganizationStore.instance()
            # TODO: is this correct?
            # When changing email, reset organizations to which the user belongs in
            user.organization_keys = org_store.get_organization_keys(user) or None

        # Update password if changed
        password = req.args.get('password')
        if password:
            if not userstore.is_local(user):
                add_warning(req, _("Can't change password for user that uses external authentication method"))
                return self.back(req)

            if len(password) < 7:
                add_warning(req, _("Password must be at least 7 characters long - please provide longer password"))
                return self.back(req)

            if password != req.args.get('confirmpw'):
                add_warning(req, _("Password do not match - please check"))
                return self.back(req)

        user.givenName = req.args.get('first')
        user.mobile = req.args.get('mobile')

        # Set or reset account expiration date
        expiration_str = req.args.get('expires', '')
        if expiration_str:
            try:
                # Parse date and set expiration time in the end of the day
                expires = datetime.strptime(expiration_str, DATEFORMATS['py'])
                expires += timedelta(hours=23, minutes=59, seconds=59)

                # If changed
                if expires != user.expires:
                    user.expires = expires
                    changes['expiration_date'] = user.expires.strftime(DATEFORMATS['py'])

            except Exception:
                self.log.exception('Date formatting failed')
                add_warning(req, _('Non-recognized expiration format'))
                pass

        # Remove expiration date
        elif user.expires:
            changes['expiration_date'] = 'Never expires'
            user.expires = None

        # Update status if set
        status = int(req.args.get('status', 0))
        if status and status in userstore.USER_STATUS_LABELS.keys() and user.status != status:
            changes['status'] = userstore.USER_STATUS_LABELS[status]
            user.status = status

        if req.args.get('removeicon'):
            user.icon = None
        else:
            icon = req.args.get('icon')
            if not isinstance(icon, unicode) and icon.filename:
                user.createIcon(req.args.get('icon'))

        self.log.info('Saving changes to user: %s' % user)
        ok = userstore.updateUser(user)
        if ok and password:
            changes['password'] = password
            ok = userstore.updatePassword(user, password)

        if not ok:
            add_warning(req, _("Could not save changes"))

        add_notice(req, _("User %s updated" % username))

        # Notify user about changes via email?
        if req.args.get('notify'):
            data = {
                'user':user,
                'changed_by':changed_by,
                'changes':changes
            }

            try:
                enotify = EmailNotifier(self.env, "Account updated", data)
                enotify.template_name = 'account_edited.txt'
                enotify.notify(user.mail)
                add_notice(req, _("Notified user about the changes"))
            except TracError:
                add_warning(req, _("Failed to send email notification - user changed anyway"))

        # Check if user has still (after modification) permission to modify user
        # NOTE: req.perm cannot be used here because it is not updated yet
        #resource = Resource('user', id=user.id)
        #perm = PermissionCache(self.env, username=req.authname)
        #if perm.has_permission('USER_AUTHOR', resource):
        #    return self.back(req)
        if self.check_author_and_deputies(changed_by.id,
            user.author_id, userstore.get_deputies(user.id), req, user.id) == True:
            return_url = 'home/admin/users/manage?username='******'You have no longer permission to modify the account: %s' % user.username))
            return req.redirect(req.href('admin/users/manage'))