diff options
Diffstat (limited to 'foundry/test_router.py')
-rw-r--r-- | foundry/test_router.py | 159 |
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 @@ | |||
1 | from router import Router, Resource | ||
2 | from router import JSONRenderer, HTMLRenderer, XMLRenderer, AtomRenderer | ||
3 | |||
4 | |||
5 | router = Router() | ||
6 | |||
7 | # Add Renderers | ||
8 | router.add_renderer(JSONRenderer, default=True) | ||
9 | router.add_renderer(HTMLRenderer) | ||
10 | router.add_renderer(AtomRenderer) | ||
11 | |||
12 | router.add_auth_source(DbAuthenticator('users.db')) | ||
13 | router.add_authenz_source(DbAuthorizor('users.db')) | ||
14 | |||
15 | revision_spec = FragmentSpec(required=False, default='tip', | ||
16 | regex='(tip|[0-9a-zA-Z]+)') | ||
17 | |||
18 | # Add Resource Mappings | ||
19 | Route('/{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 | |||
53 | class 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 | |||
73 | class 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 | |||
132 | class 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 | |||
149 | class NotSupported(object): | ||
150 | pass | ||
151 | |||
152 | |||
153 | class Resource(object): | ||
154 | |||
155 | GET = NotSupported() | ||
156 | POST = NotSupported() | ||
157 | HEAD = NotSupported() | ||
158 | PUT = NotSupported() | ||
159 | DELETE = NotSupported() | ||