Edgewall Software
Modify

Ticket #9336 (closed enhancement: fixed)

Opened 2 years ago

Last modified 5 months ago

[PATCH] trac-admin import/export permissions

Reported by: anatoly techtonik <techtonik@…> Owned by: psuter
Priority: high Milestone: 0.13
Component: admin/console Version: 0.12dev
Severity: normal Keywords:
Cc: leho@…, thijstriemstra
Release Notes:

Import and export Trac permissions with trac-admin $ENV permission <import|export>

API Changes:

Description

trac-admin should allow to export permissions from old environment, edit them and import back

Attachments

permission-import-export.patch (3.7 KB) - added by psuter <petsuter@…> 12 months ago.
CSV permission import and export trac-admin commands
permission-import-export2.patch (4.2 KB) - added by psuter <petsuter@…> 12 months ago.
one user per line; check existing perms; file completion
trac-admin-completion-on-windows.patch (2.6 KB) - added by psuter <petsuter@…> 12 months ago.
Improve trac-admin path completion on Windows.
permission-import-export-tests.patch (4.6 KB) - added by psuter <petsuter@…> 12 months ago.
Unit tests fixed and added for permission import / export (based on permission-import-export2.patch)
permission-import-export-stdin-stdout.patch (8.4 KB) - added by psuter <petsuter@…> 12 months ago.
Allow importing from stdin and exporting to stdout
permission-import-export-unicode.patch (3.2 KB) - added by psuter <petsuter@…> 12 months ago.
Workaround csv library unicode issues (incomplete)
permission-import-export-unicode2.patch (5.3 KB) - added by psuter <petsuter@…> 11 months ago.
Fix unicode issues by using the stream's encoding.

Download all attachments as: .zip

Change History

comment:1 Changed 2 years ago by lkraav <leho@…>

  • Cc leho@… added

yes, just had a case where i needed this. following.

comment:2 Changed 2 years ago by anatoly techtonik <techtonik@…>

There is also invisible upvote arrow at the top of the page. I suppose it is like a typical Google star except that it probably does not subscribe.

comment:3 Changed 20 months ago by cboos

  • Milestone set to unscheduled

comment:4 Changed 14 months ago by thijstriemstra

  • Cc thijstriemstra added

comment:5 Changed 14 months ago by thijstriemstra

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #8489 it seems.

comment:6 Changed 14 months ago by rblank

  • Milestone unscheduled deleted

comment:7 Changed 14 months ago by anatoly techtonik <techtonik@…>

Not really a duplicate. #8489 is about transparent copy of permissions from one env to another. This proposal is to export to file/edit/then import from file.

comment:8 Changed 14 months ago by thijstriemstra

  • Resolution duplicate deleted
  • Status changed from closed to reopened

comment:9 Changed 12 months ago by cboos

  • Milestone set to unscheduled

… back to unscheduled then, please provide a patch.

Changed 12 months ago by psuter <petsuter@…>

CSV permission import and export trac-admin commands

comment:10 follow-up: Changed 12 months ago by psuter <petsuter@…>

  • Summary changed from trac-admin import/export permissions to [PATCH] trac-admin import/export permissions

The above patch adds commands trac-admin permission import <filename> and trac-admin permission export <filename> to import and export simple CSV files of user, action pair rows.

  • Is CSV a good idea?
  • The ''csv'' library documenteation notes some problems with Unicode input. I'm not sure what needs o be done here.
  • Importing a user, action pair that already exists in the DB results in a IntegrityError: columns username, action are not unique. I'm not sure how to best avoid this. Should this exception just be swallowed?
  • Command completion is not implemented. One could maybe suggest a list of existing files for import?

comment:11 in reply to: ↑ 10 Changed 12 months ago by rblank

Replying to psuter <petsuter@…>:

The above patch adds commands trac-admin permission import <filename> and trac-admin permission export <filename> to import and export simple CSV files of user, action pair rows.

Excellent, thanks for working on this!

My two cents:

  • Is CSV a good idea?

Reasonable, yes. I was going to suggest space-separated, but user names can have spaces IIRC, so that's a no go.

However, instead of using (user, perm) pairs on each line, I would write one line per user, structured as (user, perm1, perm2, perm3, …).

  • Importing a user, action pair that already exists in the DB results in a IntegrityError: columns username, action are not unique. I'm not sure how to best avoid this. Should this exception just be swallowed?

The command should succeed, but not by swallowing the exception, as it's DB backend-specific, but by checking if the permission is already granted before trying to insert it.

  • Command completion is not implemented. One could maybe suggest a list of existing files for import?

Yes, absolutely. Look at the wiki import command in trac.wiki.admin for an example how to do that (basically, use get_dir_list()).

Changed 12 months ago by psuter <petsuter@…>

one user per line; check existing perms; file completion

comment:12 follow-up: Changed 12 months ago by psuter <petsuter@…>

Thanks for the review & hints. I attached an updated patch that incorporates your suggestions.

Look at the wiki import command in trac.wiki.admin for an example how to do that (basically, use get_dir_list()).

I added this as well, but I can't seem to test it successfully. (On Windows, Python 2.7 with pyreadline 1.7) Command completion itself works; however path completion seems broken, even for e.g. wiki import.

comment:13 in reply to: ↑ 12 ; follow-ups: Changed 12 months ago by rblank

  • Milestone changed from unscheduled to 0.13
  • Owner set to rblank
  • Priority changed from normal to high
  • Status changed from reopened to new

Replying to psuter <petsuter@…>:

Thanks for the review & hints. I attached an updated patch that incorporates your suggestions.

Very good! I'll apply the patch shortly. If you want to get bonus points, you could add unit tests for the new commands (see trac/admin/tests/console.py and trac/admin/tests/console-tests.txt for inspiration).

I added this as well, but I can't seem to test it successfully. (On Windows, Python 2.7 with pyreadline 1.7) Command completion itself works; however path completion seems broken, even for e.g. wiki import.

Let me try… Yes, pyreadline seems to behave quite strangely indeed. I have a feeling that it's due to an incompatibility of pyreadline, but I may be wrong.

comment:14 in reply to: ↑ 13 Changed 12 months ago by psuter <petsuter@…>

The problem seems to be that shlex.split (called in trac.admin.console.TracAdmin arg_tokenize) doesn't like Windows paths. Trailing backslashes like shlex.split('C:\\') raise a ValueError: No escaped character; others get lost: shlex.split('C:\\Code\\Trac') evaluates to ['C:CodeTrac'] and matching fails.

One could use forward slashes instead, but os.path.join called in get_dir_list inserts and appends backslashes, so matching again fails. Matching with normalized strings in trac.admin.api.PathList using os.path.normcase helps marginally - the completion result still contains backslashes preventing further completion.

http://bugs.python.org/issue1724822

Changed 12 months ago by psuter <petsuter@…>

Improve trac-admin path completion on Windows.

comment:15 follow-up: Changed 12 months ago by psuter <petsuter@…>

Sorry if this is getting somewhat off-topic. The above patch seems to improve trac-admin's path tab completion on Windows for me.

comment:16 in reply to: ↑ 15 Changed 12 months ago by psuter <petsuter@…>

Replying to psuter <petsuter@…>:

The above patch seems to improve trac-admin's path tab completion on Windows for me.

Several unit tests fail with this patch applied, so it probably breaks some other things.

Changed 12 months ago by psuter <petsuter@…>

Unit tests fixed and added for permission import / export (based on permission-import-export2.patch)

comment:17 in reply to: ↑ 13 Changed 12 months ago by psuter <petsuter@…>

Replying to rblank:

If you want to get bonus points, you could add unit tests for the new commands (see trac/admin/tests/console.py and trac/admin/tests/console-tests.txt for inspiration).

Thanks again for the pointers. The above patch fixes the existing test_help_ok patch to include the help text for the two new commands, and adds a new test each for importing / exporting. Due to the nature of these commands I had to supply a filename, which I hardcoded as 'permissions.csv'.

(I noticed again that on Windows the file must be in the current directory, as for example shlex.split('C:\\Temp\\permissions.csv') evaluates to ['C:Temppermissions.csv'].)

comment:18 follow-up: Changed 12 months ago by rblank

permission-import-export2.patch and permission-import-export-tests.patch applied in [10714], with the following minor changes:

  • Added from __future__ import with_statement in trac/admin/tests/console.py.
  • Set the CSV writer to output with a platform-specific line terminator.
  • Sorted the export by user and each line by permission for test repeatability.
  • Used a single try: except: block in _do_import().
  • Used read_file() in the export test.

As you can tell, the changes are on the level of details, so great work!

Two possible extensions:

  • Allow using a single dash (-) as a file name for exporting to / importing from stdout / stdin (the same as for wiki export and wiki import). This should also allow getting rid of the temporary permissions.csv in the unit tests.
  • Allow specifying for which users to export permissions, by passing a list of users after the file name in permission export.

I'll have a look at the completion issue, but reading that ticket, it seems we will have to have our own copy of shlex.split(), at least for 2.5 (and the fix should go into 0.12.3).

comment:19 follow-up: Changed 12 months ago by rblank

trac-admin-completion-on-windows.patch indeed solves part of the issue with auto-completion, but it opens a can of worms. The failing tests are due to parsing in non-POSIX mode, where quoting doesn't operate the same, and the DB connection string when initializing functional tests is passed as 'sqlite:db/trac.db' (including the quotes).

I have the feeling that we should rather leave the parsing in POSIX mode, but simply disable escaping on Windows. Something like the following (in addition to your changes in api.py, which are fine):

  • trac/admin/console.py

    diff --git a/trac/admin/console.py b/trac/admin/console.py
    a b import cmd 
    1616import locale 
    1717import os.path 
    1818import pkg_resources 
    19 import shlex 
     19from shlex import shlex 
    2020import StringIO 
    2121import sys 
    2222import traceback 
    class TracAdmin(cmd.Cmd): 
    7171        try: 
    7272            import readline 
    7373            delims = readline.get_completer_delims() 
    74             for c in '-/:()': 
     74            for c in '-/:()\\': 
    7575                delims = delims.replace(c, '') 
    7676            readline.set_completer_delims(delims) 
    7777             
    Type: '?' or 'help' for help on command 
    182182 
    183183        ... but shlex is not unicode friendly. 
    184184        """ 
    185         return [unicode(token, 'utf-8') 
    186                 for token in shlex.split(argstr.encode('utf-8'))] or [''] 
     185        lex = shlex(argstr.encode('utf-8'), posix=True) 
     186        lex.whitespace_split = True 
     187        lex.commenters = '' 
     188        if os.name == 'nt': 
     189            lex.escape = '' 
     190        return [unicode(token, 'utf-8') for token in lex] or [''] 
    187191 
    188192    def word_complete(self, text, words): 
    189193        words = list(set(a for a in words if a.startswith(text))) 

This makes completion work on Windows for me. It still feels weird, as it completes correctly but doesn't display all choices when hitting tab twice. But this may be due to pyrealine.

comment:20 in reply to: ↑ 19 ; follow-up: Changed 12 months ago by psuter <petsuter@…>

Replying to rblank:

I have the feeling that we should rather leave the parsing in POSIX mode, but simply disable escaping on Windows. Something like […]
This makes completion work on Windows for me. It still feels weird, as it completes correctly but doesn't display all choices when hitting tab twice. But this may be due to pyrealine.

Sounds sensible. And works fine here, too, up to the same tab-twice issue. However, I could fix that by creating %HOMEPATH%\pyreadlineconfig.ini containing: show_all_if_ambiguous("on")

comment:21 in reply to: ↑ 18 ; follow-up: Changed 12 months ago by psuter <petsuter@…>

Replying to rblank:

applied in [10714], with the following minor changes: […]

Great.

  • Allow using a single dash (-) as a file name for exporting to / importing from stdout / stdin (the same as for wiki export and wiki import). This should also allow getting rid of the temporary permissions.csv in the unit tests.

Yes, sounds useful. I assume for the wiki commands this is handled by this code: if not filename: printout(text) and if filename: ... else: data = sys.stdin.read()? I can't seem to trigger that functionality using a dash (again a argument parsing problem on Windows?)

comment:22 in reply to: ↑ 21 ; follow-up: Changed 12 months ago by rblank

Replying to psuter <petsuter@…>:

Yes, sounds useful. I assume for the wiki commands this is handled by this code: if not filename: printout(text) and if filename: ... else: data = sys.stdin.read()? I can't seem to trigger that functionality using a dash (again a argument parsing problem on Windows?)

Yes, sorry, my bad. For the wiki commands, it is triggered by the absence of a path. We should probably do the same here… except then we cannot export the permissions of only a few users. That's ok, it probably isn't that useful anyway (and easy to implement with grep).

Changed 12 months ago by psuter <petsuter@…>

Allow importing from stdin and exporting to stdout

Changed 12 months ago by psuter <petsuter@…>

Workaround csv library unicode issues (incomplete)

comment:23 in reply to: ↑ 22 Changed 12 months ago by psuter <petsuter@…>

Replying to rblank:

it is triggered by the absence of a path. We should probably do the same here…

Ah of course, that makes sense. In the two patches above I gave this another try, and also experimented a bit with the suggested wrappers from the csv library documentation to work around the Unicode issues. (It seems to help, except when importing from stdin, but I maybe don't yet understand the problem enough to fix it properly.)

comment:24 follow-up: Changed 12 months ago by rblank

Unit test modifications from permission-import-export-stdin-stdout.patch were applied in [10715]. In the import and export commands, instead of using a closure to avoid code duplication, I added a context manager that opens a file if the filename is non-empty, or uses the standard stream corresponding to the file mode otherwise. This should be reusable for the wiki commands as well, once the encoding issues are sorted out.

When exporting or importing to / from the standard streams, we should actually use the stream's encoding, instead of forcing UTF-8. The logic should probably be very similar to what's used in console_print().

comment:25 in reply to: ↑ 20 Changed 12 months ago by rblank

Replying to psuter <petsuter@…>:

However, I could fix that by creating %HOMEPATH%\pyreadlineconfig.ini containing: show_all_if_ambiguous("on")

Heh, and it's even documented. Oh well, who reads the docs, anyway? :) Installing a proper pyreadlineconfig.ini makes completion work very nicely.

So, fix applied on 0.12-stable in [10716].

Changed 11 months ago by psuter <petsuter@…>

Fix unicode issues by using the stream's encoding.

comment:26 in reply to: ↑ 24 ; follow-up: Changed 11 months ago by psuter <petsuter@…>

Replying to rblank:

When exporting or importing to / from the standard streams, we should actually use the stream's encoding, instead of forcing UTF-8. The logic should probably be very similar to what's used in console_print().

I gave this another shot in the patch above and extracted the code you indicated into get_console_encoding(). Using that in permission import and permission export makes the unittests succeed for a test_userɑ.

comment:27 Changed 11 months ago by rblank

  • Resolution set to fixed
  • Status changed from new to closed

Works great. Applied in [10722], with a few cosmetic changes. So… we're done!

comment:28 Changed 11 months ago by rblank

  • Owner changed from rblank to psuter <petsuter@…>

comment:29 in reply to: ↑ 26 ; follow-up: Changed 11 months ago by cboos

Replying to psuter <petsuter@…>:

… the unittests succeed for a test_userɑ.

Great job, but note that non-ascii usernames in general are not yet fully supported (#6318).

comment:30 in reply to: ↑ 29 Changed 11 months ago by rblank

Replying to cboos:

but note that non-ascii usernames in general are not yet fully supported (#6318).

Right, but at least this part of the code will be ready ;)

comment:31 Changed 10 months ago by psuter

  • Owner changed from psuter <petsuter@…> to psuter

comment:32 Changed 5 months ago by al.willmer@…

  • Release Notes modified (diff)
View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
to The owner will be changed from psuter. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.