Exemplo n.º 1
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()
Exemplo n.º 2
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
Exemplo n.º 3
0
 def __init__(self, boomer_id):
     try:
         boomer_id = boomer_id.id
     except:
         pass
     assert type(boomer_id) in [str, unicode], debug_type(boomer_id)
     self.boomer_id = make_username(boomer_id)
Exemplo n.º 4
0
 def __init__(self, id_list):
     """
     id_list is a list of strings
     """
     try:
         id_list = id_list.id
     except:
         pass
     if isinstance(id_list, basestring):
         id_list = [make_username(id) for id in id_list.split(',')]
     assert isinstance(id_list, list)
     self.id_list = id_list
Exemplo n.º 5
0
    def _to_python(self, value, state):
        value = make_username(unicode(value.strip()))
        if not re.search("^[\w-]*$", value):
            raise formencode.Invalid(self.message(
                "illegal_chars",
                state,
            ), value, state)
        if len(value) < self.min:
            raise formencode.Invalid(
                self.message("too_few", state, min=self.min), value, state)
        if len(value) > self.max:
            raise formencode.Invalid(
                self.message("too_long", state, max=self.max), value, state)

        from pylons import tmpl_context as c
        if c.logged_in_persona and c.logged_in_persona.id == value:  # If the current user has this username then bypass the validator
            return value
        if Session.query(Member).get(value):
            raise formencode.Invalid(
                self.message("username_taken", state, name=value), value,
                state)
        return value
Exemplo n.º 6
0
def get_lowest_role_for_user(user_list=None):
    """
    user_list is a list of integers
    the first id should always the curent logged in user id (this is appended by base)
    """
    if not user_list:
        user_list = session_get('logged_in_persona_path')

    if isinstance(user_list, basestring):
        user_list = [make_username(i) for i in user_list.split(',')]

    if not isinstance(user_list, list):
        return None

    roles = Session.query(GroupMembership).filter(
        or_(*[
            and_(GroupMembership.member_id == user_list[i],
                 GroupMembership.group_id == user_list[i + 1])
            for i in range(len(user_list) - 1)
        ])).all()

    if len(roles) != len(user_list) - 1:
        # If not all the records exisit for the user_list given then some of the links could not be found and the route is invalid. No permissions should be returned
        # Warning is logged - this could mean a permission/membership has changed since the user logged in
        # AllanC - If the warning is spamming the logs it should be removed, but I wanted to catch the error out of paranoia
        log.warn(
            'logged_in_persona_path is invalid - preventing return of group role'
        )
        session_remove('logged_in_persona_path')
        session_remove('logged_in_persona')
        return None

    role = 'admin'
    for r in roles:
        role = lowest_role(role, r.role)
    return role
Exemplo n.º 7
0
    def email(self, **kwargs):
        """
        POST /register/email: Register a new user via email
        @type action
        @api register 1.0 (WIP)
        
        @param username
        @param email
        @param follow        (optional) a comma separted list of users this registered user will follow on registration
        @param follow_mutual (optional) a comma separted list of users who will follow this user
        
        @return 200 registered ok
        An email with a verification hash is sent
        
        @comment AllanC follow_mutual will not function unless allow_registration_follows is set in user settings for that user
        @comment AllanC GET triggers HTML page
        """

        # record the username exactly as given (eg Bob Bobson), the validator
        # will return a valid username (bob-bobson). Have the username exactly
        # as given as their default display name.
        given_username = kwargs.get("username", "")

        # Pre validate the username - need to clean it before the validator fires
        if 'username' in kwargs:
            kwargs['username'] = make_username(
                unicode(kwargs['username'].strip()))

        # Is pending username or unvalidaed email exisits then update the users details and resend the validation email
        u = Session.query(User).filter(User.status == 'pending').filter(
            or_(User.email_unverified == kwargs.get('email'),
                User.id == kwargs.get('username'))
        ).first(
        )  # Try to get existing user for this email address - else create new user
        if u:
            if kwargs.get('username'):
                u.id = kwargs[
                    'username']  # Update the user.id - this should be unique becuase of the validator above. Should be safe as the original user never completed registration
            if kwargs.get('email'):
                u.email_unverified = kwargs['email']

        else:

            # Check the username and email and raise any problems via the flash message session system
            try:
                kwargs = RegisterSchemaEmailUsername().to_python(
                    kwargs)  #dict(request.params)
            except formencode.Invalid as error:
                raise action_error(status='invalid',
                                   message=error.msg,
                                   code=400)

            # Create new user
            u = User()
            u.id = kwargs['username']
            u.email_unverified = kwargs['email']
            u.name = given_username  # display name will be asked for in step #2. For now, copying username is a good enough space filler
            Session.add(u)
            Session.commit()

            # Automatically Follow Users from config and referers from other sites - These will be run once the user completes registration
            u.extra_fields.update({
                'on_register_follow':
                ','.join([
                    username.strip() for username in ','.join([
                        config['setting.username_to_auto_follow_on_signup'],
                        kwargs.get('follow', ''),
                        kwargs.get('follow_mutual', '')
                    ]).split(',')
                ]),  # AllanC - this monster line is huge confusing and awesome!
                'on_register_follow_mutual':
                kwargs.get('follow_mutual', ''),
            })

            # Accept assignment
            if 'accept_assignment' in kwargs:
                log.debug("auto accepting not implemented yet")
                # TODO: Implement
                #assignment = get_assignment(request.params['accept_assignment'])
                #accept_assignment_status = accept_assignment(new_member, assignment)
                #if accept_assignment_status == True:
                #    refered_by_member.send_notification(messages.assignment_accepted(member=new_member, assignment=assignment))

        Session.commit()

        if config['demo_mode'] and (c.format == 'html'
                                    or c.format == 'redirect'):
            return redirect(
                validation_url(u, controller='register', action='new_user'))

        user_log.info("Sending verification email to %s (%s)" %
                      (u.id, u.email_unverified))
        # Send email verification link
        send_verifiy_email(u,
                           controller='register',
                           action='new_user',
                           message=_('complete the registration process'))

        if c.format in ["html", "redirect"]:
            return redirect(url(controller="register", action="check_email"))

        return action_ok(
            _("Thank you. Please check your email to complete the registration process"
              ))
Exemplo n.º 8
0
    def create(self, **kwargs):
        """
        POST /groups: Create a new group

        Creates a new group with the specified username with the currently
        logged in user as as administrator of the new group

        @api groups 1.0 (WIP)
        
        @param username                   a unique username, cannot clash with existing usernames
        @param name                       display name
        @param description                description of groups purpose
        @param default_role
            admin
            editor
            contributor
            observer
        @param join_mode
            public
            invite
            invite_and_request
        @param member_visibility
            public
            private 
        @param default_content_visibility (plus account required)
            public
            private 
        
        @return 400  data invalid (ie, username that already exisits)
        @return 201  group created, data.id = new group id
        @return 301  if format redirect specifyed will redirect to show group
        """

        create_push_assignment = kwargs.get('create_push_assignment')
        if create_push_assignment:
            del kwargs['create_push_assignment']

        # url('groups') + POST
        # if only display name is specified, generate a user name
        if not kwargs.get('username') and kwargs.get("name"):
            kwargs["username"] = _gen_username(
                make_username(kwargs.get("name")))

        # if only user name is specified, generate a display name
        if not kwargs.get('name') and kwargs.get("username"):
            kwargs["name"] = kwargs.get("username")

        if not c.logged_in_persona.has_account_required('plus'):
            if not kwargs.get('member_visibility'):
                kwargs['member_visibility'] = 'public'
            if not kwargs.get('default_content_visibility'):
                kwargs['default_content_visibility'] = 'public'

        # Need to validate before creating group, not sure how we could do this via settings controller :S GregM
        data = {'settings': kwargs, 'action': 'create'}
        data = validate_dict(data,
                             CreateGroupSchema(),
                             dict_to_validate_key='settings',
                             template_error='groups/edit')
        group_dict = data['settings']

        # Create and set group admin here!
        group = Group()
        group.id = group_dict['username']
        group.name = group_dict['name']
        group.status = 'active'
        group_admin = GroupMembership()
        group_admin.member = c.logged_in_persona
        group_admin.role = "admin"
        group.members_roles.append(group_admin)
        group.payment_account = c.logged_in_persona.payment_account  # The group is allocated the same payment account as the creator. All groups are free but if they want the plus features like approval and private content then this is needed

        # GregM: Dirty hack, again... In demo mode users & groups don't have payment accounts, we need to override the account_type manually
        if config['demo_mode']:
            group.account_type = c.logged_in_persona.account_type

        #AllanC - TODO - limit number of groups a payment account can support - the could be the differnece between plus and corporate

        # GregM: Create current user as admin of group too to allow them to admin group (until permission tree is sorted!)
        #if isinstance(c.logged_in_persona, Group):
        #    group_admin_user        = GroupMembership()
        #    group_admin_user.member = c.logged_in_user
        #    group_admin_user.role   = "admin"
        #    group.members_roles.append(group_admin_user)

        Session.add(group)
        Session.commit()

        # AllanC - Hack
        # The group has been created, but the additional feilds handled by the settings controller need to be updated (e.g. description and logo image)
        # However, we have not set c.logged_in_persona so the call to the settings controller will not have the permissions for the newly created group
        # We fake the login here
        # We cant use set_persona as this called the set_persona controller action and calls a redirect
        logged_in_persona = c.logged_in_persona  # have to remeber previous persona to return to or set_persona below thinks were already swiched and will perform no action
        logged_in_persona_role = c.logged_in_persona_role
        c.logged_in_persona = group
        c.logged_in_persona_role = 'admin'

        # AllanC - old call? to be removed?
        # self.update(group.username, **kwargs) # Overlay any additional form fields over the new group object using the update method - also intercepts if format is redirect

        # Call settings controller to update group settings!
        kwargs['panel'] = 'general'

        settings_update(group, private=True, **kwargs)

        # GregM: Create new request for group (Arrgh, have to fudge the format otherwise we cause a redirect):
        format = c.format
        if create_push_assignment:
            c.format = 'python'
            assignment = create_content(
                type='assignment',
                private=False,
                title=_("Send us your stories"),
                content=
                _("Join us in making the news by telling us your stories, sending in videos, pictures or audio: Get recognition and get published - share your news with us now!"
                  ),
                format="python")
            group.config['push_assignment'] = assignment.get('data',
                                                             {}).get('id')

        c.format = format

        c.logged_in_persona = logged_in_persona
        c.logged_in_persona_role = logged_in_persona_role

        user_log.info("Created Group #%s (%s)" % (group.id, group.name))

        # AllanC - Temp email alert for new group
        send_email(config['email.event_alert'],
                   subject='new group',
                   content_text='%s - %s by %s' %
                   (c.logged_in_persona.username, c.logged_in_persona.name,
                    c.logged_in_user.username))

        # GregM: prompt_aggregate for new group :)
        set_persona(
            group,
            prompt_aggregate=True)  # Will redirect if in html or redirect mode

        return action_ok(message=_('group created'),
                         data={'id': group.id},
                         code=201)