Example #1
0
def deactivate_profile_view(context, request):
    page_title = 'Deactivate user account for %s %s' % (context.firstname,
                                                        context.lastname)
    api = TemplateAPI(context, request, page_title)

    name = context.__name__
    myself = authenticated_userid(request) == context.__name__

    if not api.user_is_admin and not myself:
        raise Forbidden("Only owner or admin can deactivate profile")

    confirm = request.params.get('confirm')
    if confirm:
        try:
            find_users(context).remove(name)
        except KeyError:
            pass
        workflow = get_workflow(IProfile, 'security', context)
        workflow.transition_to_state(context, request, 'inactive')
        if myself:
            return logout_view(context, request, reason='User removed')
        query = {'status_message': 'Deactivated user account: %s' % name}
        parent = context.__parent__
        location = resource_url(parent, request, query=query)

        return HTTPFound(location=location)

    # Show confirmation page.
    return dict(api=api, myself=myself)
Example #2
0
def delete_profile_view(context, request):

    confirm = request.params.get('confirm')
    if confirm:
        parent = context.__parent__
        name = context.__name__
        find_users(context).remove(name)
        del parent[name]

        if authenticated_userid(request) == name:
            return logout_view(context, request, reason='User removed')
        query = {'status_message': 'Deleted profile: %s' % name}
        location = model_url(parent, request, query=query)

        return HTTPFound(location=location)

    page_title = 'Delete Profile for %s %s' % (context.firstname,
                                               context.lastname)
    api = TemplateAPI(context, request, page_title)

    # Get a layout
    return render_template_to_response(
        'templates/delete_profile.pt',
        api=api,
        )
Example #3
0
def deactivate_profile_view(context, request):
    name = context.__name__
    myself = authenticated_userid(request) == context.__name__

    confirm = request.params.get('confirm')
    if confirm:
        try:
            find_users(context).remove(name)
        except KeyError:
            pass
        workflow = get_workflow(IProfile, 'security', context)
        workflow.transition_to_state(context, request, 'inactive')
        if myself:
            return logout_view(context, request, reason='User removed')
        query = {'status_message': 'Deactivated user account: %s' % name}
        parent = context.__parent__
        location = resource_url(parent, request, query=query)

        return HTTPFound(location=location)

    page_title = 'Deactivate user account for %s %s' % (context.firstname,
                                                        context.lastname)
    api = TemplateAPI(context, request, page_title)

    # Show confirmation page.
    return dict(api=api, myself=myself)
Example #4
0
    def checkPermission(self, info):
        """ Does user have permission to author content in the given context?

        Uses ACL security policy to test.
        """
        users = find_users(self.context)
        for target in info['targets']:
            if 'error' in target:
                continue
            report_name = target.get('report')
            if report_name is not None:
                pd = find_peopledirectory(self.context)
                context = find_resource(pd, report_name.split('+'))
                permission = "email"
            else:
                communities = find_communities(self.context)
                community = communities[target['community']]
                context = community[target['tool']]
                permission = "create"  # XXX In theory could depend on target
            user = users.get_by_id(info['author'])
            if user is not None:
                user = dict(user)
                # XXX check this!
                user['karl.identity'] = {'id': info['author']}

            # BFG Security API always assumes http request, so we fabricate a
            # fake request.
            request = Request.blank('/')
            request.environ['karl.identity'] = user
            request.context = self.context

            if not has_permission(permission, context, request):
                target['error'] = 'Permission Denied'
Example #5
0
def _check(credentials, request):
    login, password = credentials['login'], credentials['password']
    users = find_users(request.context)
    user = users.get(login=login)
    if user is None or user['password'] != get_sha_password(password):
        return None
    return [user['id']] + list(user['groups'])
Example #6
0
def delete_community(obj, event):
    # delete the groups related to the community when a community is
    # deleted
    context = obj
    users = find_users(context)
    users.delete_group(context.members_group_name)
    users.delete_group(context.moderators_group_name)
Example #7
0
File: login.py Project: lslaz1/karl
    def create_access_request(self):
        email = self.data.get('email')
        system_name = get_setting(self.context, 'title')
        self.context.access_requests[email] = self.data
        mailer = getUtility(IMailDelivery)
        message = MIMEMultipart('alternative')
        message['Subject'] = '%s Access Request(%s)' % (
            system_name, self.data.get('fullname'))
        message['From'] = get_setting(self.context, 'admin_email')
        bodyhtml = u'''<html><body>
<p>New access request has been submitted for the site %s</p>
<p><b>Email</b>: %s <br />
%s
</p>
</body></html>''' % (self.request.application_url, email, '<br />'.join([
            _email_field_tmp % (f['label'], self.data.get(f['id'], ''))
            for f in self.fields
        ]))
        bodyplain = html2text.html2text(bodyhtml)
        htmlpart = MIMEText(bodyhtml.encode('UTF-8'), 'html', 'UTF-8')
        plainpart = MIMEText(bodyplain.encode('UTF-8'), 'plain', 'UTF-8')
        message.attach(plainpart)
        message.attach(htmlpart)

        # First, send mail to all admins
        users = find_users(self.context)
        search = ICatalogSearch(self.context)
        count, docids, resolver = search(interfaces=[IProfile])
        for docid in docids:
            profile = resolver(docid)
            if getattr(profile, 'security_state', None) == 'inactive':
                continue
            userid = profile.__name__
            if not users.member_of_group(userid, 'group.KarlAdmin'):
                continue
            copyofmsg = copy.deepcopy(message)
            fullemail = '%s <%s>' % (profile.title, profile.email)
            copyofmsg['To'] = fullemail
            mailer.send([profile.email], copyofmsg)

        # next, send to person that submitted
        message = MIMEMultipart('alternative')
        message['Subject'] = 'Access Request to %s' % system_name
        message['From'] = get_setting(self.context, 'admin_email')
        user_message = get_setting(
            self.context, 'request_access_user_message', '') % (SafeDict(
                self.data, {'system_name': system_name}))
        bodyhtml = u'<html><body>%s</body></html>' % user_message
        bodyplain = html2text.html2text(bodyhtml)
        htmlpart = MIMEText(bodyhtml.encode('UTF-8'), 'html', 'UTF-8')
        plainpart = MIMEText(bodyplain.encode('UTF-8'), 'plain', 'UTF-8')
        message.attach(plainpart)
        message.attach(htmlpart)
        copyofmsg = copy.deepcopy(message)
        fullemail = '%s <%s>' % (self.data.get('fullname', ''), email)
        copyofmsg['To'] = fullemail
        mailer.send([email], copyofmsg)

        self.submitted = True
        self.errors.append('Successfully requested access')
Example #8
0
File: people.py Project: zagy/karl
def get_profile_actions(profile, request):
    profile_url = request.resource_url(profile)
    actions = []
    same_user = (authenticated_userid(request) == profile.__name__)
    if has_permission('administer', profile, request):
        actions.append(('Edit', '%sadmin_edit_profile.html' % profile_url))
    elif same_user:
        actions.append(('Edit', '%sedit_profile.html' % profile_url))
    if same_user:
        actions.append(('Manage Communities', 'manage_communities.html'))
        actions.append(('Manage Tags', 'manage_tags.html'))
    if has_permission('administer', profile, request):
        actions.append(('Advanced', '%sadvanced.html' % profile_url))
    if request.cookies.get('ux2') == 'true':
        if same_user:
            actions.append(('Deactivate My Account', 'javascript:deactivate()'))
        if has_permission('administer', profile, request) and not same_user:
            users = find_users(profile)
            userid = profile.__name__
            user = users.get_by_id(userid)
            if user is not None:
                is_active = True
            else:
                is_active = False
            if is_active:
                actions.append(('Deactivate This User', 'javascript:deactivate()'))
            if not is_active:
                actions.append(('Reactivate This User', 'javascript:reactivate()'))
    return actions
Example #9
0
    def sync(self, data):
        context = self.context
        timestamp = data.pop('timestamp', None)
        if timestamp:
            context.usersync_timestamp = timestamp
        elif hasattr(context, 'usersync_timestamp'):
            del context.usersync_timestamp

        deactivate_missing = data.pop('deactivate_missing', False)
        if deactivate_missing:
            profiles = find_profiles(self.context)
            missing = set([p.__name__ for p in profiles.values()
                           if p.security_state == 'active' and
                           getattr(p, 'usersync_managed', False)])
        else:
            missing = Empty()

        users = data.pop('users')
        for user in users:
            self.syncuser(user, missing)
        if data:
            raise ValueError("Unrecognized keys in user sync data: %s" %
                             data.keys())

        if missing:
            users = find_users(self.context)
            for username in missing:
                profile = profiles[username]
                workflow = get_workflow(IProfile, 'security', profile)
                workflow.transition_to_state(profile, None, 'inactive')
                users.remove(username)
Example #10
0
def collect_profile_metrics(context, year, month):
    result = {}
    search = ICatalogSearch(context)
    begin, end = date_range(year, month)

    users = find_users(context)
    staff_set = users.users_in_group('group.KarlStaff')

    _, docids, resolver = search(
        creation_date=(None, end),
        interfaces=[IProfile],
    )

    for profile in (resolver(docid) for docid in docids):
        userid = profile.__name__
        created_count, _, _ = search(creation_date=(begin, end),
                                     creator=userid)
        total_count, _, _ = search(creation_date=(None, end), creator=userid)
        is_staff = userid in staff_set
        result[userid] = dict(
            total=total_count,
            created=created_count,
            is_staff=is_staff,
        )
    return result
Example #11
0
def delete_community(obj, event):
    # delete the groups related to the community when a community is
    # deleted
    context = obj
    users = find_users(context)
    users.delete_group(context.members_group_name)
    users.delete_group(context.moderators_group_name)
Example #12
0
    def handle_submit(self, converted):
        context = self.context
        request = self.request
        system_name = get_setting(context, 'system_name', 'KARL')
        address = converted['email']
        if address:
            address = address.lower()

        search = getAdapter(context, ICatalogSearch)
        count, docids, resolver = search(
            interfaces=[IProfile], email=[address])

        users = find_users(context)
        for docid in docids:
            profile = resolver(docid)
            if profile is None:
                continue
            userid = profile.__name__
            user = users.get_by_id(userid)
            if user is None:
                continue
            # found the profile and user
            break
        else:
            raise ValidationError(**{"email":
                "%s has no account with the email address: %s" %
                (system_name, address)})

        request_password_reset(user, profile, request)

        url = resource_url(context, request, 'reset_sent.html') + (
            '?email=%s' % urllib.quote_plus(address))
        return HTTPFound(location=url)
Example #13
0
def _check(credentials, request):
    login, password = credentials['login'], credentials['password']
    users = find_users(request.context)
    user = users.get(login=login)
    if user is None or user['password'] != get_sha_password(password):
        return None
    return [user['id']] + list(user['groups'])
Example #14
0
 def __init__(self, context, request):
     super(AdminEditProfileFormController, self).__init__(context, request)
     self.users = find_users(context)
     self.userid = context.__name__
     self.user = self.users.get_by_id(self.userid)
     self.user_groups = set(self.user['groups'])
     self.group_options = get_group_options(self.context)
Example #15
0
    def visit(self, context):
        if IProfile.providedBy(context):
            users = find_users(context)
            person = self._get_person(context.__name__)
            person['first_last'] = ' '.join(
                (context.firstname, context.lastname))
            person['create_date'] = context.created
            person['is_staff'] = users.member_of_group(
                context.__name__, 'group.KarlStaff')
            person['location'] = context.location
            person['department'] = context.department

            tags = find_tags(context)
            person['tags'] = len(tags.getTags(users=[context.__name__]))

        elif ICommunity.providedBy(context):
            for id in context.member_names:
                self._get_person(id)['membership'] += 1
            for id in context.moderator_names:
                self._get_person(id)['communities_moderator'] += 1

        else:
            creator = getattr(context, 'creator', None)
            if creator is not None:
                person = self._get_person(creator)
                person['content_created'] += 1
                if context.created > self.one_month_ago:
                    person['created_this_month'] += 1
Example #16
0
def evolve(context):
    users = find_users(context)
    profiles = find_profiles(context)

    for id in bad_users:
        users.remove(id)
        del profiles[id]
Example #17
0
def to_profile_active(ob, info):
    acl  = [
        (Allow, ob.creator, MEMBER_PERMS + ('view_only',)),
    ]
    acl.append((Allow, 'group.KarlUserAdmin',
                ADMINISTRATOR_PERMS + ('view_only',)))
    acl.append((Allow, 'group.KarlAdmin',
                ADMINISTRATOR_PERMS + ('view_only',)))
    acl.append((Allow, 'group.KarlStaff',
                GUEST_PERMS + ('view_only',)))
    users = find_users(ob)
    user = users.get_by_id(ob.creator)
    if user is not None:
        groups = user['groups']
        for group, role in get_community_groups(groups):
            c_group = 'group.community:%s:%s' % (group, role)
            acl.append((Allow, c_group, GUEST_PERMS + ('view_only',)))
    acl.append((Allow, 'system.Authenticated', ('view_only',)))
    acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(ob, acl)
    if added or removed:
        ob.__acl__ = acl
        msg = ts('to-active', resource_path(ob), added, removed)
    _reindex(ob, texts=True)
    _reindex_peopledir(ob)
    return msg
Example #18
0
File: chatter.py Project: zagy/karl
def discover_community_members_json(context, request):
    """ Return users who share a community with the given user.

    Query string may include:

    - 'userid':  the user whose communities we enumerate (defaults to the
                 current user).
    """
    users = find_users(context)
    userid = request.GET.get('userid', None)
    if userid is None:
        userid = authenticated_userid(request)
        principals = effective_principals(request)
        communities = [x[0] for x in get_community_groups(principals)]
    else:
        info = users.get(userid)
        communities = [x[0] for x in get_community_groups(info['groups'])]
    c_groups = [(x,
                 _quippers_from_users(
                     context, request,
                     users.users_in_group('group.community:%s:members' % x)))
                for x in communities]
    return {
        'userid': userid,
        'members': dict(c_groups),
    }
Example #19
0
def to_profile_active(ob, info):
    acl = [
        (Allow, ob.creator, MEMBER_PERMS + ('view_only', )),
    ]
    acl.append(
        (Allow, 'group.KarlUserAdmin', ADMINISTRATOR_PERMS + ('view_only', )))
    acl.append(
        (Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS + ('view_only', )))
    acl.append((Allow, 'group.KarlStaff', GUEST_PERMS + ('view_only', )))
    users = find_users(ob)
    user = users.get_by_id(ob.creator)
    if user is not None:
        groups = user['groups']
        for group, role in get_community_groups(groups):
            c_group = 'group.community:%s:%s' % (group, role)
            acl.append((Allow, c_group, GUEST_PERMS + ('view_only', )))
    acl.append((Allow, 'system.Authenticated', ('view_only', )))
    acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(ob, acl)
    if added or removed:
        ob.__acl__ = acl
        msg = ts('to-active', resource_path(ob), added, removed)
    _reindex(ob, texts=True)
    _reindex_peopledir(ob)
    return msg
Example #20
0
    def checkPermission(self, info):
        """ Does user have permission to author content in the given context?

        Uses ACL security policy to test.
        """
        users = find_users(self.context)
        for target in info['targets']:
            if 'error' in target:
                continue
            report_name = target.get('report')
            if report_name is not None:
                pd = find_peopledirectory(self.context)
                context = find_model(pd, report_name.split('+'))
                permission = "email"
            else:
                communities = find_communities(self.context)
                community = communities[target['community']]
                context = community[target['tool']]
                permission = "create"   # XXX In theory could depend on target
            user = users.get_by_id(info['author'])
            if user is not None:
                user = dict(user)
                user['repoze.who.userid'] = info['author']

            # BFG Security API always assumes http request, so we fabricate a
            # fake request.
            request = webob.Request.blank('/')
            request.environ['repoze.who.identity'] = user

            if not has_permission(permission, context, request):
                target['error'] = 'Permission Denied'
Example #21
0
    def create(self, profiles):
        element = self.element
        login = self._element_value(element, 'username')
        username = login.replace(' ', '')
        password = get_random_password()
        groups = self._groups(element)

        users = find_users(profiles)
        users.add(username, login, password, groups, encrypted=False)

        profile = create_content(IProfile)
        profiles[username] = profile
        self._populate(profile)

        workflow = get_workflow(IProfile, 'security', profile)
        if workflow is not None:
            workflow.initialize(profile)

        profile.created_by = profile.modified_by = username
        profile.created = profile.modified = datetime.datetime.now()

        # Profile was indexed before workflow was initialized, so there is a
        # a bogus value for the 'allowed' index.  Unfortunately, we can't just
        # add the profile to the profiles folder (which triggers indexing)
        # after the workflow is initialized, because the workflow
        # initialization code for profiles requires that the profile already
        # be in the content tree since a call to 'find_users' is made.  The
        # work around is to just remove the profile and add it back again to
        # trigger reindexing.
        del profiles[username]
        profiles[username] = profile
Example #22
0
def evolve(context):
    out = codecs.getwriter('UTF-8')(sys.stdout)

    # Fix strange user db inconsistency from (hopefully) distant past.
    # Some users in the db have user info but their login is missing from
    # the logins dict.
    users = find_users(context)
    logins = users.logins
    for id in users.byid.keys():
        login = users.get_by_id(id)['login']
        if login not in logins:
            logins[login] = id

    # Convert profiles to new workflow.
    workflow = get_workflow(IProfile, 'security')
    for profile in find_profiles(context).values():
        print >>out, ("Updating security workflow for profile: %s" %
                      profile.__name__)
        if not hasattr(profile, 'security_state'):
            # 'formeruser' was added without initializing workflow, oops.
            workflow.initialize(profile)
            workflow.transition_to_state(profile, None, 'inactive')
            continue
        assert profile.security_state == 'profile'
        assert not has_custom_acl(profile)
        profile.security_state = 'active'
        workflow.reset(profile)
Example #23
0
    def sync(self, data):
        context = self.context
        timestamp = data.pop('timestamp', None)
        if timestamp:
            context.usersync_timestamp = timestamp
        elif hasattr(context, 'usersync_timestamp'):
            del context.usersync_timestamp

        deactivate_missing = data.pop('deactivate_missing', False)
        if deactivate_missing:
            profiles = find_profiles(self.context)
            missing = set([
                p.__name__ for p in profiles.values()
                if p.security_state == 'active'
                and getattr(p, 'usersync_managed', False)
            ])
        else:
            missing = Empty()

        users = data.pop('users')
        for user in users:
            self.syncuser(user, missing)
        if data:
            raise ValueError("Unrecognized keys in user sync data: %s" %
                             data.keys())

        if missing:
            users = find_users(self.context)
            for username in missing:
                profile = profiles[username]
                workflow = get_workflow(IProfile, 'security', profile)
                workflow.transition_to_state(profile, None, 'inactive')
                users.remove(username)
Example #24
0
File: members.py Project: zagy/karl
def _add_existing_users(context, community, profiles, text, request):
    users = find_users(community)
    for profile in profiles:
        group_name = community.members_group_name
        user_name = profile.__name__
        users.add_group(user_name, group_name)

    # Generate HTML and text mail messages and send a mail for
    # each user added to the community.
    community_href = resource_url(community, request)
    _send_aeu_emails(community, community_href, profiles, text)

    # We delivered invitation messages to each user.  Redirect to
    # Manage Members with a status message.
    n = len(profiles)
    if n == 1:
        msg = 'One member added and email sent.'
    else:
        fmt = '%s members added and emails sent.'
        msg = fmt % len(profiles)
    location = resource_url(context,
                            request,
                            'manage.html',
                            query={'status_message': msg})
    return HTTPFound(location=location)
Example #25
0
def evolve(context):
    out = codecs.getwriter('UTF-8')(sys.stdout)

    # Fix strange user db inconsistency from (hopefully) distant past.
    # Some users in the db have user info but their login is missing from
    # the logins dict.
    users = find_users(context)
    logins = users.logins
    for id in users.byid.keys():
        login = users.get_by_id(id)['login']
        if login not in logins:
            logins[login] = id

    # Convert profiles to new workflow.
    workflow = get_workflow(IProfile, 'security')
    for profile in find_profiles(context).values():
        print >> out, ("Updating security workflow for profile: %s" %
                       profile.__name__)
        if not hasattr(profile, 'security_state'):
            # 'formeruser' was added without initializing workflow, oops.
            workflow.initialize(profile)
            workflow.transition_to_state(profile, None, 'inactive')
            continue
        assert profile.security_state == 'profile'
        assert not has_custom_acl(profile)
        profile.security_state = 'active'
        workflow.reset(profile)
Example #26
0
    def handle_submit(self, converted):
        try:
            context = self.context
            request = self.request
            key = request.params.get('key')
            if not key or len(key) != 40:
                e = ResetFailed()
                e.page_title = 'Password Reset URL Problem'
                raise e
            users = find_users(context)
            user = users.get_by_login(converted['login'])
            if user is None:
                raise ValidationError(login='******')
            userid = user.get('id')
            if userid is None:
                userid = user['login']

            profiles = find_profiles(context)
            profile = profiles.get(userid)
            if profile is None:
                raise ValidationError(login='******')

            if key != getattr(profile, 'password_reset_key', None):
                e = ResetFailed()
                e.page_title = 'Password Reset Confirmation Problem'
                raise e

            now = datetime.datetime.now()
            t = getattr(profile, 'password_reset_time', None)
            if t is None or now - t > max_reset_timedelta:
                e = ResetFailed()
                e.page_title = 'Password Reset Confirmation Key Expired'
                raise e

            # The key matched.  Clear the key and reset the password.
            profile.password_reset_key = None
            profile.password_reset_time = None
            password = converted['password'].encode('UTF-8')
            users.change_password(userid, password)
            request.session['password_expired'] = False
            profile.password_expiration_date = (datetime.datetime.utcnow() +
                                                datetime.timedelta(days=180))
            max_retries = request.registry.settings.get('max_login_retries', 8)
            context.login_tries[converted['login']] = max_retries

            page_title = 'Password Reset Complete'
            api = TemplateAPI(context, request, page_title)
            return render_to_response(
                'templates/reset_complete.pt',
                dict(api=api,
                     login=converted['login'],
                     password=converted['password']),
                request=request,
            )

        except ResetFailed, e:
            api = TemplateAPI(context, request, e.page_title)
            return render_to_response('templates/reset_failed.pt',
                                      dict(api=api),
                                      request=request)
Example #27
0
def move_content(root, src, dst, wf_state):
    try:
        context = find_resource(root, src)
    except KeyError:
        print >> sys.stderr, "Source content not found: %s" % src
        sys.exit(-1)

    try:
        dest_folder = find_resource(root, dst)
    except KeyError:
        print >> sys.stderr, "Destination folder not found: %s" % dst
        sys.exit(-1)

    src_community = find_community(context)

    catalog = find_catalog(root)
    assert catalog is not None
    users = find_users(root)
    assert users is not None

    if src_community is not None:
        move_header = ('<p><em>This was originally authored '
                       'in the "%s" community.</em></p>' % src_community.title)
    else:
        move_header = ''

    src_folder = context.__parent__
    name = context.__name__

    log.info("Moving %s", resource_path(context))
    for obj in postorder(context):
        if hasattr(obj, 'docid'):
            docid = obj.docid
            catalog.document_map.remove_docid(docid)
            catalog.unindex_doc(docid)
    del src_folder[name]

    if (context.creator != 'admin'
            and users.get_by_id(context.creator) is None):
        # give the entry to the system admin
        log.warning("User %s not found; reassigning to admin", context.creator)
        context.creator = 'admin'

    if name in dest_folder:
        name = make_unique_name(dest_folder, context.title)

    dest_folder[name] = context
    for obj in postorder(context):
        if hasattr(obj, 'docid'):
            docid = obj.docid
            catalog.document_map.add(resource_path(obj), docid)
            catalog.index_doc(docid, obj)

    if wf_state is not None:
        wf = get_workflow(get_content_type(context), 'security', context)
        wf.transition_to_state(context, None, wf_state)

    if hasattr(context, 'text'):
        context.text = "%s\n%s" % (move_header, context.text)
Example #28
0
File: login.py Project: lslaz1/karl
    def login_locked_out(self, login):
        users = find_users(self.context)
        user = users and users.get(login=login)
        if not user:
            return False

        mng = LockoutManager(self.context, login)
        return mng.maxed_number_of_attempts()
Example #29
0
 def __init__(self, context, request):
     self.context = context
     self.request = request
     self.filestore = get_filestore(context, request, 'add-user')
     self.photo = None
     self.users = find_users(context)
     self.group_options = get_group_options(self.context)
     self.page_title = 'Add User'
Example #30
0
def get_groups(obj, default):
    if not IProfile.providedBy(obj):
        return default
    users = find_users(obj)
    user = users.get_by_id(obj.__name__)
    if user:
        return user.get('groups', default)
    return default
Example #31
0
def showall(args):
    root, closer = args.get_root(args.inst)
    users = find_users(root)
    mapping = getattr(users, 'kerberos_map', None)
    if not mapping:
        return
    for principal, userid in mapping.items():
        print '%s\t%s' % (userid, principal)
Example #32
0
 def __init__(self, context, request):
     self.context = context
     self.request = request
     self.filestore = get_filestore(context, request, 'add-user')
     self.photo = None
     self.users = find_users(context)
     self.group_options = get_group_options(self.context)
     self.page_title = 'Add User'
Example #33
0
File: login.py Project: lslaz1/karl
    def login_locked_out(self, login):
        users = find_users(self.context)
        user = users and users.get(login=login)
        if not user:
            return False

        mng = LockoutManager(self.context, login)
        return mng.maxed_number_of_attempts()
Example #34
0
def _authenticate(context, login, password):
    userid = None
    users = find_users(context)
    for authenticate in (password_authenticator, impersonate_authenticator):
        userid = authenticate(users, login, password)
        if userid:
            break
    return userid
Example #35
0
def _authenticate(context, login, password):
    userid = None
    users = find_users(context)
    for authenticate in (password_authenticator, impersonate_authenticator):
        userid = authenticate(users, login, password)
        if userid:
            break
    return userid
Example #36
0
def get_groups(obj, default):
    if not IProfile.providedBy(obj):
        return default
    users = find_users(obj)
    user = users.get_by_id(obj.__name__)
    if user:
        return user.get('groups', default)
    return default
Example #37
0
def showall(args):
    root, closer = args.get_root(args.inst)
    users = find_users(root)
    mapping = getattr(users, 'sso_map', None)
    if not mapping:
        return
    for principal, userid in mapping.items():
        print '%s\t%s' % (userid, principal)
Example #38
0
    def syncuser(self, data, missing):
        for key in self.required_keys:
            if not data.get(key):
                raise ValueError("Invalid user data: '%s' key is required" % key)
        users = find_users(self.context)
        profiles = find_profiles(self.context)
        username = data.pop("username")
        profile = profiles.get(username)
        active = profile and profile.security_state == "active"
        if username in missing:
            missing.remove(username)
        if not profile:
            profile = self.createuser(data)
            self.update(profile, data)
            profiles[username] = profile
            activate = data.pop("active", "true")
            security_state = "active" if activate else "inactive"
            log.info("Created user: %s", username)
        else:
            objectEventNotify(ObjectWillBeModifiedEvent(profile))
            self.update(profile, data)
            objectEventNotify(ObjectModifiedEvent(profile))
            activate = data.pop("active", None)
            if activate is not None:
                security_state = "active" if activate else "inactive"
            else:
                security_state = profile.security_state
                activate = active
            if type(missing) is Empty:
                log.info("Updated user: %s", username)
        profile.usersync_managed = True

        if active:
            info = users.get(username)
            password = data.pop("password", info["password"])
            groups = data.pop("groups", info["groups"])
            login = data.pop("login", info["login"])
            users.remove(username)

        elif activate:  # reactivate
            log.info("Reactivating user: %s", username)
            login = data.pop("login", username)
            password = data.pop("password", None)
            groups = data.pop("groups", [])
            if not password:
                raise ValueError("Invalid user data: 'password' key is required to " "reactivate user")

        if activate:
            users.add(username, login, password, groups, encrypted=True)

        if security_state != getattr(profile, "security_state", None):
            workflow = get_workflow(IProfile, "security", profile)
            workflow.transition_to_state(profile, None, security_state)
            if security_state == "inactive":
                log.info("Deactivated user: %s", username)

        if data:
            raise ValueError("Unrecognized keys in sync data for user: %s: %s" % (username, data.keys()))
Example #39
0
def login_failed(event):
    # we are only going to log attempts for valid users
    users = find_users(event.site)
    user = users and users.get(login=event.login)
    if not user:
        return

    mng = LockoutManager(event.site, event.login)
    mng.add_attempt()
Example #40
0
def reset_passwords(root, group):
    user_store = find_users(root)
    users = user_store.users_in_group(group)
    for user in users:
        password = ''.join(random.SystemRandom().choice(
            string.ascii_uppercase + string.digits)
            for _ in range(32))
        user_store.change_password(user, password)
        print "reset password for {}".format(user)
Example #41
0
def mapuser(args):
    root, closer = args.get_root(args.inst)
    users = find_users(root)
    if not hasattr(users, 'kerberos_map'):
        users.kerberos_map = PersistentMapping()
    if not users.get(args.userid):
        args.parser.error("No such userid: %s" % args.userid)
    users.kerberos_map[args.principal] = args.userid
    transaction.commit()
Example #42
0
    def handle_submit(self, converted):
        context = self.context
        users = find_users(context)
        userid = context.__name__
        users.change_password(userid, converted['password'])

        path = resource_url(context, self.request)
        msg = '?status_message=Password%20changed'
        return HTTPFound(location=path + msg)
Example #43
0
def login_failed(event):
    # we are only going to log attempts for valid users
    users = find_users(event.site)
    user = users and users.get(login=event.login)
    if not user:
        return

    mng = LockoutManager(event.site, event.login)
    mng.add_attempt()
Example #44
0
 def __init__(self, site, login):
     self.site = site
     self.login = login
     self.users = find_users(site)
     try:
         self.login_attempts = site.failed_login_attempts
     except AttributeError:
         log.warn('Upgrade step to install login_attempts storage not run')
         self.login_attempts = None
Example #45
0
 def __init__(self, site, login):
     self.site = site
     self.login = login
     self.users = find_users(site)
     try:
         self.login_attempts = site.failed_login_attempts
     except AttributeError:
         log.warn('Upgrade step to install login_attempts storage not run')
         self.login_attempts = None
Example #46
0
    def handle_submit(self, converted):
        context = self.context
        users = find_users(context)
        userid = context.__name__
        users.change_password(userid, converted['password'])

        path = resource_url(context, self.request)
        msg = '?status_message=Password%20changed'
        return HTTPFound(location=path+msg)
Example #47
0
    def __call__(self):
        context, request = self.context, self.request
        api = AdminTemplateAPI(context, request, "Admin UI: Send Email")
        admin_email = get_setting(context, "admin_email")
        system_name = get_setting(context, "system_name")
        profiles = find_profiles(context)
        admin = profiles[authenticated_userid(request)]
        from_emails = [
            ("self", "%s <%s>" % (admin.title, admin.email)),
            ("admin", "%s Administrator <%s>" % (system_name, admin_email)),
        ]

        if "send_email" in request.params:
            mailer = getUtility(IMailDelivery)
            group = request.params["to_group"]
            users = find_users(context)
            search = ICatalogSearch(context)
            count, docids, resolver = search(interfaces=[IProfile])
            n = 0
            for docid in docids:
                profile = resolver(docid)
                if getattr(profile, "security_state", None) == "inactive":
                    continue
                userid = profile.__name__
                if group and not users.member_of_group(userid, group):
                    continue

                message = Message()
                if request.params["from_email"] == "self":
                    message["From"] = from_emails[0][1]
                    message_from = admin.email
                else:
                    message["From"] = from_emails[1][1]
                    message_from = admin_email
                message["To"] = "%s <%s>" % (profile.title, profile.email)
                message["Subject"] = request.params["subject"]
                body = u"<html><body>%s</body></html>" % (request.params["text"])
                message.set_payload(body.encode("UTF-8"), "UTF-8")
                message.set_type("text/html")

                mailer.send([profile.email], message)
                n += 1

            status_message = "Sent message to %d users." % n
            if has_permission(ADMINISTER, context, request):
                redirect_to = model_url(context, request, "admin.html", query=dict(status_message=status_message))
            else:
                redirect_to = model_url(
                    find_communities(context),
                    request,
                    "all_communities.html",
                    query=dict(status_message=status_message),
                )

            return HTTPFound(location=redirect_to)

        return dict(api=api, menu=_menu_macro(), to_groups=self.to_groups, from_emails=from_emails)
Example #48
0
def mapuser(args):
    root, closer = args.get_root(args.inst)
    users = find_users(root)
    if not hasattr(users, 'sso_map'):
        users.sso_map = PersistentMapping()
    if not users.get(args.userid):
        args.parser.error("No such userid: %s" % args.userid)
    users.sso_map[args.principal] = args.userid
    transaction.commit()
    def handle_submit(self, converted):
        try:
            context = self.context
            request = self.request
            key = request.params.get('key')
            if not key or len(key) != 40:
                e = ResetFailed()
                e.page_title = 'Password Reset URL Problem'
                raise e
            users = find_users(context)
            user = users.get_by_login(converted['login'])
            if user is None:
                raise ValidationError(login='******')
            userid = user.get('id')
            if userid is None:
                userid = user['login']

            profiles = find_profiles(context)
            profile = profiles.get(userid)
            if profile is None:
                raise ValidationError(login='******')

            if key != getattr(profile, 'password_reset_key', None):
                e = ResetFailed()
                e.page_title = 'Password Reset Confirmation Problem'
                raise e

            now = datetime.datetime.now()
            t = getattr(profile, 'password_reset_time', None)
            if t is None or now - t > max_reset_timedelta:
                e = ResetFailed()
                e.page_title = 'Password Reset Confirmation Key Expired'
                raise e

            # The key matched.  Clear the key and reset the password.
            profile.password_reset_key = None
            profile.password_reset_time = None
            password = converted['password'].encode('UTF-8')
            users.change_password(userid, password)

            page_title = 'Password Reset Complete'
            api = TemplateAPI(context, request, page_title)
            return render_to_response(
                'templates/reset_complete.pt',
                dict(api=api,
                     login=converted['login'],
                     password=converted['password']),
                request = request,
                )

        except ResetFailed, e:
            api = TemplateAPI(context, request, e.page_title)
            return render_to_response(
                'templates/reset_failed.pt',
                dict(api=api),
                request=request)
Example #50
0
def change_password_view(context, request):
    min_pw_length = get_setting(context, 'min_pw_length')
    form = ChangePasswordForm(min_pw_length=min_pw_length)
    if 'form.cancel' in request.POST:
        return HTTPFound(location=model_url(context, request))

    if 'form.submitted' in request.POST:
        try:
            converted = form.validate(request.POST)
            users = find_users(context)
            userid = context.__name__
            user = users.get_by_id(userid)

            # check the old password
            # XXX: repoze.who.plugins.zodb.interfaces.IUsers
            # really should have a check_password(id, password)
            # method.  We shouldn't have to use get_sha_password
            # directly.
            enc = get_sha_password(converted['old_password'])
            if enc != user['password']:
                raise CustomInvalid({'old_password': '******'})

            users.change_password(userid, converted['password'])

            # send email
            system_name = get_setting(context, 'system_name', 'KARL')
            mail = karl.mail.Message()
            admin_email = get_setting(context, 'admin_email')
            mail["From"] = "%s Administrator <%s>" % (system_name, admin_email)
            mail["To"] = "%s <%s>" % (context.title, context.email)
            mail["Subject"] = "%s Password Change Notification" % system_name
            system_name = get_setting(context, 'system_name', 'KARL')
            body = render_template(
                "templates/email_change_password.pt",
                login=user['login'],
                password=converted['password'],
                system_name=system_name,
            )

            if isinstance(body, unicode):
                body = body.encode("UTF-8")

            mail.set_payload(body, "UTF-8")
            mail.set_type("text/html")

            recipients = [context.email]
            mailer = getUtility(IMailDelivery)
            mailer.send(admin_email, recipients, mail)

            path = model_url(context, request)
            msg = '?status_message=Password%20changed'
            return HTTPFound(location=path+msg)

        except Invalid, e:
            fielderrors = e.error_dict
            fill_values = form.convert(request.POST)
Example #51
0
    def __call__(self):
        context = self.context
        request = self.request

        errors = []
        messages = []

        # Handle CSV upload
        field = request.params.get("csv", None)
        if hasattr(field, "file"):
            reactivate = request.params.get("reactivate") == "true"
            reader = csv.DictReader(field.file)
            try:
                rows = list(reader)
            except Error, e:
                errors.append("Malformed CSV: %s" % e[0])

            # Make sure we have required fields
            if not errors:
                fieldnames = rows[0].keys()
                if None in fieldnames:
                    errors.append("Malformed CSV: line 2 does not match header.")
                else:
                    for required_field in self.required_fields:
                        if required_field not in fieldnames:
                            errors.append("Missing required field: %s" % required_field)
                    if not ("password" in fieldnames or "sha_password" in fieldnames):
                        errors.append("Must supply either password or " "sha_password field.")

                    # Restrict to allowed fields
                    allowed_fields = self.allowed_fields
                    for fieldname in fieldnames:
                        if fieldname not in allowed_fields:
                            errors.append("Unrecognized field: %s" % fieldname)

            # Add users
            if not errors:
                search = ICatalogSearch(context)
                profiles = find_profiles(context)
                users = find_users(context)

                n_added = 0
                for i, row in enumerate(rows):
                    row_has_errors = False
                    if None in row or None in row.values():
                        errors.append("Malformed CSV: line %d does not match header." % (i + 2))
                        break
                    added_users, row_messages, row_errors = self._add_user_csv_row(
                        search, profiles, users, row, reactivate, i
                    )
                    n_added += added_users
                    messages += row_messages
                    errors += row_errors

                if not errors:
                    messages.append("Created %d users." % n_added)
Example #52
0
File: login.py Project: lslaz1/karl
    def login(self):
        context = self.context
        request = self.request
        # identify
        login = request.POST.get('login')
        password = request.POST.get('password')

        if self.login_locked_out(login):
            redirect = request.resource_url(
                request.root, 'login.html', query={
                    'reason': 'User locked out. Too many failed login attempts.'})
            return HTTPFound(location=redirect)

        notify(events.LoginAttempt(context, request, login, password))

        if login is None or password is None:
            return HTTPFound(location='%s/login.html' % request.application_url)
        max_age = request.POST.get('max_age')
        if max_age is not None:
            max_age = int(max_age)

        # authenticate
        userid = None
        reason = 'Bad username or password'
        users = find_users(context)
        for authenticate in (password_authenticator, impersonate_authenticator):
            userid = authenticate(context, users, login, password)
            if userid:
                break

        # if not successful, try again
        if not userid:
            notify(events.LoginFailed(context, request, login, password))
            redirect = request.resource_url(
                request.root, 'login.html', query={'reason': reason})
            return HTTPFound(location=redirect)

        tf = TwoFactor(context, request)

        if tf.enabled:
            code = request.POST.get('code')
            if not code:
                redirect = request.resource_url(
                    request.root, 'login.html',
                    query={'reason': 'No authentication code provided'})
                notify(events.LoginFailed(context, request, login, password))
                return HTTPFound(location=redirect)
            if tf.validate(userid, code):  # noqa
                notify(events.LoginFailed(context, request, login, password))
                redirect = request.resource_url(
                    request.root, 'login.html', query={'reason': 'Invalid authorization code'})  # noqa
                return HTTPFound(location=redirect)

        # else, remember
        notify(events.LoginSuccess(context, request, login, password))
        return remember_login(context, request, userid, max_age)
Example #53
0
 def __call__(self):
     context = self.context
     kw = super(OsiEditProfileFormController, self).__call__()
     if isinstance(kw, dict):
         kw['is_own_profile'] = True
         users = find_users(context)
         userid = context.__name__
         kw['is_staff'] = users.member_of_group(userid, 'group.KarlStaff')
         kw['is_active'] = context.security_state == 'active'
     return kw
Example #54
0
    def __call__(self):
        context, request = self.context, self.request
        api = AdminTemplateAPI(context, request, 'Admin UI: Send Email')
        admin_email = get_setting(context, 'admin_email')
        system_name = get_setting(context, 'system_name')
        profiles = find_profiles(context)
        admin = profiles[authenticated_userid(request)]
        from_emails = [
            ('self', '%s <%s>' % (admin.title, admin.email)),
            ('admin', '%s Administrator <%s>' % (system_name, admin_email)),
        ]

        if 'send_email' in request.params:
            mailer = getUtility(IMailDelivery)
            group = request.params['to_group']
            users = find_users(context)
            search = ICatalogSearch(context)
            count, docids, resolver = search(interfaces=[IProfile])
            n = 0
            for docid in docids:
                profile = resolver(docid)
                userid = profile.__name__
                if group and not users.member_of_group(userid, group):
                    continue

                message = Message()
                if request.params['from_email'] == 'self':
                    message['From'] = from_emails[0][1]
                    message_from = admin.email
                else:
                    message['From'] = from_emails[1][1]
                    message_from = admin_email
                message['To'] = '%s <%s>' % (profile.title, profile.email)
                message['Subject'] = request.params['subject']
                body = u'<html><body>%s</body></html>' % (
                    request.params['text']
                )
                message.set_payload(body.encode('UTF-8'), 'UTF-8')
                message.set_type('text/html')

                mailer.send(message_from, [profile.email], message)
                n += 1

            status_message = "Sent message to %d users." % n
            redirect_to = model_url(context, request, 'admin.html',
                                    query=dict(status_message=status_message))
            return HTTPFound(location=redirect_to)

        return render_template_to_response(
            'templates/admin/email_users.pt',
            api=api,
            menu=_menu_macro(),
            to_groups = self.to_groups,
            from_emails=from_emails,
        )
Example #55
0
def mapusers(args):
    root, closer = args.get_root(args.inst)
    users = find_users(root)
    if not hasattr(users, 'kerberos_map'):
        users.kerberos_map = PersistentMapping()
    for line in sys.stdin:
        userid, principal = line.split()
        if not users.get(userid):
            args.parser.error("No such userid: %s" % userid)
        users.kerberos_map[principal] = userid
    transaction.commit()
Example #56
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        name = make_name(context, converted['title'])
        userid = authenticated_userid(request)
        community = create_content(
            ICommunity,
            converted['title'],
            converted['description'],
            converted['text'],
            userid,
        )
        community.sendalert_default = converted.get('sendalert_default', True)
        # this *must* directly follow content creation because the
        # toolinfo add stuff depends on the community having a full
        # path.
        context[name] = community

        # required to use moderators_group_name and
        # members_group_name
        community.__name__ = name
        tools_present = []
        for toolinfo in self.available_tools:
            if toolinfo['name'] in converted.get('tools', []):
                toolinfo['component'].add(community, request)
                tools_present.append(toolinfo['name'])

        # Set the default tool
        if converted.get('default_tool') in tools_present:
            community.default_tool = converted['default_tool']
        else:
            community.default_tool = None

        users = find_users(context)
        moderators_group_name = community.moderators_group_name
        members_group_name = community.members_group_name

        for group_name in moderators_group_name, members_group_name:
            users.add_group(userid, group_name)

        if self.workflow is not None:
            if 'security_state' in converted:
                self.workflow.transition_to_state(community, request,
                                                  converted['security_state'])
        # Save the tags on it.
        set_tags(community, request, converted['tags'])
        # Adding a community should take you to the Add Existing
        # User screen, so the moderator can include some users.
        location = resource_url(community,
                                request,
                                'members',
                                'add_existing.html',
                                query={'status_message': 'Community added'})
        return HTTPFound(location=location)
Example #57
0
 def __init__(self, context, request):
     super(AdminEditProfileFormController, self).__init__(context, request)
     self.users = find_users(context)
     self.userid = context.__name__
     self.user = self.users.get_by_id(self.userid)
     if self.user is not None:
         self.is_active = True
         self.user_groups = set(self.user['groups'])
         self.group_options = get_group_options(self.context)
     else:
         self.is_active = False
Example #58
0
    def handle_submit(self, converted):
        context = self.context
        users = find_users(context)
        userid = context.__name__
        user = users.get_by_id(userid)

        users.change_password(userid, converted["password"])

        path = model_url(context, self.request)
        msg = "?status_message=Password%20changed"
        return HTTPFound(location=path + msg)