summaryrefslogtreecommitdiff
path: root/foundry/test_router.py
diff options
context:
space:
mode:
Diffstat (limited to 'foundry/test_router.py')
-rw-r--r--foundry/test_router.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/foundry/test_router.py b/foundry/test_router.py
new file mode 100644
index 0000000..15e97fd
--- /dev/null
+++ b/foundry/test_router.py
@@ -0,0 +1,159 @@
1from router import Router, Resource
2from router import JSONRenderer, HTMLRenderer, XMLRenderer, AtomRenderer
3
4
5router = Router()
6
7# Add Renderers
8router.add_renderer(JSONRenderer, default=True)
9router.add_renderer(HTMLRenderer)
10router.add_renderer(AtomRenderer)
11
12router.add_auth_source(DbAuthenticator('users.db'))
13router.add_authenz_source(DbAuthorizor('users.db'))
14
15revision_spec = FragmentSpec(required=False, default='tip',
16 regex='(tip|[0-9a-zA-Z]+)')
17
18# Add Resource Mappings
19Route('/{project_name}', ProjectSummaryResource, [
20 Route('/summary', ProjectSummaryResource),
21 Route('/shortlog/{revision}', ShortLogResource,
22 uri_spec={ 'revision': revision_spec }),
23 Route('/graph/{revision}', GraphResource,
24 uri_spec={ 'revision': revision_spec }),
25 Route('/raw-rev/{revision}', RawRevisionResource,
26 uri_spec={ 'revision': revision_spec }),
27 Route('/tags', TagsResource),
28 Route('/annotate/{revision}/{filename}', AnnotateResource,
29 uri_spec={ 'revision': revision_spec,
30 'filename': FragmentSpec(required=False) }),
31 Route(('/diff/{revision}/{filename}', '/filediff/{revision}/{filename}'),
32 DiffResource,
33 uri_spec={ 'revision': revision_spec,
34 'filename': FragmentSpec(required=False) }),
35 Route('/raw-file/{revision}/{filename}', RawFileResource,
36 uri_spec={ 'revision': revision_spec,
37 'filename': FragmentSpec(required=False) }),
38 Route('/branches', BranchesResource),
39 Route('/archive/{revision}.tar.{format}', ArchiveResource,
40 uri_spec={ 'revision': FragmentSpec(regex='(tip|[0-9a-zA-Z]+)'),
41 'format': FragmentSpec(value_list=('gz', 'bz2') }),
42 Route(('/rev/{revision}','/changeset/{revision}'), RevisionResource,
43 uri_spec={ 'revision': revision_spec }),
44 Route(('/log/{revision}', '/changelog/{revision}', '/filelog/{revision}'),
45 LogResource,
46 uri_spec={ 'revision': revision_spec }),
47 Route('/file/{revision}/{filename}', FileResource,
48 uri_spec={ 'revision': revision_spec,
49 'filename': FragmentSpec(required=False) }),
50 ])
51
52
53class constant(object):
54 """
55 Constant descriptor to provide a level of protection against
56 changes to constants in class instances. Does not prevent
57 changes directly to constants in non-instances.
58 """
59
60 def __init__(self, value):
61 self.value = value
62
63 def __get__(self, instance, owner):
64 return self.value
65
66 def __set__(self, instance, value):
67 raise ValueError('Can not assign to constant.')
68
69 def __delete__(self, instance):
70 raise ValueError('Can not delete constant.')
71
72
73class Route(object):
74
75 # ----------------------------------------------------------------
76 # Constants
77 # ----------------------------------------------------------------
78 REDIRECT = constant('redirect')
79 FAILURE = constant('failure')
80
81 # ----------------------------------------------------------------
82 # Required Parameters
83 # ----------------------------------------------------------------
84
85 #: Part of the URI that will map to this route
86 uri_part = None
87
88 #: Resource existing at this route
89 resource = None
90
91 #: Resource requires that the user is using an HTTPS connection
92 #: can be True, False, REDIRECT or FAILRE. If True and no HTTPS
93 #: the route will fail to match. If REDIRECT and no HTTPS the
94 #: client will be redirect to the secure version of the resouce.
95 #: If FAILURE a 403 (Forbidden) error will be returned to the
96 #: client.
97 https = False
98
99 #: Route requires authentication
100 requires_authentication = True
101
102 # ----------------------------------------------------------------
103 # Optional, if unspecified these will not be used
104 # ----------------------------------------------------------------
105
106 #: Dictionary of uri fragment names to FragmentSpec objects used
107 #: to validate the individual uri fragments
108 uri_spec = None
109
110 #: Callable or list of callables to which the matching resouce
111 #: and context will be passed, the first failure will cause the
112 #: route to not match.
113 conditions = None
114
115 #: Type of permission required. The router doesn't care what
116 #: this object is as long as the security system understands it
117 permissions_required = None
118
119 # ----------------------------------------------------------------
120 # Optional, if unspecified these will use the router defaults
121 # ----------------------------------------------------------------
122 #: List of content-types supported by this route
123 content_types = None
124
125 #: Source for authentication
126 auth_source = None
127
128 #: Source for authorization
129 authz_source = None
130
131
132class FragmentSpec(object):
133
134 #: Indicates if the framgent is required
135 required = True
136
137 #: Regex used to check if the fragment is valid if specified
138 #: value_list may not be specified.
139 regex = r'.*'
140
141 #: Optional list of acceptable values. May not be specified
142 #: with regex
143 value_list = None
144
145 #: Default value if the user provides no value
146 default = None
147
148
149class NotSupported(object):
150 pass
151
152
153class Resource(object):
154
155 GET = NotSupported()
156 POST = NotSupported()
157 HEAD = NotSupported()
158 PUT = NotSupported()
159 DELETE = NotSupported()