Show More
@@ -24,9 +24,11 b' Base module for all VCS systems' | |||||
24 |
|
24 | |||
25 | import collections |
|
25 | import collections | |
26 | import datetime |
|
26 | import datetime | |
|
27 | import fnmatch | |||
27 | import itertools |
|
28 | import itertools | |
28 | import logging |
|
29 | import logging | |
29 | import os |
|
30 | import os | |
|
31 | import re | |||
30 | import time |
|
32 | import time | |
31 | import warnings |
|
33 | import warnings | |
32 |
|
34 | |||
@@ -1633,9 +1635,60 b' class DiffChunk(object):' | |||||
1633 |
|
1635 | |||
1634 | class BasePathPermissionChecker(object): |
|
1636 | class BasePathPermissionChecker(object): | |
1635 |
|
1637 | |||
1636 | def __init__(self, username, has_full_access = False): |
|
1638 | @staticmethod | |
1637 | self.username = username |
|
1639 | def create_from_patterns(includes, excludes): | |
1638 | self.has_full_access = has_full_access |
|
1640 | if includes and '*' in includes and not excludes: | |
|
1641 | return AllPathPermissionChecker() | |||
|
1642 | elif excludes and '*' in excludes: | |||
|
1643 | return NonePathPermissionChecker() | |||
|
1644 | else: | |||
|
1645 | return PatternPathPermissionChecker(includes, excludes) | |||
|
1646 | ||||
|
1647 | @property | |||
|
1648 | def has_full_access(self): | |||
|
1649 | raise NotImplemented() | |||
1639 |
|
1650 | |||
1640 | def has_access(self, path): |
|
1651 | def has_access(self, path): | |
1641 | raise NotImplemented() |
|
1652 | raise NotImplemented() | |
|
1653 | ||||
|
1654 | ||||
|
1655 | class AllPathPermissionChecker(BasePathPermissionChecker): | |||
|
1656 | ||||
|
1657 | @property | |||
|
1658 | def has_full_access(self): | |||
|
1659 | return True | |||
|
1660 | ||||
|
1661 | def has_access(self, path): | |||
|
1662 | return True | |||
|
1663 | ||||
|
1664 | ||||
|
1665 | class NonePathPermissionChecker(BasePathPermissionChecker): | |||
|
1666 | ||||
|
1667 | @property | |||
|
1668 | def has_full_access(self): | |||
|
1669 | return False | |||
|
1670 | ||||
|
1671 | def has_access(self, path): | |||
|
1672 | return False | |||
|
1673 | ||||
|
1674 | ||||
|
1675 | class PatternPathPermissionChecker(BasePathPermissionChecker): | |||
|
1676 | ||||
|
1677 | def __init__(self, includes, excludes): | |||
|
1678 | self.includes = includes | |||
|
1679 | self.excludes = excludes | |||
|
1680 | self.includes_re = [] if not includes else [re.compile(fnmatch.translate(pattern)) for pattern in includes] | |||
|
1681 | self.excludes_re = [] if not excludes else [re.compile(fnmatch.translate(pattern)) for pattern in excludes] | |||
|
1682 | ||||
|
1683 | @property | |||
|
1684 | def has_full_access(self): | |||
|
1685 | return '*' in self.includes and not self.excludes | |||
|
1686 | ||||
|
1687 | def has_access(self, path): | |||
|
1688 | for re in self.excludes_re: | |||
|
1689 | if re.match(path): | |||
|
1690 | return False | |||
|
1691 | for re in self.includes_re: | |||
|
1692 | if re.match(path): | |||
|
1693 | return True | |||
|
1694 | return False No newline at end of file |
@@ -21,7 +21,7 b'' | |||||
21 | """ |
|
21 | """ | |
22 | HG repository module |
|
22 | HG repository module | |
23 | """ |
|
23 | """ | |
24 |
|
24 | import ConfigParser | ||
25 | import logging |
|
25 | import logging | |
26 | import binascii |
|
26 | import binascii | |
27 | import os |
|
27 | import os | |
@@ -38,7 +38,7 b' from rhodecode.lib.utils import safe_uni' | |||||
38 | from rhodecode.lib.vcs import connection |
|
38 | from rhodecode.lib.vcs import connection | |
39 | from rhodecode.lib.vcs.backends.base import ( |
|
39 | from rhodecode.lib.vcs.backends.base import ( | |
40 | BaseRepository, CollectionGenerator, Config, MergeResponse, |
|
40 | BaseRepository, CollectionGenerator, Config, MergeResponse, | |
41 | MergeFailureReason, Reference) |
|
41 | MergeFailureReason, Reference, BasePathPermissionChecker) | |
42 | from rhodecode.lib.vcs.backends.hg.commit import MercurialCommit |
|
42 | from rhodecode.lib.vcs.backends.hg.commit import MercurialCommit | |
43 | from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff |
|
43 | from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff | |
44 | from rhodecode.lib.vcs.backends.hg.inmemory import MercurialInMemoryCommit |
|
44 | from rhodecode.lib.vcs.backends.hg.inmemory import MercurialInMemoryCommit | |
@@ -891,6 +891,33 b' class MercurialRepository(BaseRepository' | |||||
891 | self._remote.bookmark(bookmark, revision=revision) |
|
891 | self._remote.bookmark(bookmark, revision=revision) | |
892 | self._remote.invalidate_vcs_cache() |
|
892 | self._remote.invalidate_vcs_cache() | |
893 |
|
893 | |||
|
894 | def get_path_permissions(self, username): | |||
|
895 | hgacl_file = self.path + '/.hg/hgacl' | |||
|
896 | if os.path.exists(hgacl_file): | |||
|
897 | hgacl = ConfigParser.RawConfigParser() | |||
|
898 | hgacl.read(hgacl_file) | |||
|
899 | def read_patterns(suffix): | |||
|
900 | svalue = None | |||
|
901 | try: | |||
|
902 | svalue = hgacl.get('narrowhgacl', username + suffix) | |||
|
903 | except ConfigParser.NoOptionError: | |||
|
904 | try: | |||
|
905 | svalue = hgacl.get('narrowhgacl', 'default' + suffix) | |||
|
906 | except ConfigParser.NoOptionError: | |||
|
907 | pass | |||
|
908 | if not svalue: | |||
|
909 | return None | |||
|
910 | result = ['/'] | |||
|
911 | for pattern in svalue.split(): | |||
|
912 | result.append(pattern) | |||
|
913 | if '*' not in pattern and '?' not in pattern: | |||
|
914 | result.append(pattern + '/*') | |||
|
915 | return result | |||
|
916 | includes = read_patterns('.includes') | |||
|
917 | excludes = read_patterns('.excludes') | |||
|
918 | return BasePathPermissionChecker.create_from_patterns(includes, excludes) | |||
|
919 | else: | |||
|
920 | return None | |||
894 |
|
921 | |||
895 | class MercurialIndexBasedCollectionGenerator(CollectionGenerator): |
|
922 | class MercurialIndexBasedCollectionGenerator(CollectionGenerator): | |
896 |
|
923 |
General Comments 0
You need to be logged in to leave comments.
Login now