forked from quay/quay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
path_converters.py
119 lines (90 loc) · 3.57 KB
/
path_converters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from werkzeug.routing import BaseConverter
import features
class QuayBaseConverter(BaseConverter):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
if "part_isolating" not in cls.__dict__:
cls.part_isolating = "/" not in cls.regex
class APIRepositoryPathConverter(QuayBaseConverter):
"""
Converter for handling repository paths.
Does not handle library paths.
"""
def __init__(self, url_map):
super().__init__(url_map)
self.weight = 200
self.regex = r"([^/]+(/[^/]+)+)"
# TODO(kleesc): Remove after fully deprecating V1 push/pull
class V1CreateRepositoryPathConverter(QuayBaseConverter):
"""
Converter for handling PUT repository path.
Handles both library and non-library paths (if configured).
This is needed so that v1.create_repository does not match possibly
nested path from other routes.
For example:
PUT /repositories/<repopath:repository>/tags/<tag> when no tag is given
should 404, and not fallback to v1.create_repository route.
"""
def __init__(self, url_map):
super().__init__(url_map)
self.weight = 200
if features.LIBRARY_SUPPORT:
# Allow names without namespaces.
self.regex = r"[^/]+(/[^/]+)*(?<!auth)(?<!tags)(?<!images)"
else:
self.regex = r"([^/]+(/[^/]+)+)(?<!auth)(?<!tags)(?<!images)"
class RepositoryPathConverter(QuayBaseConverter):
"""
Converter for handling repository paths.
Handles both library and non-library paths (if configured).
Supports names with or without slashes (nested paths).
"""
def __init__(self, url_map):
super().__init__(url_map)
self.weight = 200
if features.LIBRARY_SUPPORT:
# Allow names without namespaces.
self.regex = r"[^/]+(/[^/]+)*"
else:
self.regex = r"([^/]+(/[^/]+)+)"
class RegexConverter(QuayBaseConverter):
"""
Converter for handling custom regular expression patterns in paths.
"""
def __init__(self, url_map, regex_value):
super().__init__(url_map)
self.regex = regex_value
class RepositoryPathRedirectConverter(QuayBaseConverter):
"""
Converter for handling redirect paths that don't match any other routes.
This needs to be separate from RepositoryPathConverter with the updated regex for
extended repo names support, otherwise, a nonexistent repopath resource would fallback
to redirecting to the repository web route.
For example:
/v2/devtable/testrepo/nested/manifests/somedigest" would previously have (correctly) returned
a 404, due to the path not matching any routes. With the regex supporting nested path for extended
repo names, Werkzeug would now (incorrectly) match to redirect to the web page of a repository with
the above path. See endpoints.web.redirect_to_repository.
"""
RESERVED_PREFIXES = [
"v1/",
"v2/",
"cnr/",
"customtrigger/setup/",
"bitbucket/setup/",
"repository/",
"github/callback/trigger/",
"push/",
]
def __init__(self, url_map):
super().__init__(url_map)
self.weight = 200
if features.LIBRARY_SUPPORT:
# Allow names without namespaces.
self.regex = r"(?!{})[^/]+(/[^/]+)*".format(
"|".join(RepositoryPathRedirectConverter.RESERVED_PREFIXES)
)
else:
self.regex = r"((?!{})[^/]+(/[^/]+)+)".format(
"|".join(RepositoryPathRedirectConverter.RESERVED_PREFIXES)
)