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
Change History
comment:1 Changed 2 years ago by lkraav <leho@…>
- Cc leho@… added
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: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@…>
- Attachment permission-import-export.patch added
CSV permission import and export trac-admin commands
comment:10 follow-up: ↓ 11 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@…>
- Attachment permission-import-export2.patch added
one user per line; check existing perms; file completion
comment:12 follow-up: ↓ 13 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: ↓ 14 ↓ 17 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.
Changed 12 months ago by psuter <petsuter@…>
- Attachment trac-admin-completion-on-windows.patch added
Improve trac-admin path completion on Windows.
comment:15 follow-up: ↓ 16 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@…>
- Attachment permission-import-export-tests.patch added
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: ↓ 21 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: ↓ 20 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 16 16 import locale 17 17 import os.path 18 18 import pkg_resources 19 import shlex19 from shlex import shlex 20 20 import StringIO 21 21 import sys 22 22 import traceback … … class TracAdmin(cmd.Cmd): 71 71 try: 72 72 import readline 73 73 delims = readline.get_completer_delims() 74 for c in '-/:() ':74 for c in '-/:()\\': 75 75 delims = delims.replace(c, '') 76 76 readline.set_completer_delims(delims) 77 77 … … Type: '?' or 'help' for help on command 182 182 183 183 ... but shlex is not unicode friendly. 184 184 """ 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 [''] 187 191 188 192 def word_complete(self, text, words): 189 193 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: ↓ 25 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: ↓ 22 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: ↓ 23 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@…>
- Attachment permission-import-export-stdin-stdout.patch added
Allow importing from stdin and exporting to stdout
Changed 12 months ago by psuter <petsuter@…>
- Attachment permission-import-export-unicode.patch added
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: ↓ 26 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@…>
- Attachment permission-import-export-unicode2.patch added
Fix unicode issues by using the stream's encoding.
comment:26 in reply to: ↑ 24 ; follow-up: ↓ 29 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: ↓ 30 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
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)



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