Example #1
0
def unfollow(follower, followed, delay_commit=False):
    followed = get_member(followed)
    follower = get_member(follower)

    if not followed:
        raise action_error(_('unable to find followed'), code=404)
    if not follower:
        raise action_error(_('unable to find follower'), code=404)
    #if followed not in follower.following:
    # GregM: can unfollow to remove trusted invite
    if not follower.is_following(
            followed) and not follower.is_follow_trusted_inviter(followed):
        raise action_error(_('not currently following'), code=400)

    #follower.following.remove(followed)
    follow = Session.query(Follow).filter(
        Follow.member_id == followed.id).filter(
            Follow.follower_id == follower.id).one()
    Session.delete(follow)

    if not delay_commit:
        Session.commit()

    #invalidate_member(follower)
    #invalidate_member(followed)

    followed.send_notification(
        messages.follow_stop(member=follower, you=followed))

    return True
Example #2
0
def follower_distrust(followed, follower, delay_commit=False):
    followed = get_member(followed)
    follower = get_member(follower)

    if not followed:
        raise action_error(_('unable to find followed'), code=404)
    if not follower:
        raise action_error(_('unable to find follower'), code=404)
    if not follower.is_following(followed):
        raise action_error(_('not currently following'), code=400)

    follow = Session.query(Follow).filter(
        Follow.member_id == followed.id).filter(
            Follow.follower_id == follower.id).one()
    if not follow:
        raise action_error(_('member is not a follower'), code=404)
    if follow.type == 'trusted':
        follow.type = 'normal'
    elif follow.type == 'trusted_invite':
        raise action_error(_('follower still has pending invite'), code=400)
    elif follow.type == 'normal':
        raise action_error(_('follower was not trusted'), code=400)

    if not delay_commit:
        Session.commit()

    # invalidate_member(follower) # GregM: Needed?
    # invalidate_member(followed) # GregM: Needed?

    follower.send_notification(
        messages.follower_distrusted(member=followed, you=follower))

    return True
Example #3
0
def payment_member_remove(payment_account, member):
    member = get_member(member)
    if not member.payment_account == payment_account:
        return False
    member.payment_account = None
    Session.commit()
    return True
Example #4
0
def payment_member_add(payment_account, member):
    member = get_member(member)
    if member.payment_account:
        return False
    member.payment_account = payment_account
    Session.commit()
    return True
Example #5
0
def get_user_and_check_password(username, password):
    """
    Called by account controller and/or AuthKit valid_password to return a user from local db
    """
    try:
        q = Session.query(User).select_from(
            join(User, UserLogin, User.login_details))
        q = q.filter(User.id == make_username(username))
        q = q.filter(User.status == 'active')
        q = q.filter(UserLogin.type == 'password')
        q = q.filter(UserLogin.token == encode_plain_text_password(password))
        return q.one()
    except NoResultFound:
        # AllanC - Added fallback to search for email as some users get confised as to how to identify themselfs
        #          emails are not indexed? performance? using this should be safe as our username policy prohibits '@' and '.'
        try:
            q = Session.query(User).select_from(
                join(User, UserLogin, User.login_details))
            q = q.filter(User.email == username)
            q = q.filter(User.status == 'active')
            q = q.filter(UserLogin.type == 'password')
            q = q.filter(
                UserLogin.token == encode_plain_text_password(password))
            return q.one()
        except NoResultFound:
            return None
Example #6
0
def follower_invite_trusted(followed, follower, delay_commit=False):
    followed = get_member(followed)
    follower = get_member(follower)

    if not followed:
        raise action_error(_('unable to find followed'), code=404)
    if not follower:
        raise action_error(_('unable to find follower'), code=404)
    if follower == followed:
        raise action_error(_('may not follow yourself'), code=400)
    #if followed in follower.following:
    if follower.is_following(followed):
        raise action_error(_('already following'), code=400)
    if follower.is_follow_trusted_inviter(followed):
        raise action_error(_('already invited to follow as trusted'))

    follow = Follow()
    follow.member = followed
    follow.follower = follower
    follow.type = 'trusted_invite'
    Session.add(follow)

    if not delay_commit:
        Session.commit()

    #invalidate_member(follower)
    #invalidate_member(followed)

    follower.send_notification(
        messages.follow_invite_trusted(member=followed, you=follower))

    return True
Example #7
0
def get_membership_tree(group, member, iter = 0):
    if iter > 5:
        return None
    member = get_member(member)
    group  = get_group(group)

    if not (member and group):
        return None

    try:
        return Session.query(GroupMembership).filter(
            and_(
                GroupMembership.group_id  == group.id,
                GroupMembership.member_id == member.id
            )
        ).one()
    except NoResultFound:
        try:
            groups = Session.query(GroupMembership).filter(
                and_(
                    GroupMembership.group_id == group.id,
                    GroupMembership.member_id != member.id,
#                    isinstance(GroupMembership.member, Group)
                )
            ).all()
            for p_group in groups:
                p_result = get_membership_tree(p_group.member.id, member.id, iter + 1)
                if p_result:
                    return p_result
            return None
        except NoResultFound:
            return None
Example #8
0
def parent_disassociate(content, delay_commit=False):
    if not content.parent:
        return False

    # Update has to be done before the commit in this case bcause the parent is needed
    #invalidate_content(content.parent) # Could update responses in the future, but for now we just invalidate the whole content
    #invalidate_content(content)        # this currently has code to update parents reponses, is the line above needed?

    if content.__type__ == 'comment':
        content.creator.send_notification(
            messages.comment_dissassociated(
                parentcreator=content.parent.creator,
                parentcontent=content.parent))
        content.visible = False
    else:
        content.creator.send_notification(
            messages.article_disassociated_from_assignment(
                member=content.parent.creator,
                article=content,
                assignment=content.parent))
        # TODO: what if an assignment is dissasocaited from an assignment?
        if content.__type__ == 'article':
            content.approval = "dissassociated"
        content.parent = None

    if not delay_commit:
        Session.commit()

    return True
Example #9
0
def worker_workout():
    print "worker_workout():"

    print '*** Session ***'
    print '>>> Session.query(Content).first()'
    print Session.query(Content).first()

    print '*** I18n ***'
    print '>>> _("This is a workout of internationalisation in the worker")'
    print _("This is a workout of internationalisation in the worker")

    print '*** Config ***'
    print '>>> cbutils.worker.config["debug"]'
    import cbutils.worker
    print cbutils.worker.config["debug"]

    print '*** Template ***'
    print '>>> ?'

    print '*** URL Generation ***'
    print '>>> url(controller="misc", action="about", id="civicboom")'
    print url(controller="misc", action="about", id="civicboom")
    print url(host='moo', controller="misc", action="about", id="civicboom")
    print url(protocol='test', host='cake', controller="misc", action="about", id="civicboom")
    print url(protocol='test', controller="misc", action="about", id="civicboom")
    print url(sub_domain='subdom', controller="misc", action="about", id="civicboom")

    return True
Example #10
0
 def viewable_by(self, member):
     """
     Check to see if a member object has the rights to view this content
     """
     # TODO check groups of creator to see if member is in the owning group
     if self.editable_by(member):
         return True  # Always allow content to be viewed by owners/editors
     if self.__type__ == "draft":
         return False  # if draft, only editors (above) can see
     if self.__type__ == "comment":
         return self.parent.viewable_by(
             member)  # if comment, show if we can see the parent article
     if self.visible == True:
         # GregM: If current content has a root parent then check viewable_by on root parent
         root = self.root_parent
         if root:
             return root.viewable_by(member)
         # GregM: If content is private check member is a trusted follower of content's creator
         #       We NEED to check has accepted, invited etc. for requests
         if self.private == True:
             if self.creator.is_follower_trusted(member):
                 return True
             elif self.__type__ == "assignment":
                 from civicboom.lib.database.get_cached import get_assigned_to
                 member_assignment = get_assigned_to(self, member)
                 if member_assignment:
                     if not member_assignment.member_viewed:
                         from civicboom.model.meta import Session
                         member_assignment.member_viewed = True
                         Session.commit()
                     return True
             return False
         return True
     return False
Example #11
0
def parent_approve(content, delay_commit=False):

    content.edit_lock = "parent_owner"
    content.approval = "approved"

    # AllanC - the direct email notifications were removed. They have now been replaced by the notification system
    # Email content parent & content creator
    #from pylons import tmpl_context as c # Needed for passing varibles to templates
    #c.content = content
    #content.parent.creator.send_email(subject=_('content request' ), content_html=render('/email/approve_lock/lock_article_to_organisation.mako'))
    #content.creator.send_email(       subject=_('content approved'), content_html=render('/email/approve_lock/lock_article_to_member.mako'))

    # Generate notifications - these have custom email templates that override the base notification
    extra_vars = {
        'content_id': content.id
    }  #extra variables for template rendering
    content.creator.send_notification(
        messages.article_approved_creator(member=content.parent.creator,
                                          parent=content.parent,
                                          content=content),
        extra_vars=extra_vars)  #, delay_commit=True
    content.parent.creator.send_notification(
        messages.article_approved_parent(member=content.parent.creator,
                                         parent=content.parent,
                                         content=content),
        extra_vars=extra_vars)  #, delay_commit=True

    if not delay_commit:
        Session.commit()

    #invalidate_content(content)
    return True
Example #12
0
def respond_assignment(parent_content, member, delay_commit=False):
    """
    When creating a response, the accepted record should be flagged as responded
    """
    member = get_member(member)
    parent_content = get_content(parent_content)

    if not member:
        raise action_error(_("cant find user"), code=404)
    if not parent_content:
        raise action_error(_("cant find parent content"), code=404)

    if parent_content.__type__ != 'assignment':
        return  # Nothing to do if parent is not assignment

    try:
        # upgrade an 'accepted' record to 'responded'
        member_assignment = Session.query(MemberAssignment).filter_by(
            member_id=member.id, content_id=parent_content.id).one()
        member_assignment.status = "responded"
    except:
        # otherwise create 'responded' record
        member_assignment = MemberAssignment()
        member_assignment.content = parent_content
        member_assignment.member = member
        #assignment_accepted.member_id = member.id
        member_assignment.status = "responded"
        Session.add(member_assignment)

    if not delay_commit:
        Session.commit()

    #invalidate_accepted_assignment(member)
    return True
Example #13
0
def withdraw_assignemnt(assignment, member, delay_commit=False):
    member = get_member(member)
    assignment = get_content(assignment)

    if not member:
        raise action_error(_("cant find user"), code=404)
    if not assignment:
        raise action_error(_("cant find assignment"), code=404)

    try:
        assignment_accepted = Session.query(MemberAssignment).filter_by(
            member_id=member.id, content_id=assignment.id,
            status="accepted").one()
        assignment_accepted.status = "withdrawn"
        #Session.update(assignment_accepted)
        Session.commit()
        #invalidate_accepted_assignment(member)

        assignment.creator.send_notification(
            messages.assignment_interest_withdrawn(member=member,
                                                   assignment=assignment,
                                                   you=assignment.creator))

        return True
    except:
        pass
    return False
Example #14
0
def associate_janrain_account(user, type, token):
    """
    Associate a login record for a Janrain account
    This is called at:
        1.) Registration
        2.) Linking multiple login accounts to a single Civicboom account
    """
    login = None
    try:
        login = Session.query(UserLogin).filter(UserLogin.token == token).filter(UserLogin.type == type).one()
    except:
        pass
    if login:
        if login.user == user:
            return # If login already belongs to this user then abort
        if login.user: # Warn existing user that account is being reallocated
            login.user.send_email(subject=_('login account reallocated'), content_text=_('your %s account has been allocated to the user %s') % (type, user.username))
        if not config['development_mode']:
            janrain('unmap', identifier=login.token, primaryKey=login.member_id)
        login.user   = user
    else:
        login = UserLogin()
        login.user   = user
        login.type   = type
        login.token  = token
        Session.add(login)
    Session.commit()
    if not config['development_mode']:
        janrain('map', identifier=login.token, primaryKey=login.member_id) # Let janrain know this users primary key id, this is needed for agrigation posts
Example #15
0
def get_media(id=None, hash=None):
    if id:
        return Session.query(Media).get(id)
    if hash:
        try:
            return Session.query(Media).filter_by(hash=hash).first()
        except NoResultFound:
            return None
Example #16
0
def del_group(group):
    group = get_group(group)
    from pylons import tmpl_context as c
    for member in [member_role.member for member_role in group.members_roles]:
        member.send_notification(
            messages.group_deleted(group=group, admin=c.logged_in_user)
        )  # AllanC - We cant use the standard group.send_notification because the group wont exisit after this line!
    Session.delete(group)
    Session.commit()
Example #17
0
def rate_content(content, member, rating):
    content = get_content(content)
    member = get_member(member)
    rating_value = int(rating)

    if not content:
        raise action_error(_('unable to find content'), code=404)
    if not member:
        raise action_error(_('unable to find member'), code=404)
    if rating and rating_value < 0 or rating_value > 5:
        raise action_error(_("Ratings can only be in the range 0 to 5"),
                           code=400)

    # remove any existing ratings
    # we need to commit after removal, otherwise SQLAlchemy
    # will optimise remove->add as modify-existing, and the
    # SQL trigger will break
    try:
        existing = Session.query(Rating).filter(
            Rating.content == content).filter(Rating.member == member).one()
        Session.delete(existing)
        Session.commit()
    except NoResultFound:
        pass

    # rating = 0 = remove vote
    # add a new one
    if rating_value > 0:
        r = Rating()
        r.content = content
        r.member = member
        r.rating = rating_value
        Session.add(r)
        Session.commit()
Example #18
0
def unboom_content(content, member, delay_commit=False):
    boom = has_boomed(content, member)
    if boom:
        Session.delete(boom)
    else:
        raise action_error(_(
            "%s has not boomed previously boomed this _content" % member),
                           code=400)

    if not delay_commit:
        Session.commit()
Example #19
0
def parent_seen(content, delay_commit=False):
    content.edit_lock = "parent_owner"
    content.approval = "seen"

    # AllanC - TODO generate notification
    #content.creator.send_notification(???, delay_commit=True)

    if not delay_commit:
        Session.commit()
    #invalidate_content(content)
    return True
Example #20
0
def verify_email_hash(user, hash, commit=False):
    user = get_member(user)
    if user and user.hash() == hash:
        if not config['demo_mode']: # AllanC - Demo mode is ALWAYS offline, there is no way we can validate members emails address's. But the hash is correct so return True
            if user.email_unverified:
                user.email            = user.email_unverified
                user.email_unverified = None
            if commit:
                Session.commit()
        return True
    return False
Example #21
0
 def part_pay_invoice_manual(self, invoice, amount=None):
     """
     Create a manual transaction against invoice
     """
     txn = BillingTransaction()
     txn.invoice = invoice
     txn.status = 'complete'
     txn.amount = amount or invoice.total_due
     txn.provider = 'manual_test'
     txn.reference = 'test'
     Session.commit()
     pass
Example #22
0
def get_tag(tag):
    """
    Returns a tag object for the string passed to it
    If it does not appear in the database then return a new tag object
    If it does exisit in the data then return the database object
    """
    tag = tag.lower()
    try:
        return Session.query(Tag).filter_by(name=unicode(tag)).one()
    except NoResultFound as nrf:
        t = Tag(unicode(tag))
        Session.add(t)
        return t
Example #23
0
 def delete_content(self, id, force=False):
     if force:  # ignore logged in user and just get rid of it
         Session.delete(Session.query(Content).get(id))
         Session.commit()
     else:
         self.assertIn('delete', self.get_actions(id))
         response = self.app.post(url('content', id=id, format="json"),
                                  params={
                                      '_method': 'delete',
                                      '_authentication_token':
                                      self.auth_token,
                                  },
                                  status=200)
    def test_delete_content(self):

        self.assertEqual(self.num_content_public('delete_cascade'), 0)
        num_content_start = self.num_content_public()

        # Step 1: Create content
        self.content_id = self.create_content(type='assignment')

        # Step 2: Create responses, comments and accept
        self.log_in_as('unitfriend')
        #self.accept_assignment(self.content_id) # Accepting should now be done automatically when responding
        response_1_id = self.create_content(parent_id=self.content_id,
                                            title='response 1',
                                            content='delete_cascade')
        response_2_id = self.create_content(parent_id=self.content_id,
                                            title='response 2',
                                            content='delete_cascade')
        self.comment(self.content_id, 'delete_cascade comment')
        self.comment(response_1_id, 'delete_cascade response comment')

        response = self.app.get(url('content',
                                    id=self.content_id,
                                    format='json'),
                                status=200)
        response_json = json.loads(response.body)
        self.assertEqual(response_json['data']['responses']['count'], 2)
        self.assertEqual(response_json['data']['comments']['count'], 1)
        self.assertEqual(response_json['data']['accepted_status']['count'], 1)

        # Step 3: Delete content
        content_delete_cascade = get_content(self.content_id)
        content_delete_cascade.delete()

        # Step 4: Check deleted
        response = self.app.get(url('content', id=response_1_id,
                                    format='json'),
                                status=200)
        self.assertIn('delete_cascade response comment', response)
        response = self.app.get(url('content', id=response_2_id,
                                    format='json'),
                                status=200)

        self.assertEqual(
            Session.query(Content).filter_by(
                parent_id=self.content_id).count(), 0)
        self.assertEqual(
            Session.query(Tag).filter_by(name=u'delete_cascade').count(), 1
        )  #Tag remains at the end, this could be tidyed witha  delete orphan cascade
        self.assertEqual(
            Session.query(MemberAssignment).filter_by(
                content_id=self.content_id).count(), 0)
Example #25
0
 def _to_python(self, value, state):
     value = unicode(value)
     from pylons import tmpl_context as c
     if c.logged_in_persona and c.logged_in_persona.email == value:  # If the current user has this email then bypass the validator
         return value
     email_count = Session.query(User).filter(User.email == value).count()
     if self.check_unverifyed_emails:
         email_count += Session.query(User).filter(
             User.email_unverified == value).count()
     if email_count > 0:
         raise formencode.Invalid(
             _('This email address is already registered with us. Please use a different address, or retrieve your password using the password recovery link.'
               ), value, state)
     return value
Example #26
0
def get_member(member):
    if not member:
        return None
    if isinstance(member, Member):
        return member

    assert type(member) in [str, unicode], debug_type(member)

    member = make_username(member)
    
    def get_member_nocache(member_id):
        try:
            return Session.query(Member).with_polymorphic('*').get(member_id)
        except NoResultFound:
            return None
    
    cache      = _cache.get('member')
    cache_func = lambda: get_member_nocache(member)
    if cache:
        result = cache.get(key='member:%s' % member, createfunc=cache_func)
        #try:
            #Session.add(result)
            #return result
        #except InvalidRequestError:
        return Session.merge(result, load=False)
    return cache_func()
Example #27
0
 def mark_messages_as_read(self, **kwargs):
     """
     POST /profile/{id}/mark_messages_as_read: Mark messages as read
     @type action
     @api contents 1.0 (WIP)
     
     @param type   type of message object to mark as read from all, to, notification
     """
     list_type = kwargs.get('list', 'all')
     if list_type in list_filters and list_type in ['all','to','notification']:
         results = Session.query(Message).filter(Message.target_id==c.logged_in_persona.id)
         results = list_filters[list_type](results)
         for message in results.all():
             message.read = True
         Session.commit()
         return action_ok(message='%s marked as read' % type, code=201)
     raise action_error(_('list %s not supported') % kwargs.get('list'), code=400)
Example #28
0
def accept_assignment(assignment,
                      member,
                      status="accepted",
                      delay_commit=False):
    member = get_member(member)
    assignment = get_content(assignment)

    if not member:
        raise action_error(_("cant find user"), code=404)
    if not assignment:
        raise action_error(_("cant find assignment"), code=404)
    if not issubclass(assignment.__class__, AssignmentContent):
        raise action_error(_("only _assignments can be accepted"), code=400)
    # all permissins hendled by controler action - so this is unneeded here
    #if not assignment.viewable_by(c.logged_in_persona):
    #    raise action_error(_('_assignment is not visible to your user and therefor cannot be accepted'), code=403)
    if assignment_previously_accepted_by(assignment, member):
        raise action_error(_(
            '_assignment has been previously accepted and cannot be accepted again'
        ),
                           code=400)
    #if assignment.creator == member:
    #    raise action_error(_("cannot accept your own _assignment"), code=400)

    assignment_accepted = MemberAssignment()
    assignment.assigned_to.append(assignment_accepted)
    assignment_accepted.member = member
    assignment_accepted.status = status
    Session.add(assignment_accepted)

    if not delay_commit:
        Session.commit()
    #invalidate_accepted_assignment(member)

    if status == "accepted":
        assignment.creator.send_notification(
            messages.assignment_accepted(member=member,
                                         assignment=assignment,
                                         you=assignment.creator))
    if status == "pending":
        member.send_notification(
            messages.assignment_invite(member=assignment.creator,
                                       assignment=assignment,
                                       you=member))

    return True
Example #29
0
def remove_member(group, member, delay_commit=False):
    group = get_group(group)
    member = get_member(member)
    membership = get_membership(group, member)

    if not group:
        raise action_error(_('unable to find group'), code=404)
    if not member:
        raise action_error(_('unable to find member'), code=404)
    if not membership:
        raise action_error(_('not a member of group'), code=400)
    # AllanC - permissions moved to controller
    #if member!=c.logged_in_persona and not group.is_admin(c.logged_in_persona):
    #    raise action_error('current user has no permissions for this group', 403)
    #AllanC - integrety moved to model
    #if membership.role=="admin" and num_admins<=1:
    #    raise action_error('cannot remove last admin', 400)

    # Notifications
    if membership.status == "active":  # member removed
        from pylons import tmpl_context as c
        if member != c.logged_in_user:
            membership.member.send_notification(
                messages.group_remove_member_to_member(admin=c.logged_in_user,
                                                       group=group))
        group.send_notification(
            messages.group_remove_member_to_group(admin=c.logged_in_user,
                                                  group=group,
                                                  member=member))
    elif membership.status == "invite":  # invitation declined
        group.send_notification(
            messages.group_invitation_declined(member=member, group=group))
    elif membership.status == "request":  # request declined
        membership.member.send_notification(
            messages.group_request_declined(group=group))

    Session.delete(membership)

    if not delay_commit:
        Session.commit()

    #invalidate_member(group)
    #invalidate_member(member)

    return True
Example #30
0
def set_role(group, member, role, delay_commit=False):
    group = get_group(group)
    member = get_member(member)
    membership = get_membership(group, member)
    role = role or membership.role or group.default_role

    if not group:
        raise action_error(_('unable to find group'), code=404)
    if not member:
        raise action_error(_('unable to find member'), code=404)
    if not membership:
        raise action_error(_('not a member of group'), code=400)
    if role not in group_member_roles.enums:
        raise action_error('not a valid role', code=400)
    # AllanC - permisions moved to controller
    #if not group.is_admin(c.logged_in_persona):
    #    raise action_error(_('no permissions for this group'), 403)
    # AllanC - integrtiy moved to model
    #if membership.role=="admin" and num_admins<=1:
    #    raise action_error('cannot remove last admin', 400)

    from pylons import tmpl_context as c
    membership.role = role
    if membership.status == "request":
        membership.status = "active"
        member.send_notification(
            messages.group_request_accepted(admin=c.logged_in_user,
                                            group=group,
                                            you=member))
        group.send_notification(
            messages.group_new_member(member=member, group=group))
    else:
        group.send_notification(
            messages.group_role_changed(admin=c.logged_in_user,
                                        member=member,
                                        group=group,
                                        role=role))

    if not delay_commit:
        Session.commit()

    #invalidate_member(group)
    #invalidate_member(member)

    return True