コード例 #1
0
    def validate_registration(self, req):
        if req.path_info == '/prefs':
            return

        acctmgr = AccountManager(self.env)
        username = acctmgr.handle_username_casing(
            req.args.get('username', '').strip())

        if not username:
            raise RegistrationError(N_("Username cannot be empty."))

        # Always exclude some special characters, i.e.
        #   ':' can't be used in HtPasswdStore
        #   '[' and ']' can't be used in SvnServePasswordStore
        blacklist = acctmgr.username_char_blacklist
        if contains_any(username, blacklist):
            pretty_blacklist = ''
            for c in blacklist:
                if pretty_blacklist == '':
                    pretty_blacklist = tag(' \'', tag.b(c), '\'')
                else:
                    pretty_blacklist = tag(pretty_blacklist,
                                           ', \'', tag.b(c), '\'')
            raise RegistrationError(N_(
                "The username must not contain any of these characters: %s"),
                tag.b(pretty_blacklist)
            )

        # All upper-cased names are reserved for permission action names.
        if username.isupper():
            raise RegistrationError(N_("A username with only upper-cased "
                                       "characters is not allowed."))

        # Prohibit some user names, that are important for Trac and therefor
        # reserved, even if not in the permission store for some reason.
        if username.lower() in ['anonymous', 'authenticated']:
            raise RegistrationError(N_("Username %s is not allowed."),
                                    tag.b(username))

        # NOTE: A user may exist in a password store but not in the permission
        #   store.  I.e. this happens, when the user (from the password store)
        #   never logged in into Trac.  So we have to perform this test here
        #   and cannot just check for the user being in the permission store.
        #   And better obfuscate whether an existing user or group name
        #   was responsible for rejection of this user name.
        for store_user in acctmgr.get_users():
            # Do it carefully by disregarding case.
            if store_user.lower() == username.lower():
                raise RegistrationError(tag_(
                    "Another account or group already exists, who's name "
                    "differs from %(username)s only by case or is identical.",
                    username=tag.b(username)))

        # Password consistency checks follow.
        password = req.args.get('password')
        if not password:
            raise RegistrationError(N_("Password cannot be empty."))
        elif password != req.args.get('password_confirm'):
            raise RegistrationError(N_("The passwords must match."))
コード例 #2
0
    def process_request(self, req):
        req.perm.assert_permission('TRAC_ADMIN')
        if not re.match(r'/autocompleteperms/autocompleteperms\.js$',
                        req.path_info):
            return

        subjects = set([])
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("SELECT username,action FROM permission")
        rows = cursor.fetchall()
        while True:
            num_users = len(subjects)
            for user, action in rows:
                if user not in subjects:
                    subjects.add(user)
                    for provider in self.group_providers:
                        subjects.update(provider.get_permission_groups(action))

                if not action.isupper() and action not in subjects:
                    subjects.add(action)
                    for provider in self.group_providers:
                        subjects.update(provider.get_permission_groups(action))

            if num_users == len(subjects):
                break

        try:
            from acct_mgr.api import AccountManager
            acc_mgr = AccountManager(self.env)
            users = acc_mgr.get_users()
        except:
            users = [x[0] for x in self.env.get_known_users()]

        group_list = list(subjects - set(users) - set('#%s' % user
                                                      for user in users))
        subjects.update(users)
        user_list = list(subjects)

        user_list.sort()
        group_list.sort()

        out = """
        var data = "%s".split(" ");
        var data_groups = "%s".split(" ");
        $(document).ready(function() {
            $("#gp_subject").autocomplete(data, {minChars: 0, max:9999});
            $("#sg_subject").autocomplete(data, {minChars: 0, max:9999});
            $("#sg_group").autocomplete(data_groups, {minChars: 0, max:9999});
        });
        """ % (" ".join(user_list), " ".join(group_list))

        req.send(out.encode("utf-8"), "text/javascript")
コード例 #3
0
 def process_admin_request(self, req, category, page, path_info):
     mgr = AccountManager(self.env)
     if path_info:
         return self._process_user_request(req, category, page, 
                                           path_info, mgr)
     else:
         if req.method == 'POST':
             if req.args.get('add'):
                 self._do_add(req, mgr)
             elif req.args.get('remove'):
                 self._do_remove(req, mgr)
     # run user list through a set to work around a bug in
     # account manager
     # see http://trac-hacks.org/ticket/180
     users = list(sets.Set(mgr.get_users()))
     users.sort()
     req.hdf['admin.users'] = \
         [{'name': u, 
           'key': u, 
           'href': self.env.href.admin(category, page, u)
          } for u in users]
     return 'admin_users.cs', None
コード例 #4
0
ファイル: userlist.py プロジェクト: leihog/TracUserfunk
    def get_users(self):

        users = {}
        try:
            from acct_mgr.api import AccountManager, get_user_attribute
            acct_mgr = AccountManager(self.env)
            for username in acct_mgr.get_users():
                users[username] = { 'username': username }

            for username, status in get_user_attribute(self.env, username=None, authenticated=None).iteritems():
                user = users.get(username)
                if user is not None and 1 in status:
                    user['name'] = status[1].get('name')
                    user['email'] = status[1].get('email')
                    user.update(self.get_last_login(username))

        except:
            for username, name, email in self.env.get_known_users():
                user = { 'username': username, 'name': name, 'email': email }
                user.update(self.get_last_login(username))
                users[username] = user

        return users
コード例 #5
0
ファイル: admin.py プロジェクト: scanterog/acct_mgr-0.4.4
def fetch_user_data(env, req):
    acctmgr = AccountManager(env)
    guard = AccountGuard(env)
    accounts = {}
    for username in acctmgr.get_users():
        if req.perm.has_permission('ACCTMGR_USER_ADMIN'):
            url = req.href.admin('accounts', 'users', user=username)
        else:
            url = None
        accounts[username] = {'username': username, 'review_url': url}
        if guard.user_locked(username):
            accounts[username]['locked'] = True
            t_lock = guard.lock_time(username)
            if t_lock > 0:
                t_release = guard.pretty_release_time(req, username)
                accounts[username]['release_hint'] = _(
                        "Locked until %(t_release)s",
                        t_release=t_release)
    for acct, status in get_user_attribute(env, username=None,
                                           authenticated=None).iteritems():
        account = accounts.get(acct)
        if account is not None and 1 in status:
            # Only use attributes related to authenticated
            # accounts.
            account['name'] = status[1].get('name')
            account['email'] = status[1].get('email')
            if account['email']:
                account['email'] = Chrome(env).format_author(req,
                                                             account['email'])
    ts_seen = last_seen(env)
    if ts_seen is not None:
        for username, last_visit in ts_seen:
            account = accounts.get(username)
            if account and last_visit:
                account['last_visit'] = to_datetime(last_visit)
    return sorted(accounts.itervalues(), key=lambda acct: acct['username'])
コード例 #6
0
ファイル: admin.py プロジェクト: pombredanne/trachacks
def fetch_user_data(env, req):
    acctmgr = AccountManager(env)
    guard = AccountGuard(env)
    accounts = {}
    for username in acctmgr.get_users():
        if req.perm.has_permission('ACCTMGR_USER_ADMIN'):
            url = req.href.admin('accounts', 'users', user=username)
        else:
            url = None
        accounts[username] = {'username': username, 'review_url': url}
        if guard.user_locked(username):
            accounts[username]['locked'] = True
            t_lock = guard.lock_time(username)
            if t_lock > 0:
                t_release = guard.pretty_release_time(req, username)
                accounts[username]['release_hint'] = _(
                    "Locked until %(t_release)s", t_release=t_release)
    for acct, status in get_user_attribute(env,
                                           username=None,
                                           authenticated=None).iteritems():
        account = accounts.get(acct)
        if account is not None and 1 in status:
            # Only use attributes related to authenticated
            # accounts.
            account['name'] = status[1].get('name')
            account['email'] = status[1].get('email')
            if account['email']:
                account['email'] = Chrome(env).format_author(
                    req, account['email'])
    ts_seen = last_seen(env)
    if ts_seen is not None:
        for username, last_visit in ts_seen:
            account = accounts.get(username)
            if account and last_visit:
                account['last_visit'] = to_datetime(last_visit)
    return sorted(accounts.itervalues(), key=lambda acct: acct['username'])
コード例 #7
0
class GroupsEditorPlugin(Component):
    """ Trac Groups Editor plugin
      Edit the groups in the group file.
      Select a group
      Display it's contents
      Delete or add listed members
      If the fine grained page permissions plugine is enabled, then
      as an option also update it.
    """
    implements(IAdminPanelProvider, ITemplateProvider)

    def __init__(self):
        self.account_manager = AccountManager(self.env)

    ### ITemplateProvider methods

    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        from pkg_resources import resource_filename
        return [('ge', resource_filename(__name__, 'htdocs'))]

    ### IAdminPanelProvider methods

    def get_admin_panels(self, req):
        if 'TRAC_ADMIN' in req.perm:
            yield ('accounts', _("Accounts"), 'groups', _("Groups"))

    def _get_filename(self, section, name):
        file_name = self.config.get(section, name)
        if len(file_name):
            if not file_name.startswith(os.path.sep) and \
                    not file_name[1] == ':':
                file_name = os.path.join(self.env.path, file_name)
            return file_name
        else:
            return None

    def _group_filename(self):
        group_file_name = self._get_filename('account-manager', 'group_file')
        if not group_file_name:
            group_file_name = self._get_filename('htgroups', 'group_file')
        if not group_file_name:
            raise TracError("""Group filename not found in the config file. In
                neither sections "account-manager" nor "htgroups" under the
                name "group_file".""")
        if not os.path.exists(group_file_name):
            raise TracError('Group filename not found: %s.' % group_file_name)

        return group_file_name

    def _get_groups_and_members(self):
        """Get the groups and their members as a dictionary of lists. """
        # could be in one of two places, depending if the  account-manager
        # is installed or not
        group_file_name = self._group_filename()
        groups_dict = dict()
        group_file = file(group_file_name)
        try:
            for group_line in group_file:
                # Ignore blank lines and lines starting with #
                group_line = group_line.strip()
                if group_line and not group_line.startswith('#'):
                    group_name = group_line.split(':', 1)[0]
                    group_members = group_line.split(':', 2)[1].split(' ')
                    groups_dict[group_name] = [member.strip() for member in
                                               group_members if member]
        finally:
            group_file.close()
        if len(groups_dict):
            return groups_dict
        else:
            return None

    def _write_groups_file(self, entries):
        """
        Write the groups and members to the groups file
        """
        group_file = open(self._group_filename(), 'w')
        for group_name in entries.keys():
            group_file.write(group_name + ': ' +
                             ' '.join(entries[group_name]) + '\n')
        group_file.close()

    def _check_for_finegrained(self):
        """Check if the fine grained permission system is enabled."""
        component = self.config.get('components',
                                    'authzpolicy.authz_policy.authzpolicy')
        return component == 'enabled'

    def _update_fine_grained(self, group_details):
        authz_policy_file_name = self._get_filename('authz_policy',
                                                    'authz_file')
        authz_policy_dict = ConfigObj(authz_policy_file_name)
        # If there isn't a group file, don't destroy the existing entries
        if group_details:
            authz_policy_dict['groups'] = group_details
        authz_policy_dict.write()

    def render_admin_panel(self, req, cat, page, path_info):
        """Render the panel.
        When applying deletions and additions, additions
        happen post deletions, so additions in effect have
        a higher precedence.  The way it is done, it shouldn't be
        possible to have both 
        """
        req.perm.require('TRAC_ADMIN')
        add_stylesheet(req, 'ge/css/htgroupeditor.css')

        page_args = {}

        group_details = self._get_groups_and_members()

        # For ease of understanding and future reading
        # being done in the ORDER displayed.
        if not req.method == 'POST':
            groups_list = ['']
            if group_details is not None:
                groups_list += group_details.keys()
            page_args['groups_list'] = groups_list
        else:
            group_name = str(req.args.get('group_name'))
            # put the selected entry at the top of the list
            groups_list = group_details.keys()
            groups_list.remove(group_name)
            groups_list.insert(0, group_name)
            # Get rid of duplicates
            users_list = list()
            for name in group_details[group_name]:
                if name not in users_list:
                    users_list.append(name)
            group_details[group_name] = users_list

            if req.args.get('deletions'):
                deletions = req.args.get('deletions')
                if not isinstance(deletions, list):
                    deletions = [deletions]
                for deletion in deletions:
                    # In case there arer multiple entries
                    while deletion in group_details[group_name]:
                        group_details[group_name].remove(deletion)

            if req.args.get('additional_names'):
                additional_names = req.args.get('additional_names')
                if not isinstance(additional_names, list):
                    additional_names = [additional_names]
                #  If a reload is done after an add, a duplicate can be created
                for name in additional_names:
                    if name not in group_details[group_name]:
                        group_details[group_name].append(name)

            # get the list of users not in the group
            addable_usernames = []
            for username in self.account_manager.get_users():
                username = username.strip()
                if len(username) and not username in group_details[group_name]:
                    addable_usernames.append(username)   

            group_details[group_name].sort()

            page_args['groups_list'] = groups_list
            page_args['users_list'] = group_details[group_name]
            page_args['addable_usernames'] = addable_usernames
            page_args['group_name'] = group_name
            page_args['finegrained'] = self._check_for_finegrained()

            if req.args.get('apply_changes'):
                self._write_groups_file(group_details)
                # update the fine grained permissions, if it is installed    
                if req.args.get('finegrained_check'):
                    self._update_fine_grained(group_details)

        return 'htgroupeditor.html', page_args
コード例 #8
0
ファイル: pape_admin.py プロジェクト: pombredanne/trachacks
class PageAuthzPolicyEditor(Component):
    implements(IAdminPanelProvider, ITemplateProvider)

    def __init__(self):
        self.account_manager = AccountManager(self.env)

    # ITemplateProvider methods
    def get_templates_dirs(self):
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        return []

    # IAdminPanelProvider methods
    def get_admin_panels(self, req):
        if 'TRAC_ADMIN' in req.perm:
            yield ('accounts', translation._('Accounts'), 'pages',
                   translation._('Page Permissions'))

    def _get_filename(self, section, name):
        file_name = self.config.get(section, name)
        if len(file_name):
            if (not file_name.startswith(os.path.sep)) and (not file_name[1]
                                                            == (':')):
                file_name = os.path.join(self.env.path, file_name)
            return (file_name)
        else:
            return (None)

    def _get_users(self):
        user_list = ', '.join(self.account_manager.get_users())
        return (user_list)

    def _group_filename(self):
        group_file_name = self._get_filename('account-manager', 'group_file')
        if not group_file_name:
            group_file_name = self._get_filename('htgroups', 'group_file')
        if not group_file_name:
            raise TracError(
                'Group filename not found in the config file. In neither sections\
                                "account-manager" nor "htgroups" under the name "group_file".'
            )
        if not os.path.exists(group_file_name):
            raise TracError('Group filename not found: %s.' % group_file_name)
        return (group_file_name)

    # Get the groups and their members so they can easily be included in the
    # groups section of the authz file.  Need it as a dictionary of arrays so it be easily
    # iterated.
    def _get_groups_and_members(self):
        """
        Get the groups and their members as a dictionary of
        lists.
        """
        # could be in one of two places, depending if the
        # account-manager is installed or not
        group_file_name = self._group_filename()
        groups_dict = dict()
        group_file = file(group_file_name)
        try:
            for group_line in group_file:
                # Ignore blank lines and lines starting with #
                group_line = group_line.strip()
                if group_line and not group_line.startswith('#'):
                    group_name = group_line.split(':', 1)[0]
                    group_members = group_line.split(':', 2)[1].split(' ')
                    groups_dict[group_name] = [
                        x
                        for x in [member.strip() for member in group_members]
                        if x
                    ]
        finally:
            group_file.close()
        if len(groups_dict):
            return groups_dict
        else:
            return None

    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('TRAC_ADMIN')
        authz_policy_file_name = self._get_filename('authz_policy',
                                                    'authz_file')
        group_details = self._get_groups_and_members()
        # Handle the return data
        if req.method == 'POST':
            if req.args.get('authz_file_contents'):
                # The data needs to be validated, otherwise duplicate
                # entries can break things.
                edited_contents = str(req.args.get('authz_file_contents'))
                edited_contents_stringio = StringIO(edited_contents)
                try:
                    test_authz_policy_dict = ConfigObj(
                        edited_contents_stringio)
                except:
                    raise TracError(
                        _('Error in edited file.  Re-edit and check for duplicate entries.'
                          ))
                authz_policy_file = open(authz_policy_file_name, 'w')
                test_authz_policy_dict.write(authz_policy_file)
                authz_policy_file.close()

        authz_policy_dict = ConfigObj(authz_policy_file_name)

        # If there isn't a group file, don't destroy the existing entries
        if (group_details):
            authz_policy_dict['groups'] = group_details

        # This is purely to fill in the text area with the contents.
        contents = StringIO()
        authz_policy_dict.write(contents)

        #contents = open(authz_policy_file_name).readlines()
        data = {
            'file_name': authz_policy_file_name,
            'contents': contents.getvalue(),
            'users': self._get_users()
        }
        return 'page_authz_policy_editor.html', {'pages_authz': data}
コード例 #9
0
class GroupsEditorPlugin(Component):
    """ Trac Groups Editor plugin
      Edit the groups in the group file.
      Select a group
      Display it's contents
      Delete or add listed members
      If the fine grained page permissions plugine is enabled, then
      as an option also update it.
    """
    implements(IAdminPanelProvider, ITemplateProvider)

    def __init__(self):
        self.account_manager = AccountManager(self.env)

    ### ITemplateProvider methods

    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        from pkg_resources import resource_filename
        return [('ge', resource_filename(__name__, 'htdocs'))]

    ### IAdminPanelProvider methods

    def get_admin_panels(self, req):
        if 'TRAC_ADMIN' in req.perm:
            yield ('accounts', _("Accounts"), 'groups', _("Groups"))

    def _get_filename(self, section, name):
        file_name = self.config.get(section, name)
        if len(file_name):
            if not file_name.startswith(os.path.sep) and \
                    not file_name[1] == ':':
                file_name = os.path.join(self.env.path, file_name)
            return file_name
        else:
            return None

    def _group_filename(self):
        group_file_name = self._get_filename('account-manager', 'group_file')
        if not group_file_name:
            group_file_name = self._get_filename('htgroups', 'group_file')
        if not group_file_name:
            raise TracError("""Group filename not found in the config file. In
                neither sections "account-manager" nor "htgroups" under the
                name "group_file".""")
        if not os.path.exists(group_file_name):
            raise TracError('Group filename not found: %s.' % group_file_name)

        return group_file_name

    def _get_groups_and_members(self):
        """Get the groups and their members as a dictionary of lists. """
        # could be in one of two places, depending if the  account-manager
        # is installed or not
        group_file_name = self._group_filename()
        groups_dict = dict()
        group_file = file(group_file_name)
        try:
            for group_line in group_file:
                # Ignore blank lines and lines starting with #
                group_line = group_line.strip()
                if group_line and not group_line.startswith('#'):
                    group_name = group_line.split(':', 1)[0]
                    group_members = group_line.split(':', 2)[1].split(' ')
                    groups_dict[group_name] = [
                        member.strip() for member in group_members if member
                    ]
        finally:
            group_file.close()
        if len(groups_dict):
            return groups_dict
        else:
            return None

    def _write_groups_file(self, entries):
        """
        Write the groups and members to the groups file
        """
        group_file = open(self._group_filename(), 'w')
        for group_name in entries.keys():
            group_file.write(group_name + ': ' +
                             ' '.join(entries[group_name]) + '\n')
        group_file.close()

    def _check_for_finegrained(self):
        """Check if the fine grained permission system is enabled."""
        component = self.config.get('components',
                                    'authzpolicy.authz_policy.authzpolicy')
        return component == 'enabled'

    def _update_fine_grained(self, group_details):
        authz_policy_file_name = self._get_filename('authz_policy',
                                                    'authz_file')
        authz_policy_dict = ConfigObj(authz_policy_file_name)
        # If there isn't a group file, don't destroy the existing entries
        if group_details:
            authz_policy_dict['groups'] = group_details
        authz_policy_dict.write()

    def render_admin_panel(self, req, cat, page, path_info):
        """Render the panel.
        When applying deletions and additions, additions
        happen post deletions, so additions in effect have
        a higher precedence.  The way it is done, it shouldn't be
        possible to have both 
        """
        req.perm.require('TRAC_ADMIN')
        add_stylesheet(req, 'ge/css/htgroupeditor.css')

        page_args = {}

        group_details = self._get_groups_and_members()

        # For ease of understanding and future reading
        # being done in the ORDER displayed.
        if not req.method == 'POST':
            groups_list = ['']
            if group_details is not None:
                groups_list += group_details.keys()
            page_args['groups_list'] = groups_list
        else:
            group_name = str(req.args.get('group_name'))
            # put the selected entry at the top of the list
            groups_list = group_details.keys()
            groups_list.remove(group_name)
            groups_list.insert(0, group_name)
            # Get rid of duplicates
            users_list = list()
            for name in group_details[group_name]:
                if name not in users_list:
                    users_list.append(name)
            group_details[group_name] = users_list

            if req.args.get('deletions'):
                deletions = req.args.get('deletions')
                if not isinstance(deletions, list):
                    deletions = [deletions]
                for deletion in deletions:
                    # In case there arer multiple entries
                    while deletion in group_details[group_name]:
                        group_details[group_name].remove(deletion)

            if req.args.get('additional_names'):
                additional_names = req.args.get('additional_names')
                if not isinstance(additional_names, list):
                    additional_names = [additional_names]
                #  If a reload is done after an add, a duplicate can be created
                for name in additional_names:
                    if name not in group_details[group_name]:
                        group_details[group_name].append(name)

            # get the list of users not in the group
            addable_usernames = []
            for username in self.account_manager.get_users():
                username = username.strip()
                if len(username) and not username in group_details[group_name]:
                    addable_usernames.append(username)

            group_details[group_name].sort()

            page_args['groups_list'] = groups_list
            page_args['users_list'] = group_details[group_name]
            page_args['addable_usernames'] = addable_usernames
            page_args['group_name'] = group_name
            page_args['finegrained'] = self._check_for_finegrained()

            if req.args.get('apply_changes'):
                self._write_groups_file(group_details)
                # update the fine grained permissions, if it is installed
                if req.args.get('finegrained_check'):
                    self._update_fine_grained(group_details)

        return 'htgroupeditor.html', page_args
コード例 #10
0
 def expand_macro(self, formatter, name, content):
     env = formatter.env
     req = formatter.req
     if not content:
         args = []
         kw = {}
     else:
         args, kw = parse_args(content)
     if name == 'ProjectStats':
         if 'wiki' in kw.keys():
             prefix = 'prefix' in kw.keys() and kw['prefix'] or None
             wiki = WikiSystem(env)
             if kw['wiki'] == 'count' or 'count' in args:
                 return tag(len(list(wiki.get_pages(prefix))))
     elif name == 'UserQuery':
         msg_no_perm = tag.p(tag_("(required %(perm)s missing)",
                                  perm=tag.strong('USER_VIEW')),
                             class_='hint')
         if 'perm' in kw.keys():
             perm_sys = PermissionSystem(self.env)
             users = perm_sys.get_users_with_permission(kw['perm'].upper())
         else:
             acct_mgr = AccountManager(env)
             users = list(set(acct_mgr.get_users()))
         if 'locked' in kw.keys() or 'locked' in args:
             guard = AccountGuard(env)
             locked = []
             for user in users:
                 if guard.user_locked(user):
                     locked.append(user)
             if kw.get('locked', 'True').lower() in ('true', 'yes', '1'):
                 users = locked
             else:
                 users = list(set(users) - set(locked))
         elif 'visit' in kw.keys() or 'visit' in args:
             if 'USER_VIEW' not in req.perm:
                 return msg_no_perm
             cols = []
             data = {'accounts': fetch_user_data(env, req), 'cls': 'wiki'}
             for col in ('email', 'name'):
                 if col in args:
                     cols.append(col)
             data['cols'] = cols
             return Chrome(env).render_template(req, 'user_table.html',
                                                data, 'text/html', True)
         if kw.get('format') == 'count' or 'count' in args:
             return tag(len(users))
         if 'USER_VIEW' not in req.perm:
             return msg_no_perm
         if 'email' in args or 'name' in args:
             # Replace username with full name, add email if available.
             for username, name, email in self.env.get_known_users():
                 if username in users:
                     if 'name' not in args or name is None:
                         name = username
                     if 'email' in args and email is not None:
                         email = ''.join(['<', email, '>'])
                         name = ' '.join([name, email])
                     if not username == name:
                         users.pop(users.index(username))
                         users.append(name)
         if not users and 'nomatch' in kw.keys():
             return format_to_oneliner(env, formatter.context,
                                       kw['nomatch'])
         users = sorted(users)
         if kw.get('format') == 'list':
             return tag.ul([
                 tag.li(Chrome(env).format_author(req, user))
                 for user in users
             ])
         else:
             # Default output format: comma-separated list.
             return tag(', '.join(
                 [Chrome(env).format_author(req, user) for user in users]))
コード例 #11
0
 def expand_macro(self, formatter, name, content):
     env = formatter.env
     req = formatter.req
     if not content:
         args = []
         kw = {}
     else:
         args, kw = parse_args(content)
     if name == 'ProjectStats':
         if 'wiki' in kw.keys():
             prefix = 'prefix' in kw.keys() and kw['prefix'] or None
             wiki = WikiSystem(env)
             if kw['wiki'] == 'count' or 'count' in args:
                 return tag(len(list(wiki.get_pages(prefix))))
     elif name == 'UserQuery':
         msg_no_perm = tag.p(tag_("(required %(perm)s missing)",
                                  perm=tag.strong('USER_VIEW')),
                             class_='hint')
         if 'perm' in kw.keys():
             perm_sys = PermissionSystem(self.env)
             users = perm_sys.get_users_with_permission(kw['perm'].upper())
         else:
             acct_mgr = AccountManager(env)
             users = list(set(acct_mgr.get_users()))
         if 'locked' in kw.keys() or 'locked' in args:
             guard = AccountGuard(env)
             locked = []
             for user in users:
                 if guard.user_locked(user):
                     locked.append(user)
             if kw.get('locked', 'True').lower() in ('true', 'yes', '1'):
                 users = locked
             else:
                 users = list(set(users) - set(locked))
         elif 'visit' in kw.keys() or 'visit' in args:
             if 'USER_VIEW' not in req.perm:
                 return msg_no_perm
             cols = []
             data = {'accounts': fetch_user_data(env, req), 'cls': 'wiki'}
             for col in ('email', 'name'):
                 if col in args:
                     cols.append(col)
             data['cols'] = cols
             return Chrome(env).render_template(
                 req, 'user_table.html', data, 'text/html', True)
         if kw.get('format') == 'count' or 'count' in args:
             return tag(len(users))
         if 'USER_VIEW' not in req.perm:
             return msg_no_perm
         if 'email' in args or 'name' in args:
             # Replace username with full name, add email if available.
             for username, name, email in self.env.get_known_users():
                 if username in users:
                     if 'name' not in args or name is None:
                         name = username
                     if 'email' in args and email is not None:
                         email = ''.join(['<', email, '>'])
                         name = ' '.join([name, email])
                     if not username == name:
                         users.pop(users.index(username))
                         users.append(name)
         if not users and 'nomatch' in kw.keys():
             return format_to_oneliner(env, formatter.context,
                                       kw['nomatch'])
         users = sorted(users)
         if kw.get('format') == 'list':
             return tag.ul([tag.li(Chrome(env).format_author(req, user))
                            for user in users])
         else:
             # Default output format: comma-separated list.
             return tag(', '.join([Chrome(env).format_author(req, user)
                                   for user in users]))
コード例 #12
0
class GroupsEditorPlugin(Component):
    implements(IAdminPanelProvider, ITemplateProvider, IPermissionGroupProvider)

    def __init__(self):
        self.account_manager = AccountManager(self.env)

    # ITemplateProvider methods
    # Used to add the plugin's templates and htdocs 
    def get_templates_dirs(self):
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        return []

    # IPermissionGroupProvider methdos
    def get_permission_groups(self, username):
        """Return a list of names of the groups that the user with the specified
        name is a member of."""

        groups_list = []
        groups_dict = self._get_groups_and_members() or {}

        for group,usernames in groups_dict.items():
            if username in usernames:
                groups_list.append(group)
        
        return groups_list

    # IAdminPanelProvider methods
    def get_admin_panels(self, req):
        """Return a list of available admin panels.
            The items returned by this function must be tuples of the form
            `(category, category_label, page, page_label)`.
        """
        if 'TRAC_ADMIN' in req.perm:
            # Simply put, it's what goes in the menu on the left!
            # the page is the name of the page that will be called for the menu entry
            # it will go ...../category/page
            yield ('accounts', translation._('Accounts'), 'groups', translation._('Groups'))


    def _get_filename(self, section, name):
        file_name = self.config.get(section, name)
        if len(file_name):
            if (not file_name.startswith(os.path.sep)) and (not file_name[1] == (':')):
                file_name = os.path.join(self.env.path, file_name)
            return(file_name)
        else:
            return(None)

    def _group_filename(self):
        group_file_name = self._get_filename('account-manager', 'group_file')
        if not group_file_name:
            group_file_name = self._get_filename('htgroups', 'group_file')
        if not group_file_name:
            raise TracError('Group filename not found in the config file. In neither sections\
                                "account-manager" nor "htgroups" under the name "group_file".')
        if not os.path.exists(group_file_name):
            raise TracError('Group filename not found: %s.' % group_file_name)
        return(group_file_name)


    def _get_groups_and_members(self):
        """
        Get the groups and their members as a dictionary of
        lists.
        """
        # could be in one of two places, depending if the 
        # account-manager is installed or not
        group_file_name = self._group_filename()
        groups_dict = dict()
        group_file = file(group_file_name)
        try:
            for group_line in group_file:
                # Ignore blank lines and lines starting with #
                group_line = group_line.strip()
                if group_line and not group_line.startswith('#'):
                    group_name = group_line.split(':', 1)[0]
                    group_members = group_line.split(':', 2)[1].split(' ')
                    groups_dict[group_name] = [ x for x in [member.strip() for member in group_members] if x ]
        finally:
            group_file.close()
        if len(groups_dict):
            return groups_dict
        else:
            return None


    def _write_groups_file(self, entries):
        """
        Write the groups and members to the groups file
        """
        group_file = open(self._group_filename(), 'w')
        for group_name in entries.keys():
            group_file.write(group_name + ': ' + ' '.join(entries[group_name]) + '\n')
        group_file.close()


    def _check_for_finegrained(self):
        """
        Check if the fine grained permission system is installed
        """
        return (self.config.getbool('components', 'authzpolicy.authz_policy.authzpolicy') or
                self.config.getbool('components', 'authz_policy.authzpolicy') )

    def _check_for_svnauthz(self):
        """
        Check if the SVN Authz Plugin is installed
        """
        return self.config.getbool('components','svnauthz.svnauthz.svnauthzplugin')

    def _update_fine_grained(self, group_details):
        #import ConfigObj
        authz_policy_file_name = self._get_filename('authz_policy', 'authz_file')
        authz_policy_dict = ConfigObj(authz_policy_file_name)
        # If there isn't a group file, don't destroy the existing entries
        if (group_details):
            authz_policy_dict['groups'] = group_details
        authz_policy_dict.write()

    def _update_svnauthz(self, group_details):
        svnauthz_policy_file_name = self._get_filename('trac','authz_file')
        svnauthz_policy_dict = ConfigObj(svnauthz_policy_file_name)
        # If there isn't a group file, don't destroy the existing entries
        if (group_details):
            svnauthz_policy_dict['groups'] = group_details
        svnauthz_policy_dict.write()
        

    def render_admin_panel(self, req, cat, page, path_info):
        """
        Render up the panel.
        When applying deletions and additions, additions
        happen post deletions, so additions in effect have
        a higher precedence.  The way it is done, it shouldn't be
        possible to have both 
        """
        req.perm.require('TRAC_ADMIN')
        add_stylesheet(req, 'ge/css/htgroupeditor.css')

        page_args = {}

        group_details = self._get_groups_and_members()
        
        # This option needs to be set if the admin can add and delete groups
        # usage in trac.ini:
        # [htgroupedit]
        # allowgroupedit = enabled
        allowgroupedit = self.config.getbool("htgroupeditor","allowgroupedit")

        # For ease of understanding and future reading
        # being done in the ORDER displayed.
        if not req.method == 'POST':
            groups_list = [''];
            if group_details is not None:
               groups_list = groups_list + group_details.keys()

            page_args['groups_list'] = groups_list
            page_args['allowgroupedit'] = allowgroupedit

            return 'htgroupeditor.html', page_args
        else:
            if req.args.get('new_group') and group_details is None:
                # It can only happen for new_group, that group_details is None
                groups_list = []
                group_details = {}
            else:
                groups_list = group_details.keys()
            
            if req.args.get('new_group') and allowgroupedit:
                # Create new group and select it
                if not req.args.get('new_group_name') or len(str(req.args.get('new_group_name')).strip()) == 0:
                    raise TracError("Group name was empty")
                
                group_name = str(req.args.get('new_group_name')).strip()
                if group_name in group_details.keys():
                    raise TracError("Group already exists")
                
                group_details[group_name] = []
                groups_list.append(group_name)
            elif req.args.get('delete_group') and allowgroupedit:
                # Deleting a group involves removing it from list and details
                delete_group_name = str(req.args.get('group_name')).strip()
                if not delete_group_name in groups_list:
                    raise TracError("Invalid group for deletion")
                
                del group_details[delete_group_name]
                groups_list.remove(delete_group_name)
                
                if len(groups_list) == 0:
                    # In case that was the last group, the subsequent won't work
                    # Thus we have to do the writing of files here and return the empty page
                    self._write_groups_file(group_details)
                    if req.args.get('finegrained_check'):
                        self._update_fine_grained(group_details)
                    if req.args.get('svnauthz_check'):
                        self._update_svnauthz(group_details)
                    
                    # Finally send the empty page
                    page_args['groups_list'] = ['']
                    page_args['allowgroupedit'] = allowgroupedit

                    return 'htgroupeditor.html', page_args
                
                # Select first group in list
                group_name = groups_list[0]
            else:
                # Select group based on the request
                group_name = str(req.args.get('group_name'))
            
            # put the selected entry at the top of the list
            groups_list.remove(group_name)
            groups_list.insert(0, group_name)
            # Get rid of duplicates
            users_list = list()
            for name in group_details[group_name]:
                if name not in users_list:
                    users_list.append(name)
            group_details[group_name] = sorted(users_list)

            if req.args.get('deletions'):
                deletions = req.args.get('deletions')
                # if only on entry it will be a string, so need to make it a list
                if not isinstance(deletions, list):
                    deletions = [deletions]
                for deletion in deletions:
                    # In case there arer multiple entries
                    while deletion in group_details[group_name]:
                        group_details[group_name].remove(deletion)

            if req.args.get('additional_names'):
                additional_names = req.args.get('additional_names')
                if not isinstance(additional_names, list):
                    additional_names = [additional_names]
                #  If a reload is done after an add, a duplicate can be created.
                for name in additional_names:
                    if name not in group_details[group_name]:
                        group_details[group_name].append(name)

            # get the list of users not in the group
            addable_usernames = []
            for username in self.account_manager.get_users():
                username = username.strip()
                if len(username) and not username in group_details[group_name]:
                    addable_usernames.append(username)   

            group_details[group_name].sort()
            addable_usernames.sort()

            page_args['groups_list'] = groups_list
            page_args['users_list'] = group_details[group_name]
            page_args['addable_usernames'] = addable_usernames
            page_args['group_name'] = group_name
            page_args['finegrained'] = self._check_for_finegrained()
            page_args['svnauthz'] = self._check_for_svnauthz()
            page_args['allowgroupedit'] = allowgroupedit

            if req.args.get('apply_changes') or req.args.get('new_group') or req.args.get('delete_group'):
                self._write_groups_file(group_details)
                # update the fine grained permissions, if it is installed    
                if req.args.get('finegrained_check'):
                    self._update_fine_grained(group_details)
                if req.args.get('svnauthz_check'):
                    self._update_svnauthz(group_details)

            return 'htgroupeditor.html', page_args
コード例 #13
0
ファイル: pape_admin.py プロジェクト: nyuhuhuu/trachacks
class PageAuthzPolicyEditor(Component):
    implements(IAdminPanelProvider, ITemplateProvider)

    def __init__(self):
        self.account_manager = AccountManager(self.env)

    # ITemplateProvider methods
    def get_templates_dirs(self):
        return [resource_filename(__name__, 'templates')]
    
    def get_htdocs_dirs(self):
        return []

    # IAdminPanelProvider methods
    def get_admin_panels(self, req):
        if 'TRAC_ADMIN' in req.perm:
            yield ('accounts', translation._('Accounts'), 'pages', translation._('Page Permissions'))

    def _get_filename(self, section, name):
        file_name = self.config.get(section, name)
        if len(file_name):
            if (not file_name.startswith(os.path.sep)) and (not file_name[1] == (':')):
                file_name = os.path.join(self.env.path, file_name)
            return(file_name)
        else:
            return(None)

    def _get_users(self):
        user_list = ', '.join(self.account_manager.get_users())
        return(user_list)

    def _group_filename(self):
        group_file_name = self._get_filename('account-manager', 'group_file')
        if not group_file_name:
            group_file_name = self._get_filename('htgroups', 'group_file')
        if not group_file_name:
            raise TracError('Group filename not found in the config file. In neither sections\
                                "account-manager" nor "htgroups" under the name "group_file".')
        if not os.path.exists(group_file_name):
            raise TracError('Group filename not found: %s.' % group_file_name)
        return(group_file_name)

    # Get the groups and their members so they can easily be included in the
    # groups section of the authz file.  Need it as a dictionary of arrays so it be easily
    # iterated.    
    def _get_groups_and_members(self):
        """
        Get the groups and their members as a dictionary of
        lists.
        """
        # could be in one of two places, depending if the 
        # account-manager is installed or not
        group_file_name = self._group_filename()
        groups_dict = dict()
        group_file = file(group_file_name)
        try:
            for group_line in group_file:
                # Ignore blank lines and lines starting with #
                group_line = group_line.strip()
                if group_line and not group_line.startswith('#'):
                    group_name = group_line.split(':', 1)[0]
                    group_members = group_line.split(':', 2)[1].split(' ')
                    groups_dict[group_name] = [ x for x in [member.strip() for member in group_members] if x ]
        finally:
            group_file.close()
        if len(groups_dict):
            return groups_dict
        else:
            return None



    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('TRAC_ADMIN')
        authz_policy_file_name = self._get_filename('authz_policy', 'authz_file')
        group_details = self._get_groups_and_members()
        # Handle the return data
        if req.method == 'POST':
             if req.args.get('authz_file_contents'):
                # The data needs to be validated, otherwise duplicate
                # entries can break things.
                edited_contents = str(req.args.get('authz_file_contents'))
                edited_contents_stringio = StringIO(edited_contents)
                try:
                    test_authz_policy_dict = ConfigObj(edited_contents_stringio)
                except:
                    raise TracError(_('Error in edited file.  Re-edit and check for duplicate entries.'))
                authz_policy_file = open(authz_policy_file_name, 'w')
                test_authz_policy_dict.write(authz_policy_file)
                authz_policy_file.close()

        authz_policy_dict = ConfigObj(authz_policy_file_name)

        # If there isn't a group file, don't destroy the existing entries
        if (group_details):
            authz_policy_dict['groups'] = group_details

        # This is purely to fill in the text area with the contents.
        contents = StringIO()
        authz_policy_dict.write(contents)


        #contents = open(authz_policy_file_name).readlines()
        data = {
            'file_name' : authz_policy_file_name,
            'contents': contents.getvalue(),
            'users' : self._get_users()
        }
        return 'page_authz_policy_editor.html', {'pages_authz': data}