예제 #1
0
 def __init__(self, user):
     super(UserFIEditor, self).__init__(None)
     self.uid = user if is_string(user) else user.uid
     self.user_repository = UserRepository()
     fi_uid = self.user.fi.uid if self.user.fi else ''
     self.fi_uid = editor.Property(fi_uid).validate(
         validators.non_empty_string)
예제 #2
0
class UserFIEditor(editor.Editor):
    def __init__(self, user):
        super(UserFIEditor, self).__init__(None)
        self.uid = user if is_string(user) else user.uid
        self.user_repository = UserRepository()
        fi_uid = self.user.fi.uid if self.user.fi else ''
        self.fi_uid = editor.Property(fi_uid).validate(
            validators.non_empty_string)

    @property
    def is_mine(self):
        current_user = security.get_user()
        return current_user and (current_user.uid == self.uid)

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    def get_facilitators(self):
        return UserData.get_facilitators()

    def commit(self):
        if not super(UserFIEditor, self).commit((), ('fi_uid',)):
            return False

        new_facilitator = self.user_repository.get_by_uid(self.fi_uid())
        self.user.fi = new_facilitator

        flashmessage.set_flash(_(u'Facilitator changed'))
        return True
예제 #3
0
class UserFIEditor(editor.Editor):
    def __init__(self, user):
        super(UserFIEditor, self).__init__(None)
        self.uid = user if is_string(user) else user.uid
        self.user_repository = UserRepository()
        fi_uid = self.user.fi.uid if self.user.fi else ''
        self.fi_uid = editor.Property(fi_uid).validate(
            validators.non_empty_string)

    @property
    def is_mine(self):
        current_user = security.get_user()
        return current_user and (current_user.uid == self.uid)

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    def get_facilitators(self):
        return UserData.get_facilitators()

    def commit(self):
        if not super(UserFIEditor, self).commit((), ('fi_uid', )):
            return False

        new_facilitator = self.user_repository.get_by_uid(self.fi_uid())
        self.user.fi = new_facilitator

        flashmessage.set_flash(_(u'Facilitator changed'))
        return True
    def setUp(self):
        super(TestWorkflow, self).setUp()

        # create the profiles that will interact with the idea
        user_repository = UserRepository()
        self.facilitator = user_repository.facilitator
        self.developer = user_repository.developer
        self.admin = user_repository.admin
        self.author = user_repository.create(uid=u'author',
                                             email=u'*****@*****.**',
                                             firstname=u'John',
                                             lastname=u'Doe',
                                             position=u'author',
                                             fi=self.facilitator)

        # create an idea domain
        domain = DomainData(
            label=u'domain',
            rank=100,
            en_label=u'en',
            fr_label=u'fr',
        )

        # create an idea
        self.idea = IdeaRepository().create(title=u'Title',
                                            description=u'description',
                                            impact=u'impact',
                                            submitted_by=self.author,
                                            domain=domain)
예제 #5
0
def apply_rule(idea, state, event, context, *args, **kw):
    from eureka.domain.repositories import UserRepository
    di_uid = kw['di']
    di = UserRepository().get_by_uid(di_uid) or UserRepository().developer
    context.assignated_di = di

    return WFStates.DI_APPRAISAL_STATE
예제 #6
0
    def setUp(self):
        super(TestWorkflow, self).setUp()

        # create the profiles that will interact with the idea
        user_repository = UserRepository()
        self.facilitator = user_repository.facilitator
        self.developer = user_repository.developer
        self.admin = user_repository.admin
        self.author = user_repository.create(
            uid=u'author',
            email=u'*****@*****.**',
            firstname=u'John',
            lastname=u'Doe',
            position=u'author',
            fi=self.facilitator
        )

        # create an idea domain
        domain = DomainData(
            label=u'domain',
            rank=100,
            en_label=u'en',
            fr_label=u'fr',
        )

        # create an idea
        self.idea = IdeaRepository().create(
            title=u'Title',
            description=u'description',
            impact=u'impact',
            submitted_by=self.author,
            domain=domain
        )
예제 #7
0
def populate_users(default_users):
    """Populate the default users (special accounts)"""
    facilitator_uid = default_users['FACILITATOR']
    developer_uid = default_users['DEVELOPER']
    admin_uid = default_users['ADMIN']
    innovator_uid = default_users['INNOVATOR']
    special_users = (
        (facilitator_uid, facilitator_uid, facilitator_uid.capitalize(),
         facilitator_uid.capitalize(),
         u'{}@eureka-open.com'.format(facilitator_uid), facilitator_uid,
         [RoleType.Facilitator]),
        (developer_uid, developer_uid, u'Ideas', developer_uid.capitalize(),
         u'{}@eureka-open.com'.format(developer_uid), facilitator_uid,
         [RoleType.Developer]),
        (admin_uid, admin_uid, admin_uid.capitalize(), u'Eureka',
         u'{}@eureka-open.com'.format(admin_uid), facilitator_uid,
         [RoleType.DSIG]),
        (innovator_uid, innovator_uid, innovator_uid.capitalize(), u'User',
         u'{}@eureka-open.com'.format(innovator_uid), facilitator_uid, []),
    )

    for (uid, password, firstname, lastname, email, fi_uid,
         roles) in special_users:
        user = UserRepository().create(uid=uid,
                                       password=password,
                                       firstname=firstname,
                                       lastname=lastname,
                                       email=email,
                                       fi_uid=fi_uid)
        for role in roles:
            user.add_role(role)

        session.flush()
예제 #8
0
    def commit(self):
        properties = ('title', 'short_title', 'created_by', 'organization', 'associated_dis', 'starting_date',
                      'ending_date', 'summary', 'description', 'mobile_description', 'outcome', 'tags')
        if not super(ChallengeEditor, self).commit((), properties):
            return False

        user_repository = UserRepository()
        created_by = user_repository.get_by_email(self.created_by.value)
        associated_dis = [user_repository.get_by_email(email) for email in self.associated_dis.value]

        challenge = self.challenge or self.challenge_repository.create()

        challenge.title = self.title.value
        challenge.short_title = self.short_title.value
        challenge.created_by = created_by
        challenge.organization = self.organization.value
        challenge.associated_dis = associated_dis
        challenge.starting_date = self.starting_date.value
        challenge.ending_date = self.ending_date.value + timedelta(days=1)  # ending_date is not included
        challenge.summary = self.summary.value
        challenge.description = self.description.value
        challenge.mobile_description = self.mobile_description.value
        challenge.outcome = self.outcome.value
        challenge.tags = self.tags.value

        # For each selected DI, if the corresponding account isn't DI, add the role to the user
        di_role = RoleType.Developer
        for u in associated_dis:
            u.add_role(di_role)

        return True
예제 #9
0
    def __init__(self, uid, email_unique=True, mobile_access=False):
        super(UserLineEditor, self).__init__(None)

        self.email_unique = email_unique
        self.mobile_access = mobile_access
        self.uid = uid
        self.user_repository = UserRepository()
        self.reset()
예제 #10
0
 def __init__(self):
     from eureka.domain.repositories import (CommentRepository,
                                             IdeaRepository, UserRepository,
                                             VoteIdeaRepository)
     self.user_repository = UserRepository()
     self.idea_repository = IdeaRepository()
     self.vote_idea_repository = VoteIdeaRepository()
     self.comment_repository = CommentRepository()
예제 #11
0
class PointsAdmin(editor.Editor):
    """User interface to assign points to some users"""
    def __init__(self):
        super(PointsAdmin, self).__init__(None)
        self._ActionList = (
            (PointCategory.GIFT_BOUGHT, _(u"Gift purchase"), -1),
            (PointCategory.OTHER_EXPENSE, _(u"Other expense"), -1),
            (PointCategory.BONUS_POINTS, _(u"Bonus points"), +1),
            (PointCategory.PENALTY_POINTS, _(u"Penalty points"), -1),
        )
        self.category = editor.Property(PointCategory.GIFT_BOUGHT)
        self.users_emails = editor.Property(u'').validate(validators.user_email_list)
        self.points = editor.Property(u'').validate(validators.positive_integer)
        self.reason = editor.Property(u'').validate(validators.non_empty_string)
        self.user_repository = UserRepository()

    def _find_sign(self, category):
        for id, _, sign in self._ActionList:
            if id == category:
                return sign

    def is_validated(self):
        return super(PointsAdmin, self).is_validated(('category', 'points', 'users_emails', 'reason'))

    def check_users_have_enough_points(self):
        emails = self.users_with_not_enough_points()
        if emails:
            msg = _(u'The following users do not have enough available points: %s') % ', '.join(emails)
            self.users_emails.error = msg

    def users_with_not_enough_points(self):
        if self._find_sign(self.category.value) > 0:
            return []

        emails = []
        for email in self.users_emails.value:
            user = self.user_repository.get_by_email(email)
            if user.available_points < self.points.value:
                emails.append(email)
        return emails

    def commit(self):
        if not self.is_validated():
            return False

        category = self.category.value
        sign = self._find_sign(category)
        nb_points = self.points.value * sign
        reason = self.reason.value
        for email in self.users_emails.value:
            user = self.user_repository.get_by_email(email)
            user.add_points(category, nb_points, reason=reason)

        flashmessage.set_flash(_(u'Modifications done'))
        return True
예제 #12
0
 def update_idea_authors(self, idea):
     co_authors = [self.co_author_1.value, self.co_author_2.value,
                   self.co_author_3.value, self.co_author_4.value,
                   self.co_author_5.value]
     authors = [idea.submitted_by]
     user_repository = UserRepository()
     for email in co_authors:
         if email:
             email = email.strip().lower()
             authors.append(user_repository.get_by_email(email))
     idea.authors = authors
예제 #13
0
 def __init__(self, uid):
     super(DIEditor, self).__init__(None)
     self.uid = uid
     self.user_repository = UserRepository()
     self.domains = editor.Property(
         [str(elt.id) for elt in self.get_domains()])
     self.successor = editor.Property('').validate(
         validators.non_empty_string)
     self.di_business_area = editor.Property(
         self.user.di_business_area
         or '').validate(validators.non_empty_string)
예제 #14
0
 def __init__(self):
     super(PointsAdmin, self).__init__(None)
     self._ActionList = (
         (PointCategory.GIFT_BOUGHT, _(u"Gift purchase"), -1),
         (PointCategory.OTHER_EXPENSE, _(u"Other expense"), -1),
         (PointCategory.BONUS_POINTS, _(u"Bonus points"), +1),
         (PointCategory.PENALTY_POINTS, _(u"Penalty points"), -1),
     )
     self.category = editor.Property(PointCategory.GIFT_BOUGHT)
     self.users_emails = editor.Property(u'').validate(validators.user_email_list)
     self.points = editor.Property(u'').validate(validators.positive_integer)
     self.reason = editor.Property(u'').validate(validators.non_empty_string)
     self.user_repository = UserRepository()
예제 #15
0
 def __init__(self, uid=None, email_unique=True, mobile_access=False):
     """User's informations editor
     In:
         - ``uid`` -- the uid of the user to edit (if we are in edit mode)
         - ``email_unique`` -- do we have to check for the email uniqueness or not (default yes)
     """
     super(UserEditor, self).__init__(None)
     self.assignable_roles = [RoleType.Facilitator, RoleType.Developer]
     if mobile_access:
         self.assignable_roles.append(RoleType.MobileAccess)
     self.email_unique = email_unique
     self.uid = uid
     self.user_repository = UserRepository()
     self.reset_fields()
예제 #16
0
 def __init__(self, user):
     super(UserFIEditor, self).__init__(None)
     self.uid = user if is_string(user) else user.uid
     self.user_repository = UserRepository()
     fi_uid = self.user.fi.uid if self.user.fi else ''
     self.fi_uid = editor.Property(fi_uid).validate(
         validators.non_empty_string)
예제 #17
0
    def __init__(self, uid, email_unique=True, mobile_access=False):
        super(UserLineEditor, self).__init__(None)

        self.email_unique = email_unique
        self.mobile_access = mobile_access
        self.uid = uid
        self.user_repository = UserRepository()
        self.reset()
예제 #18
0
def create_user(**kw):
    repository = UserRepository()

    # initialize the user fields
    if 'enabled' not in kw:
        kw['enabled'] = True

    if 'fi_uid' not in kw:
        kw['fi_uid'] = u'facilitateur'

    for f in ('uid', 'lastname', 'firstname', 'email', 'position'):
        if f not in kw.keys():
            kw[f] = random_string()

    u = repository.create(**kw)
    u = session.merge(u)
    return repository.get_by_uid(u.uid)  # make sure the new user is found in the session
예제 #19
0
 def __init__(self):
     from eureka.domain.repositories import (
         CommentRepository, IdeaRepository,
         UserRepository, VoteIdeaRepository
     )
     self.user_repository = UserRepository()
     self.idea_repository = IdeaRepository()
     self.vote_idea_repository = VoteIdeaRepository()
     self.comment_repository = CommentRepository()
예제 #20
0
    def _validate_user(self, login):
        user = UserRepository().get_by_uid(login)
        if user is None:
            raise ValueError(_(u"This user does not exist"))

        if not user.enabled:
            raise ValueError(_(u"This user account is disabled"))

        return login
예제 #21
0
def create_user(**kw):
    repository = UserRepository()

    # initialize the user fields
    if 'enabled' not in kw:
        kw['enabled'] = True

    if 'fi_uid' not in kw:
        kw['fi_uid'] = u'facilitateur'

    for f in ('uid', 'lastname', 'firstname', 'email', 'position'):
        if f not in kw.keys():
            kw[f] = random_string()

    u = repository.create(**kw)
    u = session.merge(u)
    return repository.get_by_uid(
        u.uid)  # make sure the new user is found in the session
예제 #22
0
 def __init__(self, uid):
     super(DIEditor, self).__init__(None)
     self.uid = uid
     self.user_repository = UserRepository()
     self.domains = editor.Property(
         [str(elt.id) for elt in self.get_domains()])
     self.successor = editor.Property('').validate(
         validators.non_empty_string)
     self.di_business_area = editor.Property(
         self.user.di_business_area or '').validate(
         validators.non_empty_string)
예제 #23
0
class DIAdmin(object):
    def __init__(self):
        self.user_repository = UserRepository()

    def _users(self):
        return self.user_repository.get_developers().order_by(
            UserData.lastname, UserData.firstname)

    def confirm_delete_di(self, uid, comp):
        full_name = self.user_repository.get_by_uid(uid).fullname

        confirm = PortalBox(Confirmation(
            _(u'The expert role of the user "%s" will be removed. '
              u'You must confirm this change.') % full_name,
            _(u'Ok'), _(u'Cancel')))

        if comp.call(confirm):
            user = self.user_repository.get_by_uid(uid)
            user.remove_role(RoleType.Developer)
            user.remove_responsibilities(RoleType.Developer)
예제 #24
0
def send(template_filename, to, delivery_priority=DeliveryPriority.Normal, attachments=None, **kw):
    from eureka.domain.models import MailDeliveryFrequency
    from eureka.domain.repositories import UserRepository

    user_repository = UserRepository()

    locale = to.locale if to else 'fr'

    # creates the email contents
    substitutions = _get_substitutions(to=to, **kw)
    content = _perform_substitutions(template_filename, locale, substitutions)

    # extracts and remove the metadata
    content, subject, sender, to_recipients, cc_recipients, bcc_recipients = _extract_metadata(content)

    # attachments
    attachments = attachments or ()

    # if there's no recipient, no need to send an email
    if not to_recipients:
        return

    mailer = mail.get_mailer()

    if (delivery_priority == DeliveryPriority.Normal) or attachments:
        # FIXME: for consistency, we should also send one email per recipient, using the target user locale
        # send now (one message with all the recipients)
        mailer.send_mail(subject, from_=sender, to=to_recipients, cc=cc_recipients, bcc=bcc_recipients,
                         content=content, type='html', attachments=attachments)
    elif delivery_priority == DeliveryPriority.Low:
        # send one message per user (since we need the examine the mail delivery setting of each user)
        for user_email in to_recipients + cc_recipients + bcc_recipients:
            user = user_repository.get_by_email(unicode(user_email))
            send_now = not user or user.mail_delivery_frequency == MailDeliveryFrequency.Immediately

            if send_now:
                # sends the email now
                mailer.send_mail(subject, from_=sender, to=[user_email], content=content, type='html')
            else:
                # add the message to the user's pending email messages
                user.add_pending_email_message(subject, content)
예제 #25
0
def render_comment(self, h, comp, *args):
    voters = self.voters
    voters_uids = [voter.uid for voter in voters]

    pager = UserPager(self, lambda uids=voters_uids: UserRepository().get_by_uids(uids))
    relevant_comment_users_dialog = component.Component(ModalBox(AsyncWrapper(component.Component(pager, model='minimal')),
                                                                 title=_(u'Users finding this comment relevant'),
                                                                 visible=False))

    with h.li:
        h << h.a(name='comment%s' % self.id)  # so we can navigate to comments
        sync = h.SyncRenderer()
        h << relevant_comment_users_dialog.render(sync)
        with h.div(class_='user'):
            # creator avatar
            h << component.Component(User(self, self.comment.created_by)).render(sync, model='avatar100')
        if voters:
            with h.div(class_='alert'):
                nb_voters = len(voters_uids)
                if nb_voters > 1:
                    message = _(u"%s people find this comment relevant") % nb_voters
                else:
                    message = _(u"One people find this comment relevant")

                h << h.a(message,
                         title=message,
                         href='javascript:' + relevant_comment_users_dialog().show_js(),
                         class_='votes')
        with h.div(class_='author'):
            # author
            h << _(u"From") << " "
            h << comp.render(sync, model='author') << " "

            # date
            if self.comment.submission_date:  # deal with missing dates in the database
                h << _(u'on') << " "
                with h.span(class_='date'):
                    h << format_datetime(self.comment.submission_date)
                h << " "
        h << h.p(text_to_html_elements(h, self.comment.content))

        # attachment
        if self.comment.attachment:
            with h.p:
                h << component.Component(Attachment(self.comment.attachment)).render(h)

        with h.div(class_='links'):
            h << comp.render(h, model='actions')

        # delete form
        h << comp.render(h, model='delete_form')

    return h.root
예제 #26
0
    def __init__(self):
        editor.Editor.__init__(self, None)
        self.user_repository = UserRepository()

        self.uid = editor.Property(u'')
        self.corporation_id = editor.Property(-1).validate(validators.integer)
        self.direction_id = editor.Property(-1).validate(validators.integer)
        self.service_id = editor.Property(-1).validate(validators.integer)
        self.site_id = editor.Property(-1).validate(validators.integer)
        self.subsite_id = editor.Property(-1).validate(validators.integer)
        self.enabled = editor.Property('-1')
        self.fi_uid = editor.Property('-1')
예제 #27
0
    def __init__(self, uid):
        super(FIEditor, self).__init__(None)
        self.uid = uid
        self.user_repository = UserRepository()

        # FI
        self.fi_uid = editor.Property(u'').validate(
            validators.non_empty_string)

        self.corporation_id = editor.Property(' - 1')
        self.direction_id = editor.Property(' - 1')
        self.service_id = editor.Property(' - 1')
        self.site_id = editor.Property(' - 1')
        self.subsite_id = editor.Property(' - 1')

        self.successor = editor.Property('').validate(
            validators.non_empty_string)

        self.filter = component.Component(UserFilter())
        if self.user:
            self.filter().initialize_from_user_organization(self.user)
예제 #28
0
def apply_rule(idea, state, event, context, *args, **kw):
    from eureka.domain.queries import get_published_challenge_ideas
    from eureka.domain.repositories import UserRepository

    # Affect to DI
    di_uid = kw['di']
    di = UserRepository().get_by_uid(di_uid) or UserRepository().developer
    context.assignated_di = di
    context.publication_date = datetime.now()

    # Give points to creator
    for user in idea.authors:
        user.process_point_event(PointEvent.PUBLISH_IDEA, idea=idea)

        if (idea.challenge is not None and
           [e for e in get_published_challenge_ideas(idea.challenge.id)()] == []):
            user.process_point_event(PointEvent.PUBLISH_CHALLENGE_FIRST_IDEA, idea=idea)

        idea.show_creator = True

    return WFStates.DI_APPRAISAL_STATE
예제 #29
0
class DIAdmin(object):
    def __init__(self):
        self.user_repository = UserRepository()

    def _users(self):
        return self.user_repository.get_developers().order_by(
            UserData.lastname, UserData.firstname)

    def confirm_delete_di(self, uid, comp):
        full_name = self.user_repository.get_by_uid(uid).fullname

        confirm = PortalBox(
            Confirmation(
                _(u'The expert role of the user "%s" will be removed. '
                  u'You must confirm this change.') % full_name, _(u'Ok'),
                _(u'Cancel')))

        if comp.call(confirm):
            user = self.user_repository.get_by_uid(uid)
            user.remove_role(RoleType.Developer)
            user.remove_responsibilities(RoleType.Developer)
예제 #30
0
    def add_comment(self, expert_email, content):
        current_user = security.get_user()
        assert current_user

        creator = current_user.entity
        expert = UserRepository().get_by_email(expert_email)

        c = EvalCommentData(created_by=creator,
                            expert=expert,
                            content=content,
                            submission_date=datetime.today())
        self.data.comments.append(c)
예제 #31
0
 def __init__(self, uid=None, email_unique=True, mobile_access=False):
     """User's informations editor
     In:
         - ``uid`` -- the uid of the user to edit (if we are in edit mode)
         - ``email_unique`` -- do we have to check for the email uniqueness or not (default yes)
     """
     super(UserEditor, self).__init__(None)
     self.assignable_roles = [RoleType.Facilitator, RoleType.Developer]
     if mobile_access:
         self.assignable_roles.append(RoleType.MobileAccess)
     self.email_unique = email_unique
     self.uid = uid
     self.user_repository = UserRepository()
     self.reset_fields()
예제 #32
0
    def commit(self):
        properties = ('title', 'short_title', 'created_by', 'organization',
                      'associated_dis', 'starting_date', 'ending_date',
                      'summary', 'description', 'mobile_description',
                      'outcome', 'tags')
        if not super(ChallengeEditor, self).commit((), properties):
            return False

        user_repository = UserRepository()
        created_by = user_repository.get_by_email(self.created_by.value)
        associated_dis = [
            user_repository.get_by_email(email)
            for email in self.associated_dis.value
        ]

        challenge = self.challenge or self.challenge_repository.create()

        challenge.title = self.title.value
        challenge.short_title = self.short_title.value
        challenge.created_by = created_by
        challenge.organization = self.organization.value
        challenge.associated_dis = associated_dis
        challenge.starting_date = self.starting_date.value
        challenge.ending_date = self.ending_date.value + timedelta(
            days=1)  # ending_date is not included
        challenge.summary = self.summary.value
        challenge.description = self.description.value
        challenge.mobile_description = self.mobile_description.value
        challenge.outcome = self.outcome.value
        challenge.tags = self.tags.value

        # For each selected DI, if the corresponding account isn't DI, add the role to the user
        di_role = RoleType.Developer
        for u in associated_dis:
            u.add_role(di_role)

        return True
예제 #33
0
def populate_users(default_users):
    """Populate the default users (special accounts)"""
    facilitator_uid = default_users['FACILITATOR']
    developer_uid = default_users['DEVELOPER']
    admin_uid = default_users['ADMIN']
    innovator_uid = default_users['INNOVATOR']
    special_users = (
        (facilitator_uid, facilitator_uid,
            facilitator_uid.capitalize(), facilitator_uid.capitalize(),
            u'{}@eureka-open.com'.format(facilitator_uid), facilitator_uid,
            [RoleType.Facilitator]),
        (developer_uid, developer_uid, u'Ideas', developer_uid.capitalize(),
            u'{}@eureka-open.com'.format(developer_uid), facilitator_uid,
            [RoleType.Developer]),
        (admin_uid, admin_uid, admin_uid.capitalize(), u'Eureka',
            u'{}@eureka-open.com'.format(admin_uid), facilitator_uid,
            [RoleType.DSIG]),
        (innovator_uid, innovator_uid, innovator_uid.capitalize(), u'User',
            u'{}@eureka-open.com'.format(innovator_uid), facilitator_uid,
            []),
    )

    for (uid, password, firstname, lastname,
            email, fi_uid, roles) in special_users:
        user = UserRepository().create(
            uid=uid,
            password=password,
            firstname=firstname,
            lastname=lastname,
            email=email,
            fi_uid=fi_uid
        )
        for role in roles:
            user.add_role(role)

        session.flush()
예제 #34
0
    def is_unused_uid(self, msg=_L(u'User id already used')):
        """Check that there is no user with this identifier

        In:
          - ``msg`` -- message to raise

        Return:
          - ``self``
        """
        if not self.value:
            return self

        if UserRepository().get_by_uid(self.value):
            raise ValueError(msg)

        return self
예제 #35
0
def user_email_list(text, separator=',', check_user_email=True):
    """Validate a list of email addresses between commas"""
    emails = [item.strip() for item in text.split(separator) if
              item.strip() != '']

    if not emails:
        raise ValueError(_L(u"Can't be empty"))

    for email in emails:
        if not validateEmail(email):
            raise ValueError(_L(u"%s is not a valid email address") % email)
        if check_user_email and not UserRepository().get_by_email(email):
            raise ValueError(
                _L(u"There's no user with this email address: %s") % email)

    return emails
예제 #36
0
    def is_user_email(self, msg=_L(u"No user with this email")):
        """Check that there is a known user with this email

        In:
          - ``msg`` -- message to raise

        Return:
          - ``self``
        """
        if not self.value:
            return self

        if not UserRepository().get_by_email(self.value):
            raise ValueError(msg)

        return self
예제 #37
0
def rebuild_indexes(logger):
    global apps
    logger.info('Creating search indexes')
    search_engine = apps['eureka'].search_engine
    search_engine.clear()

    logger.info('Re-indexing ideas')
    # We index *all* ideas. We are safe because results are filtered by 'published' status
    ideas = IdeaRepository().get_all().options(
        eagerload('tags'), eagerload('authors_association')).all()
    search_engine.index_many(ideas)

    logger.info('Re-indexing users')
    users = UserRepository().get_all()
    search_engine.index_many(users)

    logger.info('Done')
예제 #38
0
    def __init__(self, parent, user, selected_tab=None, online_shop=None):
        self.parent = parent
        event_management._register_listener(parent, self)
        self.uid = user if is_string(user) else user.uid
        self.user_repository = UserRepository()
        self.user_comp = User(parent, self.uid)
        self.tabs = self._create_tabs()
        selected_tab = selected_tab if selected_tab in self.tabs else 'profile'
        self.selected_tab = var.Var(selected_tab)

        # inner components displayed in the tabs or the header
        # FIXME: all these should be wrapped into a component.Component
        self.fi_editor = UserFIEditor(self.uid)
        event_management._register_listener(self, self.fi_editor)
        self.avatar_editor = AvatarEditor(self.uid)
        event_management._register_listener(self, self.avatar_editor)
        self.password_editor = PasswordEditor(self.user)
        event_management._register_listener(self, self.password_editor)
        self.profile_editor = ProfileEditor(self.user)
        event_management._register_listener(self, self.profile_editor)
        self.settings_editor = component.Component(SettingsEditor(self.user))
        event_management._register_listener(self, self.settings_editor())
        self.idea_pager = self._create_pager()
        # FIXME: the pager should not depend on the parent
        # event_management._register_listener(self, self.idea_pager)
        self.online_shop = online_shop(self)

        self.tab_labels = {
            'profile': _("My Profile") if self.is_mine else _("Her Profile"),
            'settings': _("My Settings") if self.is_mine else _("Her Settings"),
            'tracked_ideas': (_("My Tracked Ideas") if self.is_mine else _("Her Tracked Ideas")) + " (%d)" % self.new_events_count(),
            'ideas': (_("My Ideas") if self.is_mine else _("Her Ideas")) + " (%d)" % self.ideas_count,
            'points': (_("My Points") if self.is_mine else _("Her Points")) + " (%d)" % self.user.acquired_points,
            # 'rank': self.user.status_level_label,
        }

        self.menu_items = [(self.tab_labels[name], name, None, '', None) for name in self.tabs]

        self.menu = component.Component(Menu(self.menu_items),
                                        model='tab_renderer')
        self.menu.on_answer(self.select_tab)
        if selected_tab:
            index_tab = self.tabs.index(selected_tab)
        else:
            index_tab = 0
        self.select_tab(index_tab)
예제 #39
0
def render_user_admin_users_list(self, h, comp, *args):
    current_uid = security.get_user().uid
    protected_uids = [e.uid for e in UserRepository().protected_accounts if e]
    async = h.AsyncRenderer()
    with h.h1(class_="tab active big"):
        h << h.span(h.a(_(u'User management')))

    with h.div(class_='user-admin-item user_list'):
        h << h.h1(_(u'Manage users'))
        with h.div:
            # filters
            h << self.filter.render(h)

            with h.table(class_="inline-edit-list with-delete"
                         if self.with_delete else 'inline-edit-list'):
                with h.thead:
                    with h.tr:
                        with h.th:
                            h << h.span(_(u'Name'), class_='name')
                            h << h.span(_(u'Corporation'))
                            h << h.span(_(u'Direction'))
                            h << h.span(_(u'Service'))
                            h << h.span(_(u'Site'))
                            h << h.span(_(u'Facilitator'))
                            h << h.span(_(u'Enabled'), class_='enabled')
                            h << h.span("", class_="last")
                        if self.with_delete:
                            with h.th(class_='delete-column'):
                                h << h.span(_(u'Delete'))
                with h.tbody:
                    for ind, elt in enumerate(self.get_users_comp()[:self.batch_size]):
                        with h.tr(class_=['odd', 'even'][ind % 2]):
                            with h.td:
                                h << elt.render(async)
                            if self.with_delete:
                                with h.td(class_='delete-column'):
                                    if current_uid != elt().uid and elt().uid not in protected_uids:
                                        link = h.a(_('Delete')).action(lambda uid=elt().uid: self.delete(uid))
                                        msg = _('''User deletion can't be reverted, are you sure you want to delete the account %s ?''') % elt().fullname
                                        link.set('onclick', 'if (! confirm(%s)) return false;' % (json.dumps(msg)))
                                        h << link

            h << comp.render(h, 'batch')

    return h.root
예제 #40
0
    def __init__(self,
                 email_unique=True,
                 can_delete_users=False,
                 mobile_access=False):
        self.email_unique = email_unique
        self.mobile_access = mobile_access
        self.user_repository = UserRepository()

        self.create_user = component.Component(
            UserEditor(email_unique=self.email_unique,
                       mobile_access=self.mobile_access))
        self.create_user.on_answer(lambda v: self.create_user().reset_fields())
        event_management._register_listener(self, self.create_user())

        self.start = 0
        self.batch_size = 10
        self.radius = 3

        self.filter = component.Component(UserFilter())
        self.with_delete = can_delete_users
예제 #41
0
    def __init__(self, uid):
        super(FIEditor, self).__init__(None)
        self.uid = uid
        self.user_repository = UserRepository()

        # FI
        self.fi_uid = editor.Property(u'').validate(
            validators.non_empty_string)

        self.corporation_id = editor.Property(' - 1')
        self.direction_id = editor.Property(' - 1')
        self.service_id = editor.Property(' - 1')
        self.site_id = editor.Property(' - 1')
        self.subsite_id = editor.Property(' - 1')

        self.successor = editor.Property('').validate(
            validators.non_empty_string)

        self.filter = component.Component(UserFilter())
        if self.user:
            self.filter().initialize_from_user_organization(self.user)
예제 #42
0
    def commit(self):
        properties = ('show_progressing_ideas', 'show_tracked_ideas',
                      'show_challenges_ideas', 'domains_choice',
                      'keyword_filter', 'users_filter', 'period_filter')
        if not super(HomeSettingsEditor, self).is_validated(properties):
            return False

        domains = [
            domain for domain in self.domains
            if domain.id in self.domains_choice.value
        ]

        # write down the settings into the user's settings
        user = self.user
        home_settings = user.home_settings
        home_settings.show_progressing_ideas = self.show_progressing_ideas.value
        home_settings.show_tracked_ideas = self.show_tracked_ideas.value
        home_settings.show_challenges_ideas = self.show_challenges_ideas.value
        home_settings.domains = domains
        home_settings.keyword_filter = self.keyword_filter.value
        home_settings.period_filter = self.period_filter.value

        users_filter = [
            UserRepository().get_by_email(email.strip())
            for email in self.users_filter.value.split(',') if email.strip()
        ]

        for followed in set(users_filter) - set(
            [u for u in home_settings.users_filter]):
            mail_notification.send('mail-followed-user-notify.html',
                                   to=followed,
                                   comment_author=user)
            # add entry in timeline
            user.add_timeline_user(followed)

        home_settings.users_filter = users_filter

        return True
예제 #43
0
 def create_user_box(user_uids, title):
     query = lambda: UserRepository().get_by_uids(user_uids)
     pager = UserPager(self.parent, query)
     return PagerBox(pager,
                     title='Users',
                     ok_button=_(u'Back to the dashboard'))
예제 #44
0
 def __init__(self, parent, user):
     event_management._register_listener(parent, self)
     self.uid = user if is_string(user) else user.uid
     self.user_repository = UserRepository()
     self.pager = None
예제 #45
0
class StatisticsService(Unpicklable):
    """
    Service that compute statistics
    """

    def __init__(self):
        from eureka.domain.repositories import (
            CommentRepository, IdeaRepository,
            UserRepository, VoteIdeaRepository
        )
        self.user_repository = UserRepository()
        self.idea_repository = IdeaRepository()
        self.vote_idea_repository = VoteIdeaRepository()
        self.comment_repository = CommentRepository()

    @cached
    def _active_users(self):
        # Users enabled and who have logged in at least once
        return set(self.user_repository.get_active())

    @cached
    def _votes(self):
        return set(self.vote_idea_repository.get_all())

    @cached
    def _votes_by_challenge(self):
        votes_by_challenge = collections.defaultdict(set)
        for k, v in itertools.groupby(
            self._votes(),
                lambda v: v.idea.challenge):
            votes_by_challenge[k].update(set(v))

        return votes_by_challenge

    @cached
    def _comments(self):
        return set(self.comment_repository.get_all())

    @cached
    def _comments_by_challenge(self):
        comments_by_challenge = collections.defaultdict(set)
        for k, v in itertools.groupby(
                self._comments(), lambda c: c.idea.challenge):
            comments_by_challenge[k].update(set(v))
        return comments_by_challenge

    @cached
    def _ideas(self):
        return set(self.idea_repository.get_published_ideas())

    @cached
    def _ideas_by_challenge(self):
        ideas_by_challenge = collections.defaultdict(set)
        for i in self._ideas():
            ideas_by_challenge[i.challenge].add(i)
        return ideas_by_challenge

    def get_users_statistics_on_connections(self, users, after_date=None):
        intersection = users.intersection(self._active_users())
        if after_date:
            return len([u for u in intersection
                        if u.last_connection_date > after_date])
        else:
            return len(intersection)

    def get_users_statistics_on_ideas(self, users, after_date=None,
                                      challenge=NO_FILTER):
        ideas = (
            self._ideas_by_challenge()[challenge]
            if challenge is not NO_FILTER
            else self._ideas()
        )
        ideas = set(i for i in ideas if not set(i.authors).isdisjoint(users))
        if after_date:
            ideas = [
                idea for idea in ideas
                if idea.wf_context.publication_date
                and idea.wf_context.publication_date > after_date
            ]
        unique_authors = set(
            author for idea in ideas
            for author in idea.authors
            if author in users
        )

        return len(ideas), len(unique_authors)

    def get_users_statistics_on_votes(self, users, after_date=None,
                                      challenge=NO_FILTER):
        votes = (
            self._votes_by_challenge()[challenge]
            if challenge is not NO_FILTER
            else self._votes()
        )
        votes = set(v for v in votes if v.user in users)
        if after_date:
            votes = set(
                v for v in votes
                if v.timestamp and v.timestamp > after_date
            )
        unique_voters = set(vote.user for vote in votes)

        return len(votes), len(unique_voters)

    def get_users_statistics_on_comments(self, users, after_date=None,
                                         challenge=NO_FILTER):
        comments = (
            self._comments_by_challenge()[challenge]
            if challenge is not NO_FILTER
            else self._comments()
        )
        if after_date:
            comments = set(
                c for c in comments
                if c.submission_date and c.submission_date > after_date
            )
        comments = set(c for c in comments if c.created_by in users)
        unique_commentators = set(comment.created_by for comment in comments)
        return len(comments), len(unique_commentators)

    def get_users_statistics(self, users, after_date=None,
                             challenge=NO_FILTER):
        """
        Compute various statistics for a given group of users,
        returns an instance of UsersStatistics
        """
        users = set(users)
        # first connections
        nb_connected_users = self.get_users_statistics_on_connections(
            users, after_date
        )
        # ideas
        total_ideas, nb_authors = self.get_users_statistics_on_ideas(
            users, after_date, challenge
        )
        # votes
        total_votes, nb_voters = self.get_users_statistics_on_votes(
            users, after_date, challenge
        )
        # comments
        total_comments, nb_commentators = (
            self.get_users_statistics_on_comments(users, after_date, challenge)
        )

        return UsersStatistics(
            nb_connected=nb_connected_users,
            total_ideas=total_ideas,
            nb_authors=nb_authors,
            total_votes=total_votes,
            nb_voters=nb_voters,
            total_comments=total_comments,
            nb_commentators=nb_commentators,
        )

    def get_users_points_statistics(self, users):
        """Compute statistics on users points"""
        statistics = {}
        users_status_levels = [
            (user, user.status_level_label)
            for user in users if user
        ]
        for user, level in users_status_levels:
            statistics.setdefault(level, []).append(user)

        return statistics
예제 #46
0
class ProfileBox(object):
    """Show profile pages in a profile box"""
    def __init__(self, parent, user, selected_tab=None, online_shop=None):
        self.parent = parent
        event_management._register_listener(parent, self)
        self.uid = user if is_string(user) else user.uid
        self.user_repository = UserRepository()
        self.user_comp = User(parent, self.uid)
        self.tabs = self._create_tabs()
        selected_tab = selected_tab if selected_tab in self.tabs else 'profile'
        self.selected_tab = var.Var(selected_tab)

        # inner components displayed in the tabs or the header
        # FIXME: all these should be wrapped into a component.Component
        self.fi_editor = UserFIEditor(self.uid)
        event_management._register_listener(self, self.fi_editor)
        self.avatar_editor = AvatarEditor(self.uid)
        event_management._register_listener(self, self.avatar_editor)
        self.password_editor = PasswordEditor(self.user)
        event_management._register_listener(self, self.password_editor)
        self.profile_editor = ProfileEditor(self.user)
        event_management._register_listener(self, self.profile_editor)
        self.settings_editor = component.Component(SettingsEditor(self.user))
        event_management._register_listener(self, self.settings_editor())
        self.idea_pager = self._create_pager()
        # FIXME: the pager should not depend on the parent
        # event_management._register_listener(self, self.idea_pager)
        self.online_shop = online_shop(self)

        self.tab_labels = {
            'profile': _("My Profile") if self.is_mine else _("Her Profile"),
            'settings': _("My Settings") if self.is_mine else _("Her Settings"),
            'tracked_ideas': (_("My Tracked Ideas") if self.is_mine else _("Her Tracked Ideas")) + " (%d)" % self.new_events_count(),
            'ideas': (_("My Ideas") if self.is_mine else _("Her Ideas")) + " (%d)" % self.ideas_count,
            'points': (_("My Points") if self.is_mine else _("Her Points")) + " (%d)" % self.user.acquired_points,
            # 'rank': self.user.status_level_label,
        }

        self.menu_items = [(self.tab_labels[name], name, None, '', None) for name in self.tabs]

        self.menu = component.Component(Menu(self.menu_items),
                                        model='tab_renderer')
        self.menu.on_answer(self.select_tab)
        if selected_tab:
            index_tab = self.tabs.index(selected_tab)
        else:
            index_tab = 0
        self.select_tab(index_tab)

    def select_tab(self, value):
        self.selected_tab(self.menu_items[value][1])
        self.menu().selected(value)

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    @property
    def is_mine(self):
        current_user = security.get_user()
        return current_user and (current_user.uid == self.uid)

    def _create_tabs(self):
        can_edit = security.has_permissions('edit_user', self)
        can_view_tracked_ideas = security.has_permissions('view_tracked_ideas', self)

        menu_items = (
            ('profile', True),
            ('settings', can_edit),
            ('tracked_ideas', can_view_tracked_ideas),
            ('ideas', True),
            ('points', True),
            # ('rank', True),
        )
        return [name for name, enabled in menu_items if enabled]

    def profile_url(self, uid=None):
        return get_url_service().expand_url(['profile', (uid or self.uid)])

    def view_profile(self, uid=None):
        # FIXME: fix the mess with profile-related events
        event_management._emit_signal(self, "VIEW_USER_PROFILE", user_uid=(uid or self.uid))

    def show_status_level_help(self):
        event_management._emit_signal(self, "VIEW_HELP", section='faq_1_7bis')

    # roles related methods
    @property
    def privileged_roles(self):
        relevant_roles = (RoleType.DSIG, RoleType.Developer, RoleType.Facilitator)
        return [unicode(RoleLabels[role]) for role in relevant_roles if self.user.has_role(role)]

    # ideas related methods
    def _create_pager(self):
        # FIXME: late import to avoid circular dependencies problem

        idea_pager = IdeaPager(self, lambda: self._ideas)
        idea_pager.change_transform("user")
        idea_pager.change_order("publication_date_desc")
        idea_pager = InfinitePager(component.Component(idea_pager, model='ideas-list'))

        return idea_pager

    @property
    def _ideas(self):
        if security.has_permissions('view_unpublished_ideas', self):
            return get_all_user_ideas(self.uid)
        else:
            return get_published_user_ideas(self.uid)

    @property
    def ideas_count(self):
        return self._ideas.count()

    # events related methods
    def events(self, days_ago=30):
        date = datetime.today() - timedelta(days_ago)
        return sorted(self.user.visible_events(date), key=operator.attrgetter('date'), reverse=True)

    def new_events_count(self, days_ago=30):
        date = datetime.today() - timedelta(days_ago)
        return len(set([e.idea.id for e in self.user.unread_events(date)]))

    def hide_event(self, event_id):
        self.user.hide_event(event_id)
        flashmessage.set_flash(_(u'Event removed'))

    def read_event(self, event_id):
        event = self.user.read_event(event_id)
        self.view_idea(event.idea.id)

    def read_all_events(self):
        self.user.read_all_events()

    # tracked ideas related methods
    def tracked_ideas(self):
        return self.user.tracked_ideas

    def view_idea(self, idea_id):
        event_management._emit_signal(self, "VIEW_IDEA", mode='view', idea_id=idea_id)

    def remove_tracked_idea(self, idea_id):
        self.user.untrack_idea(idea_id)
        flashmessage.set_flash(_(u'Idea removed from tracking'))

    def remove_point(self, point_id):
        PointData.get(point_id).delete()
        flashmessage.set_flash(_(u"Points deleted"))
예제 #47
0
class DIEditor(editor.Editor):
    def __init__(self, uid):
        super(DIEditor, self).__init__(None)
        self.uid = uid
        self.user_repository = UserRepository()
        self.domains = editor.Property(
            [str(elt.id) for elt in self.get_domains()])
        self.successor = editor.Property('').validate(
            validators.non_empty_string)
        self.di_business_area = editor.Property(
            self.user.di_business_area or '').validate(
            validators.non_empty_string)

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    def get_domains(self):
        return DomainRepository().get_by_di(self.user)

    def get_all_domains(self):
        return DomainRepository().get_all()

    def get_di_users(self):
        return self.user_repository.get_developers()

    def clear_domains(self):
        self.domains([])

    def update_domains(self):
        if not super(DIEditor, self).commit((), ('domains',)):
            return False

        user = self.user
        if user:
            domain_ids = [int(elt) for elt in self.domains.value]
            # FIXME: use the domain repository
            user.managed_domains = DomainData.query.filter(
                DomainData.id.in_(domain_ids)).all()

        flashmessage.set_flash(_(u'Domains changed'))

        return True

    def clear_successor(self):
        self.successor('')

    def idea_url(self, idea):
        return get_url_service().expand_url(['idea', idea.id])

    def replace_developer(self):
        if not super(DIEditor, self).commit((), ('successor',)):
            return False

        # prepare the content of the confirmation email
        assigned_ideas = IdeaRepository().get_assigned_to_developer(self.user)
        comment = '\n'.join(_('%(title)s: %(url)s') % dict(title=idea.title,
                                                           url=self.idea_url(
                                                               idea))
                            for idea in assigned_ideas)

        # transfer the DI responsibilities to the new user
        new_developer = self.user_repository.get_by_uid(self.successor())
        self.user.transfer_responsibilities(RoleType.Developer, new_developer)

        # send the confirmation email
        mail_notification.send('mail-developer-replaced.html',
                               to=new_developer,
                               previous_di=self.user,
                               comment=comment)

        flashmessage.set_flash(_(u'Expert replaced'))

        return True

    def update_di_business_area(self):
        if not super(DIEditor, self).commit((), ('di_business_area',)):
            return False

        self.user.di_business_area = self.di_business_area.value

        flashmessage.set_flash(_(u"Expert's business area updated"))

        return True
예제 #48
0
 def user(self):
     return UserRepository().get_by_uid(self.uid)
예제 #49
0
 def __init__(self):
     self.user_repository = UserRepository()
     self.idea_repository = IdeaRepository()
     self.vote_idea_repository = VoteIdeaRepository()
     self.comment_repository = CommentRepository()
예제 #50
0
class UserLineEditor(editor.Editor):
    def __init__(self, uid, email_unique=True, mobile_access=False):
        super(UserLineEditor, self).__init__(None)

        self.email_unique = email_unique
        self.mobile_access = mobile_access
        self.uid = uid
        self.user_repository = UserRepository()
        self.reset()

    def reset(self):
        user = self.user_repository.get_by_uid(self.uid)
        self.orig_corp_id = user.corporation_id or -1L
        self.orig_dir_id = user.direction_id or -1L
        self.orig_service_id = user.service_id or -1L
        self.orig_site_id = user.site_id or -1L
        self.orig_subsite_id = user.subsite_id or -1L
        self.orig_enabled = user.enabled
        self.orig_fi_uid = (user.fi_uid or u'')
        self.corporation_id = editor.Property(self.orig_corp_id)
        self.direction_id = editor.Property(self.orig_dir_id)
        self.service_id = editor.Property(self.orig_service_id)
        self.site_id = editor.Property(self.orig_site_id)
        self.subsite_id = editor.Property(self.orig_subsite_id)
        self.enabled = editor.Property(user.enabled)
        self.fi_uid = editor.Property(user.fi_uid or u'').validate(
            validators.non_empty_string)
        self.firstname = user.firstname
        self.lastname = user.lastname

    @property
    def profile_imported(self):
        return getattr(self.user_repository.get_by_uid(self.uid), 'imported', False) if self.uid else False

    @property
    def fullname(self):
        return u' '.join((self.firstname, self.lastname))

    def need_update(self):
        new_corporation_id = long(self.corporation_id()) if self.corporation_id() else None
        if self.orig_corp_id != new_corporation_id:
            return True
        new_direction_id = long(self.direction_id()) if self.direction_id() else None
        if new_direction_id != self.orig_dir_id:
            return True
        new_service_id = long(self.service_id()) if self.service_id() else None
        if new_service_id != self.orig_service_id:
            return True
        new_site_id = long(self.site_id()) if self.site_id() else None
        if new_site_id != self.orig_site_id:
            return True
        new_subsite_id = long(self.subsite_id()) if self.subsite_id() else None
        if new_subsite_id != self.orig_subsite_id:
            return True
        return self.orig_enabled != bool(self.enabled()) or self.orig_fi_uid != unicode(self.fi_uid())

    def change_corp(self):
        self.direction_id('-1')
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_dir(self):
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_service(self):
        self.site_id('-1')
        self.subsite_id('-1')

    def change_site(self):
        self.subsite_id('-1')

    def update_user(self):
        # checks the other fields and updates data
        if super(UserLineEditor, self).commit((), ('corporation_id', 'direction_id', 'site_id', 'service_id', 'fi_uid', 'enabled')):

            # FIXME: use the OrganizationRepository
            get_orga = lambda id: OrganizationData.get(
                id) if id != -1 else None

            u = self.user_repository.get_by_uid(self.uid)
            u.corporation = get_orga(self.corporation_id())
            u.direction = get_orga(self.direction_id())
            u.service = get_orga(self.service_id())
            u.site = get_orga(self.site_id())
            u.subsite = get_orga(self.subsite_id())
            u.enabled = self.enabled()
            u.fi_uid = self.fi_uid()

            session.flush()

            self.orig_corp_id = u.corporation_id or -1L
            self.orig_dir_id = u.direction_id or -1L
            self.orig_service_id = u.service_id or -1L
            self.orig_site_id = u.site_id or -1L
            self.orig_subsite_id = u.subsite_id or -1L
            self.orig_enabled = u.enabled
            self.orig_fi_uid = u.fi_uid

            flashmessage.set_flash(_(u'User modified'))

            return True

    def get_fi_name(self):
        ci = self.user_repository.get_by_uid(self.fi_uid.value)
        if ci:
            return ci.fullname
        return u""

    # Refactor

    def get_corporations(self):
        return OrganizationData.get_corporations()

    def get_directions(self):
        return OrganizationData.get_directions(parent_id=self.corporation_id())

    def get_services(self):
        return OrganizationData.get_services(parent_id=self.direction_id())

    def get_sites(self):
        return OrganizationData.get_sites(parent_id=self.service_id())

    def get_subsites(self):
        return OrganizationData.get_subsites(parent_id=self.site_id())

    def edit_user(self, comp):
        message = comp.call(UserEditor(self.uid, email_unique=self.email_unique, mobile_access=self.mobile_access))
        self.reset()
        if message:
            flashmessage.set_flash(message)

    def get_facilitators(self):
        return UserData.get_facilitators()

    def delete(self):
        UserRepository().delete(self.uid)
예제 #51
0
class TestUsers(DatabaseEnabledTestCase):
    def setUp(self):
        super(TestUsers, self).setUp()
        self.user_repository = UserRepository()

    def test_unpicklable(self):
        user = create_user(uid=u'jdoe', firstname=u'John', lastname=u'Doe')
        self.assertRaises(UnpicklableError, lambda: pickle.dumps(user))

    def test_creation(self):
        uid = u'jdoe'
        firstname = u'John'
        lastname = u'Doe'
        create_user(uid=uid, firstname=firstname, lastname=lastname)
        session.flush()
        user = self.user_repository.get_by_uid(uid)
        self.assertEquals(user.uid, uid)
        self.assertEquals(user.firstname, firstname)
        self.assertEquals(user.lastname, lastname)
        self.assert_(user.enabled)

    def test_creation_not_enabled(self):
        uid = u'login'
        create_user(uid=uid, enabled=False)
        session.flush()
        user = self.user_repository.get_by_uid(uid)
        self.assert_(not user.enabled)

    def test_set_firstname_and_lastname(self):
        uid = u'jdoe'
        user = create_user(uid=uid)
        firstname = u'John'
        lastname = u'Doe'
        user.firstname = firstname
        user.lastname = lastname
        session.flush()
        user = self.user_repository.get_by_uid(uid)
        self.assertEquals(user.firstname, firstname)
        self.assertEquals(user.lastname, lastname)

    def test_enabled(self):
        uid = u'jdoe'
        create_user(uid=uid)
        session.flush()
        user = self.user_repository.get_by_uid(uid)
        self.assert_(user.enabled)  # this is what we want most of the time
        user.enabled = False
        session.flush()
        user = self.user_repository.get_by_uid(uid)
        self.assert_(not user.enabled)

    def test_by_uid(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
        )
        self.assert_(
            self.user_repository.get_by_uid(user.uid) is not None)
        self.assert_(
            self.user_repository.get_by_uid(user.uid + u'XXX') is None)

    def test_by_email(self):
        email = u'*****@*****.**'
        create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            email=email,
        )
        user = self.user_repository.get_by_email(email)
        self.assert_(user is not None)
        self.assertEquals(email, user.email)
        self.assert_(
            self.user_repository.get_by_email(user.email + u'XXX') is None)

    def test_store_password(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            password=u'password',
        )
        self.assertEqual(user.password, user.encrypt_password(u'password'))
        self.assert_(not user.should_change_password())

    def test_validate_password(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            password=u'password',
        )
        self.assert_(user.validate_password('newpass') is None)
        self.assert_(isinstance(user.validate_password('a'), basestring))

    def test_change_password_success(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            password=u'password'
        )
        new_password = u'newpass'
        user.change_password(new_password)
        session.flush()
        self.assertEqual(user.password, user.encrypt_password(new_password))

    def test_change_password_failure(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            password=u'password',
        )
        new_password = u'a'
        with self.assertRaises(ValueError):
            user.change_password(new_password)

    def test_reset_password(self):
        user = create_user(
            uid=u'jdoe',
            firstname=u'John',
            lastname=u'Doe',
            password=u'password',
        )
        new_password = user.reset_password()
        self.assertEqual(user.password, user.encrypt_password(new_password))
        self.assert_(user.should_change_password())

    def test_set_fi(self):
        user = create_user()
        fi = create_user()
        user.fi = fi
        self.assertEquals(fi, user.fi)

    def test_add_role(self):
        user = create_user()
        user.add_role(RoleType.Facilitator)
        self.assert_(user.has_role(RoleType.Facilitator))

    def test_remove_missing_role(self):
        user = create_user()
        user.add_role(RoleType.Facilitator)
        user.remove_role(RoleType.Developer)
        self.assert_(user.has_role(RoleType.Facilitator))
        self.assert_(not user.has_role(RoleType.Developer))

    def test_deleting_a_user_also_remove_her_roles(self):
        user = create_user()
        user.add_role(RoleType.Facilitator)
        session.flush()
        user_uid = user.uid
        user.delete()
        session.flush()
        facilitators_uids = [
            u.uid for u in self.user_repository.get_facilitators()
        ]
        self.assertFalse(user_uid in facilitators_uids)

    def test_remove_existing_role(self):
        user = create_user()
        user.add_role(RoleType.Facilitator)
        session.flush()
        user.remove_role(RoleType.Facilitator)
        self.assert_(not user.has_role(RoleType.Facilitator))
        session.flush()
        facilitators = self.user_repository.get_facilitators()
        self.assert_(user not in facilitators)

    def test_get_by_role(self):
        user = create_user()
        create_user()
        user.add_role(RoleType.Facilitator)
        session.flush()
        facilitators = self.user_repository.get_facilitators()
        self.assertTrue(user in facilitators)

    def create_photo(self, size=100):
        out = StringIO()
        image = Image.new("RGB", (size, size))
        image.save(out, "PNG")
        return out.getvalue()

    def test_photo(self):
        user = create_user()
        photo = self.create_photo(50)
        user.photo = photo
        session.flush()
        self.assertTrue(user.photo is not None)
        user.photo = None
        self.assertTrue(user.photo is None)
예제 #52
0
 def __init__(self):
     self.user_repository = UserRepository()
예제 #53
0
class UserEditor(editor.Editor):

    def __init__(self, uid=None, email_unique=True, mobile_access=False):
        """User's informations editor
        In:
            - ``uid`` -- the uid of the user to edit (if we are in edit mode)
            - ``email_unique`` -- do we have to check for the email uniqueness or not (default yes)
        """
        super(UserEditor, self).__init__(None)
        self.assignable_roles = [RoleType.Facilitator, RoleType.Developer]
        if mobile_access:
            self.assignable_roles.append(RoleType.MobileAccess)
        self.email_unique = email_unique
        self.uid = uid
        self.user_repository = UserRepository()
        self.reset_fields()

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    @property
    def profile_imported(self):
        return getattr(self.user, 'imported', False)

    @property
    def profile_url(self):
        return get_url_service().expand_url(['profile', self.uid])

    def view_profile(self):
        event_management._emit_signal(self, "VIEW_USER_PROFILE",
                                      user_uid=self.uid)

    @property
    def creation_mode(self):
        return self.uid is None

    def pre_action(self):
        self.clear_roles()

    def validate_login(self, value):
        if self.creation_mode or value != self.user.uid:
            value = validators.unused_uid(value, True)
        return value

    def validate_email(self, value):
        if not self.email_unique:  # We just check that a non empty email address has been supplied
            value = validators.non_empty_string(value)
        elif self.creation_mode or value != self.user.email:
            value = validators.unused_email(value, True)
        return value

    def reset_fields(self):
        user = self.user

        uid = user.uid if user else u''
        email = user.email if user else u''
        firstname = user.firstname if user else u''
        lastname = user.lastname if user else u''
        fi_uid = user.fi_uid if user else u''
        roles = [role for role in self.assignable_roles if
                 user.has_role(role)] if user else []
        work_phone = (user.work_phone or u'') if user else u''
        mobile_phone = (user.mobile_phone or u'') if user else u''
        position = user.position if user else u''
        corporation_id = (user.corporation_id or u'-1') if user else u'-1'
        direction_id = (user.direction_id or u'-1') if user else u'-1'
        service_id = (user.service_id or u'-1') if user else u'-1'
        site_id = (user.site_id or u'-1') if user else u'-1'
        subsite_id = (user.subsite_id or u'-1') if user else u'-1'
        enabled = user.enabled if user else True
        incorporated = user.incorporated if user else False

        self.login = editor.Property(uid).validate(self.validate_login)
        self.email = editor.Property(email).validate(self.validate_email)
        self.firstname = editor.Property(firstname).validate(
            validators.non_empty_string)
        self.lastname = editor.Property(lastname).validate(
            validators.non_empty_string)
        self.fi_uid = editor.Property(fi_uid).validate(
            validators.non_empty_string)
        self.roles = editor.Property(roles)
        self.work_phone = editor.Property(work_phone)
        self.mobile_phone = editor.Property(mobile_phone)
        self.position = editor.Property(position)
        self.corporation_id = editor.Property(corporation_id)
        self.direction_id = editor.Property(direction_id)
        self.service_id = editor.Property(service_id)
        self.site_id = editor.Property(site_id)
        self.subsite_id = editor.Property(subsite_id)
        self.enabled = editor.Property(enabled)
        self.incorporated = editor.Property(incorporated)

    def clear_roles(self):
        self.roles([])

    def add_role(self, role):
        self.roles().append(role)

    def change_corp(self):
        self.direction_id('-1')
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_dir(self):
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_service(self):
        self.site_id('-1')
        self.subsite_id('-1')

    def change_site(self):
        self.subsite_id('-1')

    def get_corporations(self):
        return OrganizationData.get_corporations()

    def get_directions(self):
        return OrganizationData.get_directions(parent_id=self.corporation_id())

    def get_services(self):
        return OrganizationData.get_services(parent_id=self.direction_id())

    def get_sites(self):
        return OrganizationData.get_sites(parent_id=self.service_id())

    def get_subsites(self):
        return OrganizationData.get_subsites(parent_id=self.site_id())

    def get_facilitators(self):
        return UserData.get_facilitators()

    def commit(self):
        if not super(UserEditor, self).commit(
                (),
                ('login', 'email', 'roles', 'fi_uid', 'work_phone',
                 'mobile_phone', 'firstname', 'lastname', 'position',
                 'corporation_id', 'direction_id', 'site_id', 'service_id')):
            return False

        # FIXME: use the OrganizationRepository
        get_organization = lambda id: OrganizationData.get(
            id) if id != -1 else None

        corporation = get_organization(self.corporation_id.value)
        direction = get_organization(self.direction_id.value)
        service = get_organization(self.service_id.value)
        site = get_organization(self.site_id.value)
        subsite = get_organization(self.subsite_id.value)
        facilitator = self.user_repository.get_by_uid(self.fi_uid.value)

        # create or update the user
        updates = dict(
            email=self.email.value,
            firstname=self.firstname.value,
            lastname=self.lastname.value,
            enabled=self.enabled.value,
            position=self.position.value,
            corporation=corporation,
            direction=direction,
            service=service,
            site=site,
            incorporated=self.incorporated.value,
            work_phone=self.work_phone.value,
            mobile_phone=self.mobile_phone.value,
            fi=facilitator,
            subsite=subsite,
        )

        if self.user:
            u = self.user
            u.set(**updates)
        else:
            u = self.user_repository.create(uid=self.login.value, **updates)
            password = u.reset_password()
            u.send_welcome_email(password)

        # roles
        for role in self.assignable_roles:
            if role in self.roles():
                u.add_role(role)
            else:
                u.remove_role(role)

        return True
예제 #54
0
class StatisticsService(Unpicklable):
    """
    Service that compute statistics
    """
    def __init__(self):
        from eureka.domain.repositories import (CommentRepository,
                                                IdeaRepository, UserRepository,
                                                VoteIdeaRepository)
        self.user_repository = UserRepository()
        self.idea_repository = IdeaRepository()
        self.vote_idea_repository = VoteIdeaRepository()
        self.comment_repository = CommentRepository()

    @cached
    def _active_users(self):
        # Users enabled and who have logged in at least once
        return set(self.user_repository.get_active())

    @cached
    def _votes(self):
        return set(self.vote_idea_repository.get_all())

    @cached
    def _votes_by_challenge(self):
        votes_by_challenge = collections.defaultdict(set)
        for k, v in itertools.groupby(self._votes(),
                                      lambda v: v.idea.challenge):
            votes_by_challenge[k].update(set(v))

        return votes_by_challenge

    @cached
    def _comments(self):
        return set(self.comment_repository.get_all())

    @cached
    def _comments_by_challenge(self):
        comments_by_challenge = collections.defaultdict(set)
        for k, v in itertools.groupby(self._comments(),
                                      lambda c: c.idea.challenge):
            comments_by_challenge[k].update(set(v))
        return comments_by_challenge

    @cached
    def _ideas(self):
        return set(self.idea_repository.get_published_ideas())

    @cached
    def _ideas_by_challenge(self):
        ideas_by_challenge = collections.defaultdict(set)
        for i in self._ideas():
            ideas_by_challenge[i.challenge].add(i)
        return ideas_by_challenge

    def get_users_statistics_on_connections(self, users, after_date=None):
        intersection = users.intersection(self._active_users())
        if after_date:
            return len([
                u for u in intersection if u.last_connection_date > after_date
            ])
        else:
            return len(intersection)

    def get_users_statistics_on_ideas(self,
                                      users,
                                      after_date=None,
                                      challenge=NO_FILTER):
        ideas = (self._ideas_by_challenge()[challenge]
                 if challenge is not NO_FILTER else self._ideas())
        ideas = set(i for i in ideas if not set(i.authors).isdisjoint(users))
        if after_date:
            ideas = [
                idea for idea in ideas if idea.wf_context.publication_date
                and idea.wf_context.publication_date > after_date
            ]
        unique_authors = set(author for idea in ideas
                             for author in idea.authors if author in users)

        return len(ideas), len(unique_authors)

    def get_users_statistics_on_votes(self,
                                      users,
                                      after_date=None,
                                      challenge=NO_FILTER):
        votes = (self._votes_by_challenge()[challenge]
                 if challenge is not NO_FILTER else self._votes())
        votes = set(v for v in votes if v.user in users)
        if after_date:
            votes = set(v for v in votes
                        if v.timestamp and v.timestamp > after_date)
        unique_voters = set(vote.user for vote in votes)

        return len(votes), len(unique_voters)

    def get_users_statistics_on_comments(self,
                                         users,
                                         after_date=None,
                                         challenge=NO_FILTER):
        comments = (self._comments_by_challenge()[challenge]
                    if challenge is not NO_FILTER else self._comments())
        if after_date:
            comments = set(
                c for c in comments
                if c.submission_date and c.submission_date > after_date)
        comments = set(c for c in comments if c.created_by in users)
        unique_commentators = set(comment.created_by for comment in comments)
        return len(comments), len(unique_commentators)

    def get_users_statistics(self,
                             users,
                             after_date=None,
                             challenge=NO_FILTER):
        """
        Compute various statistics for a given group of users,
        returns an instance of UsersStatistics
        """
        users = set(users)
        # first connections
        nb_connected_users = self.get_users_statistics_on_connections(
            users, after_date)
        # ideas
        total_ideas, nb_authors = self.get_users_statistics_on_ideas(
            users, after_date, challenge)
        # votes
        total_votes, nb_voters = self.get_users_statistics_on_votes(
            users, after_date, challenge)
        # comments
        total_comments, nb_commentators = (
            self.get_users_statistics_on_comments(users, after_date,
                                                  challenge))

        return UsersStatistics(
            nb_connected=nb_connected_users,
            total_ideas=total_ideas,
            nb_authors=nb_authors,
            total_votes=total_votes,
            nb_voters=nb_voters,
            total_comments=total_comments,
            nb_commentators=nb_commentators,
        )

    def get_users_points_statistics(self, users):
        """Compute statistics on users points"""
        statistics = {}
        users_status_levels = [(user, user.status_level_label)
                               for user in users if user]
        for user, level in users_status_levels:
            statistics.setdefault(level, []).append(user)

        return statistics
예제 #55
0
class FIEditor(editor.Editor):
    def __init__(self, uid):
        super(FIEditor, self).__init__(None)
        self.uid = uid
        self.user_repository = UserRepository()

        # FI
        self.fi_uid = editor.Property(u'').validate(
            validators.non_empty_string)

        self.corporation_id = editor.Property(' - 1')
        self.direction_id = editor.Property(' - 1')
        self.service_id = editor.Property(' - 1')
        self.site_id = editor.Property(' - 1')
        self.subsite_id = editor.Property(' - 1')

        self.successor = editor.Property('').validate(
            validators.non_empty_string)

        self.filter = component.Component(UserFilter())
        if self.user:
            self.filter().initialize_from_user_organization(self.user)

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)

    def get_fi_users(self):
        query = self.user_repository.get_facilitators()
        return self.filter().apply(query)

    # Refactor

    def change_corp(self):
        self.direction_id('-1')
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_dir(self):
        self.service_id('-1')
        self.site_id('-1')
        self.subsite_id('-1')

    def change_service(self):
        self.site_id('-1')
        self.subsite_id('-1')

    def change_site(self):
        self.subsite_id('-1')

    def get_corporations(self):
        return OrganizationData.get_corporations()

    def get_directions(self):
        return OrganizationData.get_directions(parent_id=self.corporation_id())

    def get_services(self):
        return OrganizationData.get_services(parent_id=self.direction_id())

    def get_sites(self):
        return OrganizationData.get_sites(parent_id=self.service_id())

    def get_subsites(self):
        return OrganizationData.get_subsites(parent_id=self.site_id())

    def clear_successor(self):
        self.successor('')

    def replace_facilitator(self):
        if not super(FIEditor, self).commit((), ('successor',)):
            return False

        # transfer the FI responsibilities to the new user
        new_facilitator = self.user_repository.get_by_uid(self.successor())
        self.user.transfer_responsibilities(RoleType.Facilitator,
                                            new_facilitator)

        flashmessage.set_flash(_(u'Facilitator replaced'))

        return True

    def _get_organization_label(self, org_id):
        if org_id == -1:
            return None
            # FIXME: use the OrganizationRepository instead
        return OrganizationData.get(org_id).label

    def add_entity(self):
        if not super(FIEditor, self).commit(
                (),
                ('corporation_id', 'direction_id', 'service_id', 'site_id')):
            return False

        corporation = self._get_organization_label(long(self.corporation_id()))
        direction = self._get_organization_label(long(self.direction_id()))
        service = self._get_organization_label(long(self.service_id()))
        site = self._get_organization_label(long(self.site_id()))
        subsite = self._get_organization_label(long(self.subsite_id()))

        users = self.user_repository.get_by_organization(corporation,
                                                         direction,
                                                         service,
                                                         site,
                                                         subsite,
                                                         True)

        for user in users:
            user.fi_uid = self.uid

        flashmessage.set_flash(_(u'Entity assigned to the facilitator'))

        return True
예제 #56
0
class User(object):
    def __init__(self, parent, user):
        event_management._register_listener(parent, self)
        self.uid = user if is_string(user) else user.uid
        self.user_repository = UserRepository()
        self.pager = None

    @property
    def user(self):
        return self.user_repository.get_by_uid(self.uid)  # the user represented by this block

    @property
    def _photo_filename(self):
        return photo_filename(self.uid, self.user.photo_date)

    def thumbnail_url(self, size):
        return get_url_service().expand_url(['profile-thumbnails', size, self._photo_filename])

    @property
    def photo_url(self):
        return get_url_service().expand_url(['profile-photo', self._photo_filename])

    @property
    def privileged_roles(self):
        relevant_roles = (RoleType.DSIG, RoleType.Developer, RoleType.Facilitator)
        return [unicode(RoleLabels[role]) for role in relevant_roles if self.user.has_role(role)]

    def profile_url(self, uid=None):
        return get_url_service().expand_url(['profile', (uid or self.uid)])

    def view_profile(self, uid=None):
        event_management._emit_signal(self, "VIEW_USER_PROFILE", user_uid=(uid or self.uid))

    def view_tracked_ideas(self, uid=None):
        event_management._emit_signal(self, "VIEW_USER_TRACKED_IDEAS", user_uid=(uid or self.uid))

    def view_basket(self, uid=None):
        event_management._emit_signal(self, "VIEW_USER_BASKET", user_uid=(uid or self.uid))

    def view_dsig_basket(self, uid=None):
        event_management._emit_signal(self, "VIEW_DSIG_BASKET", user_uid=(uid or self.uid))

    def view_di_basket(self, uid=None):
        event_management._emit_signal(self, "VIEW_DI_BASKET", user_uid=(uid or self.uid))

    def view_fi_basket(self, uid=None):
        event_management._emit_signal(self, "VIEW_FI_BASKET", user_uid=(uid or self.uid))

    def view_administration(self, uid=None):
        event_management._emit_signal(self, "VIEW_ADMINISTRATION")

    @property
    def _ideas(self):
        if security.has_permissions('view_unpublished_ideas', self):
            return get_all_user_ideas(self.uid)
        else:
            return get_published_user_ideas(self.uid)

    @property
    def ideas_count(self):
        return self._ideas.count()

    def get_idea_pager(self):
        # FIXME: late import to avoid circular dependencies problem

        if self.pager is None:

            idea_pager = IdeaPager(self, lambda: self._ideas)
            idea_pager.change_transform("user")
            idea_pager.change_order("publication_date_desc")
            self.pager = InfinitePager(component.Component(idea_pager, model='ideas-list'))
        return self.pager

    def get_tracked_idea_count(self):
        return len(self.get_tracked_ideas())

    def get_tracked_ideas(self):
        return self.user.tracked_ideas

    def remove_tracked_idea(self, idea_id):
        self.user.untrack_idea(idea_id)
        flashmessage.set_flash(_(u'Idea removed from tracking'))

    def events_history(self, days_ago=30):
        date = datetime.today() - timedelta(days_ago)
        return sorted(self.user.visible_events(date),
                      key=operator.attrgetter('date'), reverse=True)

    def new_events_count(self, days_ago=30):
        date = datetime.today() - timedelta(days_ago)
        return len(set([e.idea.id for e in self.user.unread_events(date)]))

    def remove_event(self, event_id):
        self.user.hide_event(event_id)
        flashmessage.set_flash(_(u'Event removed'))

    def read_event(self, event_id):
        event = self.user.read_event(event_id)
        self.view_idea(event.idea.id)

    def read_all_events(self):
        self.user.read_all_events()

    def get_fi_ideas_basket_count(self):
        return get_fi_process_ideas(self.uid)().count()

    def get_di_ideas_basket_count(self):
        return get_di_process_ideas(self.uid)().count()
예제 #57
0
 def setUp(self):
     super(TestUsers, self).setUp()
     self.user_repository = UserRepository()